diff --git a/.github/DISCUSSION_TEMPLATE/questions.yml b/.github/DISCUSSION_TEMPLATE/questions.yml
new file mode 100644
index 000000000..98424a341
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/questions.yml
@@ -0,0 +1,158 @@
+labels: [question]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your interest in FastAPI! 🚀
+
+ Please follow these instructions, fill every question, and do every step. 🙏
+
+ I'm asking this because answering questions and solving problems in GitHub is what consumes most of the time.
+
+ I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling questions.
+
+ All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
+
+ That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
+
+ By asking questions in a structured way (following this) it will be much easier to help you.
+
+ And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
+
+ As there are too many questions, I'll have to discard and close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
+ - type: checkboxes
+ id: checks
+ attributes:
+ label: First Check
+ description: Please confirm and check all the following options.
+ options:
+ - label: I added a very descriptive title here.
+ required: true
+ - label: I used the GitHub search to find a similar question and didn't find it.
+ required: true
+ - label: I searched the FastAPI documentation, with the integrated search.
+ required: true
+ - label: I already searched in Google "How to X in FastAPI" and didn't find any information.
+ required: true
+ - label: I already read and followed all the tutorial in the docs and didn't find an answer.
+ required: true
+ - label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/pydantic/pydantic).
+ required: true
+ - label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
+ required: true
+ - label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
+ required: true
+ - type: checkboxes
+ id: help
+ attributes:
+ label: Commit to Help
+ description: |
+ After submitting this, I commit to one of:
+
+ * Read open questions until I find 2 where I can help someone and add a comment to help there.
+ * I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
+ * Review one Pull Request by downloading the code and following [all the review process](https://fastapi.tiangolo.com/help-fastapi/#review-pull-requests).
+
+ options:
+ - label: I commit to help with one of those options 👆
+ required: true
+ - type: textarea
+ id: example
+ attributes:
+ label: Example Code
+ description: |
+ Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
+
+ If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
+
+ placeholder: |
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+
+ @app.get("/")
+ def read_root():
+ return {"Hello": "World"}
+ render: python
+ validations:
+ required: true
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: |
+ What is the problem, question, or error?
+
+ Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
+ placeholder: |
+ * Open the browser and call the endpoint `/`.
+ * It returns a JSON with `{"Hello": "World"}`.
+ * But I expected it to return `{"Hello": "Sara"}`.
+ validations:
+ required: true
+ - type: dropdown
+ id: os
+ attributes:
+ label: Operating System
+ description: What operating system are you on?
+ multiple: true
+ options:
+ - Linux
+ - Windows
+ - macOS
+ - Other
+ validations:
+ required: true
+ - type: textarea
+ id: os-details
+ attributes:
+ label: Operating System Details
+ description: You can add more details about your operating system here, in particular if you chose "Other".
+ - type: input
+ id: fastapi-version
+ attributes:
+ label: FastAPI Version
+ description: |
+ What FastAPI version are you using?
+
+ You can find the FastAPI version with:
+
+ ```bash
+ python -c "import fastapi; print(fastapi.__version__)"
+ ```
+ validations:
+ required: true
+ - type: input
+ id: pydantic-version
+ attributes:
+ label: Pydantic Version
+ description: |
+ What Pydantic version are you using?
+
+ You can find the Pydantic version with:
+
+ ```bash
+ python -c "import pydantic; print(pydantic.version.VERSION)"
+ ```
+ validations:
+ required: true
+ - type: input
+ id: python-version
+ attributes:
+ label: Python Version
+ description: |
+ What Python version are you using?
+
+ You can find the Python version with:
+
+ ```bash
+ python --version
+ ```
+ validations:
+ required: true
+ - type: textarea
+ id: context
+ attributes:
+ label: Additional Context
+ description: Add any additional context information or screenshots you think are useful.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 55749398f..fd9f3b11c 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -2,3 +2,15 @@ blank_issues_enabled: false
contact_links:
- name: Security Contact
about: Please report security vulnerabilities to security@tiangolo.com
+ - name: Question or Problem
+ about: Ask a question or ask about a problem in GitHub Discussions.
+ url: https://github.com/fastapi/fastapi/discussions/categories/questions
+ - name: Feature Request
+ about: To suggest an idea or ask about a feature, please start with a question saying what you would like to achieve. There might be a way to do it already.
+ url: https://github.com/fastapi/fastapi/discussions/categories/questions
+ - name: Show and tell
+ about: Show what you built with FastAPI or to be used with FastAPI.
+ url: https://github.com/fastapi/fastapi/discussions/categories/show-and-tell
+ - name: Translations
+ about: Coordinate translations in GitHub Discussions.
+ url: https://github.com/fastapi/fastapi/discussions/categories/translations
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
deleted file mode 100644
index 322b6536a..000000000
--- a/.github/ISSUE_TEMPLATE/feature-request.yml
+++ /dev/null
@@ -1,181 +0,0 @@
-name: Feature Request
-description: Suggest an idea or ask for a feature that you would like to have in FastAPI
-labels: [enhancement]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for your interest in FastAPI! 🚀
-
- Please follow these instructions, fill every question, and do every step. 🙏
-
- I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the time.
-
- I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling issues.
-
- All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
-
- That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
-
- By asking questions in a structured way (following this) it will be much easier to help you.
-
- And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
-
- As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
- - type: checkboxes
- id: checks
- attributes:
- label: First Check
- description: Please confirm and check all the following options.
- options:
- - label: I added a very descriptive title to this issue.
- required: true
- - label: I used the GitHub search to find a similar issue and didn't find it.
- required: true
- - label: I searched the FastAPI documentation, with the integrated search.
- required: true
- - label: I already searched in Google "How to X in FastAPI" and didn't find any information.
- required: true
- - label: I already read and followed all the tutorial in the docs and didn't find an answer.
- required: true
- - label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
- required: true
- - label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
- required: true
- - label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
- required: true
- - type: checkboxes
- id: help
- attributes:
- label: Commit to Help
- description: |
- After submitting this, I commit to one of:
-
- * Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
- * I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
- * Implement a Pull Request for a confirmed bug.
-
- options:
- - label: I commit to help with one of those options 👆
- required: true
- - type: textarea
- id: example
- attributes:
- label: Example Code
- description: |
- Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
-
- If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
-
- placeholder: |
- from fastapi import FastAPI
-
- app = FastAPI()
-
-
- @app.get("/")
- def read_root():
- return {"Hello": "World"}
- render: python
- validations:
- required: true
- - type: textarea
- id: description
- attributes:
- label: Description
- description: |
- What is your feature request?
-
- Write a short description telling me what you are trying to solve and what you are currently doing.
- placeholder: |
- * Open the browser and call the endpoint `/`.
- * It returns a JSON with `{"Hello": "World"}`.
- * I would like it to have an extra parameter to teleport me to the moon and back.
- validations:
- required: true
- - type: textarea
- id: wanted-solution
- attributes:
- label: Wanted Solution
- description: |
- Tell me what's the solution you would like.
- placeholder: |
- I would like it to have a `teleport_to_moon` parameter that defaults to `False`, and can be set to `True` to teleport me.
- validations:
- required: true
- - type: textarea
- id: wanted-code
- attributes:
- label: Wanted Code
- description: Show me an example of how you would want the code to look like.
- placeholder: |
- from fastapi import FastAPI
-
- app = FastAPI()
-
-
- @app.get("/", teleport_to_moon=True)
- def read_root():
- return {"Hello": "World"}
- render: python
- validations:
- required: true
- - type: textarea
- id: alternatives
- attributes:
- label: Alternatives
- description: |
- Tell me about alternatives you've considered.
- placeholder: |
- To wait for Space X moon travel plans to drop down long after they release them. But I would rather teleport.
- - type: dropdown
- id: os
- attributes:
- label: Operating System
- description: What operating system are you on?
- multiple: true
- options:
- - Linux
- - Windows
- - macOS
- - Other
- validations:
- required: true
- - type: textarea
- id: os-details
- attributes:
- label: Operating System Details
- description: You can add more details about your operating system here, in particular if you chose "Other".
- - type: input
- id: fastapi-version
- attributes:
- label: FastAPI Version
- description: |
- What FastAPI version are you using?
-
- You can find the FastAPI version with:
-
- ```bash
- python -c "import fastapi; print(fastapi.__version__)"
- ```
- validations:
- required: true
- - type: input
- id: python-version
- attributes:
- label: Python Version
- description: |
- What Python version are you using?
-
- You can find the Python version with:
-
- ```bash
- python --version
- ```
- validations:
- required: true
- - type: textarea
- id: context
- attributes:
- label: Additional Context
- description: Add any additional context information or screenshots you think are useful.
diff --git a/.github/ISSUE_TEMPLATE/privileged.yml b/.github/ISSUE_TEMPLATE/privileged.yml
new file mode 100644
index 000000000..2b85eb310
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/privileged.yml
@@ -0,0 +1,22 @@
+name: Privileged
+description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. 👇
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your interest in FastAPI! 🚀
+
+ If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions) instead.
+ - type: checkboxes
+ id: privileged
+ attributes:
+ label: Privileged issue
+ description: Confirm that you are allowed to create an issue here.
+ options:
+ - label: I'm @tiangolo or he asked me directly to create an issue here.
+ required: true
+ - type: textarea
+ id: content
+ attributes:
+ label: Issue Content
+ description: Add the content of the issue here.
diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
deleted file mode 100644
index 3b16b4ad0..000000000
--- a/.github/ISSUE_TEMPLATE/question.yml
+++ /dev/null
@@ -1,146 +0,0 @@
-name: Question or Problem
-description: Ask a question or ask about a problem
-labels: [question]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for your interest in FastAPI! 🚀
-
- Please follow these instructions, fill every question, and do every step. 🙏
-
- I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the time.
-
- I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling issues.
-
- All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
-
- That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
-
- By asking questions in a structured way (following this) it will be much easier to help you.
-
- And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
-
- As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
- - type: checkboxes
- id: checks
- attributes:
- label: First Check
- description: Please confirm and check all the following options.
- options:
- - label: I added a very descriptive title to this issue.
- required: true
- - label: I used the GitHub search to find a similar issue and didn't find it.
- required: true
- - label: I searched the FastAPI documentation, with the integrated search.
- required: true
- - label: I already searched in Google "How to X in FastAPI" and didn't find any information.
- required: true
- - label: I already read and followed all the tutorial in the docs and didn't find an answer.
- required: true
- - label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
- required: true
- - label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
- required: true
- - label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
- required: true
- - type: checkboxes
- id: help
- attributes:
- label: Commit to Help
- description: |
- After submitting this, I commit to one of:
-
- * Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
- * I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
- * Implement a Pull Request for a confirmed bug.
-
- options:
- - label: I commit to help with one of those options 👆
- required: true
- - type: textarea
- id: example
- attributes:
- label: Example Code
- description: |
- Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
-
- If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
-
- placeholder: |
- from fastapi import FastAPI
-
- app = FastAPI()
-
-
- @app.get("/")
- def read_root():
- return {"Hello": "World"}
- render: python
- validations:
- required: true
- - type: textarea
- id: description
- attributes:
- label: Description
- description: |
- What is the problem, question, or error?
-
- Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
- placeholder: |
- * Open the browser and call the endpoint `/`.
- * It returns a JSON with `{"Hello": "World"}`.
- * But I expected it to return `{"Hello": "Sara"}`.
- validations:
- required: true
- - type: dropdown
- id: os
- attributes:
- label: Operating System
- description: What operating system are you on?
- multiple: true
- options:
- - Linux
- - Windows
- - macOS
- - Other
- validations:
- required: true
- - type: textarea
- id: os-details
- attributes:
- label: Operating System Details
- description: You can add more details about your operating system here, in particular if you chose "Other".
- - type: input
- id: fastapi-version
- attributes:
- label: FastAPI Version
- description: |
- What FastAPI version are you using?
-
- You can find the FastAPI version with:
-
- ```bash
- python -c "import fastapi; print(fastapi.__version__)"
- ```
- validations:
- required: true
- - type: input
- id: python-version
- attributes:
- label: Python Version
- description: |
- What Python version are you using?
-
- You can find the Python version with:
-
- ```bash
- python --version
- ```
- validations:
- required: true
- - type: textarea
- id: context
- attributes:
- label: Additional Context
- description: Add any additional context information or screenshots you think are useful.
diff --git a/.github/actions/comment-docs-preview-in-pr/Dockerfile b/.github/actions/comment-docs-preview-in-pr/Dockerfile
deleted file mode 100644
index 4f20c5f10..000000000
--- a/.github/actions/comment-docs-preview-in-pr/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM python:3.7
-
-RUN pip install httpx "pydantic==1.5.1" pygithub
-
-COPY ./app /app
-
-CMD ["python", "/app/main.py"]
diff --git a/.github/actions/comment-docs-preview-in-pr/action.yml b/.github/actions/comment-docs-preview-in-pr/action.yml
deleted file mode 100644
index 0eb64402d..000000000
--- a/.github/actions/comment-docs-preview-in-pr/action.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: Comment Docs Preview in PR
-description: Comment with the docs URL preview in the PR
-author: Sebastián Ramírez
-inputs:
- token:
- description: Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}
- required: true
- deploy_url:
- description: The deployment URL to comment in the PR
- required: true
-runs:
- using: docker
- image: Dockerfile
diff --git a/.github/actions/comment-docs-preview-in-pr/app/main.py b/.github/actions/comment-docs-preview-in-pr/app/main.py
deleted file mode 100644
index 68914fdb9..000000000
--- a/.github/actions/comment-docs-preview-in-pr/app/main.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import logging
-import sys
-from pathlib import Path
-from typing import Union
-
-import httpx
-from github import Github
-from github.PullRequest import PullRequest
-from pydantic import BaseModel, BaseSettings, SecretStr, ValidationError
-
-github_api = "https://api.github.com"
-
-
-class Settings(BaseSettings):
- github_repository: str
- github_event_path: Path
- github_event_name: Union[str, None] = None
- input_token: SecretStr
- input_deploy_url: str
-
-
-class PartialGithubEventHeadCommit(BaseModel):
- id: str
-
-
-class PartialGithubEventWorkflowRun(BaseModel):
- head_commit: PartialGithubEventHeadCommit
-
-
-class PartialGithubEvent(BaseModel):
- workflow_run: PartialGithubEventWorkflowRun
-
-
-if __name__ == "__main__":
- logging.basicConfig(level=logging.INFO)
- settings = Settings()
- logging.info(f"Using config: {settings.json()}")
- g = Github(settings.input_token.get_secret_value())
- repo = g.get_repo(settings.github_repository)
- try:
- event = PartialGithubEvent.parse_file(settings.github_event_path)
- except ValidationError as e:
- logging.error(f"Error parsing event file: {e.errors()}")
- sys.exit(0)
- use_pr: Union[PullRequest, None] = None
- for pr in repo.get_pulls():
- if pr.head.sha == event.workflow_run.head_commit.id:
- use_pr = pr
- break
- if not use_pr:
- logging.error(f"No PR found for hash: {event.workflow_run.head_commit.id}")
- sys.exit(0)
- github_headers = {
- "Authorization": f"token {settings.input_token.get_secret_value()}"
- }
- url = f"{github_api}/repos/{settings.github_repository}/issues/{use_pr.number}/comments"
- logging.info(f"Using comments URL: {url}")
- response = httpx.post(
- url,
- headers=github_headers,
- json={
- "body": f"📝 Docs preview for commit {use_pr.head.sha} at: {settings.input_deploy_url}"
- },
- )
- if not (200 <= response.status_code <= 300):
- logging.error(f"Error posting comment: {response.text}")
- sys.exit(1)
- logging.info("Finished")
diff --git a/.github/actions/notify-translations/Dockerfile b/.github/actions/notify-translations/Dockerfile
deleted file mode 100644
index fa4197e6a..000000000
--- a/.github/actions/notify-translations/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM python:3.7
-
-RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
-
-COPY ./app /app
-
-CMD ["python", "/app/main.py"]
diff --git a/.github/actions/notify-translations/action.yml b/.github/actions/notify-translations/action.yml
deleted file mode 100644
index c3579977c..000000000
--- a/.github/actions/notify-translations/action.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: "Notify Translations"
-description: "Notify in the issue for a translation when there's a new PR available"
-author: "Sebastián Ramírez "
-inputs:
- token:
- description: 'Token, to read the GitHub API. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
- required: true
-runs:
- using: 'docker'
- image: 'Dockerfile'
diff --git a/.github/actions/notify-translations/app/main.py b/.github/actions/notify-translations/app/main.py
deleted file mode 100644
index d4ba0ecfc..000000000
--- a/.github/actions/notify-translations/app/main.py
+++ /dev/null
@@ -1,104 +0,0 @@
-import logging
-import random
-import time
-from pathlib import Path
-from typing import Dict, Union
-
-import yaml
-from github import Github
-from pydantic import BaseModel, BaseSettings, SecretStr
-
-awaiting_label = "awaiting review"
-lang_all_label = "lang-all"
-approved_label = "approved-2"
-translations_path = Path(__file__).parent / "translations.yml"
-
-
-class Settings(BaseSettings):
- github_repository: str
- input_token: SecretStr
- github_event_path: Path
- github_event_name: Union[str, None] = None
- input_debug: Union[bool, None] = False
-
-
-class PartialGitHubEventIssue(BaseModel):
- number: int
-
-
-class PartialGitHubEvent(BaseModel):
- pull_request: PartialGitHubEventIssue
-
-
-if __name__ == "__main__":
- settings = Settings()
- if settings.input_debug:
- logging.basicConfig(level=logging.DEBUG)
- else:
- logging.basicConfig(level=logging.INFO)
- logging.debug(f"Using config: {settings.json()}")
- g = Github(settings.input_token.get_secret_value())
- repo = g.get_repo(settings.github_repository)
- if not settings.github_event_path.is_file():
- raise RuntimeError(
- f"No github event file available at: {settings.github_event_path}"
- )
- contents = settings.github_event_path.read_text()
- github_event = PartialGitHubEvent.parse_raw(contents)
- translations_map: Dict[str, int] = yaml.safe_load(translations_path.read_text())
- logging.debug(f"Using translations map: {translations_map}")
- sleep_time = random.random() * 10 # random number between 0 and 10 seconds
- pr = repo.get_pull(github_event.pull_request.number)
- logging.debug(
- f"Processing PR: {pr.number}, with anti-race condition sleep time: {sleep_time}"
- )
- if pr.state == "open":
- logging.debug(f"PR is open: {pr.number}")
- label_strs = {label.name for label in pr.get_labels()}
- if lang_all_label in label_strs and awaiting_label in label_strs:
- logging.info(
- f"This PR seems to be a language translation and awaiting reviews: {pr.number}"
- )
- if approved_label in label_strs:
- message = (
- f"It seems this PR already has the approved label: {pr.number}"
- )
- logging.error(message)
- raise RuntimeError(message)
- langs = []
- for label in label_strs:
- if label.startswith("lang-") and not label == lang_all_label:
- langs.append(label[5:])
- for lang in langs:
- if lang in translations_map:
- num = translations_map[lang]
- logging.info(
- f"Found a translation issue for language: {lang} in issue: {num}"
- )
- issue = repo.get_issue(num)
- message = f"Good news everyone! 😉 There's a new translation PR to be reviewed: #{pr.number} 🎉"
- already_notified = False
- time.sleep(sleep_time)
- logging.info(
- f"Sleeping for {sleep_time} seconds to avoid race conditions and multiple comments"
- )
- logging.info(
- f"Checking current comments in issue: {num} to see if already notified about this PR: {pr.number}"
- )
- for comment in issue.get_comments():
- if message in comment.body:
- already_notified = True
- if not already_notified:
- logging.info(
- f"Writing comment in issue: {num} about PR: {pr.number}"
- )
- issue.create_comment(message)
- else:
- logging.info(
- f"Issue: {num} was already notified of PR: {pr.number}"
- )
- else:
- logging.info(
- f"Changing labels in a closed PR doesn't trigger comments, PR: {pr.number}"
- )
- logging.info("Finished")
diff --git a/.github/actions/notify-translations/app/translations.yml b/.github/actions/notify-translations/app/translations.yml
deleted file mode 100644
index 4338e1326..000000000
--- a/.github/actions/notify-translations/app/translations.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-pt: 1211
-es: 1218
-zh: 1228
-ru: 1362
-it: 1556
-ja: 1572
-uk: 1748
-tr: 1892
-fr: 1972
-ko: 2017
-fa: 2041
-pl: 3169
-de: 3716
-id: 3717
-az: 3994
-nl: 4701
-uz: 4883
-sv: 5146
-he: 5157
-ta: 5434
-ar: 3349
diff --git a/.github/actions/people/Dockerfile b/.github/actions/people/Dockerfile
deleted file mode 100644
index fa4197e6a..000000000
--- a/.github/actions/people/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM python:3.7
-
-RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
-
-COPY ./app /app
-
-CMD ["python", "/app/main.py"]
diff --git a/.github/actions/people/action.yml b/.github/actions/people/action.yml
deleted file mode 100644
index 16bc8cdcb..000000000
--- a/.github/actions/people/action.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: "Generate FastAPI People"
-description: "Generate the data for the FastAPI People page"
-author: "Sebastián Ramírez "
-inputs:
- token:
- description: 'User token, to read the GitHub API. Can be passed in using {{ secrets.ACTION_TOKEN }}'
- required: true
- standard_token:
- description: 'Default GitHub Action token, used for the PR. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
- required: true
-runs:
- using: 'docker'
- image: 'Dockerfile'
diff --git a/.github/actions/people/app/main.py b/.github/actions/people/app/main.py
deleted file mode 100644
index 31756a5fc..000000000
--- a/.github/actions/people/app/main.py
+++ /dev/null
@@ -1,540 +0,0 @@
-import logging
-import subprocess
-import sys
-from collections import Counter, defaultdict
-from datetime import datetime, timedelta, timezone
-from pathlib import Path
-from typing import Container, DefaultDict, Dict, List, Set, Union
-
-import httpx
-import yaml
-from github import Github
-from pydantic import BaseModel, BaseSettings, SecretStr
-
-github_graphql_url = "https://api.github.com/graphql"
-
-issues_query = """
-query Q($after: String) {
- repository(name: "fastapi", owner: "tiangolo") {
- issues(first: 100, after: $after) {
- edges {
- cursor
- node {
- number
- author {
- login
- avatarUrl
- url
- }
- title
- createdAt
- state
- comments(first: 100) {
- nodes {
- createdAt
- author {
- login
- avatarUrl
- url
- }
- }
- }
- }
- }
- }
- }
-}
-"""
-
-prs_query = """
-query Q($after: String) {
- repository(name: "fastapi", owner: "tiangolo") {
- pullRequests(first: 100, after: $after) {
- edges {
- cursor
- node {
- number
- labels(first: 100) {
- nodes {
- name
- }
- }
- author {
- login
- avatarUrl
- url
- }
- title
- createdAt
- state
- comments(first: 100) {
- nodes {
- createdAt
- author {
- login
- avatarUrl
- url
- }
- }
- }
- reviews(first:100) {
- nodes {
- author {
- login
- avatarUrl
- url
- }
- state
- }
- }
- }
- }
- }
- }
-}
-"""
-
-sponsors_query = """
-query Q($after: String) {
- user(login: "tiangolo") {
- sponsorshipsAsMaintainer(first: 100, after: $after) {
- edges {
- cursor
- node {
- sponsorEntity {
- ... on Organization {
- login
- avatarUrl
- url
- }
- ... on User {
- login
- avatarUrl
- url
- }
- }
- tier {
- name
- monthlyPriceInDollars
- }
- }
- }
- }
- }
-}
-"""
-
-
-class Author(BaseModel):
- login: str
- avatarUrl: str
- url: str
-
-
-class CommentsNode(BaseModel):
- createdAt: datetime
- author: Union[Author, None] = None
-
-
-class Comments(BaseModel):
- nodes: List[CommentsNode]
-
-
-class IssuesNode(BaseModel):
- number: int
- author: Union[Author, None] = None
- title: str
- createdAt: datetime
- state: str
- comments: Comments
-
-
-class IssuesEdge(BaseModel):
- cursor: str
- node: IssuesNode
-
-
-class Issues(BaseModel):
- edges: List[IssuesEdge]
-
-
-class IssuesRepository(BaseModel):
- issues: Issues
-
-
-class IssuesResponseData(BaseModel):
- repository: IssuesRepository
-
-
-class IssuesResponse(BaseModel):
- data: IssuesResponseData
-
-
-class LabelNode(BaseModel):
- name: str
-
-
-class Labels(BaseModel):
- nodes: List[LabelNode]
-
-
-class ReviewNode(BaseModel):
- author: Union[Author, None] = None
- state: str
-
-
-class Reviews(BaseModel):
- nodes: List[ReviewNode]
-
-
-class PullRequestNode(BaseModel):
- number: int
- labels: Labels
- author: Union[Author, None] = None
- title: str
- createdAt: datetime
- state: str
- comments: Comments
- reviews: Reviews
-
-
-class PullRequestEdge(BaseModel):
- cursor: str
- node: PullRequestNode
-
-
-class PullRequests(BaseModel):
- edges: List[PullRequestEdge]
-
-
-class PRsRepository(BaseModel):
- pullRequests: PullRequests
-
-
-class PRsResponseData(BaseModel):
- repository: PRsRepository
-
-
-class PRsResponse(BaseModel):
- data: PRsResponseData
-
-
-class SponsorEntity(BaseModel):
- login: str
- avatarUrl: str
- url: str
-
-
-class Tier(BaseModel):
- name: str
- monthlyPriceInDollars: float
-
-
-class SponsorshipAsMaintainerNode(BaseModel):
- sponsorEntity: SponsorEntity
- tier: Tier
-
-
-class SponsorshipAsMaintainerEdge(BaseModel):
- cursor: str
- node: SponsorshipAsMaintainerNode
-
-
-class SponsorshipAsMaintainer(BaseModel):
- edges: List[SponsorshipAsMaintainerEdge]
-
-
-class SponsorsUser(BaseModel):
- sponsorshipsAsMaintainer: SponsorshipAsMaintainer
-
-
-class SponsorsResponseData(BaseModel):
- user: SponsorsUser
-
-
-class SponsorsResponse(BaseModel):
- data: SponsorsResponseData
-
-
-class Settings(BaseSettings):
- input_token: SecretStr
- input_standard_token: SecretStr
- github_repository: str
- httpx_timeout: int = 30
-
-
-def get_graphql_response(
- *, settings: Settings, query: str, after: Union[str, None] = None
-):
- headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
- variables = {"after": after}
- response = httpx.post(
- github_graphql_url,
- headers=headers,
- timeout=settings.httpx_timeout,
- json={"query": query, "variables": variables, "operationName": "Q"},
- )
- if response.status_code != 200:
- logging.error(f"Response was not 200, after: {after}")
- logging.error(response.text)
- raise RuntimeError(response.text)
- data = response.json()
- return data
-
-
-def get_graphql_issue_edges(*, settings: Settings, after: Union[str, None] = None):
- data = get_graphql_response(settings=settings, query=issues_query, after=after)
- graphql_response = IssuesResponse.parse_obj(data)
- return graphql_response.data.repository.issues.edges
-
-
-def get_graphql_pr_edges(*, settings: Settings, after: Union[str, None] = None):
- data = get_graphql_response(settings=settings, query=prs_query, after=after)
- graphql_response = PRsResponse.parse_obj(data)
- return graphql_response.data.repository.pullRequests.edges
-
-
-def get_graphql_sponsor_edges(*, settings: Settings, after: Union[str, None] = None):
- data = get_graphql_response(settings=settings, query=sponsors_query, after=after)
- graphql_response = SponsorsResponse.parse_obj(data)
- return graphql_response.data.user.sponsorshipsAsMaintainer.edges
-
-
-def get_experts(settings: Settings):
- issue_nodes: List[IssuesNode] = []
- issue_edges = get_graphql_issue_edges(settings=settings)
-
- while issue_edges:
- for edge in issue_edges:
- issue_nodes.append(edge.node)
- last_edge = issue_edges[-1]
- issue_edges = get_graphql_issue_edges(settings=settings, after=last_edge.cursor)
-
- commentors = Counter()
- last_month_commentors = Counter()
- authors: Dict[str, Author] = {}
-
- now = datetime.now(tz=timezone.utc)
- one_month_ago = now - timedelta(days=30)
-
- for issue in issue_nodes:
- issue_author_name = None
- if issue.author:
- authors[issue.author.login] = issue.author
- issue_author_name = issue.author.login
- issue_commentors = set()
- for comment in issue.comments.nodes:
- if comment.author:
- authors[comment.author.login] = comment.author
- if comment.author.login == issue_author_name:
- continue
- issue_commentors.add(comment.author.login)
- for author_name in issue_commentors:
- commentors[author_name] += 1
- if issue.createdAt > one_month_ago:
- last_month_commentors[author_name] += 1
- return commentors, last_month_commentors, authors
-
-
-def get_contributors(settings: Settings):
- pr_nodes: List[PullRequestNode] = []
- pr_edges = get_graphql_pr_edges(settings=settings)
-
- while pr_edges:
- for edge in pr_edges:
- pr_nodes.append(edge.node)
- last_edge = pr_edges[-1]
- pr_edges = get_graphql_pr_edges(settings=settings, after=last_edge.cursor)
-
- contributors = Counter()
- commentors = Counter()
- reviewers = Counter()
- authors: Dict[str, Author] = {}
-
- for pr in pr_nodes:
- author_name = None
- if pr.author:
- authors[pr.author.login] = pr.author
- author_name = pr.author.login
- pr_commentors: Set[str] = set()
- pr_reviewers: Set[str] = set()
- for comment in pr.comments.nodes:
- if comment.author:
- authors[comment.author.login] = comment.author
- if comment.author.login == author_name:
- continue
- pr_commentors.add(comment.author.login)
- for author_name in pr_commentors:
- commentors[author_name] += 1
- for review in pr.reviews.nodes:
- if review.author:
- authors[review.author.login] = review.author
- pr_reviewers.add(review.author.login)
- for reviewer in pr_reviewers:
- reviewers[reviewer] += 1
- if pr.state == "MERGED" and pr.author:
- contributors[pr.author.login] += 1
- return contributors, commentors, reviewers, authors
-
-
-def get_individual_sponsors(settings: Settings):
- nodes: List[SponsorshipAsMaintainerNode] = []
- edges = get_graphql_sponsor_edges(settings=settings)
-
- while edges:
- for edge in edges:
- nodes.append(edge.node)
- last_edge = edges[-1]
- edges = get_graphql_sponsor_edges(settings=settings, after=last_edge.cursor)
-
- tiers: DefaultDict[float, Dict[str, SponsorEntity]] = defaultdict(dict)
- for node in nodes:
- tiers[node.tier.monthlyPriceInDollars][
- node.sponsorEntity.login
- ] = node.sponsorEntity
- return tiers
-
-
-def get_top_users(
- *,
- counter: Counter,
- min_count: int,
- authors: Dict[str, Author],
- skip_users: Container[str],
-):
- users = []
- for commentor, count in counter.most_common(50):
- if commentor in skip_users:
- continue
- if count >= min_count:
- author = authors[commentor]
- users.append(
- {
- "login": commentor,
- "count": count,
- "avatarUrl": author.avatarUrl,
- "url": author.url,
- }
- )
- return users
-
-
-if __name__ == "__main__":
- logging.basicConfig(level=logging.INFO)
- settings = Settings()
- logging.info(f"Using config: {settings.json()}")
- g = Github(settings.input_standard_token.get_secret_value())
- repo = g.get_repo(settings.github_repository)
- issue_commentors, issue_last_month_commentors, issue_authors = get_experts(
- settings=settings
- )
- contributors, pr_commentors, reviewers, pr_authors = get_contributors(
- settings=settings
- )
- authors = {**issue_authors, **pr_authors}
- maintainers_logins = {"tiangolo"}
- bot_names = {"codecov", "github-actions", "pre-commit-ci", "dependabot"}
- maintainers = []
- for login in maintainers_logins:
- user = authors[login]
- maintainers.append(
- {
- "login": login,
- "answers": issue_commentors[login],
- "prs": contributors[login],
- "avatarUrl": user.avatarUrl,
- "url": user.url,
- }
- )
-
- min_count_expert = 10
- min_count_last_month = 3
- min_count_contributor = 4
- min_count_reviewer = 4
- skip_users = maintainers_logins | bot_names
- experts = get_top_users(
- counter=issue_commentors,
- min_count=min_count_expert,
- authors=authors,
- skip_users=skip_users,
- )
- last_month_active = get_top_users(
- counter=issue_last_month_commentors,
- min_count=min_count_last_month,
- authors=authors,
- skip_users=skip_users,
- )
- top_contributors = get_top_users(
- counter=contributors,
- min_count=min_count_contributor,
- authors=authors,
- skip_users=skip_users,
- )
- top_reviewers = get_top_users(
- counter=reviewers,
- min_count=min_count_reviewer,
- authors=authors,
- skip_users=skip_users,
- )
-
- tiers = get_individual_sponsors(settings=settings)
- keys = list(tiers.keys())
- keys.sort(reverse=True)
- sponsors = []
- for key in keys:
- sponsor_group = []
- for login, sponsor in tiers[key].items():
- sponsor_group.append(
- {"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
- )
- sponsors.append(sponsor_group)
-
- people = {
- "maintainers": maintainers,
- "experts": experts,
- "last_month_active": last_month_active,
- "top_contributors": top_contributors,
- "top_reviewers": top_reviewers,
- }
- github_sponsors = {
- "sponsors": sponsors,
- }
- people_path = Path("./docs/en/data/people.yml")
- github_sponsors_path = Path("./docs/en/data/github_sponsors.yml")
- people_old_content = people_path.read_text(encoding="utf-8")
- github_sponsors_old_content = github_sponsors_path.read_text(encoding="utf-8")
- new_people_content = yaml.dump(
- people, sort_keys=False, width=200, allow_unicode=True
- )
- new_github_sponsors_content = yaml.dump(
- github_sponsors, sort_keys=False, width=200, allow_unicode=True
- )
- if (
- people_old_content == new_people_content
- and github_sponsors_old_content == new_github_sponsors_content
- ):
- logging.info("The FastAPI People data hasn't changed, finishing.")
- sys.exit(0)
- people_path.write_text(new_people_content, encoding="utf-8")
- github_sponsors_path.write_text(new_github_sponsors_content, encoding="utf-8")
- logging.info("Setting up GitHub Actions git user")
- subprocess.run(["git", "config", "user.name", "github-actions"], check=True)
- subprocess.run(
- ["git", "config", "user.email", "github-actions@github.com"], check=True
- )
- branch_name = "fastapi-people"
- logging.info(f"Creating a new branch {branch_name}")
- subprocess.run(["git", "checkout", "-b", branch_name], check=True)
- logging.info("Adding updated file")
- subprocess.run(
- ["git", "add", str(people_path), str(github_sponsors_path)], check=True
- )
- logging.info("Committing updated file")
- message = "👥 Update FastAPI People"
- result = subprocess.run(["git", "commit", "-m", message], check=True)
- logging.info("Pushing branch")
- subprocess.run(["git", "push", "origin", branch_name], check=True)
- logging.info("Creating PR")
- pr = repo.create_pull(title=message, body=message, base="master", head=branch_name)
- logging.info(f"Created PR: {pr.number}")
- logging.info("Finished")
diff --git a/.github/actions/watch-previews/Dockerfile b/.github/actions/watch-previews/Dockerfile
deleted file mode 100644
index b8cc64d94..000000000
--- a/.github/actions/watch-previews/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM python:3.7
-
-RUN pip install httpx PyGithub "pydantic==1.5.1"
-
-COPY ./app /app
-
-CMD ["python", "/app/main.py"]
diff --git a/.github/actions/watch-previews/action.yml b/.github/actions/watch-previews/action.yml
deleted file mode 100644
index 5c09ad487..000000000
--- a/.github/actions/watch-previews/action.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: "Watch docs previews in PRs"
-description: "Check PRs and trigger new docs deploys"
-author: "Sebastián Ramírez "
-inputs:
- token:
- description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
- required: true
-runs:
- using: 'docker'
- image: 'Dockerfile'
diff --git a/.github/actions/watch-previews/app/main.py b/.github/actions/watch-previews/app/main.py
deleted file mode 100644
index 51285d02b..000000000
--- a/.github/actions/watch-previews/app/main.py
+++ /dev/null
@@ -1,101 +0,0 @@
-import logging
-from datetime import datetime
-from pathlib import Path
-from typing import List, Union
-
-import httpx
-from github import Github
-from github.NamedUser import NamedUser
-from pydantic import BaseModel, BaseSettings, SecretStr
-
-github_api = "https://api.github.com"
-netlify_api = "https://api.netlify.com"
-
-
-class Settings(BaseSettings):
- input_token: SecretStr
- github_repository: str
- github_event_path: Path
- github_event_name: Union[str, None] = None
-
-
-class Artifact(BaseModel):
- id: int
- node_id: str
- name: str
- size_in_bytes: int
- url: str
- archive_download_url: str
- expired: bool
- created_at: datetime
- updated_at: datetime
-
-
-class ArtifactResponse(BaseModel):
- total_count: int
- artifacts: List[Artifact]
-
-
-def get_message(commit: str) -> str:
- return f"Docs preview for commit {commit} at"
-
-
-if __name__ == "__main__":
- logging.basicConfig(level=logging.INFO)
- settings = Settings()
- logging.info(f"Using config: {settings.json()}")
- g = Github(settings.input_token.get_secret_value())
- repo = g.get_repo(settings.github_repository)
- owner: NamedUser = repo.owner
- headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
- prs = list(repo.get_pulls(state="open"))
- response = httpx.get(
- f"{github_api}/repos/{settings.github_repository}/actions/artifacts",
- headers=headers,
- )
- data = response.json()
- artifacts_response = ArtifactResponse.parse_obj(data)
- for pr in prs:
- logging.info("-----")
- logging.info(f"Processing PR #{pr.number}: {pr.title}")
- pr_comments = list(pr.get_issue_comments())
- pr_commits = list(pr.get_commits())
- last_commit = pr_commits[0]
- for pr_commit in pr_commits:
- if pr_commit.commit.author.date > last_commit.commit.author.date:
- last_commit = pr_commit
- commit = last_commit.commit.sha
- logging.info(f"Last commit: {commit}")
- message = get_message(commit)
- notified = False
- for pr_comment in pr_comments:
- if message in pr_comment.body:
- notified = True
- logging.info(f"Docs preview was notified: {notified}")
- if not notified:
- artifact_name = f"docs-zip-{commit}"
- use_artifact: Union[Artifact, None] = None
- for artifact in artifacts_response.artifacts:
- if artifact.name == artifact_name:
- use_artifact = artifact
- break
- if not use_artifact:
- logging.info("Artifact not available")
- else:
- logging.info(f"Existing artifact: {use_artifact.name}")
- response = httpx.post(
- "https://api.github.com/repos/tiangolo/fastapi/actions/workflows/preview-docs.yml/dispatches",
- headers=headers,
- json={
- "ref": "master",
- "inputs": {
- "pr": f"{pr.number}",
- "name": artifact_name,
- "commit": commit,
- },
- },
- )
- logging.info(
- f"Trigger sent, response status: {response.status_code} - content: {response.content}"
- )
- logging.info("Finished")
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index cd972a0ba..8979aabf8 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -11,6 +11,6 @@ updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
- interval: "daily"
+ interval: "monthly"
commit-message:
prefix: ⬆
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 000000000..c5b1f84f3
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,38 @@
+docs:
+ - all:
+ - changed-files:
+ - any-glob-to-any-file:
+ - docs/en/docs/**
+ - docs_src/**
+ - all-globs-to-all-files:
+ - '!fastapi/**'
+ - '!pyproject.toml'
+ - '!docs/en/data/sponsors.yml'
+ - '!docs/en/overrides/main.html'
+
+lang-all:
+ - all:
+ - changed-files:
+ - any-glob-to-any-file:
+ - docs/*/docs/**
+ - all-globs-to-all-files:
+ - '!docs/en/docs/**'
+ - '!fastapi/**'
+ - '!pyproject.toml'
+
+internal:
+ - all:
+ - changed-files:
+ - any-glob-to-any-file:
+ - .github/**
+ - scripts/**
+ - .gitignore
+ - .pre-commit-config.yaml
+ - pdm_build.py
+ - requirements*.txt
+ - docs/en/data/sponsors.yml
+ - docs/en/overrides/main.html
+ - all-globs-to-all-files:
+ - '!docs/*/docs/**'
+ - '!fastapi/**'
+ - '!pyproject.toml'
diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml
new file mode 100644
index 000000000..dccea83f3
--- /dev/null
+++ b/.github/workflows/add-to-project.yml
@@ -0,0 +1,18 @@
+name: Add to Project
+
+on:
+ pull_request_target:
+ issues:
+ types:
+ - opened
+ - reopened
+
+jobs:
+ add-to-project:
+ name: Add to project
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/add-to-project@v1.0.2
+ with:
+ project-url: https://github.com/orgs/fastapi/projects/2
+ github-token: ${{ secrets.PROJECTS_TOKEN }}
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index b9bd521b3..e84e4e4ab 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -4,46 +4,134 @@ on:
branches:
- master
pull_request:
- types: [opened, synchronize]
+ types:
+ - opened
+ - synchronize
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
+ changes:
+ runs-on: ubuntu-latest
+ # Required permissions
+ permissions:
+ pull-requests: read
+ # Set job outputs to values from filter step
+ outputs:
+ docs: ${{ steps.filter.outputs.docs }}
+ steps:
+ - uses: actions/checkout@v4
+ # For pull requests it's not necessary to checkout the code but for the main branch it is
+ - uses: dorny/paths-filter@v3
+ id: filter
+ with:
+ filters: |
+ docs:
+ - README.md
+ - docs/**
+ - docs_src/**
+ - requirements-docs.txt
+ - requirements-docs-insiders.txt
+ - pyproject.toml
+ - mkdocs.yml
+ - mkdocs.insiders.yml
+ - mkdocs.maybe-insiders.yml
+ - mkdocs.no-insiders.yml
+ - .github/workflows/build-docs.yml
+ - .github/workflows/deploy-docs.yml
+ langs:
+ needs:
+ - changes
+ runs-on: ubuntu-latest
+ outputs:
+ langs: ${{ steps.show-langs.outputs.langs }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install docs extras
+ run: uv pip install -r requirements-docs.txt
+ # Install MkDocs Material Insiders here just to put it in the cache for the rest of the steps
+ - name: Install Material for MkDocs Insiders
+ if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
+ run: uv pip install -r requirements-docs-insiders.txt
+ env:
+ TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
+ - name: Verify Docs
+ run: python ./scripts/docs.py verify-docs
+ - name: Export Language Codes
+ id: show-langs
+ run: |
+ echo "langs=$(python ./scripts/docs.py langs-json)" >> $GITHUB_OUTPUT
+
build-docs:
- runs-on: ubuntu-18.04
+ needs:
+ - changes
+ - langs
+ if: ${{ needs.changes.outputs.docs == 'true' }}
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ lang: ${{ fromJson(needs.langs.outputs.langs) }}
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
- python-version: "3.7"
- - uses: actions/cache@v3
- id: cache
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install docs extras
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install .[doc]
+ run: uv pip install -r requirements-docs.txt
- name: Install Material for MkDocs Insiders
- if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
- run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
+ if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
+ run: uv pip install -r requirements-docs-insiders.txt
+ env:
+ TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
+ - name: Update Languages
+ run: python ./scripts/docs.py update-languages
+ - uses: actions/cache@v4
+ with:
+ key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
+ path: docs/${{ matrix.lang }}/.cache
- name: Build Docs
- run: python ./scripts/docs.py build-all
- - name: Zip docs
- run: bash ./scripts/zip-docs.sh
- - uses: actions/upload-artifact@v3
+ run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
+ - uses: actions/upload-artifact@v4
with:
- name: docs-zip
- path: ./site/docs.zip
- - name: Deploy to Netlify
- uses: nwtgck/actions-netlify@v2.0.0
+ name: docs-site-${{ matrix.lang }}
+ path: ./site/**
+ include-hidden-files: true
+
+ # https://github.com/marketplace/actions/alls-green#why
+ docs-all-green: # This job does nothing and is only used for the branch protection
+ if: always()
+ needs:
+ - build-docs
+ runs-on: ubuntu-latest
+ steps:
+ - name: Decide whether the needed jobs succeeded or failed
+ uses: re-actors/alls-green@release/v1
with:
- publish-dir: './site'
- production-branch: master
- github-token: ${{ secrets.GITHUB_TOKEN }}
- enable-commit-comment: false
- env:
- NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
- NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
+ jobs: ${{ toJSON(needs) }}
+ allowed-skips: build-docs
diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml
new file mode 100644
index 000000000..34b54b452
--- /dev/null
+++ b/.github/workflows/contributors.yml
@@ -0,0 +1,53 @@
+name: FastAPI People Contributors
+
+on:
+ schedule:
+ - cron: "0 3 1 * *"
+ workflow_dispatch:
+ inputs:
+ debug_enabled:
+ description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
+ required: false
+ default: "false"
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
+jobs:
+ job:
+ if: github.repository_owner == 'fastapi'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-github-actions.txt
+ # Allow debugging with tmate
+ - name: Setup tmate session
+ uses: mxschmitt/action-tmate@v3
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
+ with:
+ limit-access-to-actor: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
+ - name: FastAPI People Contributors
+ run: python ./scripts/contributors.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
new file mode 100644
index 000000000..9ca69b208
--- /dev/null
+++ b/.github/workflows/deploy-docs.yml
@@ -0,0 +1,77 @@
+name: Deploy Docs
+on:
+ workflow_run:
+ workflows:
+ - Build Docs
+ types:
+ - completed
+
+permissions:
+ deployments: write
+ issues: write
+ pull-requests: write
+ statuses: write
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
+jobs:
+ deploy-docs:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install GitHub Actions dependencies
+ run: uv pip install -r requirements-github-actions.txt
+ - name: Deploy Docs Status Pending
+ run: python ./scripts/deploy_docs_status.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
+ RUN_ID: ${{ github.run_id }}
+ - name: Clean site
+ run: |
+ rm -rf ./site
+ mkdir ./site
+ - uses: actions/download-artifact@v4
+ with:
+ path: ./site/
+ pattern: docs-site-*
+ merge-multiple: true
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ run-id: ${{ github.event.workflow_run.id }}
+ - name: Deploy to Cloudflare Pages
+ # hashFiles returns an empty string if there are no files
+ if: hashFiles('./site/*')
+ id: deploy
+ env:
+ PROJECT_NAME: fastapitiangolo
+ BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
+ uses: cloudflare/wrangler-action@v3
+ with:
+ apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+ command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
+ - name: Comment Deploy
+ run: python ./scripts/deploy_docs_status.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}
+ COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
+ RUN_ID: ${{ github.run_id }}
+ IS_DONE: "true"
diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml
index e2fb4f7a4..6a7e6143e 100644
--- a/.github/workflows/issue-manager.yml
+++ b/.github/workflows/issue-manager.yml
@@ -2,7 +2,7 @@ name: Issue Manager
on:
schedule:
- - cron: "0 0 * * *"
+ - cron: "13 22 * * *"
issue_comment:
types:
- created
@@ -14,11 +14,20 @@ on:
- labeled
workflow_dispatch:
+permissions:
+ issues: write
+ pull-requests: write
+
jobs:
issue-manager:
+ if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
steps:
- - uses: tiangolo/issue-manager@0.4.0
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: tiangolo/issue-manager@0.5.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
@@ -26,5 +35,13 @@ jobs:
"answered": {
"delay": 864000,
"message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
+ },
+ "waiting": {
+ "delay": 2628000,
+ "message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
+ },
+ "invalid": {
+ "delay": 0,
+ "message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
}
}
diff --git a/.github/workflows/label-approved.yml b/.github/workflows/label-approved.yml
index b2646dd16..908a9453d 100644
--- a/.github/workflows/label-approved.yml
+++ b/.github/workflows/label-approved.yml
@@ -3,11 +3,47 @@ name: Label Approved
on:
schedule:
- cron: "0 12 * * *"
+ workflow_dispatch:
+
+permissions:
+ pull-requests: write
+
+env:
+ UV_SYSTEM_PYTHON: 1
jobs:
label-approved:
+ if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
steps:
- - uses: docker://tiangolo/label-approved:0.0.2
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install GitHub Actions dependencies
+ run: uv pip install -r requirements-github-actions.txt
+ - name: Label Approved
+ run: python ./scripts/label_approved.py
+ env:
+ TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CONFIG: >
+ {
+ "approved-1":
+ {
+ "number": 1,
+ "await_label": "awaiting-review"
+ }
+ }
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
new file mode 100644
index 000000000..e8e58015a
--- /dev/null
+++ b/.github/workflows/labeler.yml
@@ -0,0 +1,33 @@
+name: Labels
+on:
+ pull_request_target:
+ types:
+ - opened
+ - synchronize
+ - reopened
+ # For label-checker
+ - labeled
+ - unlabeled
+
+jobs:
+ labeler:
+ permissions:
+ contents: read
+ pull-requests: write
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/labeler@v5
+ if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
+ - run: echo "Done adding labels"
+ # Run this after labeler applied labels
+ check-labels:
+ needs:
+ - labeler
+ permissions:
+ pull-requests: read
+ runs-on: ubuntu-latest
+ steps:
+ - uses: docker://agilepathway/pull-request-label-checker:latest
+ with:
+ one_of: breaking,security,feature,bug,refactor,upgrade,docs,lang-all,internal
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml
index 4aa8475b6..b8b5c42ee 100644
--- a/.github/workflows/latest-changes.yml
+++ b/.github/workflows/latest-changes.yml
@@ -14,27 +14,31 @@ on:
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
- default: false
+ default: 'false'
jobs:
latest-changes:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
with:
- # To allow latest-changes to commit to master
- token: ${{ secrets.ACTIONS_TOKEN }}
+ # To allow latest-changes to commit to the main branch
+ token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- token: ${{ secrets.ACTIONS_TOKEN }}
- standard_token: ${{ secrets.GITHUB_TOKEN }}
- - uses: docker://tiangolo/latest-changes:0.0.3
+ - uses: tiangolo/latest-changes@0.3.2
with:
token: ${{ secrets.GITHUB_TOKEN }}
latest_changes_file: docs/en/docs/release-notes.md
- latest_changes_header: '## Latest Changes\n\n'
+ latest_changes_header: '## Latest Changes'
+ end_regex: '^## '
debug_logs: true
+ label_header_prefix: '### '
diff --git a/.github/workflows/notify-translations.yml b/.github/workflows/notify-translations.yml
index 2fcb7595e..621d1253a 100644
--- a/.github/workflows/notify-translations.yml
+++ b/.github/workflows/notify-translations.yml
@@ -4,18 +4,56 @@ on:
pull_request_target:
types:
- labeled
+ - closed
+ workflow_dispatch:
+ inputs:
+ number:
+ description: PR number
+ required: true
+ debug_enabled:
+ description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
+ required: false
+ default: 'false'
+
+env:
+ UV_SYSTEM_PYTHON: 1
jobs:
- notify-translations:
+ job:
runs-on: ubuntu-latest
+ permissions:
+ discussions: write
steps:
- - uses: actions/checkout@v3
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-github-actions.txt
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- - uses: ./.github/actions/notify-translations
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Notify Translations
+ run: python ./scripts/notify_translations.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NUMBER: ${{ github.event.inputs.number || null }}
+ DEBUG: ${{ github.event.inputs.debug_enabled || 'false' }}
diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml
index 4b47b4072..11931a05a 100644
--- a/.github/workflows/people.yml
+++ b/.github/workflows/people.yml
@@ -6,24 +6,48 @@ on:
workflow_dispatch:
inputs:
debug_enabled:
- description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
+ description: Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
required: false
- default: false
+ default: "false"
+
+env:
+ UV_SYSTEM_PYTHON: 1
jobs:
- fastapi-people:
+ job:
+ if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
+ permissions:
+ contents: write
steps:
- - uses: actions/checkout@v3
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-github-actions.txt
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- token: ${{ secrets.ACTIONS_TOKEN }}
- standard_token: ${{ secrets.GITHUB_TOKEN }}
- - uses: ./.github/actions/people
- with:
- token: ${{ secrets.ACTIONS_TOKEN }}
- standard_token: ${{ secrets.GITHUB_TOKEN }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
+ - name: FastAPI People Experts
+ run: python ./scripts/people.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
diff --git a/.github/workflows/preview-docs.yml b/.github/workflows/preview-docs.yml
deleted file mode 100644
index 7d31a9c64..000000000
--- a/.github/workflows/preview-docs.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-name: Preview Docs
-on:
- workflow_run:
- workflows:
- - Build Docs
- types:
- - completed
-
-jobs:
- preview-docs:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Clean site
- run: |
- rm -rf ./site
- mkdir ./site
- - name: Download Artifact Docs
- uses: dawidd6/action-download-artifact@v2.24.2
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- workflow: build-docs.yml
- run_id: ${{ github.event.workflow_run.id }}
- name: docs-zip
- path: ./site/
- - name: Unzip docs
- run: |
- cd ./site
- unzip docs.zip
- rm -f docs.zip
- - name: Deploy to Netlify
- id: netlify
- uses: nwtgck/actions-netlify@v2.0.0
- with:
- publish-dir: './site'
- production-deploy: false
- github-token: ${{ secrets.GITHUB_TOKEN }}
- enable-commit-comment: false
- env:
- NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
- NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
- - name: Comment Deploy
- uses: ./.github/actions/comment-docs-preview-in-pr
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- deploy_url: "${{ steps.netlify.outputs.deploy-url }}"
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 8ffb493a4..bf88d59b1 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -8,39 +8,35 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ package:
+ - fastapi
+ - fastapi-slim
+ permissions:
+ id-token: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
- python-version: "3.7"
- cache: "pip"
- cache-dependency-path: pyproject.toml
- - uses: actions/cache@v3
- id: cache
- with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish
+ python-version: "3.10"
+ # Issue ref: https://github.com/actions/setup-python/issues/436
+ # cache: "pip"
+ # cache-dependency-path: pyproject.toml
- name: Install build dependencies
- if: steps.cache.outputs.cache-hit != 'true'
run: pip install build
- name: Build distribution
+ env:
+ TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
run: python -m build
- name: Publish
- uses: pypa/gh-action-pypi-publish@v1.5.2
- with:
- password: ${{ secrets.PYPI_API_TOKEN }}
+ uses: pypa/gh-action-pypi-publish@v1.12.4
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- # - name: Notify
- # env:
- # GITTER_TOKEN: ${{ secrets.GITTER_TOKEN }}
- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- # TAG: ${{ github.event.release.name }}
- # run: bash scripts/notify.sh
diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml
index 7559c24c0..d8a5dfb30 100644
--- a/.github/workflows/smokeshow.yml
+++ b/.github/workflows/smokeshow.yml
@@ -8,24 +8,49 @@ on:
permissions:
statuses: write
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
smokeshow:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- - uses: actions/setup-python@v4
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
python-version: '3.9'
-
- - run: pip install smokeshow
-
- - uses: dawidd6/action-download-artifact@v2.24.2
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
with:
- workflow: test.yml
- commit: ${{ github.event.workflow_run.head_sha }}
-
- - run: smokeshow upload coverage-html
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - run: uv pip install -r requirements-github-actions.txt
+ - uses: actions/download-artifact@v4
+ with:
+ name: coverage-html
+ path: htmlcov
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ run-id: ${{ github.event.workflow_run.id }}
+ # Try 5 times to upload coverage to smokeshow
+ - name: Upload coverage to Smokeshow
+ run: |
+ for i in 1 2 3 4 5; do
+ if smokeshow upload htmlcov; then
+ echo "Smokeshow upload success!"
+ break
+ fi
+ echo "Smokeshow upload error, sleep 1 sec and try again."
+ sleep 1
+ done
env:
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
diff --git a/.github/workflows/sponsors.yml b/.github/workflows/sponsors.yml
new file mode 100644
index 000000000..6da4d90e1
--- /dev/null
+++ b/.github/workflows/sponsors.yml
@@ -0,0 +1,52 @@
+name: FastAPI People Sponsors
+
+on:
+ schedule:
+ - cron: "0 6 1 * *"
+ workflow_dispatch:
+ inputs:
+ debug_enabled:
+ description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
+ required: false
+ default: "false"
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
+jobs:
+ job:
+ if: github.repository_owner == 'fastapi'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-github-actions.txt
+ # Allow debugging with tmate
+ - name: Setup tmate session
+ uses: mxschmitt/action-tmate@v3
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
+ with:
+ limit-access-to-actor: true
+ - name: FastAPI People Sponsors
+ run: python ./scripts/sponsors.py
+ env:
+ SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }}
+ PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
diff --git a/.github/workflows/test-redistribute.yml b/.github/workflows/test-redistribute.yml
new file mode 100644
index 000000000..693f0c603
--- /dev/null
+++ b/.github/workflows/test-redistribute.yml
@@ -0,0 +1,69 @@
+name: Test Redistribute
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ types:
+ - opened
+ - synchronize
+
+jobs:
+ test-redistribute:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ package:
+ - fastapi
+ - fastapi-slim
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.10"
+ - name: Install build dependencies
+ run: pip install build
+ - name: Build source distribution
+ env:
+ TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
+ run: python -m build --sdist
+ - name: Decompress source distribution
+ run: |
+ cd dist
+ tar xvf fastapi*.tar.gz
+ - name: Install test dependencies
+ run: |
+ cd dist/fastapi*/
+ pip install -r requirements-tests.txt
+ env:
+ TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
+ - name: Run source distribution tests
+ run: |
+ cd dist/fastapi*/
+ bash scripts/test.sh
+ - name: Build wheel distribution
+ run: |
+ cd dist
+ pip wheel --no-deps fastapi*.tar.gz
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+
+ # https://github.com/marketplace/actions/alls-green#why
+ test-redistribute-alls-green: # This job does nothing and is only used for the branch protection
+ if: always()
+ needs:
+ - test-redistribute
+ runs-on: ubuntu-latest
+ steps:
+ - name: Decide whether the needed jobs succeeded or failed
+ uses: re-actors/alls-green@release/v1
+ with:
+ jobs: ${{ toJSON(needs) }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ddc43c942..c3940be01 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -5,34 +5,87 @@ on:
branches:
- master
pull_request:
- types: [opened, synchronize]
+ types:
+ - opened
+ - synchronize
+ schedule:
+ # cron every week on monday
+ - cron: "0 0 * * 1"
+
+env:
+ UV_SYSTEM_PYTHON: 1
jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-tests.txt
+ - name: Install Pydantic v2
+ run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
+ - name: Lint
+ run: bash scripts/lint.sh
+
test:
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
+ python-version:
+ - "3.13"
+ - "3.12"
+ - "3.11"
+ - "3.10"
+ - "3.9"
+ - "3.8"
+ pydantic-version: ["pydantic-v1", "pydantic-v2"]
fail-fast: false
-
steps:
- - uses: actions/checkout@v3
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- cache: "pip"
- cache-dependency-path: pyproject.toml
- - uses: actions/cache@v3
- id: cache
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v03
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install Dependencies
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -e .[all,dev,doc,test]
- - name: Lint
- run: bash scripts/lint.sh
+ run: uv pip install -r requirements-tests.txt
+ - name: Install Pydantic v1
+ if: matrix.pydantic-version == 'pydantic-v1'
+ run: uv pip install "pydantic>=1.10.0,<2.0.0"
+ - name: Install Pydantic v2
+ if: matrix.pydantic-version == 'pydantic-v2'
+ run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
+ # TODO: Remove this once Python 3.8 is no longer supported
+ - name: Install older AnyIO in Python 3.8
+ if: matrix.python-version == '3.8'
+ run: uv pip install "anyio[trio]<4.0.0"
- run: mkdir coverage
- name: Test
run: bash scripts/test.sh
@@ -40,38 +93,63 @@ jobs:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
- name: Store coverage files
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: coverage
+ name: coverage-${{ matrix.python-version }}-${{ matrix.pydantic-version }}
path: coverage
+ include-hidden-files: true
+
coverage-combine:
needs: [test]
runs-on: ubuntu-latest
-
steps:
- - uses: actions/checkout@v3
-
- - uses: actions/setup-python@v4
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
python-version: '3.8'
- cache: "pip"
- cache-dependency-path: pyproject.toml
-
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-tests.txt
- name: Get coverage files
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
- name: coverage
+ pattern: coverage-*
path: coverage
-
- - run: pip install coverage[toml]
-
+ merge-multiple: true
- run: ls -la coverage
- run: coverage combine coverage
- run: coverage report
- - run: coverage html --show-contexts --title "Coverage for ${{ github.sha }}"
-
+ - run: coverage html --title "Coverage for ${{ github.sha }}"
- name: Store coverage HTML
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: coverage-html
path: htmlcov
+ include-hidden-files: true
+
+ # https://github.com/marketplace/actions/alls-green#why
+ check: # This job does nothing and is only used for the branch protection
+ if: always()
+ needs:
+ - coverage-combine
+ runs-on: ubuntu-latest
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - name: Decide whether the needed jobs succeeded or failed
+ uses: re-actors/alls-green@release/v1
+ with:
+ jobs: ${{ toJSON(needs) }}
diff --git a/.github/workflows/topic-repos.yml b/.github/workflows/topic-repos.yml
new file mode 100644
index 000000000..433aeb00b
--- /dev/null
+++ b/.github/workflows/topic-repos.yml
@@ -0,0 +1,40 @@
+name: Update Topic Repos
+
+on:
+ schedule:
+ - cron: "0 12 1 * *"
+ workflow_dispatch:
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
+jobs:
+ topic-repos:
+ if: github.repository_owner == 'fastapi'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install GitHub Actions dependencies
+ run: uv pip install -r requirements-github-actions.txt
+ - name: Update Topic Repos
+ run: python ./scripts/topic_repos.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
diff --git a/.gitignore b/.gitignore
index a26bb5cd6..ef6364a9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,7 @@ __pycache__
htmlcov
dist
site
-.coverage
+.coverage*
coverage.xml
.netlify
test.db
@@ -16,6 +16,7 @@ Pipfile.lock
env3.*
env
docs_build
+site_build
venv
docs.zip
archive.zip
@@ -23,3 +24,7 @@ archive.zip
# vim temporary files
*~
.*.sw?
+.cache
+
+# macOS
+.DS_Store
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 96f097caa..680cafce9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,8 +1,10 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
+default_language_version:
+ python: python3.10
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
+ rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-toml
@@ -11,34 +13,13 @@ repos:
- --unsafe
- id: end-of-file-fixer
- id: trailing-whitespace
-- repo: https://github.com/asottile/pyupgrade
- rev: v3.2.2
- hooks:
- - id: pyupgrade
- args:
- - --py3-plus
- - --keep-runtime-typing
-- repo: https://github.com/charliermarsh/ruff-pre-commit
- rev: v0.0.138
+- repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.12.2
hooks:
- id: ruff
args:
- --fix
-- repo: https://github.com/pycqa/isort
- rev: 5.10.1
- hooks:
- - id: isort
- name: isort (python)
- - id: isort
- name: isort (cython)
- types: [cython]
- - id: isort
- name: isort (pyi)
- types: [pyi]
-- repo: https://github.com/psf/black
- rev: 22.10.0
- hooks:
- - id: black
+ - id: ruff-format
ci:
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 000000000..f14700349
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,24 @@
+# This CITATION.cff file was generated with cffinit.
+# Visit https://bit.ly/cffinit to generate yours today!
+
+cff-version: 1.2.0
+title: FastAPI
+message: >-
+ If you use this software, please cite it using the
+ metadata from this file.
+type: software
+authors:
+ - given-names: Sebastián
+ family-names: Ramírez
+ email: tiangolo@gmail.com
+identifiers:
+repository-code: 'https://github.com/fastapi/fastapi'
+url: 'https://fastapi.tiangolo.com'
+abstract: >-
+ FastAPI framework, high performance, easy to learn, fast to code,
+ ready for production
+keywords:
+ - fastapi
+ - pydantic
+ - starlette
+license: MIT
diff --git a/README.md b/README.md
index 7c4a6c4b4..25a1d9179 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,11 @@
FastAPI framework, high performance, easy to learn, fast to code, ready for production
```console
-$ pip install "uvicorn[standard]"
+$ pip install "fastapi[standard]"
---> 100%
```
+**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
+
## Example
### Create it
-* Create a file `main.py` with:
+Create a file `main.py` with:
```Python
from typing import Union
@@ -203,11 +204,24 @@ Run the server with:
```console
-$ uvicorn main:app --reload
-
+$ fastapi dev main.py
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
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: Started reloader process [2248755] using WatchFiles
+INFO: Started server process [2248757]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
@@ -215,13 +229,13 @@ INFO: Application startup complete.
+
+```console
+// আপনি চাইলে MY_NAME নামে একটি env var তৈরি করতে পারেন
+$ export MY_NAME="Wade Wilson"
+
+// তারপরে এটিকে চাইলে অন্যান্য প্রোগ্রামে ব্যবহার করতে পারেন
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | উইন্ডোজ পাওয়ারশেল
+
+
+
+```console
+// MY_NAME নামে env var তৈরি
+$ $Env:MY_NAME = "Wade Wilson"
+
+// অন্যান্য প্রোগ্রামে এটিকে ব্যবহার
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## পাইথনে env vars রিড করা
+
+আপনি চাইলে পাইথনের **বাইরে**, টার্মিনালে (বা অন্য কোনো উপায়ে) এনভায়রনমেন্ট ভেরিয়েবলস তৈরি করতে পারেন, এবং পরে সেগুলো **পাইথনে রিড** (অ্যাক্সেস করতে) পারেন।
+
+উদাহরণস্বরূপ, আপনার `main.py` নামে একটি ফাইল থাকতে পারেঃ
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+
+
+```console
+// এখনো আমরা এনভায়রনমেন্ট ভেরিয়েবল সেট করিনি
+$ python main.py
+
+// যেহেতু env var সেট করা হয়নি, তাই আমরা ডিফল্ট ভ্যালু পাচ্ছি
+
+Hello World from Python
+
+// কিন্তু আমরা প্রথমে যদি একটা এনভায়রনমেন্ট ভারিয়েবল তৈরি করে নেই
+$ export MY_NAME="Wade Wilson"
+
+// এবং তারপর আবার প্রোগ্রাটিকে কল করি
+$ python main.py
+
+// এখন এটি এনভায়রনমেন্ট ভেরিয়েবল রিড করতে পারবে
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | উইন্ডোজ পাওয়ারশেল
+
+
+
+```console
+// এখনো আমরা এনভায়রনমেন্ট ভেরিয়েবল সেট করিনি
+$ python main.py
+
+// যেহেতু env var সেট করা হয়নি, তাই আমরা ডিফল্ট ভ্যালু পাচ্ছি
+
+Hello World from Python
+
+// কিন্তু আমরা প্রথমে যদি একটা এনভায়রনমেন্ট ভারিয়েবল তৈরি করে নেই
+$ $Env:MY_NAME = "Wade Wilson"
+
+// এবং তারপর আবার প্রোগ্রাটিকে কল করি
+$ python main.py
+
+// এখন এটি এনভায়রনমেন্ট ভেরিয়েবল রিড করতে পারবে
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+যেহেতু এনভায়রনমেন্ট ভেরিয়েবলস কোডের বাইরে সেট করা যায়, কিন্তু পরবর্তীতে কোড দ্বারা রিড করা যায়, এবং বাকি ফাইলগুলোর সাথে রাখতে (`git` এ কমিট) হয় না, তাই কনফিগারেশনস বা **সেটিংস** এর জন্য এগুলো সাধারণত ব্যবহৃত হয়ে থাকে।
+
+আপনি একটি এনভায়রনমেন্ট ভেরিয়েবল শুধুমাত্র একটি **নির্দিষ্ট প্রোগ্রাম ইনভোকেশনের** জন্যও তৈরি করতে পারেন, যা শুধুমাত্র সেই প্রোগ্রামের জন্যই এভেইলেবল থাকবে এবং শুধুমাত্র তার চলাকালীন সময় পর্যন্তই সক্রিয় থাকবে।
+
+এটি করতে, প্রোগ্রামটি রান করার ঠিক আগেই, একই লাইনে এনভায়রনমেন্ট ভেরিয়েবল তৈরি করুন:
+
+
+
+```console
+// প্রোগ্রামটি কল করার সময় একই লাইনে MY_NAME এনভায়রনমেন্ট ভেরিয়েবল তৈরি করুন
+$ MY_NAME="Wade Wilson" python main.py
+
+// এখন এটি এনভায়রনমেন্ট ভ্যরিয়েবলটিকে রিড করতে পারবে
+
+Hello Wade Wilson from Python
+
+// পরবর্তীতে এনভায়রনমেন্ট ভেরিয়েবলটিকে আর ব্যবহার করা যাচ্ছে না
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip
+
+এটি নিয়ে আরো বিস্তারিত পড়তে পারেন এখানে
+
+```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.
+```
+
+
+
+
+
+```console
+$ ./traefik --configFile=traefik.toml
+
+INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
+```
+
+
+
+Und jetzt starten Sie Ihre Anwendung mit Uvicorn, indem Sie die Option `--root-path` verwenden:
+
+
+
+```console
+$ npm install @hey-api/openapi-ts --save-dev
+
+---> 100%
+```
+
+
+
+#### Client-Code generieren
+
+Um den Client-Code zu generieren, können Sie das Kommandozeilentool `openapi-ts` verwenden, das soeben installiert wurde.
+
+Da es im lokalen Projekt installiert ist, könnten Sie diesen Befehl wahrscheinlich nicht direkt aufrufen, sondern würden ihn in Ihre Datei `package.json` einfügen.
+
+Diese könnte so aussehen:
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "@hey-api/openapi-ts": "^0.27.38",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+Nachdem Sie das NPM-Skript `generate-client` dort stehen haben, können Sie es ausführen mit:
+
+
+
+```console
+$ npm run generate-client
+
+frontend-app@1.0.0 generate-client /home/user/code/frontend-app
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
+```
+
+
+
+Dieser Befehl generiert Code in `./src/client` und verwendet intern `axios` (die Frontend-HTTP-Bibliothek).
+
+### Den Client-Code ausprobieren
+
+Jetzt können Sie den Client-Code importieren und verwenden. Er könnte wie folgt aussehen, beachten Sie, dass Sie automatische Codevervollständigung für die Methoden erhalten:
+
+
+
+```console
+// Sie könnten eine Umgebungsvariable MY_NAME erstellen mittels
+$ export MY_NAME="Wade Wilson"
+
+// Dann könnten Sie diese mit anderen Programmen verwenden, etwa
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Erstelle eine Umgebungsvariable MY_NAME
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Verwende sie mit anderen Programmen, etwa
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+### Umgebungsvariablen mit Python auslesen
+
+Sie können Umgebungsvariablen auch außerhalb von Python im Terminal (oder mit einer anderen Methode) erstellen und diese dann mit Python auslesen.
+
+Sie könnten zum Beispiel eine Datei `main.py` haben mit:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip | Tipp
+
+Das zweite Argument für
+
+```console
+// Hier legen wir die Umgebungsvariable noch nicht fest
+$ python main.py
+
+// Da wir die Umgebungsvariable nicht festgelegt haben, erhalten wir den Standardwert
+
+Hello World from Python
+
+// Aber wenn wir zuerst eine Umgebungsvariable erstellen
+$ export MY_NAME="Wade Wilson"
+
+// Und dann das Programm erneut aufrufen
+$ python main.py
+
+// Kann es jetzt die Umgebungsvariable lesen
+
+Hello Wade Wilson from Python
+```
+
+
+
+Da Umgebungsvariablen außerhalb des Codes festgelegt, aber vom Code gelesen werden können und nicht zusammen mit den übrigen Dateien gespeichert (an `git` committet) werden müssen, werden sie häufig für Konfigurationen oder Einstellungen verwendet.
+
+Sie können eine Umgebungsvariable auch nur für einen bestimmten Programmaufruf erstellen, die nur für dieses Programm und nur für dessen Dauer verfügbar ist.
+
+Erstellen Sie diese dazu direkt vor dem Programm selbst, in derselben Zeile:
+
+
+
+```console
+// Erstelle eine Umgebungsvariable MY_NAME inline für diesen Programmaufruf
+$ MY_NAME="Wade Wilson" python main.py
+
+// main.py kann jetzt diese Umgebungsvariable lesen
+
+Hello Wade Wilson from Python
+
+// Die Umgebungsvariable existiert danach nicht mehr
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip | Tipp
+
+Weitere Informationen dazu finden Sie unter
+
+```console
+$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+/// tip | Tipp
+
+Um mehrere Umgebungsvariablen für einen einzelnen Befehl festzulegen, trennen Sie diese einfach durch ein Leerzeichen und fügen Sie alle vor dem Befehl ein.
+
+///
+
+Und dann würde die Einstellung `admin_email` auf `"deadpool@example.com"` gesetzt.
+
+Der `app_name` wäre `"ChimichangApp"`.
+
+Und `items_per_user` würde seinen Standardwert von `50` behalten.
+
+## Einstellungen in einem anderen Modul
+
+Sie könnten diese Einstellungen in eine andere Moduldatei einfügen, wie Sie in [Größere Anwendungen – mehrere Dateien](../tutorial/bigger-applications.md){.internal-link target=_blank} gesehen haben.
+
+Sie könnten beispielsweise eine Datei `config.py` haben mit:
+
+{* ../../docs_src/settings/app01/config.py *}
+
+Und dann verwenden Sie diese in einer Datei `main.py`:
+
+{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+
+/// tip | Tipp
+
+Sie benötigen außerdem eine Datei `__init__.py`, wie in [Größere Anwendungen – mehrere Dateien](../tutorial/bigger-applications.md){.internal-link target=_blank} gesehen.
+
+///
+
+## Einstellungen in einer Abhängigkeit
+
+In manchen Fällen kann es nützlich sein, die Einstellungen mit einer Abhängigkeit bereitzustellen, anstatt ein globales Objekt `settings` zu haben, das überall verwendet wird.
+
+Dies könnte besonders beim Testen nützlich sein, da es sehr einfach ist, eine Abhängigkeit mit Ihren eigenen benutzerdefinierten Einstellungen zu überschreiben.
+
+### Die Konfigurationsdatei
+
+Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
+
+{* ../../docs_src/settings/app02/config.py hl[10] *}
+
+Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
+
+### Die Haupt-Anwendungsdatei
+
+Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurückgibt.
+
+{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
+
+/// tip | Tipp
+
+Wir werden das `@lru_cache` in Kürze besprechen.
+
+Im Moment nehmen Sie an, dass `get_settings()` eine normale Funktion ist.
+
+///
+
+Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einfordern und es überall dort verwenden, wo wir es brauchen.
+
+{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
+
+### Einstellungen und Tests
+
+Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
+
+{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
+
+Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_email` fest, wenn wir das neue `Settings`-Objekt erstellen, und geben dann dieses neue Objekt zurück.
+
+Dann können wir testen, ob das verwendet wird.
+
+## Lesen einer `.env`-Datei
+
+Wenn Sie viele Einstellungen haben, die sich möglicherweise oft ändern, vielleicht in verschiedenen Umgebungen, kann es nützlich sein, diese in eine Datei zu schreiben und sie dann daraus zu lesen, als wären sie Umgebungsvariablen.
+
+Diese Praxis ist so weit verbreitet, dass sie einen Namen hat. Diese Umgebungsvariablen werden üblicherweise in einer Datei `.env` abgelegt und die Datei wird „dotenv“ genannt.
+
+/// tip | Tipp
+
+Eine Datei, die mit einem Punkt (`.`) beginnt, ist eine versteckte Datei in Unix-ähnlichen Systemen wie Linux und macOS.
+
+Aber eine dotenv-Datei muss nicht unbedingt genau diesen Dateinamen haben.
+
+///
+
+Pydantic unterstützt das Lesen dieser Dateitypen mithilfe einer externen Bibliothek. Weitere Informationen finden Sie unter
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic uvicorn
+```
+
+
+
+/// info
+
+Es gibt andere Formate und Tools zum Definieren und Installieren von Paketabhängigkeiten.
+
+Ich zeige Ihnen später in einem Abschnitt unten ein Beispiel unter Verwendung von Poetry. 👇
+
+///
+
+### Den **FastAPI**-Code erstellen
+
+* Erstellen Sie ein `app`-Verzeichnis und betreten Sie es.
+* Erstellen Sie eine leere Datei `__init__.py`.
+* Erstellen Sie eine `main.py`-Datei mit:
+
+```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}
+```
+
+### Dockerfile
+
+Erstellen Sie nun im selben Projektverzeichnis eine Datei `Dockerfile` mit:
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9
+
+# (2)
+WORKDIR /code
+
+# (3)
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)
+COPY ./app /code/app
+
+# (6)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. Beginne mit dem offiziellen Python-Basisimage.
+
+2. Setze das aktuelle Arbeitsverzeichnis auf `/code`.
+
+ Hier plazieren wir die Datei `requirements.txt` und das Verzeichnis `app`.
+
+3. Kopiere die Datei mit den Paketanforderungen in das Verzeichnis `/code`.
+
+ Kopieren Sie zuerst **nur** die Datei mit den Anforderungen, nicht den Rest des Codes.
+
+ Da sich diese Datei **nicht oft ändert**, erkennt Docker das und verwendet den **Cache** für diesen Schritt, wodurch der Cache auch für den nächsten Schritt aktiviert wird.
+
+4. Installiere die Paketabhängigkeiten aus der Anforderungsdatei.
+
+ Die Option `--no-cache-dir` weist `pip` an, die heruntergeladenen Pakete nicht lokal zu speichern, da dies nur benötigt wird, sollte `pip` erneut ausgeführt werden, um dieselben Pakete zu installieren, aber das ist beim Arbeiten mit Containern nicht der Fall.
+
+ /// note | Hinweis
+
+ Das `--no-cache-dir` bezieht sich nur auf `pip`, es hat nichts mit Docker oder Containern zu tun.
+
+ ///
+
+ Die Option `--upgrade` weist `pip` an, die Packages zu aktualisieren, wenn sie bereits installiert sind.
+
+ Da der vorherige Schritt des Kopierens der Datei vom **Docker-Cache** erkannt werden konnte, wird dieser Schritt auch **den Docker-Cache verwenden**, sofern verfügbar.
+
+ Durch die Verwendung des Caches in diesem Schritt **sparen** Sie viel **Zeit**, wenn Sie das Image während der Entwicklung immer wieder erstellen, anstatt **jedes Mal** alle Abhängigkeiten **herunterzuladen und zu installieren**.
+
+5. Kopiere das Verzeichnis `./app` in das Verzeichnis `/code`.
+
+ Da hier der gesamte Code enthalten ist, der sich **am häufigsten ändert**, wird der Docker-**Cache** nicht ohne weiteres für diesen oder andere **folgende Schritte** verwendet.
+
+ Daher ist es wichtig, dies **nahe dem Ende** des `Dockerfile`s zu platzieren, um die Erstellungszeiten des Containerimages zu optimieren.
+
+6. Lege den **Befehl** fest, um den `uvicorn`-Server zu starten.
+
+ `CMD` nimmt eine Liste von Zeichenfolgen entgegen. Jede dieser Zeichenfolgen entspricht dem, was Sie durch Leerzeichen getrennt in die Befehlszeile eingeben würden.
+
+ Dieser Befehl wird aus dem **aktuellen Arbeitsverzeichnis** ausgeführt, dem gleichen `/code`-Verzeichnis, das Sie oben mit `WORKDIR /code` festgelegt haben.
+
+ Da das Programm unter `/code` gestartet wird und sich darin das Verzeichnis `./app` mit Ihrem Code befindet, kann **Uvicorn** `app` sehen und aus `app.main` **importieren**.
+
+/// tip | Tipp
+
+Lernen Sie, was jede Zeile bewirkt, indem Sie auf die Zahlenblasen im Code klicken. 👆
+
+///
+
+Sie sollten jetzt eine Verzeichnisstruktur wie diese haben:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ └── main.py
+├── Dockerfile
+└── requirements.txt
+```
+
+#### Hinter einem TLS-Terminierungsproxy
+
+Wenn Sie Ihren Container hinter einem TLS-Terminierungsproxy (Load Balancer) wie Nginx oder Traefik ausführen, fügen Sie die Option `--proxy-headers` hinzu. Das sagt Uvicorn, den von diesem Proxy gesendeten Headern zu vertrauen und dass die Anwendung hinter HTTPS ausgeführt wird, usw.
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+#### Docker-Cache
+
+In diesem `Dockerfile` gibt es einen wichtigen Trick: Wir kopieren zuerst die **Datei nur mit den Abhängigkeiten**, nicht den Rest des Codes. Lassen Sie mich Ihnen erklären, warum.
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+Docker und andere Tools **erstellen** diese Containerimages **inkrementell**, fügen **eine Ebene über der anderen** hinzu, beginnend am Anfang des `Dockerfile`s und fügen alle durch die einzelnen Anweisungen des `Dockerfile`s erstellten Dateien hinzu.
+
+Docker und ähnliche Tools verwenden beim Erstellen des Images auch einen **internen Cache**. Wenn sich eine Datei seit der letzten Erstellung des Containerimages nicht geändert hat, wird **dieselbe Ebene wiederverwendet**, die beim letzten Mal erstellt wurde, anstatt die Datei erneut zu kopieren und eine neue Ebene von Grund auf zu erstellen.
+
+Das bloße Vermeiden des Kopierens von Dateien führt nicht unbedingt zu einer großen Verbesserung, aber da der Cache für diesen Schritt verwendet wurde, kann **der Cache für den nächsten Schritt verwendet werden**. Beispielsweise könnte der Cache verwendet werden für die Anweisung, welche die Abhängigkeiten installiert mit:
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+```
+
+Die Datei mit den Paketanforderungen wird sich **nicht häufig ändern**. Wenn Docker also nur diese Datei kopiert, kann es für diesen Schritt **den Cache verwenden**.
+
+Und dann kann Docker **den Cache für den nächsten Schritt verwenden**, der diese Abhängigkeiten herunterlädt und installiert. Und hier **sparen wir viel Zeit**. ✨ ... und vermeiden die Langeweile beim Warten. 😪😆
+
+Das Herunterladen und Installieren der Paketabhängigkeiten **könnte Minuten dauern**, aber die Verwendung des **Cache** würde höchstens **Sekunden** dauern.
+
+Und da Sie das Containerimage während der Entwicklung immer wieder erstellen würden, um zu überprüfen, ob Ihre Codeänderungen funktionieren, würde dies viel Zeit sparen.
+
+Dann, gegen Ende des `Dockerfile`s, kopieren wir den gesamten Code. Da sich der **am häufigsten ändert**, platzieren wir das am Ende, da fast immer alles nach diesem Schritt nicht mehr in der Lage sein wird, den Cache zu verwenden.
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### Das Docker-Image erstellen
+
+Nachdem nun alle Dateien vorhanden sind, erstellen wir das Containerimage.
+
+* Gehen Sie zum Projektverzeichnis (dort, wo sich Ihr `Dockerfile` und Ihr `app`-Verzeichnis befindet).
+* Erstellen Sie Ihr FastAPI-Image:
+
+
+
+```console
+$ hypercorn main:app --bind 0.0.0.0:80
+
+Running on 0.0.0.0:8080 over http (CTRL + C to quit)
+```
+
+
+
+////
+
+/// warning | Achtung
+
+Denken Sie daran, die Option `--reload` zu entfernen, wenn Sie diese verwendet haben.
+
+Die Option `--reload` verbraucht viel mehr Ressourcen, ist instabiler, usw.
+
+Sie hilft sehr während der **Entwicklung**, aber Sie sollten sie **nicht** in der **Produktion** verwenden.
+
+///
+
+## Hypercorn mit Trio
+
+Starlette und **FastAPI** basieren auf
+
+```console
+$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80
+
+[19499] [INFO] Starting gunicorn 20.1.0
+[19499] [INFO] Listening at: http://0.0.0.0:80 (19499)
+[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker
+[19511] [INFO] Booting worker with pid: 19511
+[19513] [INFO] Booting worker with pid: 19513
+[19514] [INFO] Booting worker with pid: 19514
+[19515] [INFO] Booting worker with pid: 19515
+[19511] [INFO] Started server process [19511]
+[19511] [INFO] Waiting for application startup.
+[19511] [INFO] Application startup complete.
+[19513] [INFO] Started server process [19513]
+[19513] [INFO] Waiting for application startup.
+[19513] [INFO] Application startup complete.
+[19514] [INFO] Started server process [19514]
+[19514] [INFO] Waiting for application startup.
+[19514] [INFO] Application startup complete.
+[19515] [INFO] Started server process [19515]
+[19515] [INFO] Waiting for application startup.
+[19515] [INFO] Application startup complete.
+```
+
+
+
+Sehen wir uns an, was jede dieser Optionen bedeutet:
+
+* `main:app`: Das ist die gleiche Syntax, die auch von Uvicorn verwendet wird. `main` bedeutet das Python-Modul mit dem Namen `main`, also eine Datei `main.py`. Und `app` ist der Name der Variable, welche die **FastAPI**-Anwendung ist.
+ * Stellen Sie sich einfach vor, dass `main:app` einer Python-`import`-Anweisung wie der folgenden entspricht:
+
+ ```Python
+ from main import app
+ ```
+
+ * Der Doppelpunkt in `main:app` entspricht also dem Python-`import`-Teil in `from main import app`.
+
+* `--workers`: Die Anzahl der zu verwendenden Workerprozesse, jeder führt einen Uvicorn-Worker aus, in diesem Fall 4 Worker.
+
+* `--worker-class`: Die Gunicorn-kompatible Workerklasse zur Verwendung in den Workerprozessen.
+ * Hier übergeben wir die Klasse, die Gunicorn etwa so importiert und verwendet:
+
+ ```Python
+ import uvicorn.workers.UvicornWorker
+ ```
+
+* `--bind`: Das teilt Gunicorn die IP und den Port mit, welche abgehört werden sollen, wobei ein Doppelpunkt (`:`) verwendet wird, um die IP und den Port zu trennen.
+ * Wenn Sie Uvicorn direkt ausführen würden, würden Sie anstelle von `--bind 0.0.0.0:80` (die Gunicorn-Option) stattdessen `--host 0.0.0.0` und `--port 80` verwenden.
+
+In der Ausgabe können Sie sehen, dass die **PID** (Prozess-ID) jedes Prozesses angezeigt wird (es ist nur eine Zahl).
+
+Sie können sehen, dass:
+
+* Der Gunicorn **Prozessmanager** beginnt, mit der PID `19499` (in Ihrem Fall ist es eine andere Nummer).
+* Dann beginnt er zu lauschen: `Listening at: http://0.0.0.0:80`.
+* Dann erkennt er, dass er die Workerklasse `uvicorn.workers.UvicornWorker` verwenden muss.
+* Und dann werden **4 Worker** gestartet, jeder mit seiner eigenen PID: `19511`, `19513`, `19514` und `19515`.
+
+Gunicorn würde sich bei Bedarf auch um die Verwaltung **beendeter Prozesse** und den **Neustart** von Prozessen kümmern, um die Anzahl der Worker aufrechtzuerhalten. Das hilft also teilweise beim **Neustarts**-Konzept aus der obigen Liste.
+
+Dennoch möchten Sie wahrscheinlich auch etwas außerhalb haben, um sicherzustellen, dass Gunicorn bei Bedarf **neu gestartet wird**, und er auch **beim Hochfahren ausgeführt wird**, usw.
+
+## Uvicorn mit Workern
+
+Uvicorn bietet ebenfalls die Möglichkeit, mehrere **Workerprozesse** zu starten und auszuführen.
+
+Dennoch sind die Fähigkeiten von Uvicorn zur Abwicklung von Workerprozessen derzeit eingeschränkter als die von Gunicorn. Wenn Sie also einen Prozessmanager auf dieser Ebene (auf der Python-Ebene) haben möchten, ist es vermutlich besser, es mit Gunicorn als Prozessmanager zu versuchen.
+
+Wie auch immer, Sie würden es so ausführen:
+
+
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+
+
+Und kopieren Sie die Ausgabe in die Variable `SECRET_KEY` (verwenden Sie nicht die im Beispiel).
+
+Erstellen Sie eine Variable `ALGORITHM` für den Algorithmus, der zum Signieren des JWT-Tokens verwendet wird, und setzen Sie sie auf `"HS256"`.
+
+Erstellen Sie eine Variable für das Ablaufdatum des Tokens.
+
+Definieren Sie ein Pydantic-Modell, das im Token-Endpunkt für die Response verwendet wird.
+
+Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[6,12:14,28:30,78:86] *}
+
+## Die Abhängigkeiten aktualisieren
+
+Aktualisieren Sie `get_current_user`, um den gleichen Token wie zuvor zu erhalten, dieses Mal jedoch unter Verwendung von JWT-Tokens.
+
+Dekodieren Sie den empfangenen Token, validieren Sie ihn und geben Sie den aktuellen Benutzer zurück.
+
+Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[89:106] *}
+
+## Die *Pfadoperation* `/token` aktualisieren
+
+Erstellen Sie ein
+
+```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/de/mkdocs.yml b/docs/de/mkdocs.yml
index 8c3c42b5f..de18856f4 100644
--- a/docs/de/mkdocs.yml
+++ b/docs/de/mkdocs.yml
@@ -1,146 +1 @@
-site_name: FastAPI
-site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
-site_url: https://fastapi.tiangolo.com/de/
-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: de
-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/
- - es: /es/
- - fa: /fa/
- - fr: /fr/
- - he: /he/
- - id: /id/
- - it: /it/
- - ja: /ja/
- - ko: /ko/
- - nl: /nl/
- - pl: /pl/
- - pt: /pt/
- - ru: /ru/
- - sq: /sq/
- - sv: /sv/
- - tr: /tr/
- - uk: /uk/
- - zh: /zh/
-- features.md
-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: UA-133183413-1
- 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: /es/
- name: es - español
- - link: /fa/
- name: fa
- - link: /fr/
- name: fr - français
- - link: /he/
- name: he
- - link: /id/
- name: id
- - link: /it/
- name: it - italiano
- - link: /ja/
- name: ja - 日本語
- - link: /ko/
- name: ko - 한국어
- - 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: /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
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/em/docs/advanced/additional-responses.md b/docs/em/docs/advanced/additional-responses.md
new file mode 100644
index 000000000..655fc7ab6
--- /dev/null
+++ b/docs/em/docs/advanced/additional-responses.md
@@ -0,0 +1,247 @@
+# 🌖 📨 🗄
+
+/// warning
+
+👉 👍 🏧 ❔.
+
+🚥 👆 ▶️ ⏮️ **FastAPI**, 👆 💪 🚫 💪 👉.
+
+///
+
+👆 💪 📣 🌖 📨, ⏮️ 🌖 👔 📟, 🔉 🆎, 📛, ♒️.
+
+👈 🌖 📨 🔜 🔌 🗄 🔗, 👫 🔜 😑 🛠️ 🩺.
+
+✋️ 👈 🌖 📨 👆 ✔️ ⚒ 💭 👆 📨 `Response` 💖 `JSONResponse` 🔗, ⏮️ 👆 👔 📟 & 🎚.
+
+## 🌖 📨 ⏮️ `model`
+
+👆 💪 🚶♀️ 👆 *➡ 🛠️ 👨🎨* 🔢 `responses`.
+
+⚫️ 📨 `dict`, 🔑 👔 📟 🔠 📨, 💖 `200`, & 💲 🎏 `dict`Ⓜ ⏮️ ℹ 🔠 👫.
+
+🔠 👈 📨 `dict`Ⓜ 💪 ✔️ 🔑 `model`, ⚗ Pydantic 🏷, 💖 `response_model`.
+
+**FastAPI** 🔜 ✊ 👈 🏷, 🏗 🚮 🎻 🔗 & 🔌 ⚫️ ☑ 🥉 🗄.
+
+🖼, 📣 ➕1️⃣ 📨 ⏮️ 👔 📟 `404` & Pydantic 🏷 `Message`, 👆 💪 ✍:
+
+{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+
+/// note
+
+✔️ 🤯 👈 👆 ✔️ 📨 `JSONResponse` 🔗.
+
+///
+
+/// info
+
+`model` 🔑 🚫 🍕 🗄.
+
+**FastAPI** 🔜 ✊ Pydantic 🏷 ⚪️➡️ 📤, 🏗 `JSON Schema`, & 🚮 ⚫️ ☑ 🥉.
+
+☑ 🥉:
+
+* 🔑 `content`, 👈 ✔️ 💲 ➕1️⃣ 🎻 🎚 (`dict`) 👈 🔌:
+ * 🔑 ⏮️ 📻 🆎, ✅ `application/json`, 👈 🔌 💲 ➕1️⃣ 🎻 🎚, 👈 🔌:
+ * 🔑 `schema`, 👈 ✔️ 💲 🎻 🔗 ⚪️➡️ 🏷, 📥 ☑ 🥉.
+ * **FastAPI** 🚮 🔗 📥 🌐 🎻 🔗 ➕1️⃣ 🥉 👆 🗄 ↩️ ✅ ⚫️ 🔗. 👉 🌌, 🎏 🈸 & 👩💻 💪 ⚙️ 👈 🎻 🔗 🔗, 🚚 👻 📟 ⚡ 🧰, ♒️.
+
+///
+
+🏗 📨 🗄 👉 *➡ 🛠️* 🔜:
+
+```JSON hl_lines="3-12"
+{
+ "responses": {
+ "404": {
+ "description": "Additional Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Message"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Item"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+🔗 🔗 ➕1️⃣ 🥉 🔘 🗄 🔗:
+
+```JSON hl_lines="4-16"
+{
+ "components": {
+ "schemas": {
+ "Message": {
+ "title": "Message",
+ "required": [
+ "message"
+ ],
+ "type": "object",
+ "properties": {
+ "message": {
+ "title": "Message",
+ "type": "string"
+ }
+ }
+ },
+ "Item": {
+ "title": "Item",
+ "required": [
+ "id",
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "title": "Id",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "type": "string"
+ }
+ }
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": [
+ "loc",
+ "msg",
+ "type"
+ ],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "msg": {
+ "title": "Message",
+ "type": "string"
+ },
+ "type": {
+ "title": "Error Type",
+ "type": "string"
+ }
+ }
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+## 🌖 🔉 🆎 👑 📨
+
+👆 💪 ⚙️ 👉 🎏 `responses` 🔢 🚮 🎏 🔉 🆎 🎏 👑 📨.
+
+🖼, 👆 💪 🚮 🌖 📻 🆎 `image/png`, 📣 👈 👆 *➡ 🛠️* 💪 📨 🎻 🎚 (⏮️ 📻 🆎 `application/json`) ⚖️ 🇩🇴 🖼:
+
+{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
+
+/// note
+
+👀 👈 👆 ✔️ 📨 🖼 ⚙️ `FileResponse` 🔗.
+
+///
+
+/// info
+
+🚥 👆 ✔ 🎏 📻 🆎 🎯 👆 `responses` 🔢, FastAPI 🔜 🤔 📨 ✔️ 🎏 📻 🆎 👑 📨 🎓 (🔢 `application/json`).
+
+✋️ 🚥 👆 ✔️ ✔ 🛃 📨 🎓 ⏮️ `None` 🚮 📻 🆎, FastAPI 🔜 ⚙️ `application/json` 🙆 🌖 📨 👈 ✔️ 👨💼 🏷.
+
+///
+
+## 🌀 ℹ
+
+👆 💪 🌀 📨 ℹ ⚪️➡️ 💗 🥉, 🔌 `response_model`, `status_code`, & `responses` 🔢.
+
+👆 💪 📣 `response_model`, ⚙️ 🔢 👔 📟 `200` (⚖️ 🛃 1️⃣ 🚥 👆 💪), & ⤴️ 📣 🌖 ℹ 👈 🎏 📨 `responses`, 🔗 🗄 🔗.
+
+**FastAPI** 🔜 🚧 🌖 ℹ ⚪️➡️ `responses`, & 🌀 ⚫️ ⏮️ 🎻 🔗 ⚪️➡️ 👆 🏷.
+
+🖼, 👆 💪 📣 📨 ⏮️ 👔 📟 `404` 👈 ⚙️ Pydantic 🏷 & ✔️ 🛃 `description`.
+
+& 📨 ⏮️ 👔 📟 `200` 👈 ⚙️ 👆 `response_model`, ✋️ 🔌 🛃 `example`:
+
+{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+
+⚫️ 🔜 🌐 🌀 & 🔌 👆 🗄, & 🎦 🛠️ 🩺:
+
+
+
+```console
+$ ./traefik --configFile=traefik.toml
+
+INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
+```
+
+
+
+& 🔜 ▶️ 👆 📱 ⏮️ Uvicorn, ⚙️ `--root-path` 🎛:
+
+
+
+```console
+$ npm install @hey-api/openapi-ts --save-dev
+
+---> 100%
+```
+
+
+
+#### 🏗 👩💻 📟
+
+🏗 👩💻 📟 👆 💪 ⚙️ 📋 ⏸ 🈸 `openapi-ts` 👈 🔜 🔜 ❎.
+
+↩️ ⚫️ ❎ 🇧🇿 🏗, 👆 🎲 🚫🔜 💪 🤙 👈 📋 🔗, ✋️ 👆 🔜 🚮 ⚫️ 🔛 👆 `package.json` 📁.
+
+⚫️ 💪 👀 💖 👉:
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "@hey-api/openapi-ts": "^0.27.38",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+⏮️ ✔️ 👈 ☕ `generate-client` ✍ 📤, 👆 💪 🏃 ⚫️ ⏮️:
+
+
+
+```console
+$ npm run generate-client
+
+frontend-app@1.0.0 generate-client /home/user/code/frontend-app
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
+```
+
+
+
+👈 📋 🔜 🏗 📟 `./src/client` & 🔜 ⚙️ `axios` (🕸 🇺🇸🔍 🗃) 🔘.
+
+### 🔄 👅 👩💻 📟
+
+🔜 👆 💪 🗄 & ⚙️ 👩💻 📟, ⚫️ 💪 👀 💖 👉, 👀 👈 👆 🤚 ✍ 👩🔬:
+
+
+
+```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
+```
+
+
+
+////
+
+//// tab | 🚪 📋
+
+
+
+```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
+```
+
+
+
+////
+
+### ✍ 🇨🇻 {🐍
+
+👆 💪 ✍ 🌐 🔢 🏞 🐍, 📶 (⚖️ ⏮️ 🙆 🎏 👩🔬), & ⤴️ ✍ 👫 🐍.
+
+🖼 👆 💪 ✔️ 📁 `main.py` ⏮️:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+🥈 ❌
+
+```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
+```
+
+
+
+🌐 🔢 💪 ⚒ 🏞 📟, ✋️ 💪 ✍ 📟, & 🚫 ✔️ 🏪 (💕 `git`) ⏮️ 🎂 📁, ⚫️ ⚠ ⚙️ 👫 📳 ⚖️ ⚒.
+
+👆 💪 ✍ 🌐 🔢 🕴 🎯 📋 👼, 👈 🕴 💪 👈 📋, & 🕴 🚮 📐.
+
+👈, ✍ ⚫️ ▶️️ ⏭ 📋 ⚫️, 🔛 🎏 ⏸:
+
+
+
+```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
+```
+
+
+
+/// tip
+
+👆 💪 ✍ 🌅 🔃 ⚫️
+
+```console
+$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+/// tip
+
+⚒ 💗 🇨🇻 {👁 📋 🎏 👫 ⏮️ 🚀, & 🚮 👫 🌐 ⏭ 📋.
+
+///
+
+& ⤴️ `admin_email` ⚒ 🔜 ⚒ `"deadpool@example.com"`.
+
+`app_name` 🔜 `"ChimichangApp"`.
+
+& `items_per_user` 🔜 🚧 🚮 🔢 💲 `50`.
+
+## ⚒ ➕1️⃣ 🕹
+
+👆 💪 🚮 👈 ⚒ ➕1️⃣ 🕹 📁 👆 👀 [🦏 🈸 - 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+
+🖼, 👆 💪 ✔️ 📁 `config.py` ⏮️:
+
+{* ../../docs_src/settings/app01/config.py *}
+
+& ⤴️ ⚙️ ⚫️ 📁 `main.py`:
+
+{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+
+/// tip
+
+👆 🔜 💪 📁 `__init__.py` 👆 👀 🔛 [🦏 🈸 - 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+
+///
+
+## ⚒ 🔗
+
+🍾 ⚫️ 5️⃣📆 ⚠ 🚚 ⚒ ⚪️➡️ 🔗, ↩️ ✔️ 🌐 🎚 ⏮️ `settings` 👈 ⚙️ 🌐.
+
+👉 💪 ✴️ ⚠ ⏮️ 🔬, ⚫️ 📶 ⏩ 🔐 🔗 ⏮️ 👆 👍 🛃 ⚒.
+
+### 📁 📁
+
+👟 ⚪️➡️ ⏮️ 🖼, 👆 `config.py` 📁 💪 👀 💖:
+
+{* ../../docs_src/settings/app02/config.py hl[10] *}
+
+👀 👈 🔜 👥 🚫 ✍ 🔢 👐 `settings = Settings()`.
+
+### 👑 📱 📁
+
+🔜 👥 ✍ 🔗 👈 📨 🆕 `config.Settings()`.
+
+{* ../../docs_src/settings/app02/main.py hl[5,11:12] *}
+
+/// tip
+
+👥 🔜 🔬 `@lru_cache` 🍖.
+
+🔜 👆 💪 🤔 `get_settings()` 😐 🔢.
+
+///
+
+& ⤴️ 👥 💪 🚚 ⚫️ ⚪️➡️ *➡ 🛠️ 🔢* 🔗 & ⚙️ ⚫️ 🙆 👥 💪 ⚫️.
+
+{* ../../docs_src/settings/app02/main.py hl[16,18:20] *}
+
+### ⚒ & 🔬
+
+⤴️ ⚫️ 🔜 📶 ⏩ 🚚 🎏 ⚒ 🎚 ⏮️ 🔬 🏗 🔗 🔐 `get_settings`:
+
+{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
+
+🔗 🔐 👥 ⚒ 🆕 💲 `admin_email` 🕐❔ 🏗 🆕 `Settings` 🎚, & ⤴️ 👥 📨 👈 🆕 🎚.
+
+⤴️ 👥 💪 💯 👈 ⚫️ ⚙️.
+
+## 👂 `.env` 📁
+
+🚥 👆 ✔️ 📚 ⚒ 👈 🎲 🔀 📚, 🎲 🎏 🌐, ⚫️ 5️⃣📆 ⚠ 🚮 👫 🔛 📁 & ⤴️ ✍ 👫 ⚪️➡️ ⚫️ 🚥 👫 🌐 🔢.
+
+👉 💡 ⚠ 🥃 👈 ⚫️ ✔️ 📛, 👫 🌐 🔢 🛎 🥉 📁 `.env`, & 📁 🤙 "🇨🇻".
+
+/// tip
+
+📁 ▶️ ⏮️ ❣ (`.`) 🕵♂ 📁 🖥-💖 ⚙️, 💖 💾 & 🇸🇻.
+
+✋️ 🇨🇻 📁 🚫 🤙 ✔️ ✔️ 👈 ☑ 📁.
+
+///
+
+Pydantic ✔️ 🐕🦺 👂 ⚪️➡️ 👉 🆎 📁 ⚙️ 🔢 🗃. 👆 💪 ✍ 🌖
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic uvicorn
+```
+
+
+
+/// info
+
+📤 🎏 📁 & 🧰 🔬 & ❎ 📦 🔗.
+
+👤 🔜 🎦 👆 🖼 ⚙️ 🎶 ⏪ 📄 🔛. 👶
+
+///
+
+### ✍ **FastAPI** 📟
+
+* ✍ `app` 📁 & ⛔ ⚫️.
+* ✍ 🛁 📁 `__init__.py`.
+* ✍ `main.py` 📁 ⏮️:
+
+```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}
+```
+
+### 📁
+
+🔜 🎏 🏗 📁 ✍ 📁 `Dockerfile` ⏮️:
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9
+
+# (2)
+WORKDIR /code
+
+# (3)
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)
+COPY ./app /code/app
+
+# (6)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1️⃣. ▶️ ⚪️➡️ 🛂 🐍 🧢 🖼.
+
+2️⃣. ⚒ ⏮️ 👷 📁 `/code`.
+
+ 👉 🌐❔ 👥 🔜 🚮 `requirements.txt` 📁 & `app` 📁.
+
+3️⃣. 📁 📁 ⏮️ 📄 `/code` 📁.
+
+ 📁 **🕴** 📁 ⏮️ 📄 🥇, 🚫 🎂 📟.
+
+ 👉 📁 **🚫 🔀 🛎**, ☁ 🔜 🔍 ⚫️ & ⚙️ **💾** 👉 🔁, 🛠️ 💾 ⏭ 🔁 💁♂️.
+
+4️⃣. ❎ 📦 🔗 📄 📁.
+
+ `--no-cache-dir` 🎛 💬 `pip` 🚫 🖊 ⏬ 📦 🌐, 👈 🕴 🚥 `pip` 🔜 🏃 🔄 ❎ 🎏 📦, ✋️ 👈 🚫 💼 🕐❔ 👷 ⏮️ 📦.
+
+ /// note
+
+ `--no-cache-dir` 🕴 🔗 `pip`, ⚫️ ✔️ 🕳 ⏮️ ☁ ⚖️ 📦.
+
+ ///
+
+ `--upgrade` 🎛 💬 `pip` ♻ 📦 🚥 👫 ⏪ ❎.
+
+ ↩️ ⏮️ 🔁 🖨 📁 💪 🔍 **☁ 💾**, 👉 🔁 🔜 **⚙️ ☁ 💾** 🕐❔ 💪.
+
+ ⚙️ 💾 👉 🔁 🔜 **🖊** 👆 📚 **🕰** 🕐❔ 🏗 🖼 🔄 & 🔄 ⏮️ 🛠️, ↩️ **⏬ & ❎** 🌐 🔗 **🔠 🕰**.
+
+5️⃣. 📁 `./app` 📁 🔘 `/code` 📁.
+
+ 👉 ✔️ 🌐 📟 ❔ ⚫️❔ **🔀 🌅 🛎** ☁ **💾** 🏆 🚫 ⚙️ 👉 ⚖️ 🙆 **📄 🔁** 💪.
+
+ , ⚫️ ⚠ 🚮 👉 **🏘 🔚** `Dockerfile`, 🔬 📦 🖼 🏗 🕰.
+
+6️⃣. ⚒ **📋** 🏃 `uvicorn` 💽.
+
+ `CMD` ✊ 📇 🎻, 🔠 👫 🎻 ⚫️❔ 👆 🔜 🆎 📋 ⏸ 👽 🚀.
+
+ 👉 📋 🔜 🏃 ⚪️➡️ **⏮️ 👷 📁**, 🎏 `/code` 📁 👆 ⚒ 🔛 ⏮️ `WORKDIR /code`.
+
+ ↩️ 📋 🔜 ▶️ `/code` & 🔘 ⚫️ 📁 `./app` ⏮️ 👆 📟, **Uvicorn** 🔜 💪 👀 & **🗄** `app` ⚪️➡️ `app.main`.
+
+/// tip
+
+📄 ⚫️❔ 🔠 ⏸ 🔨 🖊 🔠 🔢 💭 📟. 👶
+
+///
+
+👆 🔜 🔜 ✔️ 📁 📊 💖:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ └── main.py
+├── Dockerfile
+└── requirements.txt
+```
+
+#### ⛅ 🤝 ❎ 🗳
+
+🚥 👆 🏃♂ 👆 📦 ⛅ 🤝 ❎ 🗳 (📐 ⚙) 💖 👌 ⚖️ Traefik, 🚮 🎛 `--proxy-headers`, 👉 🔜 💬 Uvicorn 💙 🎚 📨 👈 🗳 💬 ⚫️ 👈 🈸 🏃 ⛅ 🇺🇸🔍, ♒️.
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+#### ☁ 💾
+
+📤 ⚠ 🎱 👉 `Dockerfile`, 👥 🥇 📁 **📁 ⏮️ 🔗 😞**, 🚫 🎂 📟. ➡️ 👤 💬 👆 ⚫️❔ 👈.
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+☁ & 🎏 🧰 **🏗** 👉 📦 🖼 **🔁**, 🚮 **1️⃣ 🧽 🔛 🔝 🎏**, ▶️ ⚪️➡️ 🔝 `Dockerfile` & ❎ 🙆 📁 ✍ 🔠 👩🌾 `Dockerfile`.
+
+☁ & 🎏 🧰 ⚙️ **🔗 💾** 🕐❔ 🏗 🖼, 🚥 📁 🚫 🔀 ↩️ 🏁 🕰 🏗 📦 🖼, ⤴️ ⚫️ 🔜 **🏤-⚙️ 🎏 🧽** ✍ 🏁 🕰, ↩️ 🖨 📁 🔄 & 🏗 🆕 🧽 ⚪️➡️ 🖌.
+
+❎ 📁 📁 🚫 🎯 📉 👜 💁♂️ 🌅, ✋️ ↩️ ⚫️ ⚙️ 💾 👈 🔁, ⚫️ 💪 **⚙️ 💾 ⏭ 🔁**. 🖼, ⚫️ 💪 ⚙️ 💾 👩🌾 👈 ❎ 🔗 ⏮️:
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+```
+
+📁 ⏮️ 📦 📄 **🏆 🚫 🔀 🛎**. , 🖨 🕴 👈 📁, ☁ 🔜 💪 **⚙️ 💾** 👈 🔁.
+
+& ⤴️, ☁ 🔜 💪 **⚙️ 💾 ⏭ 🔁** 👈 ⏬ & ❎ 👈 🔗. & 📥 🌐❔ 👥 **🖊 📚 🕰**. 👶 ...& ❎ 😩 ⌛. 👶 👶
+
+⏬ & ❎ 📦 🔗 **💪 ✊ ⏲**, ✋️ ⚙️ **💾** 🔜 **✊ 🥈** 🌅.
+
+& 👆 🔜 🏗 📦 🖼 🔄 & 🔄 ⏮️ 🛠️ ✅ 👈 👆 📟 🔀 👷, 📤 📚 📈 🕰 👉 🔜 🖊.
+
+⤴️, 🏘 🔚 `Dockerfile`, 👥 📁 🌐 📟. 👉 ⚫️❔ **🔀 🏆 🛎**, 👥 🚮 ⚫️ 🏘 🔚, ↩️ 🌖 🕧, 🕳 ⏮️ 👉 🔁 🔜 🚫 💪 ⚙️ 💾.
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### 🏗 ☁ 🖼
+
+🔜 👈 🌐 📁 🥉, ➡️ 🏗 📦 🖼.
+
+* 🚶 🏗 📁 (🌐❔ 👆 `Dockerfile` , ⚗ 👆 `app` 📁).
+* 🏗 👆 FastAPI 🖼:
+
+
+
+```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 ⏮️ 🎻
+
+💃 & **FastAPI** ⚓️ 🔛
+
+```console
+$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80
+
+[19499] [INFO] Starting gunicorn 20.1.0
+[19499] [INFO] Listening at: http://0.0.0.0:80 (19499)
+[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker
+[19511] [INFO] Booting worker with pid: 19511
+[19513] [INFO] Booting worker with pid: 19513
+[19514] [INFO] Booting worker with pid: 19514
+[19515] [INFO] Booting worker with pid: 19515
+[19511] [INFO] Started server process [19511]
+[19511] [INFO] Waiting for application startup.
+[19511] [INFO] Application startup complete.
+[19513] [INFO] Started server process [19513]
+[19513] [INFO] Waiting for application startup.
+[19513] [INFO] Application startup complete.
+[19514] [INFO] Started server process [19514]
+[19514] [INFO] Waiting for application startup.
+[19514] [INFO] Application startup complete.
+[19515] [INFO] Started server process [19515]
+[19515] [INFO] Waiting for application startup.
+[19515] [INFO] Application startup complete.
+```
+
+
+
+➡️ 👀 ⚫️❔ 🔠 👈 🎛 ⛓:
+
+* `main:app`: 👉 🎏 ❕ ⚙️ Uvicorn, `main` ⛓ 🐍 🕹 📛 "`main`",, 📁 `main.py`. & `app` 📛 🔢 👈 **FastAPI** 🈸.
+ * 👆 💪 🌈 👈 `main:app` 🌓 🐍 `import` 📄 💖:
+
+ ```Python
+ from main import app
+ ```
+
+ * , ❤ `main:app` 🔜 🌓 🐍 `import` 🍕 `from main import app`.
+* `--workers`: 🔢 👨🏭 🛠️ ⚙️, 🔠 🔜 🏃 Uvicorn 👨🏭, 👉 💼, 4️⃣ 👨🏭.
+* `--worker-class`: 🐁-🔗 👨🏭 🎓 ⚙️ 👨🏭 🛠️.
+ * 📥 👥 🚶♀️ 🎓 👈 🐁 💪 🗄 & ⚙️ ⏮️:
+
+ ```Python
+ import uvicorn.workers.UvicornWorker
+ ```
+
+* `--bind`: 👉 💬 🐁 📢 & ⛴ 👂, ⚙️ ❤ (`:`) 🎏 📢 & ⛴.
+ * 🚥 👆 🏃♂ Uvicorn 🔗, ↩️ `--bind 0.0.0.0:80` (🐁 🎛) 👆 🔜 ⚙️ `--host 0.0.0.0` & `--port 80`.
+
+🔢, 👆 💪 👀 👈 ⚫️ 🎦 **🕹** (🛠️ 🆔) 🔠 🛠️ (⚫️ 🔢).
+
+👆 💪 👀 👈:
+
+* 🐁 **🛠️ 👨💼** ▶️ ⏮️ 🕹 `19499` (👆 💼 ⚫️ 🔜 🎏 🔢).
+* ⤴️ ⚫️ ▶️ `Listening at: http://0.0.0.0:80`.
+* ⤴️ ⚫️ 🔍 👈 ⚫️ ✔️ ⚙️ 👨🏭 🎓 `uvicorn.workers.UvicornWorker`.
+* & ⤴️ ⚫️ ▶️ **4️⃣ 👨🏭**, 🔠 ⏮️ 🚮 👍 🕹: `19511`, `19513`, `19514`, & `19515`.
+
+🐁 🔜 ✊ 💅 🛠️ **☠️ 🛠️** & **🔁** 🆕 🕐 🚥 💚 🚧 🔢 👨🏭. 👈 ℹ 🍕 ⏮️ **⏏** 🔧 ⚪️➡️ 📇 🔛.
+
+👐, 👆 🔜 🎲 💚 ✔️ 🕳 🏞 ⚒ 💭 **⏏ 🐁** 🚥 💪, & **🏃 ⚫️ 🔛 🕴**, ♒️.
+
+## Uvicorn ⏮️ 👨🏭
+
+Uvicorn ✔️ 🎛 ▶️ & 🏃 📚 **👨🏭 🛠️**.
+
+👐, 🔜, Uvicorn 🛠️ 🚚 👨🏭 🛠️ 🌅 📉 🌘 🐁. , 🚥 👆 💚 ✔️ 🛠️ 👨💼 👉 🎚 (🐍 🎚), ⤴️ ⚫️ 💪 👍 🔄 ⏮️ 🐁 🛠️ 👨💼.
+
+🙆 💼, 👆 🔜 🏃 ⚫️ 💖 👉:
+
+
+
+```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.
+```
+
+
+
+
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+
+
+& 📁 🔢 🔢 `SECRET_KEY` (🚫 ⚙️ 1️⃣ 🖼).
+
+✍ 🔢 `ALGORITHM` ⏮️ 📊 ⚙️ 🛑 🥙 🤝 & ⚒ ⚫️ `"HS256"`.
+
+✍ 🔢 👔 🤝.
+
+🔬 Pydantic 🏷 👈 🔜 ⚙️ 🤝 🔗 📨.
+
+✍ 🚙 🔢 🏗 🆕 🔐 🤝.
+
+{* ../../docs_src/security/tutorial004.py hl[6,12:14,28:30,78:86] *}
+
+## ℹ 🔗
+
+ℹ `get_current_user` 📨 🎏 🤝 ⏭, ✋️ 👉 🕰, ⚙️ 🥙 🤝.
+
+🔣 📨 🤝, ✔ ⚫️, & 📨 ⏮️ 👩💻.
+
+🚥 🤝 ❌, 📨 🇺🇸🔍 ❌ ▶️️ ↖️.
+
+{* ../../docs_src/security/tutorial004.py hl[89:106] *}
+
+## ℹ `/token` *➡ 🛠️*
+
+✍ `timedelta` ⏮️ 👔 🕰 🤝.
+
+✍ 🎰 🥙 🔐 🤝 & 📨 ⚫️.
+
+{* ../../docs_src/security/tutorial004.py hl[115:130] *}
+
+### 📡 ℹ 🔃 🥙 "📄" `sub`
+
+🥙 🔧 💬 👈 📤 🔑 `sub`, ⏮️ 📄 🤝.
+
+⚫️ 📦 ⚙️ ⚫️, ✋️ 👈 🌐❔ 👆 🔜 🚮 👩💻 🆔, 👥 ⚙️ ⚫️ 📥.
+
+🥙 5️⃣📆 ⚙️ 🎏 👜 ↖️ ⚪️➡️ ⚖ 👩💻 & 🤝 👫 🎭 🛠️ 🔗 🔛 👆 🛠️.
+
+🖼, 👆 💪 🔬 "🚘" ⚖️ "📰 🏤".
+
+⤴️ 👆 💪 🚮 ✔ 🔃 👈 👨💼, 💖 "💾" (🚘) ⚖️ "✍" (📰).
+
+& ⤴️, 👆 💪 🤝 👈 🥙 🤝 👩💻 (⚖️ 🤖), & 👫 💪 ⚙️ ⚫️ 🎭 👈 🎯 (💾 🚘, ⚖️ ✍ 📰 🏤) 🍵 💆♂ ✔️ 🏧, ⏮️ 🥙 🤝 👆 🛠️ 🏗 👈.
+
+⚙️ 👫 💭, 🥙 💪 ⚙️ 🌌 🌖 🤓 😐.
+
+📚 💼, 📚 👈 👨💼 💪 ✔️ 🎏 🆔, ➡️ 💬 `foo` (👩💻 `foo`, 🚘 `foo`, & 📰 🏤 `foo`).
+
+, ❎ 🆔 💥, 🕐❔ 🏗 🥙 🤝 👩💻, 👆 💪 🔡 💲 `sub` 🔑, ✅ ⏮️ `username:`. , 👉 🖼, 💲 `sub` 💪 ✔️: `username:johndoe`.
+
+⚠ 👜 ✔️ 🤯 👈 `sub` 🔑 🔜 ✔️ 😍 🆔 🤭 🎂 🈸, & ⚫️ 🔜 🎻.
+
+## ✅ ⚫️
+
+🏃 💽 & 🚶 🩺:
+
+```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/em/mkdocs.yml b/docs/em/mkdocs.yml
new file mode 100644
index 000000000..de18856f4
--- /dev/null
+++ b/docs/em/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/en/data/contributors.yml b/docs/en/data/contributors.yml
new file mode 100644
index 000000000..e06510ac4
--- /dev/null
+++ b/docs/en/data/contributors.yml
@@ -0,0 +1,560 @@
+tiangolo:
+ login: tiangolo
+ count: 753
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+dependabot:
+ login: dependabot
+ count: 104
+ avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
+ url: https://github.com/apps/dependabot
+alejsdev:
+ login: alejsdev
+ count: 47
+ avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=638c65283ac9e9e2c3a0f9d1e3370db4b8a2c58d&v=4
+ url: https://github.com/alejsdev
+pre-commit-ci:
+ login: pre-commit-ci
+ count: 33
+ avatarUrl: https://avatars.githubusercontent.com/in/68672?v=4
+ url: https://github.com/apps/pre-commit-ci
+github-actions:
+ login: github-actions
+ count: 26
+ avatarUrl: https://avatars.githubusercontent.com/in/15368?v=4
+ url: https://github.com/apps/github-actions
+Kludex:
+ login: Kludex
+ count: 23
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
+ url: https://github.com/Kludex
+dmontagu:
+ login: dmontagu
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
+ url: https://github.com/dmontagu
+euri10:
+ login: euri10
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
+ url: https://github.com/euri10
+kantandane:
+ login: kantandane
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/3978368?u=cccc199291f991a73b1ebba5abc735a948e0bd16&v=4
+ url: https://github.com/kantandane
+nilslindemann:
+ login: nilslindemann
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
+ url: https://github.com/nilslindemann
+zhaohan-dong:
+ login: zhaohan-dong
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/65422392?u=8260f8781f50248410ebfa4c9bf70e143fe5c9f2&v=4
+ url: https://github.com/zhaohan-dong
+mariacamilagl:
+ login: mariacamilagl
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
+ url: https://github.com/mariacamilagl
+handabaldeep:
+ login: handabaldeep
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/12239103?u=6c39ef15d14c6d5211f5dd775cc4842f8d7f2f3a&v=4
+ url: https://github.com/handabaldeep
+vishnuvskvkl:
+ login: vishnuvskvkl
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/84698110?u=8af5de0520dd4fa195f53c2850a26f57c0f6bc64&v=4
+ url: https://github.com/vishnuvskvkl
+svlandeg:
+ login: svlandeg
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
+ url: https://github.com/svlandeg
+alissadb:
+ login: alissadb
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/96190409?u=be42d85938c241be781505a5a872575be28b2906&v=4
+ url: https://github.com/alissadb
+wshayes:
+ login: wshayes
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
+ url: https://github.com/wshayes
+samuelcolvin:
+ login: samuelcolvin
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
+ url: https://github.com/samuelcolvin
+waynerv:
+ login: waynerv
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
+ url: https://github.com/waynerv
+krishnamadhavan:
+ login: krishnamadhavan
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/31798870?u=950693b28f3ae01105fd545c046e46ca3d31ab06&v=4
+ url: https://github.com/krishnamadhavan
+alv2017:
+ login: alv2017
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+jekirl:
+ login: jekirl
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
+ url: https://github.com/jekirl
+hitrust:
+ login: hitrust
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/3360631?u=5fa1f475ad784d64eb9666bdd43cc4d285dcc773&v=4
+ url: https://github.com/hitrust
+ShahriyarR:
+ login: ShahriyarR
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/3852029?u=631b2ae59360ab380c524b32bc3d245aff1165af&v=4
+ url: https://github.com/ShahriyarR
+adriangb:
+ login: adriangb
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
+ url: https://github.com/adriangb
+iudeen:
+ login: iudeen
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
+ url: https://github.com/iudeen
+philipokiokio:
+ login: philipokiokio
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/55271518?u=d30994d339aaaf1f6bf1b8fc810132016fbd4fdc&v=4
+ url: https://github.com/philipokiokio
+AlexWendland:
+ login: AlexWendland
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/3949212?u=c4c0c615e0ea33d00bfe16b779cf6ebc0f58071c&v=4
+ url: https://github.com/AlexWendland
+divums:
+ login: divums
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/1397556?v=4
+ url: https://github.com/divums
+prostomarkeloff:
+ login: prostomarkeloff
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=6918e39a1224194ba636e897461a02a20126d7ad&v=4
+ url: https://github.com/prostomarkeloff
+nsidnev:
+ login: nsidnev
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
+ url: https://github.com/nsidnev
+pawamoy:
+ login: pawamoy
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
+ url: https://github.com/pawamoy
+patrickmckenna:
+ login: patrickmckenna
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3589536?u=53aef07250d226d35e526768e26891964907b41a&v=4
+ url: https://github.com/patrickmckenna
+hukkin:
+ login: hukkin
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3275109?u=77bb83759127965eacbfe67e2ca983066e964fde&v=4
+ url: https://github.com/hukkin
+marcosmmb:
+ login: marcosmmb
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/6181089?u=03c50eec631857d84df5232890780d00a3f76903&v=4
+ url: https://github.com/marcosmmb
+Serrones:
+ login: Serrones
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
+ url: https://github.com/Serrones
+uriyyo:
+ login: uriyyo
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/32038156?u=a27b65a9ec3420586a827a0facccbb8b6df1ffb3&v=4
+ url: https://github.com/uriyyo
+andrew222651:
+ login: andrew222651
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/889657?u=d70187989940b085bcbfa3bedad8dbc5f3ab1fe7&v=4
+ url: https://github.com/andrew222651
+rkbeatss:
+ login: rkbeatss
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/23391143?u=56ab6bff50be950fa8cae5cf736f2ae66e319ff3&v=4
+ url: https://github.com/rkbeatss
+asheux:
+ login: asheux
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/22955146?u=4553ebf5b5a7c7fe031a46182083aa224faba2e1&v=4
+ url: https://github.com/asheux
+n25a:
+ login: n25a
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/49960770?u=7d8a6d5f0a75a5e9a865a2527edfd48895ea27ae&v=4
+ url: https://github.com/n25a
+ghandic:
+ login: ghandic
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
+ url: https://github.com/ghandic
+TeoZosa:
+ login: TeoZosa
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/13070236?u=96fdae85800ef85dcfcc4b5f8281dc8778c8cb7d&v=4
+ url: https://github.com/TeoZosa
+graingert:
+ login: graingert
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
+ url: https://github.com/graingert
+jaystone776:
+ login: jaystone776
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
+ url: https://github.com/jaystone776
+zanieb:
+ login: zanieb
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/2586601?u=e5c86f7ff3b859e7e183187ac2b17fd6ee32b3ab&v=4
+ url: https://github.com/zanieb
+MicaelJarniac:
+ login: MicaelJarniac
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/19514231?u=158c91874ea98d6e9e6f0c6db37ee2ce60c55ff2&v=4
+ url: https://github.com/MicaelJarniac
+papb:
+ login: papb
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/20914054?u=890511fae7ea90d887e2a65ce44a1775abba38d5&v=4
+ url: https://github.com/papb
+musicinmybrain:
+ login: musicinmybrain
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
+ url: https://github.com/musicinmybrain
+gitworkflows:
+ login: gitworkflows
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/118260833?v=4
+ url: https://github.com/gitworkflows
+Nimitha-jagadeesha:
+ login: Nimitha-jagadeesha
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/58389915?v=4
+ url: https://github.com/Nimitha-jagadeesha
+lucaromagnoli:
+ login: lucaromagnoli
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/38782977?u=e66396859f493b4ddcb3a837a1b2b2039c805417&v=4
+ url: https://github.com/lucaromagnoli
+salmantec:
+ login: salmantec
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/41512228?u=443551b893ff2425c59d5d021644f098cf7c68d5&v=4
+ url: https://github.com/salmantec
+OCE1960:
+ login: OCE1960
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/45076670?u=0e9a44712b92ffa89ddfbaa83c112f3f8e1d68e2&v=4
+ url: https://github.com/OCE1960
+hamidrasti:
+ login: hamidrasti
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/43915620?v=4
+ url: https://github.com/hamidrasti
+kkinder:
+ login: kkinder
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1115018?u=c5e90284a9f5c5049eae1bb029e3655c7dc913ed&v=4
+ url: https://github.com/kkinder
+kabirkhan:
+ login: kabirkhan
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/13891834?u=e0eabf792376443ac853e7dca6f550db4166fe35&v=4
+ url: https://github.com/kabirkhan
+zamiramir:
+ login: zamiramir
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
+ url: https://github.com/zamiramir
+trim21:
+ login: trim21
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/13553903?u=3cadf0f02095c9621aa29df6875f53a80ca4fbfb&v=4
+ url: https://github.com/trim21
+koxudaxi:
+ login: koxudaxi
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
+ url: https://github.com/koxudaxi
+pablogamboa:
+ login: pablogamboa
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/12892536?u=326a57059ee0c40c4eb1b38413957236841c631b&v=4
+ url: https://github.com/pablogamboa
+dconathan:
+ login: dconathan
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/15098095?v=4
+ url: https://github.com/dconathan
+Jamim:
+ login: Jamim
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/5607572?u=9ce0b6a6d1a5124e28b3c04d8d26827ca328713a&v=4
+ url: https://github.com/Jamim
+svalouch:
+ login: svalouch
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/54674660?v=4
+ url: https://github.com/svalouch
+frankie567:
+ login: frankie567
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=c159fe047727aedecbbeeaa96a1b03ceb9d39add&v=4
+ url: https://github.com/frankie567
+marier-nico:
+ login: marier-nico
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30477068?u=c7df6af853c8f4163d1517814f3e9a0715c82713&v=4
+ url: https://github.com/marier-nico
+Dustyposa:
+ login: Dustyposa
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
+ url: https://github.com/Dustyposa
+aviramha:
+ login: aviramha
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/41201924?u=6883cc4fc13a7b2e60d4deddd4be06f9c5287880&v=4
+ url: https://github.com/aviramha
+iwpnd:
+ login: iwpnd
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=ec59396e9437fff488791c5ecdf6d23f1f1ebf3a&v=4
+ url: https://github.com/iwpnd
+raphaelauv:
+ login: raphaelauv
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
+ url: https://github.com/raphaelauv
+windson:
+ login: windson
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1826682?u=8b28dcd716c46289f191f8828e01d74edd058bef&v=4
+ url: https://github.com/windson
+sm-Fifteen:
+ login: sm-Fifteen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
+ url: https://github.com/sm-Fifteen
+sattosan:
+ login: sattosan
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20574756?u=b0d8474d2938189c6954423ae8d81d91013f80a8&v=4
+ url: https://github.com/sattosan
+michaeloliverx:
+ login: michaeloliverx
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/55017335?u=efb0cb6e261ff64d862fafb91ee80fc2e1f8a2ed&v=4
+ url: https://github.com/michaeloliverx
+voegtlel:
+ login: voegtlel
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/5764745?u=db8df3d70d427928ab6d7dbfc395a4a7109c1d1b&v=4
+ url: https://github.com/voegtlel
+HarshaLaxman:
+ login: HarshaLaxman
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/19939186?u=a112f38b0f6b4d4402dc8b51978b5a0b2e5c5970&v=4
+ url: https://github.com/HarshaLaxman
+RunningIkkyu:
+ login: RunningIkkyu
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
+ url: https://github.com/RunningIkkyu
+cassiobotaro:
+ login: cassiobotaro
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=a08022b191ddbd0a6159b2981d9d878b6d5bb71f&v=4
+ url: https://github.com/cassiobotaro
+chenl:
+ login: chenl
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1677651?u=c618508eaad6d596cea36c8ea784b424288f6857&v=4
+ url: https://github.com/chenl
+retnikt:
+ login: retnikt
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
+ url: https://github.com/retnikt
+yankeexe:
+ login: yankeexe
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/13623913?u=f970e66421775a8d3cdab89c0c752eaead186f6d&v=4
+ url: https://github.com/yankeexe
+patrickkwang:
+ login: patrickkwang
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1263870?u=4bf74020e15be490f19ef8322a76eec882220b96&v=4
+ url: https://github.com/patrickkwang
+victorphoenix3:
+ login: victorphoenix3
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/48182195?u=e4875bd088623cb4ddeb7be194ec54b453aff035&v=4
+ url: https://github.com/victorphoenix3
+davidefiocco:
+ login: davidefiocco
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/4547987?v=4
+ url: https://github.com/davidefiocco
+adriencaccia:
+ login: adriencaccia
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/19605940?u=980b0b366a02791a5600b2e9f9ac2037679acaa8&v=4
+ url: https://github.com/adriencaccia
+jamescurtin:
+ login: jamescurtin
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10189269?u=0b491fc600ca51f41cf1d95b49fa32a3eba1de57&v=4
+ url: https://github.com/jamescurtin
+jmriebold:
+ login: jmriebold
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/6983392?u=4efdc97bf2422dcc7e9ff65b9ff80087c8eb2a20&v=4
+ url: https://github.com/jmriebold
+nukopy:
+ login: nukopy
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/42367320?u=6061be0bd060506f6d564a8df3ae73fab048cdfe&v=4
+ url: https://github.com/nukopy
+imba-tjd:
+ login: imba-tjd
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/24759802?u=01e901a4fe004b4b126549d3ff1c4000fe3720b5&v=4
+ url: https://github.com/imba-tjd
+johnthagen:
+ login: johnthagen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10340167?u=47147fc4e4db1f573bee3fe428deeacb3197bc5f&v=4
+ url: https://github.com/johnthagen
+paxcodes:
+ login: paxcodes
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/13646646?u=e7429cc7ab11211ef762f4cd3efea7db6d9ef036&v=4
+ url: https://github.com/paxcodes
+kaustubhgupta:
+ login: kaustubhgupta
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/43691873?u=8dd738718ac7ffad4ef31e86b5d780a1141c695d&v=4
+ url: https://github.com/kaustubhgupta
+kinuax:
+ login: kinuax
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/13321374?u=22dc9873d6d9f2c7e4fc44c6480c3505efb1531f&v=4
+ url: https://github.com/kinuax
+wakabame:
+ login: wakabame
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/35513518?u=41ef6b0a55076e5c540620d68fb006e386c2ddb0&v=4
+ url: https://github.com/wakabame
+nzig:
+ login: nzig
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/7372858?u=e769add36ed73c778cdb136eb10bf96b1e119671&v=4
+ url: https://github.com/nzig
+yezz123:
+ login: yezz123
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4
+ url: https://github.com/yezz123
+softwarebloat:
+ login: softwarebloat
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/16540684?v=4
+ url: https://github.com/softwarebloat
+Lancetnik:
+ login: Lancetnik
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/44573917?u=f9a18be7324333daf9cc314c35c3051f0a20a7a6&v=4
+ url: https://github.com/Lancetnik
+joakimnordling:
+ login: joakimnordling
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/6637576?u=df5d99db9b899b399effd429f4358baaa6f7199c&v=4
+ url: https://github.com/joakimnordling
+yogabonito:
+ login: yogabonito
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/7026269?v=4
+ url: https://github.com/yogabonito
+s111d:
+ login: s111d
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/4954856?v=4
+ url: https://github.com/s111d
+estebanx64:
+ login: estebanx64
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
+ url: https://github.com/estebanx64
+tamird:
+ login: tamird
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1535036?v=4
+ url: https://github.com/tamird
+ndimares:
+ login: ndimares
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/6267663?u=cfb27efde7a7212be8142abb6c058a1aeadb41b1&v=4
+ url: https://github.com/ndimares
+rabinlamadong:
+ login: rabinlamadong
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/170439781?v=4
+ url: https://github.com/rabinlamadong
+AyushSinghal1794:
+ login: AyushSinghal1794
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/89984761?v=4
+ url: https://github.com/AyushSinghal1794
+gsheni:
+ login: gsheni
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/8726321?u=ee3bd9ff6320f4715d1dd9671a3d55cccb65b984&v=4
+ url: https://github.com/gsheni
+DanielKusyDev:
+ login: DanielKusyDev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4
+ url: https://github.com/DanielKusyDev
+DanielYang59:
+ login: DanielYang59
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/80093591?u=63873f701c7c74aac83c906800a1dddc0bc8c92f&v=4
+ url: https://github.com/DanielYang59
+valentinDruzhinin:
+ login: valentinDruzhinin
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
+ url: https://github.com/valentinDruzhinin
+blueswen:
+ login: blueswen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1564148?u=6d6b8cc8f2b5cef715e68d6175154a8a94d518ee&v=4
+ url: https://github.com/blueswen
+YuriiMotov:
+ login: YuriiMotov
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
diff --git a/docs/en/data/external_links.yml b/docs/en/data/external_links.yml
index 934c5842b..50f84ecbf 100644
--- a/docs/en/data/external_links.yml
+++ b/docs/en/data/external_links.yml
@@ -1,9 +1,69 @@
-articles:
- english:
- - author: WayScript
- author_link: https://www.wayscript.com
- link: https://blog.wayscript.com/fast-api-quickstart/
- title: Quickstart Guide to Build and Host Responsive APIs with Fast API and WayScript
+Articles:
+ English:
+ - author: Balthazar Rouberol
+ author_link: https://balthazar-rouberol.com
+ link: https://blog.balthazar-rouberol.com/how-to-profile-a-fastapi-asynchronous-request
+ title: How to profile a FastAPI asynchronous request
+ - author: Stephen Siegert - Neon
+ link: https://neon.tech/blog/deploy-a-serverless-fastapi-app-with-neon-postgres-and-aws-app-runner-at-any-scale
+ title: Deploy a Serverless FastAPI App with Neon Postgres and AWS App Runner at any scale
+ - author: Kurtis Pykes - NVIDIA
+ link: https://developer.nvidia.com/blog/building-a-machine-learning-microservice-with-fastapi/
+ title: Building a Machine Learning Microservice with FastAPI
+ - author: Ravgeet Dhillon - Twilio
+ link: https://www.twilio.com/en-us/blog/booking-appointments-twilio-notion-fastapi
+ title: Booking Appointments with Twilio, Notion, and FastAPI
+ - author: Abhinav Tripathi - Microsoft Blogs
+ link: https://devblogs.microsoft.com/cosmosdb/azure-cosmos-db-python-and-fastapi/
+ title: Write a Python data layer with Azure Cosmos DB and FastAPI
+ - author: Donny Peeters
+ author_link: https://github.com/Donnype
+ link: https://bitestreams.com/blog/fastapi-sqlalchemy/
+ title: 10 Tips for adding SQLAlchemy to FastAPI
+ - author: Jessica Temporal
+ author_link: https://jtemporal.com/socials
+ link: https://jtemporal.com/tips-on-migrating-from-flask-to-fastapi-and-vice-versa/
+ title: Tips on migrating from Flask to FastAPI and vice-versa
+ - author: Ankit Anchlia
+ author_link: https://linkedin.com/in/aanchlia21
+ link: https://hackernoon.com/explore-how-to-effectively-use-jwt-with-fastapi
+ title: Explore How to Effectively Use JWT With FastAPI
+ - author: Nicoló Lino
+ author_link: https://www.nlino.com
+ link: https://github.com/softwarebloat/python-tracing-demo
+ title: Instrument FastAPI with OpenTelemetry tracing and visualize traces in Grafana Tempo.
+ - author: Mikhail Rozhkov, Elena Samuylova
+ author_link: https://www.linkedin.com/in/mnrozhkov/
+ link: https://www.evidentlyai.com/blog/fastapi-tutorial
+ title: ML serving and monitoring with FastAPI and Evidently
+ - author: Visual Studio Code Team
+ author_link: https://code.visualstudio.com/
+ link: https://code.visualstudio.com/docs/python/tutorial-fastapi
+ title: FastAPI Tutorial in Visual Studio Code
+ - author: Apitally
+ author_link: https://apitally.io
+ link: https://blog.apitally.io/fastapi-application-monitoring-made-easy
+ title: FastAPI application monitoring made easy
+ - author: John Philip
+ author_link: https://medium.com/@amjohnphilip
+ link: https://python.plainenglish.io/building-a-restful-api-with-fastapi-secure-signup-and-login-functionality-included-45cdbcb36106
+ title: "Building a RESTful API with FastAPI: Secure Signup and Login Functionality Included"
+ - author: Keshav Malik
+ author_link: https://theinfosecguy.xyz/
+ link: https://blog.theinfosecguy.xyz/building-a-crud-api-with-fastapi-and-supabase-a-step-by-step-guide
+ title: Building a CRUD API with FastAPI and Supabase
+ - author: Adejumo Ridwan Suleiman
+ author_link: https://www.linkedin.com/in/adejumoridwan/
+ link: https://medium.com/python-in-plain-english/build-an-sms-spam-classifier-serverless-database-with-faunadb-and-fastapi-23dbb275bc5b
+ title: Build an SMS Spam Classifier Serverless Database with FaunaDB and FastAPI
+ - author: Raf Rasenberg
+ author_link: https://rafrasenberg.com/about/
+ link: https://rafrasenberg.com/fastapi-lambda/
+ title: 'FastAPI lambda container: serverless simplified'
+ - author: Teresa N. Fontanella De Santis
+ author_link: https://dev.to/
+ link: https://dev.to/teresafds/authorization-on-fastapi-with-casbin-41og
+ title: Authorization on FastAPI with Casbin
- author: New Relic
author_link: https://newrelic.com
link: https://newrelic.com/instant-observability/fastapi/e559ec64-f765-4470-a15f-1901fcebb468
@@ -56,10 +116,6 @@ articles:
author_link: https://dev.to/factorlive
link: https://dev.to/factorlive/python-facebook-messenger-webhook-with-fastapi-on-glitch-4n90
title: Python Facebook messenger webhook with FastAPI on Glitch
- - author: Dom Patmore
- author_link: https://twitter.com/dompatmore
- link: https://dompatmore.com/blog/authenticate-your-fastapi-app-with-auth0
- title: Authenticate Your FastAPI App with auth0
- author: Valon Januzaj
author_link: https://www.linkedin.com/in/valon-januzaj-b02692187/
link: https://valonjanuzaj.medium.com/deploy-a-dockerized-fastapi-application-to-aws-cc757830ba1b
@@ -72,10 +128,6 @@ articles:
author_link: https://twitter.com/louis_guitton
link: https://guitton.co/posts/fastapi-monitoring/
title: How to monitor your FastAPI service
- - author: Julien Harbulot
- author_link: https://julienharbulot.com/
- link: https://julienharbulot.com/notification-server.html
- title: HTTP server to display desktop notifications
- author: Precious Ndubueze
author_link: https://medium.com/@gabbyprecious2000
link: https://medium.com/@gabbyprecious2000/creating-a-crud-app-with-fastapi-part-one-7c049292ad37
@@ -124,18 +176,10 @@ articles:
author_link: https://wuilly.com/
link: https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/
title: Real-time Notifications with Python and Postgres
- - author: Benjamin Ramser
- author_link: https://iwpnd.pw
- link: https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream
- title: Apache Kafka producer and consumer with FastAPI and aiokafka
- author: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/
title: Create and Deploy FastAPI app to Heroku without using Docker
- - author: Benjamin Ramser
- author_link: https://iwpnd.pw
- link: https://iwpnd.pw/articles/2020-01/deploy-fastapi-to-aws-lambda
- title: How to continuously deploy a FastAPI to AWS Lambda with AWS SAM
- author: Arthur Henrique
author_link: https://twitter.com/arthurheinrique
link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb
@@ -160,10 +204,6 @@ articles:
author_link: https://dev.to/dbanty
link: https://dev.to/dbanty/why-i-m-leaving-flask-3ki6
title: Why I'm Leaving Flask
- - author: Rob Wagner
- author_link: https://robwagner.dev/
- link: https://robwagner.dev/tortoise-fastapi-setup/
- title: Setting up Tortoise ORM with FastAPI
- author: Mike Moritz
author_link: https://medium.com/@mike.p.moritz
link: https://medium.com/@mike.p.moritz/using-docker-compose-to-deploy-a-lightweight-python-rest-api-with-a-job-queue-37e6072a209b
@@ -224,7 +264,23 @@ articles:
author_link: https://medium.com/@krishnardt365
link: https://medium.com/@krishnardt365/fastapi-docker-and-postgres-91943e71be92
title: Fastapi, Docker(Docker compose) and Postgres
- german:
+ - author: Devon Ray
+ author_link: https://devonray.com
+ link: https://devonray.com/blog/deploying-a-fastapi-project-using-aws-lambda-aurora-cdk
+ title: Deployment using Docker, Lambda, Aurora, CDK & GH Actions
+ - author: Shubhendra Kushwaha
+ author_link: https://www.linkedin.com/in/theshubhendra/
+ link: https://theshubhendra.medium.com/mastering-soft-delete-advanced-sqlalchemy-techniques-4678f4738947
+ title: 'Mastering Soft Delete: Advanced SQLAlchemy Techniques'
+ - author: Shubhendra Kushwaha
+ author_link: https://www.linkedin.com/in/theshubhendra/
+ link: https://theshubhendra.medium.com/role-based-row-filtering-advanced-sqlalchemy-techniques-733e6b1328f6
+ title: 'Role based row filtering: Advanced SQLAlchemy Techniques'
+ German:
+ - author: Marcel Sander (actidoo)
+ author_link: https://www.actidoo.com
+ link: https://www.actidoo.com/de/blog/python-fastapi-domain-driven-design
+ title: Domain-driven Design mit Python und FastAPI
- author: Nico Axtmann
author_link: https://twitter.com/_nicoax
link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
@@ -233,7 +289,7 @@ articles:
author_link: https://hellocoding.de/autor/felix-schuermeyer/
link: https://hellocoding.de/blog/coding-language/python/fastapi
title: REST-API Programmieren mittels Python und dem FastAPI Modul
- japanese:
+ Japanese:
- author: '@bee2'
author_link: https://qiita.com/bee2
link: https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9
@@ -282,7 +338,16 @@ articles:
author_link: https://qiita.com/mtitg
link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築
- russian:
+ Portuguese:
+ - author: Eduardo Mendes
+ author_link: https://bolha.us/@dunossauro
+ link: https://fastapidozero.dunossauro.com/
+ title: FastAPI do ZERO
+ - author: Jessica Temporal
+ author_link: https://jtemporal.com/socials
+ link: https://jtemporal.com/dicas-para-migrar-de-flask-para-fastapi-e-vice-versa/
+ title: Dicas para migrar uma aplicação de Flask para FastAPI e vice-versa
+ Russian:
- author: Troy Köhler
author_link: https://www.linkedin.com/in/trkohler/
link: https://trkohler.com/fast-api-introduction-to-framework
@@ -295,13 +360,31 @@ articles:
author_link: https://habr.com/ru/users/57uff3r/
link: https://habr.com/ru/post/454440/
title: 'Мелкая питонячая радость #2: Starlette - Солидная примочка – FastAPI'
- vietnamese:
+ Vietnamese:
- author: Nguyễn Nhân
author_link: https://fullstackstation.com/author/figonking/
link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
title: 'FASTAPI: TRIỂN KHAI BẰNG DOCKER'
-podcasts:
- english:
+ Taiwanese:
+ - author: Leon
+ author_link: http://editor.leonh.space/
+ link: https://editor.leonh.space/2022/tortoise/
+ title: 'Tortoise ORM / FastAPI 整合快速筆記'
+ Spanish:
+ - author: Eduardo Zepeda
+ author_link: https://coffeebytes.dev/en/authors/eduardo-zepeda/
+ link: https://coffeebytes.dev/es/python-fastapi-el-mejor-framework-de-python/
+ title: 'Tutorial de FastAPI, ¿el mejor framework de Python?'
+Podcasts:
+ English:
+ - author: Real Python
+ author_link: https://realpython.com/
+ link: https://realpython.com/podcasts/rpp/72/
+ title: Starting With FastAPI and Examining Python's Import System - Episode 72
+ - author: Python Bytes FM
+ author_link: https://pythonbytes.fm/
+ link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
+ title: 'Do you dare to press "."? - Episode 247 - Dan #6: SQLModel - use the same models for SQL and FastAPI'
- author: Podcast.`__init__`
author_link: https://www.pythonpodcast.com/
link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
@@ -310,8 +393,12 @@ podcasts:
author_link: https://pythonbytes.fm/
link: https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855
title: FastAPI on PythonBytes
-talks:
- english:
+Talks:
+ English:
+ - author: Jeny Sadadia
+ author_link: https://github.com/JenySadadia
+ link: https://www.youtube.com/watch?v=uZdTe8_Z6BQ
+ title: 'PyCon AU 2023: Testing asynchronous applications with FastAPI and pytest'
- author: Sebastián Ramírez (tiangolo)
author_link: https://twitter.com/tiangolo
link: https://www.youtube.com/watch?v=PnpTY1f4k2U
@@ -324,3 +411,8 @@ talks:
author_link: https://twitter.com/chriswithers13
link: https://www.youtube.com/watch?v=3DLwPcrE5mA
title: 'PyCon UK 2019: FastAPI from the ground up'
+ Taiwanese:
+ - author: Blueswen
+ author_link: https://github.com/blueswen
+ link: https://www.youtube.com/watch?v=y3sumuoDq4w
+ title: 'PyCon TW 2024: 全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例'
diff --git a/docs/en/data/github_sponsors.yml b/docs/en/data/github_sponsors.yml
index 1953df801..0cb200185 100644
--- a/docs/en/data/github_sponsors.yml
+++ b/docs/en/data/github_sponsors.yml
@@ -1,622 +1,457 @@
sponsors:
-- - login: jina-ai
- avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
- url: https://github.com/jina-ai
-- - login: Doist
- avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4
- url: https://github.com/Doist
- - login: cryptapi
- avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
- url: https://github.com/cryptapi
- - login: jrobbins-LiveData
- avatarUrl: https://avatars.githubusercontent.com/u/79278744?u=bae8175fc3f09db281aca1f97a9ddc1a914a8c4f&v=4
- url: https://github.com/jrobbins-LiveData
-- - login: nihpo
- avatarUrl: https://avatars.githubusercontent.com/u/1841030?u=0264956d7580f7e46687a762a7baa629f84cf97c&v=4
- url: https://github.com/nihpo
- - login: ObliviousAI
+- - login: classmethod
+ avatarUrl: https://avatars.githubusercontent.com/u/1532151?v=4
+ url: https://github.com/classmethod
+- - login: renderinc
+ avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4
+ url: https://github.com/renderinc
+ - login: andrew-propelauth
+ avatarUrl: https://avatars.githubusercontent.com/u/89474256?u=c98993dec8553c09d424ede67bbe86e5c35f48c9&v=4
+ url: https://github.com/andrew-propelauth
+ - login: blockbee-io
+ avatarUrl: https://avatars.githubusercontent.com/u/115143449?u=1b8620c2d6567c4df2111a371b85a51f448f9b85&v=4
+ url: https://github.com/blockbee-io
+ - login: zuplo
+ avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4
+ url: https://github.com/zuplo
+ - login: coderabbitai
+ avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4
+ url: https://github.com/coderabbitai
+ - login: madisonredtfeldt
+ avatarUrl: https://avatars.githubusercontent.com/u/152656511?v=4
+ url: https://github.com/madisonredtfeldt
+ - login: subtotal
+ avatarUrl: https://avatars.githubusercontent.com/u/176449348?v=4
+ url: https://github.com/subtotal
+ - login: Nixtla
+ avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4
+ url: https://github.com/Nixtla
+ - login: scalar
+ avatarUrl: https://avatars.githubusercontent.com/u/301879?v=4
+ url: https://github.com/scalar
+- - login: ObliviousAI
avatarUrl: https://avatars.githubusercontent.com/u/65656077?v=4
url: https://github.com/ObliviousAI
- - login: chaserowbotham
- avatarUrl: https://avatars.githubusercontent.com/u/97751084?v=4
- url: https://github.com/chaserowbotham
-- - login: mikeckennedy
- avatarUrl: https://avatars.githubusercontent.com/u/2035561?u=1bb18268bcd4d9249e1f783a063c27df9a84c05b&v=4
- url: https://github.com/mikeckennedy
- - login: deta
- avatarUrl: https://avatars.githubusercontent.com/u/47275976?v=4
- url: https://github.com/deta
- - login: deepset-ai
- avatarUrl: https://avatars.githubusercontent.com/u/51827949?v=4
- url: https://github.com/deepset-ai
- - login: investsuite
- avatarUrl: https://avatars.githubusercontent.com/u/73833632?v=4
- url: https://github.com/investsuite
- - login: VincentParedes
- avatarUrl: https://avatars.githubusercontent.com/u/103889729?v=4
- url: https://github.com/VincentParedes
-- - login: getsentry
- avatarUrl: https://avatars.githubusercontent.com/u/1396951?v=4
- url: https://github.com/getsentry
-- - login: InesIvanova
- avatarUrl: https://avatars.githubusercontent.com/u/22920417?u=409882ec1df6dbd77455788bb383a8de223dbf6f&v=4
- url: https://github.com/InesIvanova
-- - login: vyos
- avatarUrl: https://avatars.githubusercontent.com/u/5647000?v=4
- url: https://github.com/vyos
- - login: SendCloud
- avatarUrl: https://avatars.githubusercontent.com/u/7831959?v=4
- url: https://github.com/SendCloud
- - login: matallan
- avatarUrl: https://avatars.githubusercontent.com/u/12107723?v=4
- url: https://github.com/matallan
- - login: takashi-yoneya
- avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4
- url: https://github.com/takashi-yoneya
+- - login: dribia
+ avatarUrl: https://avatars.githubusercontent.com/u/41189616?v=4
+ url: https://github.com/dribia
+ - login: svix
+ avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
+ url: https://github.com/svix
+ - login: stainless-api
+ avatarUrl: https://avatars.githubusercontent.com/u/88061651?v=4
+ url: https://github.com/stainless-api
+ - login: speakeasy-api
+ avatarUrl: https://avatars.githubusercontent.com/u/91446104?v=4
+ url: https://github.com/speakeasy-api
+ - login: databento
+ avatarUrl: https://avatars.githubusercontent.com/u/64141749?v=4
+ url: https://github.com/databento
+ - login: permitio
+ avatarUrl: https://avatars.githubusercontent.com/u/71775833?v=4
+ url: https://github.com/permitio
+- - login: xoflare
+ avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
+ url: https://github.com/xoflare
+ - login: marvin-robot
+ avatarUrl: https://avatars.githubusercontent.com/u/41086007?u=b9fcab402d0cd0aec738b6574fe60855cb0cd36d&v=4
+ url: https://github.com/marvin-robot
- login: mercedes-benz
avatarUrl: https://avatars.githubusercontent.com/u/34240465?v=4
url: https://github.com/mercedes-benz
- - login: xoflare
- avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
- url: https://github.com/xoflare
- - login: Striveworks
- avatarUrl: https://avatars.githubusercontent.com/u/45523576?v=4
- url: https://github.com/Striveworks
+ - login: Ponte-Energy-Partners
+ avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
+ url: https://github.com/Ponte-Energy-Partners
+ - login: snapit-cypher
+ avatarUrl: https://avatars.githubusercontent.com/u/115662654?v=4
+ url: https://github.com/snapit-cypher
+ - login: LambdaTest-Inc
+ avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4
+ url: https://github.com/LambdaTest-Inc
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
-- - login: johnadjei
- avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
- url: https://github.com/johnadjei
- - login: gvisniuc
- avatarUrl: https://avatars.githubusercontent.com/u/1614747?u=502dfdb2b087ddcf5460026297c98c7907bc2795&v=4
- url: https://github.com/gvisniuc
- - login: HiredScore
- avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4
- url: https://github.com/HiredScore
- - login: Trivie
+ - login: acsone
+ avatarUrl: https://avatars.githubusercontent.com/u/7601056?v=4
+ url: https://github.com/acsone
+- - login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie
- - login: Lovage-Labs
- avatarUrl: https://avatars.githubusercontent.com/u/71685552?v=4
- url: https://github.com/Lovage-Labs
-- - login: moellenbeck
- avatarUrl: https://avatars.githubusercontent.com/u/169372?v=4
- url: https://github.com/moellenbeck
- - login: AccentDesign
- avatarUrl: https://avatars.githubusercontent.com/u/2429332?v=4
- url: https://github.com/AccentDesign
- - login: RodneyU215
- avatarUrl: https://avatars.githubusercontent.com/u/3329665?u=ec6a9adf8e7e8e306eed7d49687c398608d1604f&v=4
- url: https://github.com/RodneyU215
- - login: tizz98
- avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
- url: https://github.com/tizz98
- - login: dorianturba
- avatarUrl: https://avatars.githubusercontent.com/u/9381120?u=4bfc7032a824d1ed1994aa8256dfa597c8f187ad&v=4
- url: https://github.com/dorianturba
- - login: jmaralc
- avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
- url: https://github.com/jmaralc
- - login: mainframeindustries
+- - login: takashi-yoneya
+ avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4
+ url: https://github.com/takashi-yoneya
+ - login: Doist
+ avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4
+ url: https://github.com/Doist
+- - login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
-- - login: povilasb
- avatarUrl: https://avatars.githubusercontent.com/u/1213442?u=b11f58ed6ceea6e8297c9b310030478ebdac894d&v=4
- url: https://github.com/povilasb
- - login: primer-io
+ - login: yasyf
+ avatarUrl: https://avatars.githubusercontent.com/u/709645?u=f36736b3c6a85f578886ecc42a740e7b436e7a01&v=4
+ url: https://github.com/yasyf
+- - login: alixlahuec
+ avatarUrl: https://avatars.githubusercontent.com/u/29543316?u=44357eb2a93bccf30fb9d389b8befe94a3d00985&v=4
+ url: https://github.com/alixlahuec
+- - login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
-- - login: indeedeng
- avatarUrl: https://avatars.githubusercontent.com/u/2905043?v=4
- url: https://github.com/indeedeng
- - login: A-Edge
- avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
- url: https://github.com/A-Edge
-- - login: Kludex
- avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
- url: https://github.com/Kludex
- - login: samuelcolvin
- avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
+- - login: upciti
+ avatarUrl: https://avatars.githubusercontent.com/u/43346262?v=4
+ url: https://github.com/upciti
+- - login: samuelcolvin
+ avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
url: https://github.com/samuelcolvin
- - login: jefftriplett
- avatarUrl: https://avatars.githubusercontent.com/u/50527?u=af1ddfd50f6afd6d99f333ba2ac8d0a5b245ea74&v=4
- url: https://github.com/jefftriplett
- - login: medecau
- avatarUrl: https://avatars.githubusercontent.com/u/59870?u=f9341c95adaba780828162fd4c7442357ecfcefa&v=4
- url: https://github.com/medecau
- - login: kamalgill
- avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
- url: https://github.com/kamalgill
- - login: dekoza
- avatarUrl: https://avatars.githubusercontent.com/u/210980?u=c03c78a8ae1039b500dfe343665536ebc51979b2&v=4
- url: https://github.com/dekoza
- - login: pamelafox
- avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
- url: https://github.com/pamelafox
- - login: deserat
- avatarUrl: https://avatars.githubusercontent.com/u/299332?v=4
- url: https://github.com/deserat
- - login: ericof
- avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4
- url: https://github.com/ericof
- - login: wshayes
- avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
- url: https://github.com/wshayes
- - login: koxudaxi
- avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
- url: https://github.com/koxudaxi
- - login: falkben
- avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
- url: https://github.com/falkben
- - login: jqueguiner
- avatarUrl: https://avatars.githubusercontent.com/u/690878?u=bd65cc1f228ce6455e56dfaca3ef47c33bc7c3b0&v=4
- url: https://github.com/jqueguiner
- - login: alexsantos
- avatarUrl: https://avatars.githubusercontent.com/u/932219?v=4
- url: https://github.com/alexsantos
- - login: tcsmith
- avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4
- url: https://github.com/tcsmith
- - login: ltieman
- avatarUrl: https://avatars.githubusercontent.com/u/1084689?u=e69b17de17cb3ca141a17daa7ccbe173ceb1eb17&v=4
- url: https://github.com/ltieman
- - login: mrkmcknz
- avatarUrl: https://avatars.githubusercontent.com/u/1089376?u=2b9b8a8c25c33a4f6c220095638bd821cdfd13a3&v=4
- url: https://github.com/mrkmcknz
- - login: coffeewasmyidea
- avatarUrl: https://avatars.githubusercontent.com/u/1636488?u=8e32a4f200eff54dd79cd79d55d254bfce5e946d&v=4
- url: https://github.com/coffeewasmyidea
- - login: corleyma
- avatarUrl: https://avatars.githubusercontent.com/u/2080732?u=aed2ff652294a87d666b1c3f6dbe98104db76d26&v=4
- url: https://github.com/corleyma
- - login: madisonmay
- avatarUrl: https://avatars.githubusercontent.com/u/2645393?u=f22b93c6ea345a4d26a90a3834dfc7f0789fcb63&v=4
- url: https://github.com/madisonmay
- - login: saivarunk
- avatarUrl: https://avatars.githubusercontent.com/u/2976867?u=71f4385e781e9a9e871a52f2d4686f9a8d69ba2f&v=4
- url: https://github.com/saivarunk
- - login: andre1sk
- avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
- url: https://github.com/andre1sk
- - login: Shark009
- avatarUrl: https://avatars.githubusercontent.com/u/3163309?u=0c6f4091b0eda05c44c390466199826e6dc6e431&v=4
- url: https://github.com/Shark009
- - login: ColliotL
- avatarUrl: https://avatars.githubusercontent.com/u/3412402?u=ca64b07ecbef2f9da1cc2cac3f37522aa4814902&v=4
- url: https://github.com/ColliotL
- - login: grillazz
- avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=453cd1725c8d7fe3e258016bc19cff861d4fcb53&v=4
- url: https://github.com/grillazz
+ - login: CoodingPenguin
+ avatarUrl: https://avatars.githubusercontent.com/u/37505775?u=6a9e1f6647fbf95f99afeee82a3682e15fc6e959&v=4
+ url: https://github.com/CoodingPenguin
+ - login: deight93
+ avatarUrl: https://avatars.githubusercontent.com/u/37678115?u=a608798b5bd0034183a9c430ebb42fb266db86ce&v=4
+ url: https://github.com/deight93
+ - login: otosky
+ avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
+ url: https://github.com/otosky
+ - login: ramonalmeidam
+ avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
+ url: https://github.com/ramonalmeidam
+ - login: kaoru0310
+ avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4
+ url: https://github.com/kaoru0310
+ - login: RaamEEIL
+ avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
+ url: https://github.com/RaamEEIL
+ - login: ehaca
+ avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
+ url: https://github.com/ehaca
+ - login: raphaellaude
+ avatarUrl: https://avatars.githubusercontent.com/u/28026311?u=91e1c00d9ac4f8045527e13de8050d504531cbc0&v=4
+ url: https://github.com/raphaellaude
+ - login: timlrx
+ avatarUrl: https://avatars.githubusercontent.com/u/28362229?u=9a745ca31372ee324af682715ae88ce8522f9094&v=4
+ url: https://github.com/timlrx
+ - login: Leay15
+ avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
+ url: https://github.com/Leay15
+ - login: ProteinQure
+ avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
+ url: https://github.com/ProteinQure
+ - login: DelfinaCare
+ avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
+ url: https://github.com/DelfinaCare
+ - login: Karine-Bauch
+ avatarUrl: https://avatars.githubusercontent.com/u/90465103?u=7feb1018abb1a5631cfd9a91fea723d1ceb5f49b&v=4
+ url: https://github.com/Karine-Bauch
+ - login: eruditis
+ avatarUrl: https://avatars.githubusercontent.com/u/95244703?v=4
+ url: https://github.com/eruditis
+ - login: jugeeem
+ avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4
+ url: https://github.com/jugeeem
+ - login: logic-automation
+ avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4
+ url: https://github.com/logic-automation
+ - login: roboflow
+ avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4
+ url: https://github.com/roboflow
+ - login: dudikbender
+ avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4
+ url: https://github.com/dudikbender
+ - login: patsatsia
+ avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
+ url: https://github.com/patsatsia
+ - login: anthonycepeda
+ avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
+ url: https://github.com/anthonycepeda
+ - login: patricioperezv
+ avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4
+ url: https://github.com/patricioperezv
+ - login: chickenandstats
+ avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4
+ url: https://github.com/chickenandstats
+ - login: dodo5522
+ avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4
+ url: https://github.com/dodo5522
+ - login: nihpo
+ avatarUrl: https://avatars.githubusercontent.com/u/1841030?u=0264956d7580f7e46687a762a7baa629f84cf97c&v=4
+ url: https://github.com/nihpo
+ - login: knallgelb
+ avatarUrl: https://avatars.githubusercontent.com/u/2358812?u=c48cb6362b309d74cbf144bd6ad3aed3eb443e82&v=4
+ url: https://github.com/knallgelb
- login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- - login: MarekBleschke
- avatarUrl: https://avatars.githubusercontent.com/u/3616870?v=4
- url: https://github.com/MarekBleschke
+ - login: kennywakeland
+ avatarUrl: https://avatars.githubusercontent.com/u/3631417?u=7c8f743f1ae325dfadea7c62bbf1abd6a824fc55&v=4
+ url: https://github.com/kennywakeland
- login: aacayaco
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
url: https://github.com/aacayaco
- login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly
- - login: peterHoburg
- avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
- url: https://github.com/peterHoburg
- - login: jgreys
- avatarUrl: https://avatars.githubusercontent.com/u/4136890?u=c66ae617d614f6c886f1f1c1799d22100b3c848d&v=4
- url: https://github.com/jgreys
+ - login: mj0331
+ avatarUrl: https://avatars.githubusercontent.com/u/3890353?u=1c627ac1a024515b4871de5c3ebbfaa1a57f65d4&v=4
+ url: https://github.com/mj0331
- login: gorhack
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
url: https://github.com/gorhack
+ - login: vincentkoc
+ avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
+ url: https://github.com/vincentkoc
+ - login: jstanden
+ avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
+ url: https://github.com/jstanden
+ - login: paulcwatts
+ avatarUrl: https://avatars.githubusercontent.com/u/150269?u=1819e145d573b44f0ad74b87206d21cd60331d4e&v=4
+ url: https://github.com/paulcwatts
+ - login: andreaso
+ avatarUrl: https://avatars.githubusercontent.com/u/285964?u=837265cc7562c0685f25b2d81cd9de0434fe107c&v=4
+ url: https://github.com/andreaso
+ - login: robintw
+ avatarUrl: https://avatars.githubusercontent.com/u/296686?v=4
+ url: https://github.com/robintw
+ - login: pamelafox
+ avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
+ url: https://github.com/pamelafox
+ - login: ericof
+ avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4
+ url: https://github.com/ericof
+ - login: wshayes
+ avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
+ url: https://github.com/wshayes
+ - login: koxudaxi
+ avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
+ url: https://github.com/koxudaxi
+ - login: falkben
+ avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
+ url: https://github.com/falkben
+ - login: mintuhouse
+ avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
+ url: https://github.com/mintuhouse
+ - login: wdwinslow
+ avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=371272f2c69e680e0559a7b0a57385e83a5dc728&v=4
+ url: https://github.com/wdwinslow
+ - login: jsoques
+ avatarUrl: https://avatars.githubusercontent.com/u/12414216?u=620921d94196546cc8b9eae2cc4cbc3f95bab42f&v=4
+ url: https://github.com/jsoques
+ - login: joeds13
+ avatarUrl: https://avatars.githubusercontent.com/u/13631604?u=628eb122e08bef43767b3738752b883e8e7f6259&v=4
+ url: https://github.com/joeds13
+ - login: dannywade
+ avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
+ url: https://github.com/dannywade
+ - login: khadrawy
+ avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
+ url: https://github.com/khadrawy
+ - login: mjohnsey
+ avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
+ url: https://github.com/mjohnsey
+ - login: ashi-agrawal
+ avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
+ url: https://github.com/ashi-agrawal
+ - login: Ryandaydev
+ avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4
+ url: https://github.com/Ryandaydev
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- login: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen
- - login: Rey8d01
- avatarUrl: https://avatars.githubusercontent.com/u/4836190?u=5942598a23a377602c1669522334ab5ebeaf9165&v=4
- url: https://github.com/Rey8d01
- - login: ScrimForever
- avatarUrl: https://avatars.githubusercontent.com/u/5040124?u=091ec38bfe16d6e762099e91309b59f248616a65&v=4
- url: https://github.com/ScrimForever
- - login: ennui93
- avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
- url: https://github.com/ennui93
- login: ternaus
- avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=fabc8d75c921b3380126adb5a931c5da6e7db04f&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
url: https://github.com/ternaus
- - login: Yaleesa
- avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4
- url: https://github.com/Yaleesa
- - login: iwpnd
- avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=c485eefca5c6329600cae63dd35e4f5682ce6924&v=4
- url: https://github.com/iwpnd
- - login: simw
- avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
- url: https://github.com/simw
- - login: pkucmus
- avatarUrl: https://avatars.githubusercontent.com/u/6347418?u=98f5918b32e214a168a2f5d59b0b8ebdf57dca0d&v=4
- url: https://github.com/pkucmus
- - login: s3ich4n
- avatarUrl: https://avatars.githubusercontent.com/u/6926298?u=6690c5403bc1d9a1837886defdc5256e9a43b1db&v=4
- url: https://github.com/s3ich4n
+ - login: eseglem
+ avatarUrl: https://avatars.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
+ url: https://github.com/eseglem
+ - login: FernandoCelmer
+ avatarUrl: https://avatars.githubusercontent.com/u/6262214?u=58ba6d5888fa7f355934e52db19f950e20b38162&v=4
+ url: https://github.com/FernandoCelmer
- login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
- login: hiancdtrsnm
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
url: https://github.com/hiancdtrsnm
- - login: Shackelford-Arden
- avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
- url: https://github.com/Shackelford-Arden
- - login: wdwinslow
- avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
- url: https://github.com/wdwinslow
- - login: bapi24
- avatarUrl: https://avatars.githubusercontent.com/u/11890901?u=45cc721d8f66ad2f62b086afc3d4761d0c16b9c6&v=4
- url: https://github.com/bapi24
- - login: svats2k
- avatarUrl: https://avatars.githubusercontent.com/u/12378398?u=ecf28c19f61052e664bdfeb2391f8107d137915c&v=4
- url: https://github.com/svats2k
- - login: gokulyc
- avatarUrl: https://avatars.githubusercontent.com/u/13468848?u=269f269d3e70407b5fb80138c52daba7af783997&v=4
- url: https://github.com/gokulyc
- - login: dannywade
- avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
- url: https://github.com/dannywade
- - login: khadrawy
- avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
- url: https://github.com/khadrawy
- - login: pablonnaoji
- avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=afc15bd5a4ba9c5c7206bbb1bcaeef606a0932e0&v=4
- url: https://github.com/pablonnaoji
- - login: wedwardbeck
- avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
- url: https://github.com/wedwardbeck
- - login: m4knV
- avatarUrl: https://avatars.githubusercontent.com/u/19666130?u=843383978814886be93c137d10d2e20e9f13af07&v=4
- url: https://github.com/m4knV
- - login: Filimoa
- avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4
- url: https://github.com/Filimoa
- - login: shuheng-liu
- avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
- url: https://github.com/shuheng-liu
- - login: Joeriksson
- avatarUrl: https://avatars.githubusercontent.com/u/25037079?v=4
- url: https://github.com/Joeriksson
- - login: cometa-haley
- avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
- url: https://github.com/cometa-haley
- - login: LarryGF
- avatarUrl: https://avatars.githubusercontent.com/u/26148349?u=431bb34d36d41c172466252242175281ae132152&v=4
- url: https://github.com/LarryGF
- - login: veprimk
- avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
- url: https://github.com/veprimk
- - login: BrettskiPy
- avatarUrl: https://avatars.githubusercontent.com/u/30988215?u=d8a94a67e140d5ee5427724b292cc52d8827087a&v=4
- url: https://github.com/BrettskiPy
- - login: mauroalejandrojm
- avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
- url: https://github.com/mauroalejandrojm
- - login: Leay15
- avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
- url: https://github.com/Leay15
- - login: ygorpontelo
- avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4
- url: https://github.com/ygorpontelo
- - login: AlrasheedA
- avatarUrl: https://avatars.githubusercontent.com/u/33544979?u=7fe66bf62b47682612b222e3e8f4795ef3be769b&v=4
- url: https://github.com/AlrasheedA
- - login: ProteinQure
- avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
- url: https://github.com/ProteinQure
- - login: faviasono
- avatarUrl: https://avatars.githubusercontent.com/u/37707874?u=f0b75ca4248987c08ed8fb8ed682e7e74d5d7091&v=4
- url: https://github.com/faviasono
- - login: ybressler
- avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=41e2c00f1eebe3c402635f0325e41b4e6511462c&v=4
- url: https://github.com/ybressler
- - login: ddilidili
- avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4
- url: https://github.com/ddilidili
- - login: VictorCalderon
- avatarUrl: https://avatars.githubusercontent.com/u/44529243?u=cea69884f826a29aff1415493405209e0706d07a&v=4
- url: https://github.com/VictorCalderon
- - login: arthuRHD
- avatarUrl: https://avatars.githubusercontent.com/u/48015496?u=05a0d5b8b9320eeb7990d35c9337b823f269d2ff&v=4
- url: https://github.com/arthuRHD
- - login: rafsaf
- avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
- url: https://github.com/rafsaf
- - login: dudikbender
- avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
- url: https://github.com/dudikbender
- - login: dazeddd
- avatarUrl: https://avatars.githubusercontent.com/u/59472056?u=7a1b668449bf8b448db13e4c575576d24d7d658b&v=4
- url: https://github.com/dazeddd
- - login: yakkonaut
- avatarUrl: https://avatars.githubusercontent.com/u/60633704?u=90a71fd631aa998ba4a96480788f017c9904e07b&v=4
- url: https://github.com/yakkonaut
- - login: patsatsia
- avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
- url: https://github.com/patsatsia
- - login: predictionmachine
- avatarUrl: https://avatars.githubusercontent.com/u/63719559?v=4
- url: https://github.com/predictionmachine
- - login: minsau
- avatarUrl: https://avatars.githubusercontent.com/u/64386242?u=7e45f24b2958caf946fa3546ea33bacf5cd886f8&v=4
- url: https://github.com/minsau
- - login: daverin
- avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
- url: https://github.com/daverin
- - login: anthonycepeda
- avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=4252c6b6dc5024af502a823a3ac5e7a03a69963f&v=4
- url: https://github.com/anthonycepeda
- - login: fpiem
- avatarUrl: https://avatars.githubusercontent.com/u/77389987?u=f667a25cd4832b28801189013b74450e06cc232c&v=4
- url: https://github.com/fpiem
- - login: DelfinaCare
- avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
- url: https://github.com/DelfinaCare
- - login: programvx
- avatarUrl: https://avatars.githubusercontent.com/u/96057906?v=4
- url: https://github.com/programvx
- - login: pyt3h
- avatarUrl: https://avatars.githubusercontent.com/u/99658549?v=4
- url: https://github.com/pyt3h
- - login: Dagmaara
- avatarUrl: https://avatars.githubusercontent.com/u/115501964?v=4
- url: https://github.com/Dagmaara
-- - login: linux-china
- avatarUrl: https://avatars.githubusercontent.com/u/46711?u=cd77c65338b158750eb84dc7ff1acf3209ccfc4f&v=4
- url: https://github.com/linux-china
+- - login: jpizquierdo
+ avatarUrl: https://avatars.githubusercontent.com/u/6716239?v=4
+ url: https://github.com/jpizquierdo
+- - login: pawamoy
+ avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
+ url: https://github.com/pawamoy
+ - login: petercool
+ avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=81c525232bb35780945a68e88afd96bb2cdad9c4&v=4
+ url: https://github.com/petercool
+ - login: siavashyj
+ avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4
+ url: https://github.com/siavashyj
+ - login: mobyw
+ avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4
+ url: https://github.com/mobyw
+ - login: ArtyomVancyan
+ avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
+ url: https://github.com/ArtyomVancyan
+ - login: caviri
+ avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4
+ url: https://github.com/caviri
+ - login: joshuatz
+ avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
+ url: https://github.com/joshuatz
+ - login: SebTota
+ avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
+ url: https://github.com/SebTota
+ - login: nisutec
+ avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
+ url: https://github.com/nisutec
+ - login: hoenie-ams
+ avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
+ url: https://github.com/hoenie-ams
+ - login: joerambo
+ avatarUrl: https://avatars.githubusercontent.com/u/26282974?v=4
+ url: https://github.com/joerambo
+ - login: rlnchow
+ avatarUrl: https://avatars.githubusercontent.com/u/28018479?u=a93ca9cf1422b9ece155784a72d5f2fdbce7adff&v=4
+ url: https://github.com/rlnchow
+ - login: engineerjoe440
+ avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
+ url: https://github.com/engineerjoe440
+ - login: bnkc
+ avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=db5e6f4f87836cad26c2aa90ce390ce49041c5a9&v=4
+ url: https://github.com/bnkc
+ - login: lukzmu
+ avatarUrl: https://avatars.githubusercontent.com/u/175964415?u=75348f25bb99a5f92ddb40c0b9b1ff7acb39c150&v=4
+ url: https://github.com/lukzmu
+ - login: hgalytoby
+ avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4
+ url: https://github.com/hgalytoby
+ - login: PunRabbit
+ avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
+ url: https://github.com/PunRabbit
+ - login: PelicanQ
+ avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
+ url: https://github.com/PelicanQ
+ - login: browniebroke
+ avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
+ url: https://github.com/browniebroke
+ - login: miguelgr
+ avatarUrl: https://avatars.githubusercontent.com/u/1484589?u=54556072b8136efa12ae3b6902032ea2a39ace4b&v=4
+ url: https://github.com/miguelgr
+ - login: WillHogan
+ avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=8a80356e3e7d5a417157aba7ea565dabc8678327&v=4
+ url: https://github.com/WillHogan
+ - login: my3
+ avatarUrl: https://avatars.githubusercontent.com/u/1825270?v=4
+ url: https://github.com/my3
+ - login: Alisa-lisa
+ avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
+ url: https://github.com/Alisa-lisa
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
- - login: jhb
- avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
- url: https://github.com/jhb
- - login: justinrmiller
- avatarUrl: https://avatars.githubusercontent.com/u/143998?u=b507a940394d4fc2bc1c27cea2ca9c22538874bd&v=4
- url: https://github.com/justinrmiller
- login: bryanculbertson
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
url: https://github.com/bryanculbertson
- - login: hhatto
- avatarUrl: https://avatars.githubusercontent.com/u/150309?u=3e8f63c27bf996bfc68464b0ce3f7a3e40e6ea7f&v=4
- url: https://github.com/hhatto
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- - login: adamghill
- avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
- url: https://github.com/adamghill
- - login: eteq
- avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4
- url: https://github.com/eteq
- - login: dmig
- avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
- url: https://github.com/dmig
- - login: rinckd
- avatarUrl: https://avatars.githubusercontent.com/u/546002?u=8ec88ab721a5636346f19dcd677a6f323058be8b&v=4
- url: https://github.com/rinckd
- - login: securancy
- avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
- url: https://github.com/securancy
- - login: hardbyte
- avatarUrl: https://avatars.githubusercontent.com/u/855189?u=aa29e92f34708814d6b67fcd47ca4cf2ce1c04ed&v=4
- url: https://github.com/hardbyte
- - login: browniebroke
- avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
- url: https://github.com/browniebroke
- - login: janfilips
- avatarUrl: https://avatars.githubusercontent.com/u/870699?u=50de77b93d3a0b06887e672d4e8c7b9d643085aa&v=4
- url: https://github.com/janfilips
- - login: woodrad
- avatarUrl: https://avatars.githubusercontent.com/u/1410765?u=86707076bb03d143b3b11afc1743d2aa496bd8bf&v=4
- url: https://github.com/woodrad
- - login: Pytlicek
- avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=01b1f2f7671ce3131e0877d08e2e3f8bdbb0a38a&v=4
- url: https://github.com/Pytlicek
- - login: allen0125
- avatarUrl: https://avatars.githubusercontent.com/u/1448456?u=dc2ad819497eef494b88688a1796e0adb87e7cae&v=4
- url: https://github.com/allen0125
- - login: WillHogan
- avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
- url: https://github.com/WillHogan
- - login: cbonoz
- avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
- url: https://github.com/cbonoz
- - login: Debakel
- avatarUrl: https://avatars.githubusercontent.com/u/2857237?u=07df6d11c8feef9306d071cb1c1005a2dd596585&v=4
- url: https://github.com/Debakel
- - login: paul121
- avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
- url: https://github.com/paul121
- - login: igorcorrea
- avatarUrl: https://avatars.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4
- url: https://github.com/igorcorrea
- - login: anthonycorletti
- avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
- url: https://github.com/anthonycorletti
- - login: jonathanhle
- avatarUrl: https://avatars.githubusercontent.com/u/3851599?u=76b9c5d2fecd6c3a16e7645231878c4507380d4d&v=4
- url: https://github.com/jonathanhle
- - login: pawamoy
- avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
- url: https://github.com/pawamoy
- - login: nikeee
- avatarUrl: https://avatars.githubusercontent.com/u/4068864?u=63f8eee593f25138e0f1032ef442e9ad24907d4c&v=4
- url: https://github.com/nikeee
- - login: Alisa-lisa
- avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
- url: https://github.com/Alisa-lisa
- - login: danielunderwood
- avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
- url: https://github.com/danielunderwood
- - login: unredundant
- avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=1ffbf39f5bb8736b75c0d235707d6e8f803725c5&v=4
- url: https://github.com/unredundant
- - login: Baghdady92
- avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
- url: https://github.com/Baghdady92
- - login: holec
- avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
- url: https://github.com/holec
- - login: mattwelke
- avatarUrl: https://avatars.githubusercontent.com/u/7719209?u=5d963ead289969257190b133250653bd99df06ba&v=4
- url: https://github.com/mattwelke
- - login: hcristea
- avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
- url: https://github.com/hcristea
+ - login: ceb10n
+ avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
+ url: https://github.com/ceb10n
+ - login: tochikuji
+ avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
+ url: https://github.com/tochikuji
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- - login: yenchenLiu
- avatarUrl: https://avatars.githubusercontent.com/u/9199638?u=8cdf5ae507448430d90f6f3518d1665a23afe99b&v=4
- url: https://github.com/yenchenLiu
+ - login: msehnout
+ avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
+ url: https://github.com/msehnout
- login: xncbf
- avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=866a1311e4bd3ec5ae84185c4fcc99f397c883d7&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
url: https://github.com/xncbf
- login: DMantis
- avatarUrl: https://avatars.githubusercontent.com/u/9536869?v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
url: https://github.com/DMantis
- login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- - login: satwikkansal
- avatarUrl: https://avatars.githubusercontent.com/u/10217535?u=b12d6ef74ea297de9e46da6933b1a5b7ba9e6a61&v=4
- url: https://github.com/satwikkansal
+ - login: supdann
+ avatarUrl: https://avatars.githubusercontent.com/u/9986994?u=9671810f4ae9504c063227fee34fd47567ff6954&v=4
+ url: https://github.com/supdann
- login: mntolia
avatarUrl: https://avatars.githubusercontent.com/u/10390224?v=4
url: https://github.com/mntolia
- login: pheanex
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
url: https://github.com/pheanex
- - login: JimFawkes
- avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
- url: https://github.com/JimFawkes
- - login: giuliano-oliveira
- avatarUrl: https://avatars.githubusercontent.com/u/13181797?u=0ef2dfbf7fc9a9726d45c21d32b5d1038a174870&v=4
- url: https://github.com/giuliano-oliveira
- - login: logan-connolly
- avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
- url: https://github.com/logan-connolly
- - login: cdsre
- avatarUrl: https://avatars.githubusercontent.com/u/16945936?v=4
- url: https://github.com/cdsre
- - login: jangia
- avatarUrl: https://avatars.githubusercontent.com/u/17927101?u=9261b9bb0c3e3bb1ecba43e8915dc58d8c9a077e&v=4
- url: https://github.com/jangia
- - login: paulowiz
- avatarUrl: https://avatars.githubusercontent.com/u/18649504?u=d8a6ac40321f2bded0eba78b637751c7f86c6823&v=4
- url: https://github.com/paulowiz
- - login: yannicschroeer
- avatarUrl: https://avatars.githubusercontent.com/u/22749683?u=4df05a7296c207b91c5d7c7a11c29df5ab313e2b&v=4
- url: https://github.com/yannicschroeer
- - login: ghandic
- avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
- url: https://github.com/ghandic
- - login: fstau
- avatarUrl: https://avatars.githubusercontent.com/u/24669867?u=60e7c8c09f8dafabee8fc3edcd6f9e19abbff918&v=4
- url: https://github.com/fstau
- - login: pers0n4
- avatarUrl: https://avatars.githubusercontent.com/u/24864600?u=444441027bc2c9f9db68e8047d65ff23d25699cf&v=4
- url: https://github.com/pers0n4
- - login: SebTota
- avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
- url: https://github.com/SebTota
- - login: joerambo
- avatarUrl: https://avatars.githubusercontent.com/u/26282974?v=4
- url: https://github.com/joerambo
- - login: mertguvencli
- avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
- url: https://github.com/mertguvencli
- - login: ruizdiazever
- avatarUrl: https://avatars.githubusercontent.com/u/29817086?u=2df54af55663d246e3a4dc8273711c37f1adb117&v=4
- url: https://github.com/ruizdiazever
- - login: HosamAlmoghraby
- avatarUrl: https://avatars.githubusercontent.com/u/32025281?u=aa1b09feabccbf9dc506b81c71155f32d126cefa&v=4
- url: https://github.com/HosamAlmoghraby
- - login: engineerjoe440
- avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
- url: https://github.com/engineerjoe440
- - login: bnkc
- avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=20f362505e2a994805233f42e69f9f14b4a9dd0c&v=4
- url: https://github.com/bnkc
- - login: declon
- avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
- url: https://github.com/declon
- - login: alvarobartt
- avatarUrl: https://avatars.githubusercontent.com/u/36760800?u=9b38695807eb981d452989699ff72ec2d8f6508e&v=4
- url: https://github.com/alvarobartt
- - login: d-e-h-i-o
- avatarUrl: https://avatars.githubusercontent.com/u/36816716?v=4
- url: https://github.com/d-e-h-i-o
- - login: ww-daniel-mora
- avatarUrl: https://avatars.githubusercontent.com/u/38921751?u=ae14bc1e40f2dd5a9c5741fc0b0dffbd416a5fa9&v=4
- url: https://github.com/ww-daniel-mora
+ - login: Zuzah
+ avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
+ url: https://github.com/Zuzah
+ - login: artempronevskiy
+ avatarUrl: https://avatars.githubusercontent.com/u/12235104?u=03df6e1e55c9c6fe5d230adabb8dd7d43d8bbe8f&v=4
+ url: https://github.com/artempronevskiy
+ - login: TheR1D
+ avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
+ url: https://github.com/TheR1D
+ - login: danielunderwood
+ avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
+ url: https://github.com/danielunderwood
+ - login: rangulvers
+ avatarUrl: https://avatars.githubusercontent.com/u/5235430?u=e254d4af4ace5a05fa58372ae677c7d26f0d5a53&v=4
+ url: https://github.com/rangulvers
+ - login: sdevkota
+ avatarUrl: https://avatars.githubusercontent.com/u/5250987?u=4ed9a120c89805a8aefda1cbdc0cf6512e64d1b4&v=4
+ url: https://github.com/sdevkota
+ - login: brizzbuzz
+ avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=58d5aae33bc97e52f11f334d2702e8710314b5c1&v=4
+ url: https://github.com/brizzbuzz
+ - login: Baghdady92
+ avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
+ url: https://github.com/Baghdady92
+ - login: KentShikama
+ avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
+ url: https://github.com/KentShikama
+ - login: katnoria
+ avatarUrl: https://avatars.githubusercontent.com/u/7674948?u=09767eb13e07e09496c5fee4e5ce21d9eac34a56&v=4
+ url: https://github.com/katnoria
+ - login: harsh183
+ avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
+ url: https://github.com/harsh183
+- - login: andrecorumba
+ avatarUrl: https://avatars.githubusercontent.com/u/37807517?u=9b9be3b41da9bda60957da9ef37b50dbf65baa61&v=4
+ url: https://github.com/andrecorumba
- login: rwxd
- avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=9ddf8023ca3326381ba8fb77285ae36598a15de3&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd
- - login: ilias-ant
- avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=a2d6121bac4d125d92ec207460fa3f1842d37e66&v=4
- url: https://github.com/ilias-ant
- - login: arrrrrmin
- avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=2a812c1a2ec58227ed01778837f255143de9df97&v=4
- url: https://github.com/arrrrrmin
- - login: MauriceKuenicke
- avatarUrl: https://avatars.githubusercontent.com/u/47433175?u=37455bc95c7851db296ac42626f0cacb77ca2443&v=4
- url: https://github.com/MauriceKuenicke
- - login: hgalytoby
- avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=f4888c2c54929bd86eed0d3971d09fcb306e5088&v=4
- url: https://github.com/hgalytoby
- - login: akanz1
- avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
- url: https://github.com/akanz1
- - login: shidenko97
- avatarUrl: https://avatars.githubusercontent.com/u/54946990?u=3fdc0caea36af9217dacf1cc7760c7ed9d67dcfe&v=4
- url: https://github.com/shidenko97
- - login: data-djinn
- avatarUrl: https://avatars.githubusercontent.com/u/56449985?u=42146e140806908d49bd59ccc96f222abf587886&v=4
- url: https://github.com/data-djinn
- - login: leo-jp-edwards
- avatarUrl: https://avatars.githubusercontent.com/u/58213433?u=2c128e8b0794b7a66211cd7d8ebe05db20b7e9c0&v=4
- url: https://github.com/leo-jp-edwards
- - login: apar-tiwari
- avatarUrl: https://avatars.githubusercontent.com/u/61064197?v=4
- url: https://github.com/apar-tiwari
- - login: Vyvy-vi
- avatarUrl: https://avatars.githubusercontent.com/u/62864373?u=1a9b0b28779abc2bc9b62cb4d2e44d453973c9c3&v=4
- url: https://github.com/Vyvy-vi
- - login: 0417taehyun
- avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
- url: https://github.com/0417taehyun
- - login: realabja
- avatarUrl: https://avatars.githubusercontent.com/u/66185192?u=001e2dd9297784f4218997981b4e6fa8357bb70b&v=4
- url: https://github.com/realabja
- - login: alessio-proietti
- avatarUrl: https://avatars.githubusercontent.com/u/67370599?u=8ac73db1e18e946a7681f173abdb640516f88515&v=4
- url: https://github.com/alessio-proietti
- - login: pondDevThai
- avatarUrl: https://avatars.githubusercontent.com/u/71592181?u=08af9a59bccfd8f6b101de1005aa9822007d0a44&v=4
- url: https://github.com/pondDevThai
-- - login: wardal
- avatarUrl: https://avatars.githubusercontent.com/u/15804042?v=4
- url: https://github.com/wardal
- - login: gabrielmbmb
- avatarUrl: https://avatars.githubusercontent.com/u/29572918?u=6d1e00b5d558e96718312ff910a2318f47cc3145&v=4
- url: https://github.com/gabrielmbmb
- - login: danburonline
- avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
- url: https://github.com/danburonline
- - login: Moises6669
- avatarUrl: https://avatars.githubusercontent.com/u/66188523?u=96af25b8d5be9f983cb96e9dd7c605c716caf1f5&v=4
- url: https://github.com/Moises6669
+ - login: morzan1001
+ avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
+ url: https://github.com/morzan1001
+ - login: sadikkuzu
+ avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
+ url: https://github.com/sadikkuzu
+ - login: Olegt0rr
+ avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4
+ url: https://github.com/Olegt0rr
+ - login: larsyngvelundin
+ avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
+ url: https://github.com/larsyngvelundin
+ - login: 0ne-stone
+ avatarUrl: https://avatars.githubusercontent.com/u/62360849?u=746dd21c34e7e06eefb11b03e8bb01aaae3c2a4f&v=4
+ url: https://github.com/0ne-stone
+ - login: darixsamani
+ avatarUrl: https://avatars.githubusercontent.com/u/67915678?u=cfa82128692eeeec4bf0e7a0faaa9a614695c0f9&v=4
+ url: https://github.com/darixsamani
+ - login: nayasinghania
+ avatarUrl: https://avatars.githubusercontent.com/u/74111380?u=af853245a21fe052b6a27e41a8de8cf4cdf76e85&v=4
+ url: https://github.com/nayasinghania
+ - login: Toothwitch
+ avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4
+ url: https://github.com/Toothwitch
+ - login: roboman-tech
+ avatarUrl: https://avatars.githubusercontent.com/u/8183070?u=fdeaa2ed29f598eb7901693884c0ad32b16982e3&v=4
+ url: https://github.com/roboman-tech
+ - login: andreagrandi
+ avatarUrl: https://avatars.githubusercontent.com/u/636391?u=13d90cb8ec313593a5b71fbd4e33b78d6da736f5&v=4
+ url: https://github.com/andreagrandi
diff --git a/docs/en/data/members.yml b/docs/en/data/members.yml
new file mode 100644
index 000000000..7ec16e917
--- /dev/null
+++ b/docs/en/data/members.yml
@@ -0,0 +1,22 @@
+members:
+- login: tiangolo
+ avatar_url: https://avatars.githubusercontent.com/u/1326112
+ url: https://github.com/tiangolo
+- login: Kludex
+ avatar_url: https://avatars.githubusercontent.com/u/7353520
+ url: https://github.com/Kludex
+- login: alejsdev
+ avatar_url: https://avatars.githubusercontent.com/u/90076947
+ url: https://github.com/alejsdev
+- login: svlandeg
+ avatar_url: https://avatars.githubusercontent.com/u/8796347
+ url: https://github.com/svlandeg
+- login: YuriiMotov
+ avatar_url: https://avatars.githubusercontent.com/u/109919500
+ url: https://github.com/YuriiMotov
+- login: patrick91
+ avatar_url: https://avatars.githubusercontent.com/u/667029
+ url: https://github.com/patrick91
+- login: luzzodev
+ avatar_url: https://avatars.githubusercontent.com/u/27291415
+ url: https://github.com/luzzodev
diff --git a/docs/en/data/people.yml b/docs/en/data/people.yml
index 51940a6b1..a94c7c63c 100644
--- a/docs/en/data/people.yml
+++ b/docs/en/data/people.yml
@@ -1,530 +1,726 @@
maintainers:
- login: tiangolo
- answers: 1837
- prs: 360
- avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4
+ answers: 1898
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
experts:
+- login: tiangolo
+ count: 1898
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+- login: github-actions
+ count: 770
+ avatarUrl: https://avatars.githubusercontent.com/in/15368?v=4
+ url: https://github.com/apps/github-actions
- login: Kludex
- count: 374
- avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
+ count: 655
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
+- login: jgould22
+ count: 263
+ avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
+ url: https://github.com/jgould22
+- login: YuriiMotov
+ count: 247
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
- login: dmontagu
- count: 262
- avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
+ count: 240
+ avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
-- login: ycd
- count: 221
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
- url: https://github.com/ycd
- login: Mause
- count: 207
+ count: 219
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
+- login: ycd
+ count: 217
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
+ url: https://github.com/ycd
- login: JarroVGIT
count: 192
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: euri10
- count: 166
+ count: 153
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
+- login: iudeen
+ count: 128
+ avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
+ url: https://github.com/iudeen
- login: phy25
- count: 130
+ count: 126
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
-- login: iudeen
- count: 87
- avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
- url: https://github.com/iudeen
+- login: JavierSanchezCastro
+ count: 91
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
- login: raphaelauv
- count: 77
+ count: 83
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
+- login: ghandic
+ count: 71
+ avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
+ url: https://github.com/ghandic
- login: ArcLightSlavik
count: 71
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
url: https://github.com/ArcLightSlavik
+- login: n8sty
+ count: 67
+ avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
+ url: https://github.com/n8sty
+- login: luzzodev
+ count: 61
+ avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
+ url: https://github.com/luzzodev
- login: falkben
count: 59
- avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
url: https://github.com/falkben
-- login: jgould22
- count: 55
- avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
- url: https://github.com/jgould22
-- login: sm-Fifteen
+- login: acidjunk
count: 50
+ avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
+ url: https://github.com/acidjunk
+- login: yinziyan1206
+ count: 49
+ avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
+ url: https://github.com/yinziyan1206
+- login: sm-Fifteen
+ count: 49
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
-- login: insomnes
+- login: adriangb
count: 46
+ avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
+ url: https://github.com/adriangb
+- login: insomnes
+ count: 45
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: Dustyposa
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
-- login: adriangb
- count: 40
- avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=75087f0cf0e9f725f3cd18a899218b6c63ae60d3&v=4
- url: https://github.com/adriangb
+- login: odiseo0
+ count: 43
+ avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=241a71f6b7068738b81af3e57f45ffd723538401&v=4
+ url: https://github.com/odiseo0
+- login: frankie567
+ count: 43
+ avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=c159fe047727aedecbbeeaa96a1b03ceb9d39add&v=4
+ url: https://github.com/frankie567
+- login: sinisaos
+ count: 41
+ avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
+ url: https://github.com/sinisaos
- login: includeamin
- count: 39
+ count: 40
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
+- login: chbndrhnns
+ count: 37
+ avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
+ url: https://github.com/chbndrhnns
- login: STeveShary
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
-- login: chbndrhnns
- count: 36
- avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
- url: https://github.com/chbndrhnns
-- login: frankie567
- count: 33
- avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
- url: https://github.com/frankie567
-- login: prostomarkeloff
- count: 33
- avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
- url: https://github.com/prostomarkeloff
-- login: acidjunk
- count: 32
- avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
- url: https://github.com/acidjunk
- login: krishnardt
- count: 31
+ count: 35
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt
-- login: wshayes
- count: 29
- avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
- url: https://github.com/wshayes
- login: panla
- count: 29
+ count: 32
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla
-- login: ghandic
- count: 25
- avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
- url: https://github.com/ghandic
+- login: prostomarkeloff
+ count: 28
+ avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=6918e39a1224194ba636e897461a02a20126d7ad&v=4
+ url: https://github.com/prostomarkeloff
+- login: hasansezertasan
+ count: 27
+ avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
+ url: https://github.com/hasansezertasan
- login: dbanty
- count: 25
- avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
+ count: 26
+ avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9d726785d08e50b1e1cd96505800c8ea8405bce2&v=4
url: https://github.com/dbanty
-- login: yinziyan1206
+- login: alv2017
count: 25
- avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
- url: https://github.com/yinziyan1206
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+- login: wshayes
+ count: 25
+ avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
+ url: https://github.com/wshayes
- login: SirTelemak
- count: 24
+ count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
-- login: odiseo0
- count: 24
- avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4
- url: https://github.com/odiseo0
-- login: acnebs
+- login: connebs
count: 22
- avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
- url: https://github.com/acnebs
-- login: nsidnev
+ avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=e151d5f545a3395136d711c227c22032fda67cfa&v=4
+ url: https://github.com/connebs
+- login: nymous
count: 22
+ avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
+ url: https://github.com/nymous
+- login: chrisK824
+ count: 22
+ avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
+ url: https://github.com/chrisK824
+- login: rafsaf
+ count: 21
+ avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=5fe59a56e1f2f9ccd8005d71752a8276f133ae1a&v=4
+ url: https://github.com/rafsaf
+- login: ebottos94
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=8b91053b3abe4a9209375e3651e1c1ef192d884b&v=4
+ url: https://github.com/ebottos94
+- login: nsidnev
+ count: 20
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
url: https://github.com/nsidnev
- login: chris-allnutt
- count: 21
+ count: 20
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt
-- login: retnikt
+- login: estebanx64
count: 19
+ avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
+ url: https://github.com/estebanx64
+- login: zoliknemet
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
+ url: https://github.com/zoliknemet
+- login: sehraramiz
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
+ url: https://github.com/sehraramiz
+- login: retnikt
+ count: 18
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
url: https://github.com/retnikt
-- login: rafsaf
- count: 19
- avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
- url: https://github.com/rafsaf
+- login: caeser1996
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
+ url: https://github.com/caeser1996
- login: Hultner
- count: 18
+ count: 17
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
url: https://github.com/Hultner
-- login: jorgerpo
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
- url: https://github.com/jorgerpo
-- login: nkhitrov
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
- url: https://github.com/nkhitrov
- login: harunyasar
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
url: https://github.com/harunyasar
-- login: waynerv
+- login: nkhitrov
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=e19427d8dc296d6950e9c424adacc92d37496fe9&v=4
+ url: https://github.com/nkhitrov
+- login: jonatasoli
count: 16
- avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
- url: https://github.com/waynerv
+ avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=f601c3f111f2148bd9244c2cb3ebbd57b592e674&v=4
+ url: https://github.com/jonatasoli
- login: dstlny
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
-- login: jonatasoli
+- login: abhint
count: 15
- avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
- url: https://github.com/jonatasoli
-- login: mbroton
+ avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
+ url: https://github.com/abhint
+- login: ceb10n
count: 15
- avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4
- url: https://github.com/mbroton
-- login: hellocoldworld
- count: 14
- avatarUrl: https://avatars.githubusercontent.com/u/47581948?u=3d2186796434c507a6cb6de35189ab0ad27c356f&v=4
- url: https://github.com/hellocoldworld
-- login: haizaar
- count: 13
- avatarUrl: https://avatars.githubusercontent.com/u/58201?u=dd40d99a3e1935d0b768f122bfe2258d6ea53b2b&v=4
- url: https://github.com/haizaar
-- login: valentin994
- count: 13
- avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
- url: https://github.com/valentin994
-- login: David-Lor
- count: 12
- avatarUrl: https://avatars.githubusercontent.com/u/17401854?u=474680c02b94cba810cb9032fb7eb787d9cc9d22&v=4
- url: https://github.com/David-Lor
-- login: n8sty
- count: 12
- avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
- url: https://github.com/n8sty
-last_month_active:
-- login: jgould22
+ avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
+ url: https://github.com/ceb10n
+- login: jorgerpo
+ count: 15
+ avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
+ url: https://github.com/jorgerpo
+- login: simondale00
+ count: 15
+ avatarUrl: https://avatars.githubusercontent.com/u/33907262?u=2721fb37014d50daf473267c808aa678ecaefe09&v=4
+ url: https://github.com/simondale00
+last_month_experts:
+- login: YuriiMotov
count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
+- login: luzzodev
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
+ url: https://github.com/luzzodev
+- login: alv2017
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+- login: sachinh35
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4
+ url: https://github.com/sachinh35
+- login: KianAnbarestani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4
+ url: https://github.com/KianAnbarestani
+- login: tiangolo
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+three_months_experts:
+- login: luzzodev
+ count: 25
+ avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
+ url: https://github.com/luzzodev
+- login: YuriiMotov
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
+- login: alv2017
+ count: 22
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+- login: jgould22
+ count: 13
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
-- login: yinziyan1206
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
- url: https://github.com/yinziyan1206
-- login: iudeen
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
- url: https://github.com/iudeen
- login: Kludex
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
-- login: JarroVGIT
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
- url: https://github.com/JarroVGIT
-- login: TheJumpyWizard
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/90986815?u=67e9c13c9f063dd4313db7beb64eaa2f3a37f1fe&v=4
- url: https://github.com/TheJumpyWizard
-- login: mbroton
+- login: yauhen-sobaleu
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/51629535?u=fc1817060daf2df438bfca86c44f33da5cd667db&v=4
+ url: https://github.com/yauhen-sobaleu
+- login: JavierSanchezCastro
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
+- login: tiangolo
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+- login: sachinh35
count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4
- url: https://github.com/mbroton
-- login: mateoradman
+ avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4
+ url: https://github.com/sachinh35
+- login: SobikXexe
count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/48420316?u=066f36b8e8e263b0d90798113b0f291d3266db7c&v=4
- url: https://github.com/mateoradman
-top_contributors:
-- login: waynerv
- count: 25
- avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
- url: https://github.com/waynerv
-- login: tokusumi
- count: 22
- avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
- url: https://github.com/tokusumi
-- login: jaystone776
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
- url: https://github.com/jaystone776
-- login: dmontagu
- count: 16
- avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
- url: https://github.com/dmontagu
+ avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4
+ url: https://github.com/SobikXexe
+- login: KianAnbarestani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4
+ url: https://github.com/KianAnbarestani
+- login: sinisaos
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
+ url: https://github.com/sinisaos
+- login: Ale-Cas
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
+ url: https://github.com/Ale-Cas
+- login: adsouza
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/275832?v=4
+ url: https://github.com/adsouza
+- login: marsboy02
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/86903678?u=fa4a6b91eea3a11ae93c162616ca5edf51c68572&v=4
+ url: https://github.com/marsboy02
+- login: EverStarck
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/51029456?u=343409b7cb6b3ea6a59359f4e8370d9c3f140ecd&v=4
+ url: https://github.com/EverStarck
+- login: vtgn
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
+ url: https://github.com/vtgn
+six_months_experts:
+- login: luzzodev
+ count: 57
+ avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
+ url: https://github.com/luzzodev
+- login: YuriiMotov
+ count: 56
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
- login: Kludex
- count: 15
- avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
+ count: 34
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
-- login: euri10
- count: 13
- avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
- url: https://github.com/euri10
-- login: mariacamilagl
- count: 12
- avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
- url: https://github.com/mariacamilagl
-- login: Smlep
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
- url: https://github.com/Smlep
-- login: Serrones
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
- url: https://github.com/Serrones
-- login: RunningIkkyu
- count: 7
- avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=efb5b45b55584450507834f279ce48d4d64dea2f&v=4
- url: https://github.com/RunningIkkyu
-- login: hard-coders
+- login: alv2017
+ count: 25
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+- login: jgould22
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
+ url: https://github.com/jgould22
+- login: sehraramiz
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
+ url: https://github.com/sehraramiz
+- login: JavierSanchezCastro
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
+- login: yauhen-sobaleu
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/51629535?u=fc1817060daf2df438bfca86c44f33da5cd667db&v=4
+ url: https://github.com/yauhen-sobaleu
+- login: estebanx64
count: 7
- avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
- url: https://github.com/hard-coders
-- login: rjNemo
+ avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
+ url: https://github.com/estebanx64
+- login: yvallois
count: 7
- avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
- url: https://github.com/rjNemo
-- login: wshayes
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
- url: https://github.com/wshayes
-- login: SwftAlpc
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
- url: https://github.com/SwftAlpc
-- login: Attsun1031
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
- url: https://github.com/Attsun1031
-- login: ComicShrimp
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4
- url: https://github.com/ComicShrimp
-- login: batlopes
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4
- url: https://github.com/batlopes
-- login: jekirl
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
- url: https://github.com/jekirl
-- login: samuelcolvin
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
- url: https://github.com/samuelcolvin
-- login: jfunez
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
- url: https://github.com/jfunez
-- login: ycd
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
- url: https://github.com/ycd
-- login: komtaki
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
- url: https://github.com/komtaki
-- login: hitrust
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/3360631?u=5fa1f475ad784d64eb9666bdd43cc4d285dcc773&v=4
- url: https://github.com/hitrust
-- login: lsglucas
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
- url: https://github.com/lsglucas
-- login: NinaHwang
+ avatarUrl: https://avatars.githubusercontent.com/u/36999744?v=4
+ url: https://github.com/yvallois
+- login: tiangolo
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+- login: yokwejuste
count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
- url: https://github.com/NinaHwang
-top_reviewers:
+ avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=592c1e42aa0ee5cb94890e0b863e2acc78cc3bbc&v=4
+ url: https://github.com/yokwejuste
+- login: sachinh35
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4
+ url: https://github.com/sachinh35
+- login: viniciusCalcantara
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=3d7ffe5808843ee4372f9cc5a559ff1674cf1792&v=4
+ url: https://github.com/viniciusCalcantara
+- login: SobikXexe
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4
+ url: https://github.com/SobikXexe
+- login: chaitanyarahalkar
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/24942959?u=d3fbbc622540cb50b956585d5aec5037e01e4b1f&v=4
+ url: https://github.com/chaitanyarahalkar
+- login: KianAnbarestani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4
+ url: https://github.com/KianAnbarestani
+- login: sinisaos
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
+ url: https://github.com/sinisaos
+- login: Ale-Cas
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
+ url: https://github.com/Ale-Cas
+- login: adsouza
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/275832?v=4
+ url: https://github.com/adsouza
+- login: Synrom
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30272537?v=4
+ url: https://github.com/Synrom
+- login: PREPONDERANCE
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/112809059?u=30ab12dc9ddba2f94ab90e6ad4ad8bc5cfa7fccd&v=4
+ url: https://github.com/PREPONDERANCE
+- login: nbx3
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/34649527?u=943812f69e0d40adbd3fa1c9b8ef50dd971a2a45&v=4
+ url: https://github.com/nbx3
+- login: marsboy02
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/86903678?u=fa4a6b91eea3a11ae93c162616ca5edf51c68572&v=4
+ url: https://github.com/marsboy02
+- login: EverStarck
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/51029456?u=343409b7cb6b3ea6a59359f4e8370d9c3f140ecd&v=4
+ url: https://github.com/EverStarck
+- login: vtgn
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
+ url: https://github.com/vtgn
+- login: Trinkes
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4
+ url: https://github.com/Trinkes
+- login: XiaoXinYo
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=1eebf5ce25a8067f7bfa6251a24f667be492d9d6&v=4
+ url: https://github.com/XiaoXinYo
+- login: iloveitaly
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/150855?v=4
+ url: https://github.com/iloveitaly
+- login: LincolnPuzey
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/18750802?v=4
+ url: https://github.com/LincolnPuzey
+- login: Knighthawk-Leo
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/72437494?u=27c68db94a3107b605e603cc136f4ba83f0106d5&v=4
+ url: https://github.com/Knighthawk-Leo
+- login: gelezo43
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/40732698?u=611f39d3c1d2f4207a590937a78c1f10eed6232c&v=4
+ url: https://github.com/gelezo43
+- login: AliYmn
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/18416653?u=98c1fca46c7e4dabe8c39d17b5e55d1511d41cf9&v=4
+ url: https://github.com/AliYmn
+- login: RichieB2B
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1461970?u=edaa57d1077705244ea5c9244f4783d94ff11f12&v=4
+ url: https://github.com/RichieB2B
+- login: iiotsrc
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/131771119?u=bcaf2559ef6266af70b151b7fda31a1ee3dbecb3&v=4
+ url: https://github.com/iiotsrc
+- login: Kfir-G
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/57500876?u=0cd29db046a17f12f382d398141319fca7ff230a&v=4
+ url: https://github.com/Kfir-G
+one_year_experts:
+- login: YuriiMotov
+ count: 172
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
- login: Kludex
- count: 109
- avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
+ count: 63
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
-- login: BilalAlpaslan
- count: 70
- avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
- url: https://github.com/BilalAlpaslan
-- login: yezz123
- count: 59
- avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
- url: https://github.com/yezz123
-- login: tokusumi
- count: 50
- avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
- url: https://github.com/tokusumi
-- login: waynerv
- count: 47
- avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
- url: https://github.com/waynerv
-- login: Laineyzhang55
- count: 47
- avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
- url: https://github.com/Laineyzhang55
-- login: ycd
- count: 45
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
- url: https://github.com/ycd
-- login: cikay
+- login: luzzodev
+ count: 61
+ avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
+ url: https://github.com/luzzodev
+- login: sinisaos
count: 41
- avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4
- url: https://github.com/cikay
-- login: JarroVGIT
- count: 34
- avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
- url: https://github.com/JarroVGIT
-- login: AdrianDeAnda
- count: 33
- avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=b2ea249c6b41ddf98679c8d110d0f67d4a3ebf93&v=4
- url: https://github.com/AdrianDeAnda
-- login: iudeen
+ avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
+ url: https://github.com/sinisaos
+- login: JavierSanchezCastro
count: 33
- avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
- url: https://github.com/iudeen
-- login: ArcLightSlavik
- count: 31
- avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
- url: https://github.com/ArcLightSlavik
-- login: komtaki
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
+- login: jgould22
count: 27
- avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
- url: https://github.com/komtaki
-- login: cassiobotaro
- count: 26
- avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
- url: https://github.com/cassiobotaro
-- login: lsglucas
- count: 26
- avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
- url: https://github.com/lsglucas
-- login: dmontagu
- count: 23
- avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
- url: https://github.com/dmontagu
-- login: hard-coders
- count: 20
- avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
- url: https://github.com/hard-coders
-- login: 0417taehyun
- count: 19
- avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
- url: https://github.com/0417taehyun
-- login: rjNemo
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
- url: https://github.com/rjNemo
-- login: Smlep
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
- url: https://github.com/Smlep
-- login: zy7y
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/67154681?u=5d634834cc514028ea3f9115f7030b99a1f4d5a4&v=4
- url: https://github.com/zy7y
-- login: yanever
- count: 16
- avatarUrl: https://avatars.githubusercontent.com/u/21978760?v=4
- url: https://github.com/yanever
-- login: SwftAlpc
- count: 16
- avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
- url: https://github.com/SwftAlpc
-- login: DevDae
- count: 16
- avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
- url: https://github.com/DevDae
-- login: pedabraham
- count: 15
- avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
- url: https://github.com/pedabraham
-- login: delhi09
- count: 15
- avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
- url: https://github.com/delhi09
-- login: odiseo0
+ avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
+ url: https://github.com/jgould22
+- login: alv2017
+ count: 25
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+- login: tiangolo
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+- login: ceb10n
count: 15
- avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4
- url: https://github.com/odiseo0
-- login: sh0nk
+ avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
+ url: https://github.com/ceb10n
+- login: estebanx64
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
+ url: https://github.com/estebanx64
+- login: n8sty
count: 13
- avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
- url: https://github.com/sh0nk
-- login: RunningIkkyu
- count: 12
- avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=efb5b45b55584450507834f279ce48d4d64dea2f&v=4
- url: https://github.com/RunningIkkyu
-- login: LorhanSohaky
+ avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
+ url: https://github.com/n8sty
+- login: Kfir-G
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/57500876?u=0cd29db046a17f12f382d398141319fca7ff230a&v=4
+ url: https://github.com/Kfir-G
+- login: sehraramiz
count: 11
- avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
- url: https://github.com/LorhanSohaky
-- login: solomein-sv
+ avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
+ url: https://github.com/sehraramiz
+- login: PhysicallyActive
count: 11
- avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
- url: https://github.com/solomein-sv
-- login: mariacamilagl
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
- url: https://github.com/mariacamilagl
-- login: Attsun1031
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
- url: https://github.com/Attsun1031
-- login: maoyibo
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
- url: https://github.com/maoyibo
-- login: ComicShrimp
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4
- url: https://github.com/ComicShrimp
-- login: peidrao
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=88c2cb42a99e0f50cdeae3606992568184783ee5&v=4
- url: https://github.com/peidrao
-- login: izaguerreiro
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
- url: https://github.com/izaguerreiro
-- login: graingert
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/413772?u=64b77b6aa405c68a9c6bcf45f84257c66eea5f32&v=4
- url: https://github.com/graingert
-- login: PandaHun
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
- url: https://github.com/PandaHun
-- login: kty4119
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/49435654?v=4
- url: https://github.com/kty4119
-- login: bezaca
+ avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4
+ url: https://github.com/PhysicallyActive
+- login: mattmess1221
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/3409962?u=d22ea18aa8ea688af25a45df306134d593621a44&v=4
+ url: https://github.com/mattmess1221
+- login: yauhen-sobaleu
count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
- url: https://github.com/bezaca
-- login: raphaelauv
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
- url: https://github.com/raphaelauv
-- login: blt232018
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
- url: https://github.com/blt232018
-- login: rogerbrinkmann
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
- url: https://github.com/rogerbrinkmann
-- login: NinaHwang
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
- url: https://github.com/NinaHwang
-- login: dimaqq
+ avatarUrl: https://avatars.githubusercontent.com/u/51629535?u=fc1817060daf2df438bfca86c44f33da5cd667db&v=4
+ url: https://github.com/yauhen-sobaleu
+- login: AIdjis
count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/662249?v=4
- url: https://github.com/dimaqq
-- login: Xewus
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=4bdd4a0300530a504987db27488ba79c37f2fb18&v=4
- url: https://github.com/Xewus
-- login: Serrones
- count: 7
- avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
- url: https://github.com/Serrones
-- login: jovicon
+ avatarUrl: https://avatars.githubusercontent.com/u/88404339?u=2a80d80b054e9228391e32fb9bb39571509dab6a&v=4
+ url: https://github.com/AIdjis
+- login: yvallois
count: 7
- avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
- url: https://github.com/jovicon
+ avatarUrl: https://avatars.githubusercontent.com/u/36999744?v=4
+ url: https://github.com/yvallois
+- login: hasansezertasan
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
+ url: https://github.com/hasansezertasan
+- login: gustavosett
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/99373133?u=1382fe27034a0179f07cf989f63c4f23017f043c&v=4
+ url: https://github.com/gustavosett
+- login: chyok
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/32629225?u=3b7c30e8a09426a1b9284f6e8a0ae53a525596bf&v=4
+ url: https://github.com/chyok
+- login: PREPONDERANCE
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/112809059?u=30ab12dc9ddba2f94ab90e6ad4ad8bc5cfa7fccd&v=4
+ url: https://github.com/PREPONDERANCE
+- login: svlandeg
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
+ url: https://github.com/svlandeg
+- login: TomFaulkner
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/14956620?v=4
+ url: https://github.com/TomFaulkner
+- login: yokwejuste
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=592c1e42aa0ee5cb94890e0b863e2acc78cc3bbc&v=4
+ url: https://github.com/yokwejuste
+- login: binbjz
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/8213913?u=40b777c625cf53dcdc6afc4aa127de67c48bf610&v=4
+ url: https://github.com/binbjz
+- login: dbfreem
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/9778569?u=f2f1e9135b5e4f1b0c6821a548b17f97572720fc&v=4
+ url: https://github.com/dbfreem
+- login: sachinh35
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4
+ url: https://github.com/sachinh35
+- login: viniciusCalcantara
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=3d7ffe5808843ee4372f9cc5a559ff1674cf1792&v=4
+ url: https://github.com/viniciusCalcantara
+- login: SobikXexe
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4
+ url: https://github.com/SobikXexe
+- login: DeoLeung
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3764720?u=4c222ef513814de4c7fb3736d0a7adf11d953d43&v=4
+ url: https://github.com/DeoLeung
+- login: pawelad
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/7062874?u=d27dc220545a8401ad21840590a97d474d7101e6&v=4
+ url: https://github.com/pawelad
+- login: Isuxiz
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/48672727?u=34d7b4ade252687d22a27cf53037b735b244bfc1&v=4
+ url: https://github.com/Isuxiz
+- login: bertomaniac
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/10235051?u=14484a96833228a7b29fee4a7916d411c242c4f6&v=4
+ url: https://github.com/bertomaniac
+- login: deight93
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/37678115?u=a608798b5bd0034183a9c430ebb42fb266db86ce&v=4
+ url: https://github.com/deight93
+- login: Minibrams
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/8108085?u=b028dbc308fa8485e0e2e9402b3d03d8deb22bf9&v=4
+ url: https://github.com/Minibrams
+- login: alexandercronin
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/8014288?u=69580504c51a0cdd756fc47b23bb7f404bd694e7&v=4
+ url: https://github.com/alexandercronin
+- login: yanggeorge
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/2434407?v=4
+ url: https://github.com/yanggeorge
+- login: chaitanyarahalkar
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/24942959?u=d3fbbc622540cb50b956585d5aec5037e01e4b1f&v=4
+ url: https://github.com/chaitanyarahalkar
+- login: KianAnbarestani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4
+ url: https://github.com/KianAnbarestani
+- login: rustonaut
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/7632017?u=652bb86c1399727082c929fd4666fd7fa65923b1&v=4
+ url: https://github.com/rustonaut
+- login: Ale-Cas
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
+ url: https://github.com/Ale-Cas
+- login: CharlesPerrotMinotHCHB
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/112571330?u=a9628848d6096b491135727435a2a253152995a1&v=4
+ url: https://github.com/CharlesPerrotMinotHCHB
+- login: adsouza
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/275832?v=4
+ url: https://github.com/adsouza
+- login: Synrom
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30272537?v=4
+ url: https://github.com/Synrom
+- login: gaby
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/835733?u=8c72dec16fa560bdc81113354f2ffd79ad062bde&v=4
+ url: https://github.com/gaby
+- login: nbx3
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/34649527?u=943812f69e0d40adbd3fa1c9b8ef50dd971a2a45&v=4
+ url: https://github.com/nbx3
+- login: marsboy02
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/86903678?u=fa4a6b91eea3a11ae93c162616ca5edf51c68572&v=4
+ url: https://github.com/marsboy02
+- login: EverStarck
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/51029456?u=343409b7cb6b3ea6a59359f4e8370d9c3f140ecd&v=4
+ url: https://github.com/EverStarck
+- login: Trolldemorted
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10261186?v=4
+ url: https://github.com/Trolldemorted
+- login: anantgupta129
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/66518357?u=6e25dcd84638f17d2c6df5dc26f07fd7c6dc118e&v=4
+ url: https://github.com/anantgupta129
+- login: slafs
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
+ url: https://github.com/slafs
+- login: ddahan
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1933516?u=1d200a620e8d6841df017e9f2bb7efb58b580f40&v=4
+ url: https://github.com/ddahan
+- login: vtgn
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
+ url: https://github.com/vtgn
+- login: redb0
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30475117?v=4
+ url: https://github.com/redb0
+- login: pedroconceicao
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/32837064?u=5a0e6559bc391442629a28b6923790b54deb4464&v=4
+ url: https://github.com/pedroconceicao
+- login: msukmanowsky
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/362755?u=782e6bf5b9f0356c3f74b4d894fda9f179252086&v=4
+ url: https://github.com/msukmanowsky
+- login: rishabhc32
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/15983714?u=147776509107af8bdf099223e1840d3f40f944da&v=4
+ url: https://github.com/rishabhc32
+- login: meower1
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/109747197?u=0a5cc2a6ae74e558f0afc2874da85132e5953d8b&v=4
+ url: https://github.com/meower1
+- login: Trinkes
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4
+ url: https://github.com/Trinkes
diff --git a/docs/en/data/skip_users.yml b/docs/en/data/skip_users.yml
new file mode 100644
index 000000000..cf24003af
--- /dev/null
+++ b/docs/en/data/skip_users.yml
@@ -0,0 +1,5 @@
+- tiangolo
+- codecov
+- github-actions
+- pre-commit-ci
+- dependabot
diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml
index 749f528c5..f712b6179 100644
--- a/docs/en/data/sponsors.yml
+++ b/docs/en/data/sponsors.yml
@@ -1,42 +1,60 @@
gold:
- - url: https://bit.ly/3dmXC5S
- title: The data structure for unstructured multimodal data
- img: https://fastapi.tiangolo.com/img/sponsors/docarray.svg
- - url: https://bit.ly/3JJ7y5C
- title: Build cross-modal and multimodal applications on the cloud
- img: https://fastapi.tiangolo.com/img/sponsors/jina2.svg
- - url: https://cryptapi.io/
- title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
- img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg
- - url: https://doist.com/careers/9B437B1615-wa-senior-backend-engineer-python
- title: Help us migrate doist to FastAPI
- img: https://fastapi.tiangolo.com/img/sponsors/doist.svg
+ - url: https://blockbee.io?ref=fastapi
+ title: BlockBee Cryptocurrency Payment Gateway
+ img: https://fastapi.tiangolo.com/img/sponsors/blockbee.png
+ - url: https://platform.sh/try-it-now/?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023
+ title: "Build, run and scale your apps on a modern, reliable, and secure PaaS."
+ img: https://fastapi.tiangolo.com/img/sponsors/platform-sh.png
+ - url: https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge
+ title: "Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files"
+ img: https://fastapi.tiangolo.com/img/sponsors/scalar.svg
+ - url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge
+ title: Auth, user management and more for your B2B product
+ img: https://fastapi.tiangolo.com/img/sponsors/propelauth.png
+ - url: https://zuplo.link/fastapi-gh
+ title: 'Zuplo: Deploy, Secure, Document, and Monetize your FastAPI'
+ img: https://fastapi.tiangolo.com/img/sponsors/zuplo.png
+ - url: https://liblab.com?utm_source=fastapi
+ title: liblab - Generate SDKs from FastAPI
+ img: https://fastapi.tiangolo.com/img/sponsors/liblab.png
+ - url: https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi
+ title: Deploy & scale any full-stack web app on Render. Focus on building apps, not infra.
+ img: https://fastapi.tiangolo.com/img/sponsors/render.svg
+ - url: https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi
+ title: Cut Code Review Time & Bugs in Half with CodeRabbit
+ img: https://fastapi.tiangolo.com/img/sponsors/coderabbit.png
+ - url: https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source
+ title: The Gold Standard in Retail Account Linking
+ img: https://fastapi.tiangolo.com/img/sponsors/subtotal.svg
silver:
- - url: https://www.deta.sh/?ref=fastapi
- title: The launchpad for all your (team's) ideas
- img: https://fastapi.tiangolo.com/img/sponsors/deta.svg
- - url: https://www.investsuite.com/jobs
- title: Wealthtech jobs with FastAPI
- img: https://fastapi.tiangolo.com/img/sponsors/investsuite.svg
- - url: https://training.talkpython.fm/fastapi-courses
- title: FastAPI video courses on demand from people you trust
- img: https://fastapi.tiangolo.com/img/sponsors/talkpython.png
- - url: https://testdriven.io/courses/tdd-fastapi/
- title: Learn to build high-quality web apps with best practices
- img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
- - url: https://github.com/deepset-ai/haystack/
- title: Build powerful search from composable, open source building blocks
- img: https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg
- - url: https://www.udemy.com/course/fastapi-rest/
- title: Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails.
- img: https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg
- - url: https://careers.budget-insight.com/
- title: Budget Insight is hiring!
- img: https://fastapi.tiangolo.com/img/sponsors/budget-insight.svg
+ - url: https://databento.com/
+ title: Pay as you go for market data
+ img: https://fastapi.tiangolo.com/img/sponsors/databento.svg
+ - url: https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship
+ title: SDKs for your API | Speakeasy
+ img: https://fastapi.tiangolo.com/img/sponsors/speakeasy.png
+ - url: https://www.svix.com/
+ title: Svix - Webhooks as a service
+ img: https://fastapi.tiangolo.com/img/sponsors/svix.svg
+ - url: https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral
+ title: Stainless | Generate best-in-class SDKs
+ img: https://fastapi.tiangolo.com/img/sponsors/stainless.png
+ - url: https://www.permit.io/blog/implement-authorization-in-fastapi?utm_source=github&utm_medium=referral&utm_campaign=fastapi
+ title: Fine-Grained Authorization for FastAPI
+ img: https://fastapi.tiangolo.com/img/sponsors/permit.png
+ - url: https://www.interviewpal.com/?utm_source=fastapi&utm_medium=open-source&utm_campaign=dev-hiring
+ title: InterviewPal - AI Interview Coach for Engineers and Devs
+ img: https://fastapi.tiangolo.com/img/sponsors/interviewpal.png
+ - url: https://dribia.com/en/
+ title: Dribia - Data Science within your reach
+ img: https://fastapi.tiangolo.com/img/sponsors/dribia.png
bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy.
img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png
- - url: https://bit.ly/3ccLCmM
- title: https://striveworks.us/careers
- img: https://fastapi.tiangolo.com/img/sponsors/striveworks2.png
+ # - url: https://testdriven.io/courses/tdd-fastapi/
+ # title: Learn to build high-quality web apps with best practices
+ # img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
+ - url: https://lambdatest.com/?utm_source=fastapi&utm_medium=partner&utm_campaign=sponsor&utm_term=opensource&utm_content=webpage
+ title: LambdaTest, AI-Powered Cloud-based Test Orchestration Platform
+ img: https://fastapi.tiangolo.com/img/sponsors/lambdatest.png
diff --git a/docs/en/data/sponsors_badge.yml b/docs/en/data/sponsors_badge.yml
index a8bfb0b1b..d145e7372 100644
--- a/docs/en/data/sponsors_badge.yml
+++ b/docs/en/data/sponsors_badge.yml
@@ -5,11 +5,41 @@ logins:
- mikeckennedy
- deepset-ai
- cryptapi
- - Striveworks
- xoflare
- - InesIvanova
- DropbaseHQ
- VincentParedes
- BLUE-DEVIL1134
- ObliviousAI
- Doist
+ - nihpo
+ - armand-sauzay
+ - databento-bot
+ - databento
+ - nanram22
+ - Flint-company
+ - porter-dev
+ - fern-api
+ - ndimares
+ - svixhq
+ - Alek99
+ - codacy
+ - zanfaruqui
+ - scalar
+ - bump-sh
+ - andrew-propelauth
+ - svix
+ - zuplo-oss
+ - zuplo
+ - Kong
+ - speakeasy-api
+ - jess-render
+ - blockbee-io
+ - liblaber
+ - render-sponsorships
+ - renderinc
+ - stainless-api
+ - snapit-cypher
+ - coderabbitai
+ - permitio
+ - LambdaTest-Inc
+ - dribia
diff --git a/docs/en/data/topic_repos.yml b/docs/en/data/topic_repos.yml
new file mode 100644
index 000000000..ab9f21995
--- /dev/null
+++ b/docs/en/data/topic_repos.yml
@@ -0,0 +1,495 @@
+- name: full-stack-fastapi-template
+ html_url: https://github.com/fastapi/full-stack-fastapi-template
+ stars: 34156
+ owner_login: fastapi
+ owner_html_url: https://github.com/fastapi
+- name: Hello-Python
+ html_url: https://github.com/mouredev/Hello-Python
+ stars: 30835
+ owner_login: mouredev
+ owner_html_url: https://github.com/mouredev
+- name: serve
+ html_url: https://github.com/jina-ai/serve
+ stars: 21631
+ owner_login: jina-ai
+ owner_html_url: https://github.com/jina-ai
+- name: HivisionIDPhotos
+ html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
+ stars: 18125
+ owner_login: Zeyi-Lin
+ owner_html_url: https://github.com/Zeyi-Lin
+- name: sqlmodel
+ html_url: https://github.com/fastapi/sqlmodel
+ stars: 16249
+ owner_login: fastapi
+ owner_html_url: https://github.com/fastapi
+- name: Douyin_TikTok_Download_API
+ html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
+ stars: 13279
+ owner_login: Evil0ctal
+ owner_html_url: https://github.com/Evil0ctal
+- name: fastapi-best-practices
+ html_url: https://github.com/zhanymkanov/fastapi-best-practices
+ stars: 12334
+ owner_login: zhanymkanov
+ owner_html_url: https://github.com/zhanymkanov
+- name: awesome-fastapi
+ html_url: https://github.com/mjhea0/awesome-fastapi
+ stars: 9934
+ owner_login: mjhea0
+ owner_html_url: https://github.com/mjhea0
+- name: FastUI
+ html_url: https://github.com/pydantic/FastUI
+ stars: 8838
+ owner_login: pydantic
+ owner_html_url: https://github.com/pydantic
+- name: XHS-Downloader
+ html_url: https://github.com/JoeanAmier/XHS-Downloader
+ stars: 7962
+ owner_login: JoeanAmier
+ owner_html_url: https://github.com/JoeanAmier
+- name: nonebot2
+ html_url: https://github.com/nonebot/nonebot2
+ stars: 6834
+ owner_login: nonebot
+ owner_html_url: https://github.com/nonebot
+- name: FileCodeBox
+ html_url: https://github.com/vastsa/FileCodeBox
+ stars: 6783
+ owner_login: vastsa
+ owner_html_url: https://github.com/vastsa
+- name: fastapi_mcp
+ html_url: https://github.com/tadata-org/fastapi_mcp
+ stars: 5846
+ owner_login: tadata-org
+ owner_html_url: https://github.com/tadata-org
+- name: hatchet
+ html_url: https://github.com/hatchet-dev/hatchet
+ stars: 5773
+ owner_login: hatchet-dev
+ owner_html_url: https://github.com/hatchet-dev
+- name: serge
+ html_url: https://github.com/serge-chat/serge
+ stars: 5728
+ owner_login: serge-chat
+ owner_html_url: https://github.com/serge-chat
+- name: polar
+ html_url: https://github.com/polarsource/polar
+ stars: 5709
+ owner_login: polarsource
+ owner_html_url: https://github.com/polarsource
+- name: fastapi-users
+ html_url: https://github.com/fastapi-users/fastapi-users
+ stars: 5336
+ owner_login: fastapi-users
+ owner_html_url: https://github.com/fastapi-users
+- name: strawberry
+ html_url: https://github.com/strawberry-graphql/strawberry
+ stars: 4317
+ owner_login: strawberry-graphql
+ owner_html_url: https://github.com/strawberry-graphql
+- name: chatgpt-web-share
+ html_url: https://github.com/chatpire/chatgpt-web-share
+ stars: 4301
+ owner_login: chatpire
+ owner_html_url: https://github.com/chatpire
+- name: atrilabs-engine
+ html_url: https://github.com/Atri-Labs/atrilabs-engine
+ stars: 4106
+ owner_login: Atri-Labs
+ owner_html_url: https://github.com/Atri-Labs
+- name: dynaconf
+ html_url: https://github.com/dynaconf/dynaconf
+ stars: 4045
+ owner_login: dynaconf
+ owner_html_url: https://github.com/dynaconf
+- name: poem
+ html_url: https://github.com/poem-web/poem
+ stars: 4037
+ owner_login: poem-web
+ owner_html_url: https://github.com/poem-web
+- name: farfalle
+ html_url: https://github.com/rashadphz/farfalle
+ stars: 3348
+ owner_login: rashadphz
+ owner_html_url: https://github.com/rashadphz
+- name: LitServe
+ html_url: https://github.com/Lightning-AI/LitServe
+ stars: 3347
+ owner_login: Lightning-AI
+ owner_html_url: https://github.com/Lightning-AI
+- name: fastapi-admin
+ html_url: https://github.com/fastapi-admin/fastapi-admin
+ stars: 3309
+ owner_login: fastapi-admin
+ owner_html_url: https://github.com/fastapi-admin
+- name: datamodel-code-generator
+ html_url: https://github.com/koxudaxi/datamodel-code-generator
+ stars: 3291
+ owner_login: koxudaxi
+ owner_html_url: https://github.com/koxudaxi
+- name: logfire
+ html_url: https://github.com/pydantic/logfire
+ stars: 3288
+ owner_login: pydantic
+ owner_html_url: https://github.com/pydantic
+- name: huma
+ html_url: https://github.com/danielgtaylor/huma
+ stars: 3201
+ owner_login: danielgtaylor
+ owner_html_url: https://github.com/danielgtaylor
+- name: opyrator
+ html_url: https://github.com/ml-tooling/opyrator
+ stars: 3132
+ owner_login: ml-tooling
+ owner_html_url: https://github.com/ml-tooling
+- name: Kokoro-FastAPI
+ html_url: https://github.com/remsky/Kokoro-FastAPI
+ stars: 3099
+ owner_login: remsky
+ owner_html_url: https://github.com/remsky
+- name: docarray
+ html_url: https://github.com/docarray/docarray
+ stars: 3075
+ owner_login: docarray
+ owner_html_url: https://github.com/docarray
+- name: fastapi-realworld-example-app
+ html_url: https://github.com/nsidnev/fastapi-realworld-example-app
+ stars: 2902
+ owner_login: nsidnev
+ owner_html_url: https://github.com/nsidnev
+- name: tracecat
+ html_url: https://github.com/TracecatHQ/tracecat
+ stars: 2888
+ owner_login: TracecatHQ
+ owner_html_url: https://github.com/TracecatHQ
+- name: uvicorn-gunicorn-fastapi-docker
+ html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
+ stars: 2775
+ owner_login: tiangolo
+ owner_html_url: https://github.com/tiangolo
+- name: best-of-web-python
+ html_url: https://github.com/ml-tooling/best-of-web-python
+ stars: 2537
+ owner_login: ml-tooling
+ owner_html_url: https://github.com/ml-tooling
+- name: RasaGPT
+ html_url: https://github.com/paulpierre/RasaGPT
+ stars: 2427
+ owner_login: paulpierre
+ owner_html_url: https://github.com/paulpierre
+- name: fastapi-react
+ html_url: https://github.com/Buuntu/fastapi-react
+ stars: 2397
+ owner_login: Buuntu
+ owner_html_url: https://github.com/Buuntu
+- name: FastAPI-template
+ html_url: https://github.com/s3rius/FastAPI-template
+ stars: 2334
+ owner_login: s3rius
+ owner_html_url: https://github.com/s3rius
+- name: nextpy
+ html_url: https://github.com/dot-agent/nextpy
+ stars: 2295
+ owner_login: dot-agent
+ owner_html_url: https://github.com/dot-agent
+- name: sqladmin
+ html_url: https://github.com/aminalaee/sqladmin
+ stars: 2235
+ owner_login: aminalaee
+ owner_html_url: https://github.com/aminalaee
+- name: 30-Days-of-Python
+ html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
+ stars: 2181
+ owner_login: codingforentrepreneurs
+ owner_html_url: https://github.com/codingforentrepreneurs
+- name: langserve
+ html_url: https://github.com/langchain-ai/langserve
+ stars: 2119
+ owner_login: langchain-ai
+ owner_html_url: https://github.com/langchain-ai
+- name: fastapi-utils
+ html_url: https://github.com/fastapiutils/fastapi-utils
+ stars: 2100
+ owner_login: fastapiutils
+ owner_html_url: https://github.com/fastapiutils
+- name: supabase-py
+ html_url: https://github.com/supabase/supabase-py
+ stars: 2084
+ owner_login: supabase
+ owner_html_url: https://github.com/supabase
+- name: solara
+ html_url: https://github.com/widgetti/solara
+ stars: 2056
+ owner_login: widgetti
+ owner_html_url: https://github.com/widgetti
+- name: mangum
+ html_url: https://github.com/Kludex/mangum
+ stars: 1923
+ owner_login: Kludex
+ owner_html_url: https://github.com/Kludex
+- name: python-week-2022
+ html_url: https://github.com/rochacbruno/python-week-2022
+ stars: 1821
+ owner_login: rochacbruno
+ owner_html_url: https://github.com/rochacbruno
+- name: agentkit
+ html_url: https://github.com/BCG-X-Official/agentkit
+ stars: 1765
+ owner_login: BCG-X-Official
+ owner_html_url: https://github.com/BCG-X-Official
+- name: manage-fastapi
+ html_url: https://github.com/ycd/manage-fastapi
+ stars: 1756
+ owner_login: ycd
+ owner_html_url: https://github.com/ycd
+- name: ormar
+ html_url: https://github.com/collerek/ormar
+ stars: 1755
+ owner_login: collerek
+ owner_html_url: https://github.com/collerek
+- name: langchain-serve
+ html_url: https://github.com/jina-ai/langchain-serve
+ stars: 1631
+ owner_login: jina-ai
+ owner_html_url: https://github.com/jina-ai
+- name: piccolo
+ html_url: https://github.com/piccolo-orm/piccolo
+ stars: 1629
+ owner_login: piccolo-orm
+ owner_html_url: https://github.com/piccolo-orm
+- name: termpair
+ html_url: https://github.com/cs01/termpair
+ stars: 1616
+ owner_login: cs01
+ owner_html_url: https://github.com/cs01
+- name: openapi-python-client
+ html_url: https://github.com/openapi-generators/openapi-python-client
+ stars: 1603
+ owner_login: openapi-generators
+ owner_html_url: https://github.com/openapi-generators
+- name: fastapi-cache
+ html_url: https://github.com/long2ice/fastapi-cache
+ stars: 1589
+ owner_login: long2ice
+ owner_html_url: https://github.com/long2ice
+- name: coronavirus-tracker-api
+ html_url: https://github.com/ExpDev07/coronavirus-tracker-api
+ stars: 1580
+ owner_login: ExpDev07
+ owner_html_url: https://github.com/ExpDev07
+- name: slowapi
+ html_url: https://github.com/laurentS/slowapi
+ stars: 1533
+ owner_login: laurentS
+ owner_html_url: https://github.com/laurentS
+- name: fastapi-crudrouter
+ html_url: https://github.com/awtkns/fastapi-crudrouter
+ stars: 1518
+ owner_login: awtkns
+ owner_html_url: https://github.com/awtkns
+- name: awesome-fastapi-projects
+ html_url: https://github.com/Kludex/awesome-fastapi-projects
+ stars: 1461
+ owner_login: Kludex
+ owner_html_url: https://github.com/Kludex
+- name: vue-fastapi-admin
+ html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
+ stars: 1409
+ owner_login: mizhexiaoxiao
+ owner_html_url: https://github.com/mizhexiaoxiao
+- name: awesome-python-resources
+ html_url: https://github.com/DjangoEx/awesome-python-resources
+ stars: 1393
+ owner_login: DjangoEx
+ owner_html_url: https://github.com/DjangoEx
+- name: fastapi-pagination
+ html_url: https://github.com/uriyyo/fastapi-pagination
+ stars: 1378
+ owner_login: uriyyo
+ owner_html_url: https://github.com/uriyyo
+- name: fastapi-boilerplate
+ html_url: https://github.com/teamhide/fastapi-boilerplate
+ stars: 1348
+ owner_login: teamhide
+ owner_html_url: https://github.com/teamhide
+- name: budgetml
+ html_url: https://github.com/ebhy/budgetml
+ stars: 1344
+ owner_login: ebhy
+ owner_html_url: https://github.com/ebhy
+- name: fastapi-amis-admin
+ html_url: https://github.com/amisadmin/fastapi-amis-admin
+ stars: 1284
+ owner_login: amisadmin
+ owner_html_url: https://github.com/amisadmin
+- name: bracket
+ html_url: https://github.com/evroon/bracket
+ stars: 1274
+ owner_login: evroon
+ owner_html_url: https://github.com/evroon
+- name: fastapi-tutorial
+ html_url: https://github.com/liaogx/fastapi-tutorial
+ stars: 1265
+ owner_login: liaogx
+ owner_html_url: https://github.com/liaogx
+- name: fastapi-code-generator
+ html_url: https://github.com/koxudaxi/fastapi-code-generator
+ stars: 1216
+ owner_login: koxudaxi
+ owner_html_url: https://github.com/koxudaxi
+- name: bolt-python
+ html_url: https://github.com/slackapi/bolt-python
+ stars: 1190
+ owner_login: slackapi
+ owner_html_url: https://github.com/slackapi
+- name: fastcrud
+ html_url: https://github.com/benavlabs/fastcrud
+ stars: 1169
+ owner_login: benavlabs
+ owner_html_url: https://github.com/benavlabs
+- name: prometheus-fastapi-instrumentator
+ html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
+ stars: 1167
+ owner_login: trallnag
+ owner_html_url: https://github.com/trallnag
+- name: fastapi_production_template
+ html_url: https://github.com/zhanymkanov/fastapi_production_template
+ stars: 1165
+ owner_login: zhanymkanov
+ owner_html_url: https://github.com/zhanymkanov
+- name: bedrock-chat
+ html_url: https://github.com/aws-samples/bedrock-chat
+ stars: 1163
+ owner_login: aws-samples
+ owner_html_url: https://github.com/aws-samples
+- name: langchain-extract
+ html_url: https://github.com/langchain-ai/langchain-extract
+ stars: 1142
+ owner_login: langchain-ai
+ owner_html_url: https://github.com/langchain-ai
+- name: odmantic
+ html_url: https://github.com/art049/odmantic
+ stars: 1121
+ owner_login: art049
+ owner_html_url: https://github.com/art049
+- name: fastapi_best_architecture
+ html_url: https://github.com/fastapi-practices/fastapi_best_architecture
+ stars: 1118
+ owner_login: fastapi-practices
+ owner_html_url: https://github.com/fastapi-practices
+- name: fastapi-alembic-sqlmodel-async
+ html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
+ stars: 1116
+ owner_login: jonra1993
+ owner_html_url: https://github.com/jonra1993
+- name: FastAPI-boilerplate
+ html_url: https://github.com/benavlabs/FastAPI-boilerplate
+ stars: 1070
+ owner_login: benavlabs
+ owner_html_url: https://github.com/benavlabs
+- name: restish
+ html_url: https://github.com/rest-sh/restish
+ stars: 1069
+ owner_login: rest-sh
+ owner_html_url: https://github.com/rest-sh
+- name: runhouse
+ html_url: https://github.com/run-house/runhouse
+ stars: 1037
+ owner_login: run-house
+ owner_html_url: https://github.com/run-house
+- name: autollm
+ html_url: https://github.com/viddexa/autollm
+ stars: 994
+ owner_login: viddexa
+ owner_html_url: https://github.com/viddexa
+- name: lanarky
+ html_url: https://github.com/ajndkr/lanarky
+ stars: 992
+ owner_login: ajndkr
+ owner_html_url: https://github.com/ajndkr
+- name: authx
+ html_url: https://github.com/yezz123/authx
+ stars: 953
+ owner_login: yezz123
+ owner_html_url: https://github.com/yezz123
+- name: secure
+ html_url: https://github.com/TypeError/secure
+ stars: 941
+ owner_login: TypeError
+ owner_html_url: https://github.com/TypeError
+- name: energy-forecasting
+ html_url: https://github.com/iusztinpaul/energy-forecasting
+ stars: 928
+ owner_login: iusztinpaul
+ owner_html_url: https://github.com/iusztinpaul
+- name: langcorn
+ html_url: https://github.com/msoedov/langcorn
+ stars: 927
+ owner_login: msoedov
+ owner_html_url: https://github.com/msoedov
+- name: titiler
+ html_url: https://github.com/developmentseed/titiler
+ stars: 901
+ owner_login: developmentseed
+ owner_html_url: https://github.com/developmentseed
+- name: flock
+ html_url: https://github.com/Onelevenvy/flock
+ stars: 896
+ owner_login: Onelevenvy
+ owner_html_url: https://github.com/Onelevenvy
+- name: fastapi-langgraph-agent-production-ready-template
+ html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template
+ stars: 896
+ owner_login: wassim249
+ owner_html_url: https://github.com/wassim249
+- name: marker-api
+ html_url: https://github.com/adithya-s-k/marker-api
+ stars: 875
+ owner_login: adithya-s-k
+ owner_html_url: https://github.com/adithya-s-k
+- name: httpdbg
+ html_url: https://github.com/cle-b/httpdbg
+ stars: 870
+ owner_login: cle-b
+ owner_html_url: https://github.com/cle-b
+- name: fastapi-do-zero
+ html_url: https://github.com/dunossauro/fastapi-do-zero
+ stars: 855
+ owner_login: dunossauro
+ owner_html_url: https://github.com/dunossauro
+- name: ludic
+ html_url: https://github.com/getludic/ludic
+ stars: 849
+ owner_login: getludic
+ owner_html_url: https://github.com/getludic
+- name: fastapi-observability
+ html_url: https://github.com/blueswen/fastapi-observability
+ stars: 837
+ owner_login: blueswen
+ owner_html_url: https://github.com/blueswen
+- name: fastapi-scaf
+ html_url: https://github.com/atpuxiner/fastapi-scaf
+ stars: 821
+ owner_login: atpuxiner
+ owner_html_url: https://github.com/atpuxiner
+- name: starlette-admin
+ html_url: https://github.com/jowilf/starlette-admin
+ stars: 808
+ owner_login: jowilf
+ owner_html_url: https://github.com/jowilf
+- name: fastapi-mail
+ html_url: https://github.com/sabuhish/fastapi-mail
+ stars: 807
+ owner_login: sabuhish
+ owner_html_url: https://github.com/sabuhish
+- name: aktools
+ html_url: https://github.com/akfamily/aktools
+ stars: 796
+ owner_login: akfamily
+ owner_html_url: https://github.com/akfamily
+- name: RuoYi-Vue3-FastAPI
+ html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI
+ stars: 782
+ owner_login: insistence
+ owner_html_url: https://github.com/insistence
diff --git a/docs/en/data/translation_reviewers.yml b/docs/en/data/translation_reviewers.yml
new file mode 100644
index 000000000..4f3c95b27
--- /dev/null
+++ b/docs/en/data/translation_reviewers.yml
@@ -0,0 +1,1820 @@
+s111d:
+ login: s111d
+ count: 147
+ avatarUrl: https://avatars.githubusercontent.com/u/4954856?v=4
+ url: https://github.com/s111d
+Xewus:
+ login: Xewus
+ count: 140
+ avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
+ url: https://github.com/Xewus
+sodaMelon:
+ login: sodaMelon
+ count: 126
+ avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4
+ url: https://github.com/sodaMelon
+ceb10n:
+ login: ceb10n
+ count: 112
+ avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
+ url: https://github.com/ceb10n
+tokusumi:
+ login: tokusumi
+ count: 104
+ avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
+ url: https://github.com/tokusumi
+hasansezertasan:
+ login: hasansezertasan
+ count: 95
+ avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
+ url: https://github.com/hasansezertasan
+hard-coders:
+ login: hard-coders
+ count: 93
+ avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
+ url: https://github.com/hard-coders
+alv2017:
+ login: alv2017
+ count: 88
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+nazarepiedady:
+ login: nazarepiedady
+ count: 83
+ avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4
+ url: https://github.com/nazarepiedady
+AlertRED:
+ login: AlertRED
+ count: 81
+ avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4
+ url: https://github.com/AlertRED
+Alexandrhub:
+ login: Alexandrhub
+ count: 68
+ avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
+ url: https://github.com/Alexandrhub
+waynerv:
+ login: waynerv
+ count: 63
+ avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
+ url: https://github.com/waynerv
+cassiobotaro:
+ login: cassiobotaro
+ count: 62
+ avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=a08022b191ddbd0a6159b2981d9d878b6d5bb71f&v=4
+ url: https://github.com/cassiobotaro
+mattwang44:
+ login: mattwang44
+ count: 59
+ avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4
+ url: https://github.com/mattwang44
+tiangolo:
+ login: tiangolo
+ count: 53
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+Laineyzhang55:
+ login: Laineyzhang55
+ count: 48
+ avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
+ url: https://github.com/Laineyzhang55
+Kludex:
+ login: Kludex
+ count: 47
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
+ url: https://github.com/Kludex
+komtaki:
+ login: komtaki
+ count: 45
+ avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
+ url: https://github.com/komtaki
+rostik1410:
+ login: rostik1410
+ count: 42
+ avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
+ url: https://github.com/rostik1410
+svlandeg:
+ login: svlandeg
+ count: 42
+ avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
+ url: https://github.com/svlandeg
+alperiox:
+ login: alperiox
+ count: 42
+ avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4
+ url: https://github.com/alperiox
+Rishat-F:
+ login: Rishat-F
+ count: 42
+ avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
+ url: https://github.com/Rishat-F
+Winand:
+ login: Winand
+ count: 40
+ avatarUrl: https://avatars.githubusercontent.com/u/53390?u=bb0e71a2fc3910a8e0ee66da67c33de40ea695f8&v=4
+ url: https://github.com/Winand
+solomein-sv:
+ login: solomein-sv
+ count: 38
+ avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=789927ee09cfabd752d3bd554fa6baf4850d2777&v=4
+ url: https://github.com/solomein-sv
+JavierSanchezCastro:
+ login: JavierSanchezCastro
+ count: 38
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
+stlucasgarcia:
+ login: stlucasgarcia
+ count: 36
+ avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=c22d8850e9dc396a8820766a59837f967e14f9a0&v=4
+ url: https://github.com/stlucasgarcia
+SwftAlpc:
+ login: SwftAlpc
+ count: 36
+ avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
+ url: https://github.com/SwftAlpc
+alejsdev:
+ login: alejsdev
+ count: 36
+ avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=638c65283ac9e9e2c3a0f9d1e3370db4b8a2c58d&v=4
+ url: https://github.com/alejsdev
+timothy-jeong:
+ login: timothy-jeong
+ count: 36
+ avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
+ url: https://github.com/timothy-jeong
+nilslindemann:
+ login: nilslindemann
+ count: 35
+ avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
+ url: https://github.com/nilslindemann
+mezgoodle:
+ login: mezgoodle
+ count: 35
+ avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=4a9c765af688389d54296845d18b8f6cd6ddf09a&v=4
+ url: https://github.com/mezgoodle
+rjNemo:
+ login: rjNemo
+ count: 34
+ avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
+ url: https://github.com/rjNemo
+codingjenny:
+ login: codingjenny
+ count: 34
+ avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4
+ url: https://github.com/codingjenny
+akarev0:
+ login: akarev0
+ count: 33
+ avatarUrl: https://avatars.githubusercontent.com/u/53393089?u=6e528bb4789d56af887ce6fe237bea4010885406&v=4
+ url: https://github.com/akarev0
+romashevchenko:
+ login: romashevchenko
+ count: 32
+ avatarUrl: https://avatars.githubusercontent.com/u/132477732?v=4
+ url: https://github.com/romashevchenko
+LorhanSohaky:
+ login: LorhanSohaky
+ count: 30
+ avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
+ url: https://github.com/LorhanSohaky
+Vincy1230:
+ login: Vincy1230
+ count: 30
+ avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
+ url: https://github.com/Vincy1230
+black-redoc:
+ login: black-redoc
+ count: 29
+ avatarUrl: https://avatars.githubusercontent.com/u/18581590?u=7b6336166d0797fbbd44ea70c1c3ecadfc89af9e&v=4
+ url: https://github.com/black-redoc
+pedabraham:
+ login: pedabraham
+ count: 28
+ avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
+ url: https://github.com/pedabraham
+Smlep:
+ login: Smlep
+ count: 28
+ avatarUrl: https://avatars.githubusercontent.com/u/16785985?u=ffe99fa954c8e774ef1117e58d34aece92051e27&v=4
+ url: https://github.com/Smlep
+dedkot01:
+ login: dedkot01
+ count: 28
+ avatarUrl: https://avatars.githubusercontent.com/u/26196675?u=e2966887124e67932853df4f10f86cb526edc7b0&v=4
+ url: https://github.com/dedkot01
+hsuanchi:
+ login: hsuanchi
+ count: 28
+ avatarUrl: https://avatars.githubusercontent.com/u/24913710?u=7d25a398e478b6e63503bf6f26c54efa9e0da07b&v=4
+ url: https://github.com/hsuanchi
+dpinezich:
+ login: dpinezich
+ count: 28
+ avatarUrl: https://avatars.githubusercontent.com/u/3204540?u=a2e1465e3ee10d537614d513589607eddefde09f&v=4
+ url: https://github.com/dpinezich
+maoyibo:
+ login: maoyibo
+ count: 27
+ avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
+ url: https://github.com/maoyibo
+0417taehyun:
+ login: 0417taehyun
+ count: 27
+ avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
+ url: https://github.com/0417taehyun
+BilalAlpaslan:
+ login: BilalAlpaslan
+ count: 26
+ avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
+ url: https://github.com/BilalAlpaslan
+junah201:
+ login: junah201
+ count: 26
+ avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4
+ url: https://github.com/junah201
+zy7y:
+ login: zy7y
+ count: 25
+ avatarUrl: https://avatars.githubusercontent.com/u/67154681?u=5d634834cc514028ea3f9115f7030b99a1f4d5a4&v=4
+ url: https://github.com/zy7y
+mycaule:
+ login: mycaule
+ count: 25
+ avatarUrl: https://avatars.githubusercontent.com/u/6161385?u=e3cec75bd6d938a0d73fae0dc5534d1ab2ed1b0e&v=4
+ url: https://github.com/mycaule
+YuriiMotov:
+ login: YuriiMotov
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
+Aruelius:
+ login: Aruelius
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/25380989?u=574f8cfcda3ea77a3f81884f6b26a97068e36a9d&v=4
+ url: https://github.com/Aruelius
+wisderfin:
+ login: wisderfin
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/77553770?u=9a23740d520d65dc0051cdc1ecd87f31cb900313&v=4
+ url: https://github.com/wisderfin
+OzgunCaglarArslan:
+ login: OzgunCaglarArslan
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/86166426?v=4
+ url: https://github.com/OzgunCaglarArslan
+sh0nk:
+ login: sh0nk
+ count: 23
+ avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
+ url: https://github.com/sh0nk
+axel584:
+ login: axel584
+ count: 23
+ avatarUrl: https://avatars.githubusercontent.com/u/1334088?u=9667041f5b15dc002b6f9665fda8c0412933ac04&v=4
+ url: https://github.com/axel584
+DianaTrufanova:
+ login: DianaTrufanova
+ count: 23
+ avatarUrl: https://avatars.githubusercontent.com/u/119067607?u=1cd55f841b68b4a187fa6d06a7dafa5f070195aa&v=4
+ url: https://github.com/DianaTrufanova
+AGolicyn:
+ login: AGolicyn
+ count: 21
+ avatarUrl: https://avatars.githubusercontent.com/u/86262613?u=3c21606ab8d210a061a1673decff1e7d5592b380&v=4
+ url: https://github.com/AGolicyn
+Attsun1031:
+ login: Attsun1031
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
+ url: https://github.com/Attsun1031
+ycd:
+ login: ycd
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
+ url: https://github.com/ycd
+delhi09:
+ login: delhi09
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
+ url: https://github.com/delhi09
+rogerbrinkmann:
+ login: rogerbrinkmann
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
+ url: https://github.com/rogerbrinkmann
+DevDae:
+ login: DevDae
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
+ url: https://github.com/DevDae
+sattosan:
+ login: sattosan
+ count: 19
+ avatarUrl: https://avatars.githubusercontent.com/u/20574756?u=b0d8474d2938189c6954423ae8d81d91013f80a8&v=4
+ url: https://github.com/sattosan
+yes0ng:
+ login: yes0ng
+ count: 19
+ avatarUrl: https://avatars.githubusercontent.com/u/25501794?u=3aed18b0d491e0220a167a1e9e58bea3638c6707&v=4
+ url: https://github.com/yes0ng
+ComicShrimp:
+ login: ComicShrimp
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=d2fbf412e7730183ce91686ca48d4147e1b7dc74&v=4
+ url: https://github.com/ComicShrimp
+simatheone:
+ login: simatheone
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/78508673?u=1b9658d9ee0bde33f56130dd52275493ddd38690&v=4
+ url: https://github.com/simatheone
+ivan-abc:
+ login: ivan-abc
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/36765187?u=c6e0ba571c1ccb6db9d94e62e4b8b5eda811a870&v=4
+ url: https://github.com/ivan-abc
+Limsunoh:
+ login: Limsunoh
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/90311848?u=f456e0c5709fd50c8cd2898b551558eda14e5f21&v=4
+ url: https://github.com/Limsunoh
+SofiiaTrufanova:
+ login: SofiiaTrufanova
+ count: 18
+ avatarUrl: https://avatars.githubusercontent.com/u/63260929?u=483e0b64fabc76343b3be39b7e1dcb930a95e1bb&v=4
+ url: https://github.com/SofiiaTrufanova
+bezaca:
+ login: bezaca
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
+ url: https://github.com/bezaca
+lbmendes:
+ login: lbmendes
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/80999926?u=646619e2f07ac5a7c3f65fe7834197461a4fff9f&v=4
+ url: https://github.com/lbmendes
+spacesphere:
+ login: spacesphere
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/34628304?u=cde91f6002dd33156e1bf8005f11a7a3ed76b790&v=4
+ url: https://github.com/spacesphere
+panko:
+ login: panko
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/1569515?u=a84a5d255621ed82f8e1ca052f5f2eeb75997da2&v=4
+ url: https://github.com/panko
+jeison-araya:
+ login: jeison-araya
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/57369279?u=17001e68af7d8e5b8c343e5e9df4050f419998d5&v=4
+ url: https://github.com/jeison-araya
+yanever:
+ login: yanever
+ count: 16
+ avatarUrl: https://avatars.githubusercontent.com/u/21978760?v=4
+ url: https://github.com/yanever
+mastizada:
+ login: mastizada
+ count: 16
+ avatarUrl: https://avatars.githubusercontent.com/u/1975818?u=0751a06d7271c8bf17cb73b1b845644ab4d2c6dc&v=4
+ url: https://github.com/mastizada
+Joao-Pedro-P-Holanda:
+ login: Joao-Pedro-P-Holanda
+ count: 16
+ avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4
+ url: https://github.com/Joao-Pedro-P-Holanda
+JaeHyuckSa:
+ login: JaeHyuckSa
+ count: 16
+ avatarUrl: https://avatars.githubusercontent.com/u/104830931?u=6e352201714a05154e5d0ccf91b4715a951c622e&v=4
+ url: https://github.com/JaeHyuckSa
+Jedore:
+ login: Jedore
+ count: 15
+ avatarUrl: https://avatars.githubusercontent.com/u/17944025?u=81d503e1c800eb666b3861ca47a3a773bbc3f539&v=4
+ url: https://github.com/Jedore
+kim-sangah:
+ login: kim-sangah
+ count: 15
+ avatarUrl: https://avatars.githubusercontent.com/u/173775778?v=4
+ url: https://github.com/kim-sangah
+PandaHun:
+ login: PandaHun
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
+ url: https://github.com/PandaHun
+dukkee:
+ login: dukkee
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/36825394?u=ccfd86e6a4f2d093dad6f7544cc875af67fa2df8&v=4
+ url: https://github.com/dukkee
+BORA040126:
+ login: BORA040126
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/88664069?u=98e382727a485971e04aaa7c873d9a75a17ee3be&v=4
+ url: https://github.com/BORA040126
+mattkoehne:
+ login: mattkoehne
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/80362153?v=4
+ url: https://github.com/mattkoehne
+jovicon:
+ login: jovicon
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
+ url: https://github.com/jovicon
+izaguerreiro:
+ login: izaguerreiro
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
+ url: https://github.com/izaguerreiro
+jburckel:
+ login: jburckel
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/11768758?u=044462e4130e086a0621f4abb45f0d7a289ab7fa&v=4
+ url: https://github.com/jburckel
+peidrao:
+ login: peidrao
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=64c634bb10381905038ff7faf3c8c3df47fb799a&v=4
+ url: https://github.com/peidrao
+impocode:
+ login: impocode
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/109408819?u=9cdfc5ccb31a2094c520f41b6087012fa9048982&v=4
+ url: https://github.com/impocode
+wesinalves:
+ login: wesinalves
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/13563128?u=9eb17ed50645dd684bfec47e75dba4e9772ec9c1&v=4
+ url: https://github.com/wesinalves
+NastasiaSaby:
+ login: NastasiaSaby
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
+ url: https://github.com/NastasiaSaby
+oandersonmagalhaes:
+ login: oandersonmagalhaes
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
+ url: https://github.com/oandersonmagalhaes
+mkdir700:
+ login: mkdir700
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/56359329?u=3d6ea8714f5000829b60dcf7b13a75b1e73aaf47&v=4
+ url: https://github.com/mkdir700
+batlopes:
+ login: batlopes
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4
+ url: https://github.com/batlopes
+joonas-yoon:
+ login: joonas-yoon
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/9527681?u=0166d22ef4749e617c6516e79f833cd8d73f1949&v=4
+ url: https://github.com/joonas-yoon
+baseplate-admin:
+ login: baseplate-admin
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/61817579?u=ce4c268fa949ae9a0290996e7949195302055812&v=4
+ url: https://github.com/baseplate-admin
+KaniKim:
+ login: KaniKim
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/19832624?u=296dbdd490e0eb96e3d45a2608c065603b17dc31&v=4
+ url: https://github.com/KaniKim
+andersonrocha0:
+ login: andersonrocha0
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/22346169?u=93a1359c8c5461d894802c0cc65bcd09217e7a02&v=4
+ url: https://github.com/andersonrocha0
+gitgernit:
+ login: gitgernit
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/129539613?u=d04f10143ab32c93f563ea14bf242d1d2bc991b0&v=4
+ url: https://github.com/gitgernit
+kwang1215:
+ login: kwang1215
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
+ url: https://github.com/kwang1215
+AdrianDeAnda:
+ login: AdrianDeAnda
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=b2ea249c6b41ddf98679c8d110d0f67d4a3ebf93&v=4
+ url: https://github.com/AdrianDeAnda
+blt232018:
+ login: blt232018
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
+ url: https://github.com/blt232018
+NinaHwang:
+ login: NinaHwang
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=241f2cb6d38a2d379536608a8ea5a22ed4b1a3ea&v=4
+ url: https://github.com/NinaHwang
+glsglsgls:
+ login: glsglsgls
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/76133879?v=4
+ url: https://github.com/glsglsgls
+k94-ishi:
+ login: k94-ishi
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
+ url: https://github.com/k94-ishi
+codespearhead:
+ login: codespearhead
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/72931357?u=0fce6b82219b604d58adb614a761556425579cb5&v=4
+ url: https://github.com/codespearhead
+emrhnsyts:
+ login: emrhnsyts
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/42899027?u=ad26798e3f8feed2041c5dd5f87e58933d6c3283&v=4
+ url: https://github.com/emrhnsyts
+Lufa1u:
+ login: Lufa1u
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/112495876?u=087658920ed9e74311597bdd921d8d2de939d276&v=4
+ url: https://github.com/Lufa1u
+waketzheng:
+ login: waketzheng
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/35413830?u=df19e4fd5bb928e7d086e053ef26a46aad23bf84&v=4
+ url: https://github.com/waketzheng
+KNChiu:
+ login: KNChiu
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/36751646?v=4
+ url: https://github.com/KNChiu
+mariacamilagl:
+ login: mariacamilagl
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
+ url: https://github.com/mariacamilagl
+ryuckel:
+ login: ryuckel
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/36391432?u=094eec0cfddd5013f76f31e55e56147d78b19553&v=4
+ url: https://github.com/ryuckel
+umitkaanusta:
+ login: umitkaanusta
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/53405015?v=4
+ url: https://github.com/umitkaanusta
+kty4119:
+ login: kty4119
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/49435654?v=4
+ url: https://github.com/kty4119
+RobotToI:
+ login: RobotToI
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/44951382?u=e41dbc19191ce7abed86694b1a44ea0523e1c60e&v=4
+ url: https://github.com/RobotToI
+vitumenezes:
+ login: vitumenezes
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/9680878?u=05fd25cfafdc09382bf8907c37293a696c205754&v=4
+ url: https://github.com/vitumenezes
+fcrozetta:
+ login: fcrozetta
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/8006246?u=fa2a743e803de2c3a84d3ed8042faefed16c5e43&v=4
+ url: https://github.com/fcrozetta
+sUeharaE4:
+ login: sUeharaE4
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/44468359?v=4
+ url: https://github.com/sUeharaE4
+Ernilia:
+ login: Ernilia
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/125735800?u=13bfaac417a53fd5b5cf992efea363ca72598813&v=4
+ url: https://github.com/Ernilia
+socket-socket:
+ login: socket-socket
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/121552599?u=104df6503242e8d762fe293e7036f7260f245d49&v=4
+ url: https://github.com/socket-socket
+nick-cjyx9:
+ login: nick-cjyx9
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/119087246?u=c35aab03f082430be8a1edd80f5625b44819a0d8&v=4
+ url: https://github.com/nick-cjyx9
+lucasbalieiro:
+ login: lucasbalieiro
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4
+ url: https://github.com/lucasbalieiro
+maru0123-2004:
+ login: maru0123-2004
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4
+ url: https://github.com/maru0123-2004
+Zhongheng-Cheng:
+ login: Zhongheng-Cheng
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
+ url: https://github.com/Zhongheng-Cheng
+RunningIkkyu:
+ login: RunningIkkyu
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
+ url: https://github.com/RunningIkkyu
+JulianMaurin:
+ login: JulianMaurin
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/63545168?u=b7d15ac865268cbefc2d739e2f23d9aeeac1a622&v=4
+ url: https://github.com/JulianMaurin
+JeongHyeongKim:
+ login: JeongHyeongKim
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/26577800?u=77f060f4686f32c248907b81b16ee2b3177ca44c&v=4
+ url: https://github.com/JeongHyeongKim
+arthurio:
+ login: arthurio
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/950449?u=76b997138273ce5e1990b971c4f27c9aff979fd5&v=4
+ url: https://github.com/arthurio
+Lenclove:
+ login: Lenclove
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/32355298?u=d0065e01650c63c2b2413f42d983634b2ea85481&v=4
+ url: https://github.com/Lenclove
+eVery1337:
+ login: eVery1337
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/84917945?u=7af243f05ecfba59191199a70d8ba365c1327768&v=4
+ url: https://github.com/eVery1337
+aykhans:
+ login: aykhans
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/88669260?u=798da457cc3276d3c6dd7fd628d0005ad8b298cc&v=4
+ url: https://github.com/aykhans
+riroan:
+ login: riroan
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/33053284?u=2d18e3771506ee874b66d6aa2b3b1107fd95c38f&v=4
+ url: https://github.com/riroan
+MinLee0210:
+ login: MinLee0210
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/57653278?u=8ca05a7efbc76048183da00da87d148b755a3ba8&v=4
+ url: https://github.com/MinLee0210
+yodai-yodai:
+ login: yodai-yodai
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/7031039?u=4f3593f5931892b931a745cfab846eff6e9332e7&v=4
+ url: https://github.com/yodai-yodai
+marcelomarkus:
+ login: marcelomarkus
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/20115018?u=dda090ce9160ef0cd2ff69b1e5ea741283425cba&v=4
+ url: https://github.com/marcelomarkus
+JoaoGustavoRogel:
+ login: JoaoGustavoRogel
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/29525510?u=a0a91251f5e43e132608d55d28ccb8645c5ea405&v=4
+ url: https://github.com/JoaoGustavoRogel
+Yarous:
+ login: Yarous
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4
+ url: https://github.com/Yarous
+dimaqq:
+ login: dimaqq
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/662249?u=15313dec91bae789685e4abb3c2152251de41948&v=4
+ url: https://github.com/dimaqq
+julianofischer:
+ login: julianofischer
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/158303?u=d91662eb949d4cc7368831cf37a5cdfd90b7010c&v=4
+ url: https://github.com/julianofischer
+bnzone:
+ login: bnzone
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/39371503?u=c16f00c41d88479fa2d57b0d7d233b758eacce2d&v=4
+ url: https://github.com/bnzone
+shamosishen:
+ login: shamosishen
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/9498321?u=c83c20c79e019a0b555a125adf20fc4fb7a882c8&v=4
+ url: https://github.com/shamosishen
+mertssmnoglu:
+ login: mertssmnoglu
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/61623638?u=59dd885b68ff1832f9ab3b4a4446896358c23442&v=4
+ url: https://github.com/mertssmnoglu
+mahone3297:
+ login: mahone3297
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/1701379?u=20588ff0e456d13e8017333eb237595d11410234&v=4
+ url: https://github.com/mahone3297
+KimJoonSeo:
+ login: KimJoonSeo
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/17760162?u=a58cdc77ae1c069a64166f7ecc4d42eecfd9a468&v=4
+ url: https://github.com/KimJoonSeo
+camigomezdev:
+ login: camigomezdev
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/16061815?u=25b5ebc042fff53fa03dc107ded10e36b1b7a5b9&v=4
+ url: https://github.com/camigomezdev
+minaton-ru:
+ login: minaton-ru
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/53541518?u=67336ca11a85493f75031508aade588dad3b9910&v=4
+ url: https://github.com/minaton-ru
+sungchan1:
+ login: sungchan1
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/28076127?u=a816d86ef3e60450a7225f128caf9a394c9320f9&v=4
+ url: https://github.com/sungchan1
+Serrones:
+ login: Serrones
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
+ url: https://github.com/Serrones
+israteneda:
+ login: israteneda
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/20668624?u=67574648f89019d1c73b16a6a009da659557f9e5&v=4
+ url: https://github.com/israteneda
+krocdort:
+ login: krocdort
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/34248814?v=4
+ url: https://github.com/krocdort
+anthonycepeda:
+ login: anthonycepeda
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
+ url: https://github.com/anthonycepeda
+Muaytie666:
+ login: Muaytie666
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/198508825?v=4
+ url: https://github.com/Muaytie666
+fabioueno:
+ login: fabioueno
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/14273852?u=edd700982b16317ac6ebfd24c47bc0029b21d360&v=4
+ url: https://github.com/fabioueno
+cfraboulet:
+ login: cfraboulet
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/62244267?u=ed0e286ba48fa1dafd64a08e50f3364b8e12df34&v=4
+ url: https://github.com/cfraboulet
+HiemalBeryl:
+ login: HiemalBeryl
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/63165207?u=276f4af2829baf28b912c718675852bfccb0e7b4&v=4
+ url: https://github.com/HiemalBeryl
+pablocm83:
+ login: pablocm83
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/28315068?u=3310fbb05bb8bfc50d2c48b6cb64ac9ee4a14549&v=4
+ url: https://github.com/pablocm83
+d2a-raudenaerde:
+ login: d2a-raudenaerde
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/5213150?v=4
+ url: https://github.com/d2a-raudenaerde
+valentinDruzhinin:
+ login: valentinDruzhinin
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
+ url: https://github.com/valentinDruzhinin
+Zerohertz:
+ login: Zerohertz
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=5ebf4d33e73b1ad373154f6cdee44f7cab4d05ba&v=4
+ url: https://github.com/Zerohertz
+deniscapeto:
+ login: deniscapeto
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/12864353?u=20c5b2300b264a585a8381acf3cef44bcfcc1ead&v=4
+ url: https://github.com/deniscapeto
+bsab:
+ login: bsab
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/9799799?u=c4a09b1abb794cd8280c4793d43d0e2eb963ecda&v=4
+ url: https://github.com/bsab
+ArcLightSlavik:
+ login: ArcLightSlavik
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
+ url: https://github.com/ArcLightSlavik
+Cajuteq:
+ login: Cajuteq
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/26676532?u=8ee0422981810e51480855de1c0d67b6b79cd3f2&v=4
+ url: https://github.com/Cajuteq
+emmrichard:
+ login: emmrichard
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/1328018?u=8114d8fc0e8e42a092e4283013a1c54b792c466b&v=4
+ url: https://github.com/emmrichard
+wakabame:
+ login: wakabame
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/35513518?u=41ef6b0a55076e5c540620d68fb006e386c2ddb0&v=4
+ url: https://github.com/wakabame
+mawassk:
+ login: mawassk
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/84179197?v=4
+ url: https://github.com/mawassk
+diogoduartec:
+ login: diogoduartec
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/31852339?u=7514a5f05fcbeccc62f8c5dc25879efeb1ef9335&v=4
+ url: https://github.com/diogoduartec
+aqcool:
+ login: aqcool
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/52229895?v=4
+ url: https://github.com/aqcool
+'1320555911':
+ login: '1320555911'
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/58590086?u=6d8f4fbf08d5ac72c1c895892c461c5e0b013dc3&v=4
+ url: https://github.com/1320555911
+mcthesw:
+ login: mcthesw
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/61224072?u=82a1b106298348f060c3f4f39817e0cae5ce2b7c&v=4
+ url: https://github.com/mcthesw
+xzmeng:
+ login: xzmeng
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/40202897?v=4
+ url: https://github.com/xzmeng
+negadive:
+ login: negadive
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/47322392?u=c1be2e9b9b346b4a77d9157da2a5739ab25ce0f8&v=4
+ url: https://github.com/negadive
+mbroton:
+ login: mbroton
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4
+ url: https://github.com/mbroton
+Kirilex:
+ login: Kirilex
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/100281552?v=4
+ url: https://github.com/Kirilex
+arunppsg:
+ login: arunppsg
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/26398753?v=4
+ url: https://github.com/arunppsg
+dimastbk:
+ login: dimastbk
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/3132181?u=66587398d43466a1dc75c238df5f048e0afc77ed&v=4
+ url: https://github.com/dimastbk
+dudyaosuplayer:
+ login: dudyaosuplayer
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/62661898?u=7864cc5f01b1c845ae8ad49acf45dec6faca0c57&v=4
+ url: https://github.com/dudyaosuplayer
+talhaumer:
+ login: talhaumer
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/46643702?u=5d1fd7057ea9534fb3221931b809a3d750157212&v=4
+ url: https://github.com/talhaumer
+bankofsardine:
+ login: bankofsardine
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/44944207?u=0368e1b698ffab6bf29e202f9fd2dddd352429f1&v=4
+ url: https://github.com/bankofsardine
+Rekl0w:
+ login: Rekl0w
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/91488737?u=3b62b04a3e6699eab9b1eea4e88c09a39b753a17&v=4
+ url: https://github.com/Rekl0w
+rsip22:
+ login: rsip22
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/16676222?v=4
+ url: https://github.com/rsip22
+jessicapaz:
+ login: jessicapaz
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/20428941?u=6ffdaab5a85bf77a2d8870dade5e53555f34577b&v=4
+ url: https://github.com/jessicapaz
+mohsen-mahmoodi:
+ login: mohsen-mahmoodi
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/2872586?u=3a9fc1aa16a3a0ab93a1f8550de82a940592857d&v=4
+ url: https://github.com/mohsen-mahmoodi
+jeesang7:
+ login: jeesang7
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/30719956?u=35fc8bca04d32d3c4ce085956f0636b959ba30f6&v=4
+ url: https://github.com/jeesang7
+TemaSpb:
+ login: TemaSpb
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/20205738?u=d7dce0718720a7107803a573d628d8dd3d5c2fb4&v=4
+ url: https://github.com/TemaSpb
+BugLight:
+ login: BugLight
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/13618366?u=7d733749f80e5f7e66a434cf42aedcfc60340f43&v=4
+ url: https://github.com/BugLight
+0x4Dark:
+ login: 0x4Dark
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/7569289?v=4
+ url: https://github.com/0x4Dark
+Wuerike:
+ login: Wuerike
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/35462243?u=80c753dedf4a78db12ef66316dbdebbe6d84a2b9&v=4
+ url: https://github.com/Wuerike
+jvmazagao:
+ login: jvmazagao
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/22477816?u=2b57addf5830906bf6ae5f25cd4c8c2fa5c2d68e&v=4
+ url: https://github.com/jvmazagao
+cun3yt:
+ login: cun3yt
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/24409240?u=06abfd77786db859b0602d5369d2ae18c932c17c&v=4
+ url: https://github.com/cun3yt
+Mordson:
+ login: Mordson
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/39025897?u=b94ea96ef35bbe43bc85359cfb31d28ac16d470c&v=4
+ url: https://github.com/Mordson
+aminkhani:
+ login: aminkhani
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/51851950?u=051896c4933816bc61d11091d887f6e8dfd1d27b&v=4
+ url: https://github.com/aminkhani
+nifadyev:
+ login: nifadyev
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/36514612?u=e101da8641d5a09901d2155255a93f8ab3d9c468&v=4
+ url: https://github.com/nifadyev
+LaurEars:
+ login: LaurEars
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/4914725?v=4
+ url: https://github.com/LaurEars
+Chushine:
+ login: Chushine
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/135534400?v=4
+ url: https://github.com/Chushine
+ChuyuChoyeon:
+ login: ChuyuChoyeon
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/129537877?u=f0c76f3327817a8b86b422d62e04a34bf2827f2b&v=4
+ url: https://github.com/ChuyuChoyeon
+frwl404:
+ login: frwl404
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/42642656?u=8395a3d991d9fac86901277d76f0f70857b56ec5&v=4
+ url: https://github.com/frwl404
+esrefzeki:
+ login: esrefzeki
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/54935247?u=193cf5a169ca05fc54995a4dceabc82c7dc6e5ea&v=4
+ url: https://github.com/esrefzeki
+dtleal:
+ login: dtleal
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/31096951?v=4
+ url: https://github.com/dtleal
+art3xa:
+ login: art3xa
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/92092049?v=4
+ url: https://github.com/art3xa
+SamuelBFavarin:
+ login: SamuelBFavarin
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/17628602?u=5aac13ae492fa9a86e397a70803ac723dba2efe7&v=4
+ url: https://github.com/SamuelBFavarin
+takacs:
+ login: takacs
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/44911031?u=f6c6b70b3ba86ceb93b0f9bcab609bf9328b2305&v=4
+ url: https://github.com/takacs
+anton2yakovlev:
+ login: anton2yakovlev
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/44229180?u=bdd445ba99074b378e7298d23c4bf6d707d2c282&v=4
+ url: https://github.com/anton2yakovlev
+ILoveSorasakiHina:
+ login: ILoveSorasakiHina
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/114038930?u=3d3ed8dc3bf57e641d1b26badee5bc79ef34f25b&v=4
+ url: https://github.com/ILoveSorasakiHina
+devluisrodrigues:
+ login: devluisrodrigues
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4
+ url: https://github.com/devluisrodrigues
+11kkw:
+ login: 11kkw
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
+ url: https://github.com/11kkw
+lpdswing:
+ login: lpdswing
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/20874036?u=7a4fc3e4d0719e37b305deb7af234a7b63200787&v=4
+ url: https://github.com/lpdswing
+SepehrRasouli:
+ login: SepehrRasouli
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/81516241?u=3987e880c77d653dd85963302150e07bb7c0ef99&v=4
+ url: https://github.com/SepehrRasouli
+Zxilly:
+ login: Zxilly
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/31370133?u=c5359b8d9d80a7cdc23d5295d179ed90174996c8&v=4
+ url: https://github.com/Zxilly
+eavv:
+ login: eavv
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/18273429?u=c05e8b4ea62810ee7889ca049e510cdd0a66fd26&v=4
+ url: https://github.com/eavv
+AlexandreBiguet:
+ login: AlexandreBiguet
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/1483079?u=ff926455cd4cab03c6c49441aa5dc2b21df3e266&v=4
+ url: https://github.com/AlexandreBiguet
+FelipeSilva93:
+ login: FelipeSilva93
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/66804965?u=e7cb4b580e46f2e04ecb4cd4d7a12acdddd3c6c1&v=4
+ url: https://github.com/FelipeSilva93
+peacekimjapan:
+ login: peacekimjapan
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/33534175?u=e4219bcebc3773a7068cc34c3eb268ef77cec31b&v=4
+ url: https://github.com/peacekimjapan
+bas-baskara:
+ login: bas-baskara
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/41407847?u=cdabfaff7481c3323f24a76d9350393b964f2b89&v=4
+ url: https://github.com/bas-baskara
+odiseo0:
+ login: odiseo0
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=241a71f6b7068738b81af3e57f45ffd723538401&v=4
+ url: https://github.com/odiseo0
+eryknn:
+ login: eryknn
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/87120651?v=4
+ url: https://github.com/eryknn
+personage-hub:
+ login: personage-hub
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/76659786?v=4
+ url: https://github.com/personage-hub
+aminalaee:
+ login: aminalaee
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/19784933?v=4
+ url: https://github.com/aminalaee
+erfan-rfmhr:
+ login: erfan-rfmhr
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/98986056?u=0acda1ff1df0989f3f3eb79977baa35da4cb6c8c&v=4
+ url: https://github.com/erfan-rfmhr
+Scorpionchiques:
+ login: Scorpionchiques
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/15703294?v=4
+ url: https://github.com/Scorpionchiques
+lordqyxz:
+ login: lordqyxz
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/31722468?u=974553c0ba53526d9be7e9876544283291be3b0d&v=4
+ url: https://github.com/lordqyxz
+heysaeid:
+ login: heysaeid
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/63112273?u=5397ead391319a147a18b70cc04d1a334f235ef3&v=4
+ url: https://github.com/heysaeid
+Yois4101:
+ login: Yois4101
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/119609381?v=4
+ url: https://github.com/Yois4101
+tamtam-fitness:
+ login: tamtam-fitness
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/62091034?u=8da19a6bd3d02f5d6ba30c7247d5b46c98dd1403&v=4
+ url: https://github.com/tamtam-fitness
+mpmeleshko:
+ login: mpmeleshko
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/34425664?v=4
+ url: https://github.com/mpmeleshko
+SonnyYou:
+ login: SonnyYou
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/18657569?v=4
+ url: https://github.com/SonnyYou
+matiasbertani:
+ login: matiasbertani
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/65260383?u=d5edd86a6e2ab4fb1aab7751931fe045a963afd7&v=4
+ url: https://github.com/matiasbertani
+thiennc254:
+ login: thiennc254
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/97406628?u=1b2860679694b9a552764d0fa81dbd7a016322ec&v=4
+ url: https://github.com/thiennc254
+javillegasna:
+ login: javillegasna
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/38879192?u=df9ab0d628f8c1f1c849db7b3c0939337f42c3f1&v=4
+ url: https://github.com/javillegasna
+9zimin9:
+ login: 9zimin9
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/174453744?v=4
+ url: https://github.com/9zimin9
+ilhamfadillah:
+ login: ilhamfadillah
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/20577838?u=c56192cf99b55affcaad408b240259c62e633450&v=4
+ url: https://github.com/ilhamfadillah
+gerry-sabar:
+ login: gerry-sabar
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
+ url: https://github.com/gerry-sabar
+cookie-byte217:
+ login: cookie-byte217
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/57880178?v=4
+ url: https://github.com/cookie-byte217
+tyronedamasceno:
+ login: tyronedamasceno
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/12273721?u=913bca6bab96d9416ad8c9874c80de0833782050&v=4
+ url: https://github.com/tyronedamasceno
+LikoIlya:
+ login: LikoIlya
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/15039930?v=4
+ url: https://github.com/LikoIlya
+ss-o-furda:
+ login: ss-o-furda
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/56111536?u=d2326baa464a3778c280ed85fd14c00f87eb1080&v=4
+ url: https://github.com/ss-o-furda
+Frans06:
+ login: Frans06
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/5842109?u=77529d5517ae80438249b1a45f2d59372a31a212&v=4
+ url: https://github.com/Frans06
+Jefidev:
+ login: Jefidev
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/9964497?u=1da6eee587a8b425ca4afbfdfc6c3a639fe85d02&v=4
+ url: https://github.com/Jefidev
+Xaraxx:
+ login: Xaraxx
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/29824698?u=dde2e233e22bb5ca1f8bb0c6e353ccd0d06e6066&v=4
+ url: https://github.com/Xaraxx
+Suyoung789:
+ login: Suyoung789
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/31277231?u=744bd3e641413e19bfad6b06a90bb0887c3f9332&v=4
+ url: https://github.com/Suyoung789
+akagaeng:
+ login: akagaeng
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/17076841?u=9ada2eb6a33dc705ba96d58f802c787dea3859b8&v=4
+ url: https://github.com/akagaeng
+phamquanganh31101998:
+ login: phamquanganh31101998
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/43257497?u=36fa4ee689415d869a98453083a7c4213d2136ee&v=4
+ url: https://github.com/phamquanganh31101998
+peebbv6364:
+ login: peebbv6364
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/26784747?u=75583df215ee01a5cd2dc646aecb81e7dbd33d06&v=4
+ url: https://github.com/peebbv6364
+mrparalon:
+ login: mrparalon
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/19637629?u=6339508ceb665717cae862a4d33816ac874cbb8f&v=4
+ url: https://github.com/mrparalon
+creyD:
+ login: creyD
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/15138480?u=51cd2873cd93807beb578af8e23975856fdbc945&v=4
+ url: https://github.com/creyD
+zhoonit:
+ login: zhoonit
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/17230883?u=698cb26dcce4770374b592aad3b7489e91c07fc6&v=4
+ url: https://github.com/zhoonit
+Sefank:
+ login: Sefank
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/12670778?u=ca16995c68a82cabc7435c54ac0564930f62dd59&v=4
+ url: https://github.com/Sefank
+RuslanTer:
+ login: RuslanTer
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/48125303?v=4
+ url: https://github.com/RuslanTer
+FedorGN:
+ login: FedorGN
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/66411909?u=22382380e7d66ee57ffbfc2ae6bd5efd0cdb672e&v=4
+ url: https://github.com/FedorGN
+rafsaf:
+ login: rafsaf
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=5fe59a56e1f2f9ccd8005d71752a8276f133ae1a&v=4
+ url: https://github.com/rafsaf
+frnsimoes:
+ login: frnsimoes
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=a405e8f10654251e239a4a1d9dd5bda59216727d&v=4
+ url: https://github.com/frnsimoes
+lieryan:
+ login: lieryan
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/1006989?v=4
+ url: https://github.com/lieryan
+ValeryVal:
+ login: ValeryVal
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/85856176?v=4
+ url: https://github.com/ValeryVal
+chesstrian:
+ login: chesstrian
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3923412?u=8ea9bea6cfb5e6c64dc81be65ac2a9aaf23c5d47&v=4
+ url: https://github.com/chesstrian
+PabloEmidio:
+ login: PabloEmidio
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/69937719?u=f4d04cb78da68bb93a641f0b793ff665162e712a&v=4
+ url: https://github.com/PabloEmidio
+PraveenNanda124:
+ login: PraveenNanda124
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/116082827?u=b40c4f23c191692e88f676dc3bf33fc7f315edd4&v=4
+ url: https://github.com/PraveenNanda124
+guites:
+ login: guites
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/71985299?u=5dab5eb82b0a67fe709fc893f47a423df4de5d46&v=4
+ url: https://github.com/guites
+Junhyung21:
+ login: Junhyung21
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/138214497?u=66377988eaad4f57004decb183f396560407a73f&v=4
+ url: https://github.com/Junhyung21
+rinaatt:
+ login: rinaatt
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/6111202?u=9f62ebd2a72879db54d0b51c07c1d1e7203a4813&v=4
+ url: https://github.com/rinaatt
+Slijeff:
+ login: Slijeff
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/31459252?u=083776331690bbcf427766071e33ac28bb8d271d&v=4
+ url: https://github.com/Slijeff
+GeorchW:
+ login: GeorchW
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/8687777?u=ae4160f1d88f32692760003f3be9b5fc40a6e00d&v=4
+ url: https://github.com/GeorchW
+Vlad0395:
+ login: Vlad0395
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/37487589?u=57dc6660b9904cc0bc59b73569bbfb1ac871a4a1&v=4
+ url: https://github.com/Vlad0395
+bisibuka:
+ login: bisibuka
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/221887?v=4
+ url: https://github.com/bisibuka
+aimasheraz1:
+ login: aimasheraz1
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/132935019?v=4
+ url: https://github.com/aimasheraz1
+whysage:
+ login: whysage
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/67018871?u=a05d63a1b315dcf56a4c0dda3c0ca84ce3d6c87f&v=4
+ url: https://github.com/whysage
+Chake9928:
+ login: Chake9928
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/62596047?u=7aa2c0aad46911934ce3d22f83a895d05fa54e09&v=4
+ url: https://github.com/Chake9928
+qaerial:
+ login: qaerial
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/41595550?v=4
+ url: https://github.com/qaerial
+bluefish6:
+ login: bluefish6
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3324881?u=d107f6d0017927191644829fb845a8ceb8ac20ee&v=4
+ url: https://github.com/bluefish6
+Sion99:
+ login: Sion99
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/82511301?v=4
+ url: https://github.com/Sion99
+nymous:
+ login: nymous
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
+ url: https://github.com/nymous
+EpsilonRationes:
+ login: EpsilonRationes
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/148639079?v=4
+ url: https://github.com/EpsilonRationes
+SametEmin:
+ login: SametEmin
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/115692383?u=bda9052f698e50b0df6657fb9436d07e8496fe2f&v=4
+ url: https://github.com/SametEmin
+fhabers21:
+ login: fhabers21
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/58401847?v=4
+ url: https://github.com/fhabers21
+kohiry:
+ login: kohiry
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/57669492?u=f6ab0a062740261e882879269a41a47788c84043&v=4
+ url: https://github.com/kohiry
+ptt3199:
+ login: ptt3199
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=2c3d947a80283e32bf616d4c3af139a6be69680f&v=4
+ url: https://github.com/ptt3199
+arynoot:
+ login: arynoot
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/73756088?v=4
+ url: https://github.com/arynoot
+GDemay:
+ login: GDemay
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/7033942?u=bbdcb4e2a67df4ec9caa2440362d8cebc44d65e8&v=4
+ url: https://github.com/GDemay
+maxscheijen:
+ login: maxscheijen
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/47034840?v=4
+ url: https://github.com/maxscheijen
+celestywang:
+ login: celestywang
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/184830753?v=4
+ url: https://github.com/celestywang
+RyaWcksn:
+ login: RyaWcksn
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/42831964?u=0cb4265faf3e3425a89e59b6fddd3eb2de180af0&v=4
+ url: https://github.com/RyaWcksn
+tienduong-21:
+ login: tienduong-21
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/80129618?v=4
+ url: https://github.com/tienduong-21
+soroushgh1:
+ login: soroushgh1
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/178516095?u=5e26f6a5f66cdb32d7b56e6ab362bf18ba7858b9&v=4
+ url: https://github.com/soroushgh1
+zbellos:
+ login: zbellos
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/204500646?v=4
+ url: https://github.com/zbellos
+blaisep:
+ login: blaisep
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/254456?u=97d584b7c0a6faf583aa59975df4f993f671d121&v=4
+ url: https://github.com/blaisep
+SirTelemak:
+ login: SirTelemak
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
+ url: https://github.com/SirTelemak
+ovezovs:
+ login: ovezovs
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/44060682?u=9cb4d738b15e64157cb65afbe2e31bd0c8f3f6e6&v=4
+ url: https://github.com/ovezovs
+neatek:
+ login: neatek
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/3075678?u=3001e778e4aa0bf6d3142d09f0b9d13b2c55066f&v=4
+ url: https://github.com/neatek
+sprytnyk:
+ login: sprytnyk
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/16718258?u=4893ea96bfebfbdbde8abd9e06851eca12b01bc9&v=4
+ url: https://github.com/sprytnyk
+wfpinedar:
+ login: wfpinedar
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/5309214?u=4af7b6b3907b015699a9994d0808137dd68f7658&v=4
+ url: https://github.com/wfpinedar
+italopenaforte:
+ login: italopenaforte
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/7786881?u=e64a8f24b1ba95eb82f283be8ab90892e40c5465&v=4
+ url: https://github.com/italopenaforte
+hackerneocom:
+ login: hackerneocom
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/67042948?u=ca365045bd261cec5a64059aa23cf80065148c3c&v=4
+ url: https://github.com/hackerneocom
+dmas-at-wiris:
+ login: dmas-at-wiris
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/24917162?u=0df147936a375b4b64232c650de31a227a6b59a0&v=4
+ url: https://github.com/dmas-at-wiris
+TorhamDev:
+ login: TorhamDev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/87639984?u=07e5429fbd9c5d63c5ca55a0f31ef541216f0ce6&v=4
+ url: https://github.com/TorhamDev
+jaystone776:
+ login: jaystone776
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
+ url: https://github.com/jaystone776
+AaronDewes:
+ login: AaronDewes
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/67546953?v=4
+ url: https://github.com/AaronDewes
+kunansy:
+ login: kunansy
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20476946?u=d8321cd00787d5ee29bfdd8ff6fde23ad783a581&v=4
+ url: https://github.com/kunansy
+TimorChow:
+ login: TimorChow
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/18365403?u=bcbb357be0a447bc682a161932eab5032cede4af&v=4
+ url: https://github.com/TimorChow
+ataberkciftlikli:
+ login: ataberkciftlikli
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/64265169?u=ca7c1348242559f70bc1dc027a4be277c464676f&v=4
+ url: https://github.com/ataberkciftlikli
+leandrodesouzadev:
+ login: leandrodesouzadev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/85115541?u=4eb25f43f1fe23727d61e986cf83b73b86e2a95a&v=4
+ url: https://github.com/leandrodesouzadev
+dutkiewicz:
+ login: dutkiewicz
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/6649846?u=e941be6e1ab2ffdf41cea227a73f0ffbef20628f&v=4
+ url: https://github.com/dutkiewicz
+mirusu400:
+ login: mirusu400
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/25397908?u=deda776115e4ee6f76fa526bb5127bd1a6c4b231&v=4
+ url: https://github.com/mirusu400
+its0x08:
+ login: its0x08
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/15280042?u=d7c2058f29d4e8fbdae09b194e04c5e410350211&v=4
+ url: https://github.com/its0x08
+lindsayzhou:
+ login: lindsayzhou
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/23748021?u=4db169ce262b69aa7292f82b785436544f69fb88&v=4
+ url: https://github.com/lindsayzhou
+0xflotus:
+ login: 0xflotus
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/26602940?u=3c52ce6393bb547c97e6380ccdee03e0c64152c6&v=4
+ url: https://github.com/0xflotus
+jonatasoli:
+ login: jonatasoli
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=f601c3f111f2148bd9244c2cb3ebbd57b592e674&v=4
+ url: https://github.com/jonatasoli
+tyzh-dev:
+ login: tyzh-dev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/51972581?u=ba3882da7c009918a8e2d6b9ead31c89f09c922d&v=4
+ url: https://github.com/tyzh-dev
+yurkevich-dev:
+ login: yurkevich-dev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/45145188?u=db2de8c186073d95693279dcf085fcebffab57d0&v=4
+ url: https://github.com/yurkevich-dev
+emp7yhead:
+ login: emp7yhead
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20521260?u=9494c74cb9e1601d734b1f2726e292e257777d98&v=4
+ url: https://github.com/emp7yhead
+BartoszCki:
+ login: BartoszCki
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/17833351?u=40025e1182c32a9664834baec268dadad127703d&v=4
+ url: https://github.com/BartoszCki
+hakancelikdev:
+ login: hakancelikdev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/19157033?u=095ea8e0af1de642edd92e5f806c70359e00c977&v=4
+ url: https://github.com/hakancelikdev
+KaterinaSolovyeva:
+ login: KaterinaSolovyeva
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/85114725?u=1fe81463cb6b1fd01ac047172fa4895e2a3cecaa&v=4
+ url: https://github.com/KaterinaSolovyeva
+zhanymkanov:
+ login: zhanymkanov
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/22341602?u=aa1c47285a4f5692d165ccb2a441c5553f23ef83&v=4
+ url: https://github.com/zhanymkanov
+felipebpl:
+ login: felipebpl
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62957465?u=3c05f0f358b9575503c03122daefb115b6ac1414&v=4
+ url: https://github.com/felipebpl
+iudeen:
+ login: iudeen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
+ url: https://github.com/iudeen
+dwisulfahnur:
+ login: dwisulfahnur
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/12431528?v=4
+ url: https://github.com/dwisulfahnur
+ayr-ton:
+ login: ayr-ton
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1090517?u=5cf70a0e0f0dbf084e074e494aa94d7c91a46ba6&v=4
+ url: https://github.com/ayr-ton
+raphaelauv:
+ login: raphaelauv
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
+ url: https://github.com/raphaelauv
+Fahad-Md-Kamal:
+ login: Fahad-Md-Kamal
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/34704464?u=141086368c5557d5a1a533fe291f21f9fc584458&v=4
+ url: https://github.com/Fahad-Md-Kamal
+zxcq544:
+ login: zxcq544
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/5781268?u=25959ea03803742c3b28220b27fc07923a491dcb&v=4
+ url: https://github.com/zxcq544
+AlexandrMaltsevYDX:
+ login: AlexandrMaltsevYDX
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/109986802?u=ed275d72bfcdb4d15abdd54e7be026adbb9ca098&v=4
+ url: https://github.com/AlexandrMaltsevYDX
+realFranco:
+ login: realFranco
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/45880759?u=22fea3007d3e2d4c8c82d6ccfbde71454c4c6dd8&v=4
+ url: https://github.com/realFranco
+piaria:
+ login: piaria
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/110835535?u=5af3d56254faa05bbca4258a46c5723489480f90&v=4
+ url: https://github.com/piaria
+mojtabapaso:
+ login: mojtabapaso
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/121169359?u=ced1d5ad673bcd9e949ebf967a4ab50185637443&v=4
+ url: https://github.com/mojtabapaso
+eghbalpoorMH:
+ login: eghbalpoorMH
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/36267498?v=4
+ url: https://github.com/eghbalpoorMH
+Tiazen:
+ login: Tiazen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/16170159?u=0ce5e32f76e3f10733c8f25d97db9e31b753838c&v=4
+ url: https://github.com/Tiazen
+jfunez:
+ login: jfunez
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
+ url: https://github.com/jfunez
+s-rigaud:
+ login: s-rigaud
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/46346622?u=eee0adaa9fdff9e312d52526fbd4020dd6860c27&v=4
+ url: https://github.com/s-rigaud
+Artem4es:
+ login: Artem4es
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/110793967?u=0f9d4e80e055adc1aa8b548e951f6b4989fa2e78&v=4
+ url: https://github.com/Artem4es
+sulemanhelp:
+ login: sulemanhelp
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/22400366?u=3e8e68750655c7f5b2e0ba1d54f5779ee526707d&v=4
+ url: https://github.com/sulemanhelp
+theRealNonso:
+ login: theRealNonso
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/29557286?u=6f062680edccfeb4c802daf3b1d8b2a9e21ae013&v=4
+ url: https://github.com/theRealNonso
+AhsanSheraz:
+ login: AhsanSheraz
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/51913596?u=08e31cacb3048be30722c94010ddd028f3fdbec4&v=4
+ url: https://github.com/AhsanSheraz
+HealerNguyen:
+ login: HealerNguyen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/29653304?u=6ab095689054c63b1f4ceb26dd66847450225c87&v=4
+ url: https://github.com/HealerNguyen
+isulim:
+ login: isulim
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30448496?u=44c47838defa48a16606b895dce08890fca8482f&v=4
+ url: https://github.com/isulim
+siavashyj:
+ login: siavashyj
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4
+ url: https://github.com/siavashyj
+DevSpace88:
+ login: DevSpace88
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/102557040?u=6b356e3e1b9b6bc6a208b363988d4089ef94193f&v=4
+ url: https://github.com/DevSpace88
+Yum-git:
+ login: Yum-git
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/56100888?u=7c6ae21af081488b5fb703ab096fb1926025fd50&v=4
+ url: https://github.com/Yum-git
+oubush:
+ login: oubush
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/7489099?u=c86448bc61f5e7f03a1f14a768beeb09c33899d4&v=4
+ url: https://github.com/oubush
+KAZAMA-DREAM:
+ login: KAZAMA-DREAM
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/73453137?u=5108c757a3842733a448d9a16cdc65d82899eee1&v=4
+ url: https://github.com/KAZAMA-DREAM
+aprilcoskun:
+ login: aprilcoskun
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/17393603?u=18177d5bdba3a4567b8664587c882fb734e5fa09&v=4
+ url: https://github.com/aprilcoskun
+zhiquanchi:
+ login: zhiquanchi
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/29973289?u=744c74bc2635f839235ec32a0a934c5cef9a156d&v=4
+ url: https://github.com/zhiquanchi
+Jamim:
+ login: Jamim
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/5607572?u=9ce0b6a6d1a5124e28b3c04d8d26827ca328713a&v=4
+ url: https://github.com/Jamim
+alvinkhalil:
+ login: alvinkhalil
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/84583022?u=ab0eeb9ce6ffe93fd9bb23daf782b9867b864149&v=4
+ url: https://github.com/alvinkhalil
+leylaeminova:
+ login: leylaeminova
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/100516839?u=0b0dab9e31742076b22812b14a39b4e6d8f6de4a&v=4
+ url: https://github.com/leylaeminova
+UN-9BOT:
+ login: UN-9BOT
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/111110804?u=39e158937ed795972c2d0400fc521c50e9bfb9e7&v=4
+ url: https://github.com/UN-9BOT
+flasonme:
+ login: flasonme
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/30571019?v=4
+ url: https://github.com/flasonme
+gustavoprezoto:
+ login: gustavoprezoto
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62812585?u=2e936a0c6a2f11ecf3a735ebd33386100bcfebf8&v=4
+ url: https://github.com/gustavoprezoto
+johnny630:
+ login: johnny630
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/2870590?v=4
+ url: https://github.com/johnny630
+JCTrapero:
+ login: JCTrapero
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/109148166?u=bea607a04058176c4c2ae0d7c2e9ec647ccef002&v=4
+ url: https://github.com/JCTrapero
+ZhibangYue:
+ login: ZhibangYue
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/93324586?u=20fb23e3718e0364bb217966470d35e0637dd4fe&v=4
+ url: https://github.com/ZhibangYue
+saeye:
+ login: saeye
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62229734?u=312d619db2588b60d5d5bde65260a2f44fdc6c76&v=4
+ url: https://github.com/saeye
+Heumhub:
+ login: Heumhub
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/173761521?v=4
+ url: https://github.com/Heumhub
+manumolina:
+ login: manumolina
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/2404208?u=fdc5502910f8dec814b2477f89587b9e45fac846&v=4
+ url: https://github.com/manumolina
+logan2d5:
+ login: logan2d5
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/146642263?u=dbd6621f8b0330d6919f6a7131277b92e26fbe87&v=4
+ url: https://github.com/logan2d5
+tiaggo16:
+ login: tiaggo16
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62227573?u=359f4e2c51a4b13c8553ac5af405d635b07bb61f&v=4
+ url: https://github.com/tiaggo16
+kiharito:
+ login: kiharito
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/38311245?v=4
+ url: https://github.com/kiharito
+t4f1d:
+ login: t4f1d
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/4054172?u=463d5ce0ec8ad8582f6e9351bb8c9a5105b39bb7&v=4
+ url: https://github.com/t4f1d
+J-Fuji:
+ login: J-Fuji
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/101452903?v=4
+ url: https://github.com/J-Fuji
+MrL8199:
+ login: MrL8199
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/39489075?u=3fc4f89c86973e40b5970d838c801bdbc13ac828&v=4
+ url: https://github.com/MrL8199
+ivintoiu:
+ login: ivintoiu
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1853336?u=5e3d0977f44661fb9712fa297cc8f7608ea6ce48&v=4
+ url: https://github.com/ivintoiu
+EgorOnishchuk:
+ login: EgorOnishchuk
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/120256301?v=4
+ url: https://github.com/EgorOnishchuk
+iamantonreznik:
+ login: iamantonreznik
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/112612414?u=bf6de9a1ab17326fe14de0709719fff3826526d0&v=4
+ url: https://github.com/iamantonreznik
+Azazul123:
+ login: Azazul123
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/102759111?u=b48ce6e30a81a23467cc30e0c011bcc57f0326ab&v=4
+ url: https://github.com/Azazul123
+ykertytsky:
+ login: ykertytsky
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/83857001?u=1172902656ee604cf37f5e36abe938cd34a97a32&v=4
+ url: https://github.com/ykertytsky
+NavesSapnis:
+ login: NavesSapnis
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/79222417?u=b5b10291b8e9130ca84fd20f0a641e04ed94b6b1&v=4
+ url: https://github.com/NavesSapnis
diff --git a/docs/en/data/translators.yml b/docs/en/data/translators.yml
new file mode 100644
index 000000000..3cd6120d0
--- /dev/null
+++ b/docs/en/data/translators.yml
@@ -0,0 +1,535 @@
+nilslindemann:
+ login: nilslindemann
+ count: 120
+ avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
+ url: https://github.com/nilslindemann
+jaystone776:
+ login: jaystone776
+ count: 46
+ avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
+ url: https://github.com/jaystone776
+valentinDruzhinin:
+ login: valentinDruzhinin
+ count: 29
+ avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
+ url: https://github.com/valentinDruzhinin
+ceb10n:
+ login: ceb10n
+ count: 27
+ avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
+ url: https://github.com/ceb10n
+tokusumi:
+ login: tokusumi
+ count: 23
+ avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
+ url: https://github.com/tokusumi
+SwftAlpc:
+ login: SwftAlpc
+ count: 23
+ avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
+ url: https://github.com/SwftAlpc
+hasansezertasan:
+ login: hasansezertasan
+ count: 22
+ avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
+ url: https://github.com/hasansezertasan
+waynerv:
+ login: waynerv
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
+ url: https://github.com/waynerv
+AlertRED:
+ login: AlertRED
+ count: 16
+ avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4
+ url: https://github.com/AlertRED
+hard-coders:
+ login: hard-coders
+ count: 15
+ avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
+ url: https://github.com/hard-coders
+Joao-Pedro-P-Holanda:
+ login: Joao-Pedro-P-Holanda
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4
+ url: https://github.com/Joao-Pedro-P-Holanda
+codingjenny:
+ login: codingjenny
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4
+ url: https://github.com/codingjenny
+Xewus:
+ login: Xewus
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
+ url: https://github.com/Xewus
+Zhongheng-Cheng:
+ login: Zhongheng-Cheng
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
+ url: https://github.com/Zhongheng-Cheng
+Smlep:
+ login: Smlep
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/16785985?u=ffe99fa954c8e774ef1117e58d34aece92051e27&v=4
+ url: https://github.com/Smlep
+marcelomarkus:
+ login: marcelomarkus
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/20115018?u=dda090ce9160ef0cd2ff69b1e5ea741283425cba&v=4
+ url: https://github.com/marcelomarkus
+KaniKim:
+ login: KaniKim
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/19832624?u=296dbdd490e0eb96e3d45a2608c065603b17dc31&v=4
+ url: https://github.com/KaniKim
+Vincy1230:
+ login: Vincy1230
+ count: 9
+ avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
+ url: https://github.com/Vincy1230
+rjNemo:
+ login: rjNemo
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
+ url: https://github.com/rjNemo
+xzmeng:
+ login: xzmeng
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/40202897?v=4
+ url: https://github.com/xzmeng
+pablocm83:
+ login: pablocm83
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/28315068?u=3310fbb05bb8bfc50d2c48b6cb64ac9ee4a14549&v=4
+ url: https://github.com/pablocm83
+ptt3199:
+ login: ptt3199
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=2c3d947a80283e32bf616d4c3af139a6be69680f&v=4
+ url: https://github.com/ptt3199
+NinaHwang:
+ login: NinaHwang
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=241f2cb6d38a2d379536608a8ea5a22ed4b1a3ea&v=4
+ url: https://github.com/NinaHwang
+batlopes:
+ login: batlopes
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4
+ url: https://github.com/batlopes
+lucasbalieiro:
+ login: lucasbalieiro
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4
+ url: https://github.com/lucasbalieiro
+Alexandrhub:
+ login: Alexandrhub
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
+ url: https://github.com/Alexandrhub
+Serrones:
+ login: Serrones
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
+ url: https://github.com/Serrones
+RunningIkkyu:
+ login: RunningIkkyu
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
+ url: https://github.com/RunningIkkyu
+Attsun1031:
+ login: Attsun1031
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
+ url: https://github.com/Attsun1031
+tiangolo:
+ login: tiangolo
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
+ url: https://github.com/tiangolo
+rostik1410:
+ login: rostik1410
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
+ url: https://github.com/rostik1410
+alv2017:
+ login: alv2017
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
+ url: https://github.com/alv2017
+komtaki:
+ login: komtaki
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
+ url: https://github.com/komtaki
+JulianMaurin:
+ login: JulianMaurin
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/63545168?u=b7d15ac865268cbefc2d739e2f23d9aeeac1a622&v=4
+ url: https://github.com/JulianMaurin
+stlucasgarcia:
+ login: stlucasgarcia
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=c22d8850e9dc396a8820766a59837f967e14f9a0&v=4
+ url: https://github.com/stlucasgarcia
+ComicShrimp:
+ login: ComicShrimp
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=d2fbf412e7730183ce91686ca48d4147e1b7dc74&v=4
+ url: https://github.com/ComicShrimp
+BilalAlpaslan:
+ login: BilalAlpaslan
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
+ url: https://github.com/BilalAlpaslan
+axel584:
+ login: axel584
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/1334088?u=9667041f5b15dc002b6f9665fda8c0412933ac04&v=4
+ url: https://github.com/axel584
+tamtam-fitness:
+ login: tamtam-fitness
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/62091034?u=8da19a6bd3d02f5d6ba30c7247d5b46c98dd1403&v=4
+ url: https://github.com/tamtam-fitness
+Limsunoh:
+ login: Limsunoh
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/90311848?u=f456e0c5709fd50c8cd2898b551558eda14e5f21&v=4
+ url: https://github.com/Limsunoh
+kwang1215:
+ login: kwang1215
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
+ url: https://github.com/kwang1215
+k94-ishi:
+ login: k94-ishi
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
+ url: https://github.com/k94-ishi
+jfunez:
+ login: jfunez
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
+ url: https://github.com/jfunez
+ycd:
+ login: ycd
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
+ url: https://github.com/ycd
+mariacamilagl:
+ login: mariacamilagl
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
+ url: https://github.com/mariacamilagl
+maoyibo:
+ login: maoyibo
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
+ url: https://github.com/maoyibo
+blt232018:
+ login: blt232018
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
+ url: https://github.com/blt232018
+magiskboy:
+ login: magiskboy
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/13352088?u=18b6d672523f9e9d98401f31dd50e28bb27d826f&v=4
+ url: https://github.com/magiskboy
+luccasmmg:
+ login: luccasmmg
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/11317382?u=65099a5a0d492b89119471f8a7014637cc2e04da&v=4
+ url: https://github.com/luccasmmg
+lbmendes:
+ login: lbmendes
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/80999926?u=646619e2f07ac5a7c3f65fe7834197461a4fff9f&v=4
+ url: https://github.com/lbmendes
+Zssaer:
+ login: Zssaer
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/45691504?u=4c0c195f25cb5ac6af32acfb0ab35427682938d2&v=4
+ url: https://github.com/Zssaer
+ChuyuChoyeon:
+ login: ChuyuChoyeon
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/129537877?u=f0c76f3327817a8b86b422d62e04a34bf2827f2b&v=4
+ url: https://github.com/ChuyuChoyeon
+ivan-abc:
+ login: ivan-abc
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/36765187?u=c6e0ba571c1ccb6db9d94e62e4b8b5eda811a870&v=4
+ url: https://github.com/ivan-abc
+mojtabapaso:
+ login: mojtabapaso
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/121169359?u=ced1d5ad673bcd9e949ebf967a4ab50185637443&v=4
+ url: https://github.com/mojtabapaso
+hsuanchi:
+ login: hsuanchi
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/24913710?u=7d25a398e478b6e63503bf6f26c54efa9e0da07b&v=4
+ url: https://github.com/hsuanchi
+alejsdev:
+ login: alejsdev
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=638c65283ac9e9e2c3a0f9d1e3370db4b8a2c58d&v=4
+ url: https://github.com/alejsdev
+riroan:
+ login: riroan
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/33053284?u=2d18e3771506ee874b66d6aa2b3b1107fd95c38f&v=4
+ url: https://github.com/riroan
+nayeonkinn:
+ login: nayeonkinn
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/98254573?u=64a75ac99b320d4935eff8d1fceea9680fa07473&v=4
+ url: https://github.com/nayeonkinn
+pe-brian:
+ login: pe-brian
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/1783138?u=7e6242eb9e85bcf673fa88bbac9dd6dc3f03b1b5&v=4
+ url: https://github.com/pe-brian
+maxscheijen:
+ login: maxscheijen
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/47034840?v=4
+ url: https://github.com/maxscheijen
+ilacftemp:
+ login: ilacftemp
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/159066669?v=4
+ url: https://github.com/ilacftemp
+devluisrodrigues:
+ login: devluisrodrigues
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4
+ url: https://github.com/devluisrodrigues
+devfernandoa:
+ login: devfernandoa
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/28360583?u=c4308abd62e8847c9e572e1bb9fe6b9dc9ef8e50&v=4
+ url: https://github.com/devfernandoa
+kim-sangah:
+ login: kim-sangah
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/173775778?v=4
+ url: https://github.com/kim-sangah
+9zimin9:
+ login: 9zimin9
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/174453744?v=4
+ url: https://github.com/9zimin9
+nahyunkeem:
+ login: nahyunkeem
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/174440096?u=e12401d492eee58570f8914d0872b52e421a776e&v=4
+ url: https://github.com/nahyunkeem
+timothy-jeong:
+ login: timothy-jeong
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
+ url: https://github.com/timothy-jeong
+gerry-sabar:
+ login: gerry-sabar
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
+ url: https://github.com/gerry-sabar
+Rishat-F:
+ login: Rishat-F
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
+ url: https://github.com/Rishat-F
+ruzia:
+ login: ruzia
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/24503?v=4
+ url: https://github.com/ruzia
+izaguerreiro:
+ login: izaguerreiro
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
+ url: https://github.com/izaguerreiro
+Xaraxx:
+ login: Xaraxx
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/29824698?u=dde2e233e22bb5ca1f8bb0c6e353ccd0d06e6066&v=4
+ url: https://github.com/Xaraxx
+sh0nk:
+ login: sh0nk
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
+ url: https://github.com/sh0nk
+dukkee:
+ login: dukkee
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/36825394?u=ccfd86e6a4f2d093dad6f7544cc875af67fa2df8&v=4
+ url: https://github.com/dukkee
+oandersonmagalhaes:
+ login: oandersonmagalhaes
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
+ url: https://github.com/oandersonmagalhaes
+leandrodesouzadev:
+ login: leandrodesouzadev
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/85115541?u=4eb25f43f1fe23727d61e986cf83b73b86e2a95a&v=4
+ url: https://github.com/leandrodesouzadev
+kty4119:
+ login: kty4119
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/49435654?v=4
+ url: https://github.com/kty4119
+ASpathfinder:
+ login: ASpathfinder
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/31813636?u=2090bd1b7abb65cfeff0c618f99f11afa82c0548&v=4
+ url: https://github.com/ASpathfinder
+jujumilk3:
+ login: jujumilk3
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/41659814?u=538f7dfef03b59f25e43f10d59a31c19ef538a0c&v=4
+ url: https://github.com/jujumilk3
+ayr-ton:
+ login: ayr-ton
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1090517?u=5cf70a0e0f0dbf084e074e494aa94d7c91a46ba6&v=4
+ url: https://github.com/ayr-ton
+KdHyeon0661:
+ login: KdHyeon0661
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20253352?u=5ae1aae34b091a39f22cbe60a02b79dcbdbea031&v=4
+ url: https://github.com/KdHyeon0661
+LorhanSohaky:
+ login: LorhanSohaky
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
+ url: https://github.com/LorhanSohaky
+cfraboulet:
+ login: cfraboulet
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62244267?u=ed0e286ba48fa1dafd64a08e50f3364b8e12df34&v=4
+ url: https://github.com/cfraboulet
+dedkot01:
+ login: dedkot01
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/26196675?u=e2966887124e67932853df4f10f86cb526edc7b0&v=4
+ url: https://github.com/dedkot01
+AGolicyn:
+ login: AGolicyn
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/86262613?u=3c21606ab8d210a061a1673decff1e7d5592b380&v=4
+ url: https://github.com/AGolicyn
+fhabers21:
+ login: fhabers21
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/58401847?v=4
+ url: https://github.com/fhabers21
+TabarakoAkula:
+ login: TabarakoAkula
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/113298631?u=add801e370dbc502cd94ce6d3484760d7fef5406&v=4
+ url: https://github.com/TabarakoAkula
+AhsanSheraz:
+ login: AhsanSheraz
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/51913596?u=08e31cacb3048be30722c94010ddd028f3fdbec4&v=4
+ url: https://github.com/AhsanSheraz
+ArtemKhymenko:
+ login: ArtemKhymenko
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/14346625?u=f2fa553d9e5ec5e0f05d66bd649f7be347169631&v=4
+ url: https://github.com/ArtemKhymenko
+hasnatsajid:
+ login: hasnatsajid
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/86589885?u=49958789e6385be624f2c6a55a860c599eb05e2c&v=4
+ url: https://github.com/hasnatsajid
+alperiox:
+ login: alperiox
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4
+ url: https://github.com/alperiox
+emrhnsyts:
+ login: emrhnsyts
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/42899027?u=ad26798e3f8feed2041c5dd5f87e58933d6c3283&v=4
+ url: https://github.com/emrhnsyts
+vusallyv:
+ login: vusallyv
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/85983771?u=53a7b755cb338d9313966dbf2e4e68b512565186&v=4
+ url: https://github.com/vusallyv
+jackleeio:
+ login: jackleeio
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20477587?u=c5184dab6d021733d10c8f975b20e391856303d6&v=4
+ url: https://github.com/jackleeio
+choi-haram:
+ login: choi-haram
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62204475?v=4
+ url: https://github.com/choi-haram
+imtiaz101325:
+ login: imtiaz101325
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/54007087?u=194d972b501b9ea9d2ddeaed757c492936e0121a&v=4
+ url: https://github.com/imtiaz101325
+fabianfalon:
+ login: fabianfalon
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/3700760?u=95f69e31280b17ac22299cdcd345323b142fe0af&v=4
+ url: https://github.com/fabianfalon
+waketzheng:
+ login: waketzheng
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/35413830?u=df19e4fd5bb928e7d086e053ef26a46aad23bf84&v=4
+ url: https://github.com/waketzheng
+billzhong:
+ login: billzhong
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/1644011?v=4
+ url: https://github.com/billzhong
+chaoless:
+ login: chaoless
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/64477804?v=4
+ url: https://github.com/chaoless
+logan2d5:
+ login: logan2d5
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/146642263?u=dbd6621f8b0330d6919f6a7131277b92e26fbe87&v=4
+ url: https://github.com/logan2d5
+andersonrocha0:
+ login: andersonrocha0
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/22346169?u=93a1359c8c5461d894802c0cc65bcd09217e7a02&v=4
+ url: https://github.com/andersonrocha0
+saeye:
+ login: saeye
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/62229734?u=312d619db2588b60d5d5bde65260a2f44fdc6c76&v=4
+ url: https://github.com/saeye
+11kkw:
+ login: 11kkw
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
+ url: https://github.com/11kkw
+yes0ng:
+ login: yes0ng
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/25501794?u=3aed18b0d491e0220a167a1e9e58bea3638c6707&v=4
+ url: https://github.com/yes0ng
+EgorOnishchuk:
+ login: EgorOnishchuk
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/120256301?v=4
+ url: https://github.com/EgorOnishchuk
+NavesSapnis:
+ login: NavesSapnis
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/79222417?u=b5b10291b8e9130ca84fd20f0a641e04ed94b6b1&v=4
+ url: https://github.com/NavesSapnis
diff --git a/docs/en/docs/about/index.md b/docs/en/docs/about/index.md
new file mode 100644
index 000000000..27b78696b
--- /dev/null
+++ b/docs/en/docs/about/index.md
@@ -0,0 +1,3 @@
+# About
+
+About FastAPI, its design, inspiration and more. 🤓
diff --git a/docs/en/docs/advanced/additional-responses.md b/docs/en/docs/advanced/additional-responses.md
index dca5f6a98..03d48c2a7 100644
--- a/docs/en/docs/advanced/additional-responses.md
+++ b/docs/en/docs/advanced/additional-responses.md
@@ -1,9 +1,12 @@
# Additional Responses in OpenAPI
-!!! warning
- This is a rather advanced topic.
+/// warning
- If you are starting with **FastAPI**, you might not need this.
+This is a rather advanced topic.
+
+If you are starting with **FastAPI**, you might not need this.
+
+///
You can declare additional responses, with additional status codes, media types, descriptions, etc.
@@ -15,7 +18,7 @@ But for those additional responses you have to make sure you return a `Response`
You can pass to your *path operation decorators* a parameter `responses`.
-It receives a `dict`, the keys are status codes for each response, like `200`, and the values are other `dict`s with the information for each of them.
+It receives a `dict`: the keys are status codes for each response (like `200`), and the values are other `dict`s with the information for each of them.
Each of those response `dict`s can have a key `model`, containing a Pydantic model, just like `response_model`.
@@ -23,24 +26,28 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod
For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:
-```Python hl_lines="18 22"
-{!../../../docs_src/additional_responses/tutorial001.py!}
-```
+{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+
+/// note
+
+Keep in mind that you have to return the `JSONResponse` directly.
+
+///
+
+/// info
-!!! note
- Have in mind that you have to return the `JSONResponse` directly.
+The `model` key is not part of OpenAPI.
-!!! info
- The `model` key is not part of OpenAPI.
+**FastAPI** will take the Pydantic model from there, generate the JSON Schema, and put it in the correct place.
- **FastAPI** will take the Pydantic model from there, generate the `JSON Schema`, and put it in the correct place.
+The correct place is:
- The correct place is:
+* In the key `content`, that has as value another JSON object (`dict`) that contains:
+ * A key with the media type, e.g. `application/json`, that contains as value another JSON object, that contains:
+ * A key `schema`, that has as the value the JSON Schema from the model, here's the correct place.
+ * **FastAPI** adds a reference here to the global JSON Schemas in another place in your OpenAPI instead of including it directly. This way, other applications and clients can use those JSON Schemas directly, provide better code generation tools, etc.
- * In the key `content`, that has as value another JSON object (`dict`) that contains:
- * A key with the media type, e.g. `application/json`, that contains as value another JSON object, that contains:
- * A key `schema`, that has as the value the JSON Schema from the model, here's the correct place.
- * **FastAPI** adds a reference here to the global JSON Schemas in another place in your OpenAPI instead of including it directly. This way, other applications and clients can use those JSON Schemas directly, provide better code generation tools, etc.
+///
The generated responses in the OpenAPI for this *path operation* will be:
@@ -168,17 +175,21 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
-```Python hl_lines="19-24 28"
-{!../../../docs_src/additional_responses/tutorial002.py!}
-```
+{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
+
+/// note
+
+Notice that you have to return the image using a `FileResponse` directly.
+
+///
-!!! note
- Notice that you have to return the image using a `FileResponse` directly.
+/// info
-!!! info
- Unless you specify a different media type explicitly in your `responses` parameter, FastAPI will assume the response has the same media type as the main response class (default `application/json`).
+Unless you specify a different media type explicitly in your `responses` parameter, FastAPI will assume the response has the same media type as the main response class (default `application/json`).
- But if you have specified a custom response class with `None` as its media type, FastAPI will use `application/json` for any additional response that has an associated model.
+But if you have specified a custom response class with `None` as its media type, FastAPI will use `application/json` for any additional response that has an associated model.
+
+///
## Combining information
@@ -192,9 +203,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd
And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:
-```Python hl_lines="20-31"
-{!../../../docs_src/additional_responses/tutorial003.py!}
-```
+{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
It will all be combined and included in your OpenAPI, and shown in the API docs:
@@ -224,17 +233,15 @@ Here, `new_dict` will contain all the key-value pairs from `old_dict` plus the n
}
```
-You can use that technique to re-use some predefined responses in your *path operations* and combine them with additional custom ones.
+You can use that technique to reuse some predefined responses in your *path operations* and combine them with additional custom ones.
For example:
-```Python hl_lines="13-17 26"
-{!../../../docs_src/additional_responses/tutorial004.py!}
-```
+{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
## More information about OpenAPI responses
To see what exactly you can include in the responses, you can check these sections in the OpenAPI specification:
-*
@@ -144,13 +105,15 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
+////
+
The only new option here is `--workers` telling Uvicorn to start 4 worker processes.
You can also see that it shows the **PID** of each process, `27365` for the parent process (this is the **process manager**) and one for each worker process: `27368`, `27369`, `27370`, and `27367`.
## Deployment Concepts
-Here you saw how to use **Gunicorn** (or Uvicorn) managing **Uvicorn worker processes** to **parallelize** the execution of the application, take advantage of **multiple cores** in the CPU, and be able to serve **more requests**.
+Here you saw how to use multiple **workers** to **parallelize** the execution of the application, take advantage of **multiple cores** in the CPU, and be able to serve **more requests**.
From the list of deployment concepts from above, using workers would mainly help with the **replication** part, and a little bit with the **restarts**, but you still need to take care of the others:
@@ -163,15 +126,13 @@ From the list of deployment concepts from above, using workers would mainly help
## Containers and Docker
-In the next chapter about [FastAPI in Containers - Docker](./docker.md){.internal-link target=_blank} I'll tell some strategies you could use to handle the other **deployment concepts**.
-
-I'll also show you the **official Docker image** that includes **Gunicorn with Uvicorn workers** and some default configurations that can be useful for simple cases.
+In the next chapter about [FastAPI in Containers - Docker](docker.md){.internal-link target=_blank} I'll explain some strategies you could use to handle the other **deployment concepts**.
-There I'll also show you how to **build your own image from scratch** to run a single Uvicorn process (without Gunicorn). It is a simple process and is probably what you would want to do when using a distributed container management system like **Kubernetes**.
+I'll show you how to **build your own image from scratch** to run a single Uvicorn process. It is a simple process and is probably what you would want to do when using a distributed container management system like **Kubernetes**.
## Recap
-You can use **Gunicorn** (or also Uvicorn) as a process manager with Uvicorn workers to take advantage of **multi-core CPUs**, to run **multiple processes in parallel**.
+You can use multiple worker processes with the `--workers` CLI option with the `fastapi` or `uvicorn` commands to take advantage of **multi-core CPUs**, to run **multiple processes in parallel**.
You could use these tools and ideas if you are setting up **your own deployment system** while taking care of the other deployment concepts yourself.
diff --git a/docs/en/docs/deployment/versions.md b/docs/en/docs/deployment/versions.md
index 4be9385dd..23f49cf99 100644
--- a/docs/en/docs/deployment/versions.md
+++ b/docs/en/docs/deployment/versions.md
@@ -12,25 +12,25 @@ You can create production applications with **FastAPI** right now (and you have
The first thing you should do is to "pin" the version of **FastAPI** you are using to the specific latest version that you know works correctly for your application.
-For example, let's say you are using version `0.45.0` in your app.
+For example, let's say you are using version `0.112.0` in your app.
If you use a `requirements.txt` file you could specify the version with:
```txt
-fastapi==0.45.0
+fastapi[standard]==0.112.0
```
-that would mean that you would use exactly the version `0.45.0`.
+that would mean that you would use exactly the version `0.112.0`.
Or you could also pin it with:
```txt
-fastapi>=0.45.0,<0.46.0
+fastapi[standard]>=0.112.0,<0.113.0
```
-that would mean that you would use the versions `0.45.0` or above, but less than `0.46.0`, for example, a version `0.45.2` would still be accepted.
+that would mean that you would use the versions `0.112.0` or above, but less than `0.113.0`, for example, a version `0.112.2` would still be accepted.
-If you use any other tool to manage your installations, like Poetry, Pipenv, or others, they all have a way that you can use to define specific versions for your packages.
+If you use any other tool to manage your installations, like `uv`, Poetry, Pipenv, or others, they all have a way that you can use to define specific versions for your packages.
## Available versions
@@ -42,8 +42,11 @@ Following the Semantic Versioning conventions, any version below `1.0.0` could p
FastAPI also follows the convention that any "PATCH" version change is for bug fixes and non-breaking changes.
-!!! tip
- The "PATCH" is the last number, for example, in `0.2.3`, the PATCH version is `3`.
+/// tip
+
+The "PATCH" is the last number, for example, in `0.2.3`, the PATCH version is `3`.
+
+///
So, you should be able to pin to a version like:
@@ -53,8 +56,11 @@ fastapi>=0.45.0,<0.46.0
Breaking changes and new features are added in "MINOR" versions.
-!!! tip
- The "MINOR" is the number in the middle, for example, in `0.2.3`, the MINOR version is `2`.
+/// tip
+
+The "MINOR" is the number in the middle, for example, in `0.2.3`, the MINOR version is `2`.
+
+///
## Upgrading the FastAPI versions
@@ -78,10 +84,10 @@ So, you can just let **FastAPI** use the correct Starlette version.
Pydantic includes the tests for **FastAPI** with its own tests, so new versions of Pydantic (above `1.0.0`) are always compatible with FastAPI.
-You can pin Pydantic to any version above `1.0.0` that works for you and below `2.0.0`.
+You can pin Pydantic to any version above `1.0.0` that works for you.
For example:
```txt
-pydantic>=1.2.0,<2.0.0
+pydantic>=2.7.0,<3.0.0
```
diff --git a/docs/en/docs/environment-variables.md b/docs/en/docs/environment-variables.md
new file mode 100644
index 000000000..43dd06add
--- /dev/null
+++ b/docs/en/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# Environment Variables
+
+/// tip
+
+If you already know what "environment variables" are and how to use them, feel free to skip this.
+
+///
+
+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).
+
+Environment variables could be useful for handling application **settings**, as part of the **installation** of Python, etc.
+
+## Create and Use Env Vars
+
+You can **create** and use environment variables in the **shell (terminal)**, without needing Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```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
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```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
+```
+
+
+
+////
+
+## 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
+
+```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
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```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
+```
+
+
+
+////
+
+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:
+
+
+
+```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
+```
+
+
+
+/// tip
+
+You can read more about it at
```console
-$ pip install "uvicorn[standard]"
+$ pip install "fastapi[standard]"
---> 100%
```
+**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
+
## Example
### Create it
-* Create a file `main.py` with:
+Create a file `main.py` with:
```Python
from typing import Union
@@ -200,11 +202,24 @@ Run the server with:
```console
-$ uvicorn main:app --reload
-
+$ fastapi dev main.py
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
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: Started reloader process [2248755] using WatchFiles
+INFO: Started server process [2248757]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
@@ -212,13 +227,13 @@ INFO: Application startup complete.
```console
-$ pip install "fastapi[all]"
+$ pip install "fastapi[standard]"
---> 100%
```
-...that also includes `uvicorn`, that you can use as the server that runs your code.
-
-!!! note
- You can also install it part by part.
-
- This is what you would probably do once you want to deploy your application to production:
+/// note
- ```
- pip install fastapi
- ```
+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
+
+```console
+$ ./traefik --configFile=traefik.toml
+
+INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
+```
+
+
+
+Y ahora inicia tu app, utilizando la opción `--root-path`:
+
+
+
+```console
+$ npm install @hey-api/openapi-ts --save-dev
+
+---> 100%
+```
+
+
+
+#### Generar el Código del Cliente
+
+Para generar el código del cliente puedes usar la aplicación de línea de comandos `openapi-ts` que ahora estaría instalada.
+
+Como está instalada en el proyecto local, probablemente no podrías llamar a ese comando directamente, pero podrías ponerlo en tu archivo `package.json`.
+
+Podría verse como esto:
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "@hey-api/openapi-ts": "^0.27.38",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+Después de tener ese script de NPM `generate-client` allí, puedes ejecutarlo con:
+
+
+
+```console
+$ npm run generate-client
+
+frontend-app@1.0.0 generate-client /home/user/code/frontend-app
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
+```
+
+
+
+Ese comando generará código en `./src/client` y usará `axios` (el paquete HTTP de frontend) internamente.
+
+### Prueba el Código del Cliente
+
+Ahora puedes importar y usar el código del cliente, podría verse así, nota que tienes autocompletado para los métodos:
+
+
+
+```console
+$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+/// tip | Consejo
+
+Para establecer múltiples variables de entorno para un solo comando, simplemente sepáralas con un espacio y ponlas todas antes del comando.
+
+///
+
+Y luego la configuración `admin_email` se establecería en `"deadpool@example.com"`.
+
+El `app_name` sería `"ChimichangApp"`.
+
+Y el `items_per_user` mantendría su valor por defecto de `50`.
+
+## Configuraciones en otro módulo
+
+Podrías poner esas configuraciones en otro archivo de módulo como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+
+Por ejemplo, podrías tener un archivo `config.py` con:
+
+{* ../../docs_src/settings/app01/config.py *}
+
+Y luego usarlo en un archivo `main.py`:
+
+{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+
+/// tip | Consejo
+
+También necesitarías un archivo `__init__.py` como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+
+///
+
+## Configuraciones en una dependencia
+
+En algunas ocasiones podría ser útil proporcionar las configuraciones desde una dependencia, en lugar de tener un objeto global con `settings` que se use en todas partes.
+
+Esto podría ser especialmente útil durante las pruebas, ya que es muy fácil sobrescribir una dependencia con tus propias configuraciones personalizadas.
+
+### El archivo de configuración
+
+Proveniente del ejemplo anterior, tu archivo `config.py` podría verse como:
+
+{* ../../docs_src/settings/app02/config.py hl[10] *}
+
+Nota que ahora no creamos una instance por defecto `settings = Settings()`.
+
+### El archivo principal de la app
+
+Ahora creamos una dependencia que devuelve un nuevo `config.Settings()`.
+
+{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
+
+/// tip | Consejo
+
+Hablaremos del `@lru_cache` en un momento.
+
+Por ahora puedes asumir que `get_settings()` es una función normal.
+
+///
+
+Y luego podemos requerirlo desde la *path operation function* como una dependencia y usarlo donde lo necesitemos.
+
+{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
+
+### Configuraciones y pruebas
+
+Luego sería muy fácil proporcionar un objeto de configuraciones diferente durante las pruebas al sobrescribir una dependencia para `get_settings`:
+
+{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
+
+En la dependencia sobreescrita establecemos un nuevo valor para el `admin_email` al crear el nuevo objeto `Settings`, y luego devolvemos ese nuevo objeto.
+
+Luego podemos probar que se está usando.
+
+## Leer un archivo `.env`
+
+Si tienes muchas configuraciones que posiblemente cambien mucho, tal vez en diferentes entornos, podría ser útil ponerlos en un archivo y luego leerlos desde allí como si fueran variables de entorno.
+
+Esta práctica es lo suficientemente común que tiene un nombre, estas variables de entorno generalmente se colocan en un archivo `.env`, y el archivo se llama un "dotenv".
+
+/// tip | Consejo
+
+Un archivo que comienza con un punto (`.`) es un archivo oculto en sistemas tipo Unix, como Linux y macOS.
+
+Pero un archivo dotenv realmente no tiene que tener ese nombre exacto.
+
+///
+
+Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic
+```
+
+
+
+/// info | Información
+
+Existen otros formatos y herramientas para definir e instalar dependencias de paquetes.
+
+///
+
+### Crear el Código de **FastAPI**
+
+* Crea un directorio `app` y entra en él.
+* Crea un archivo vacío `__init__.py`.
+* Crea un archivo `main.py` con:
+
+```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}
+```
+
+### Dockerfile
+
+Ahora, en el mismo directorio del proyecto, crea un archivo `Dockerfile` con:
+
+```{ .dockerfile .annotate }
+# (1)!
+FROM python:3.9
+
+# (2)!
+WORKDIR /code
+
+# (3)!
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)!
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)!
+COPY ./app /code/app
+
+# (6)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
+```
+
+1. Comenzar desde la imagen base oficial de Python.
+
+2. Establecer el directorio de trabajo actual a `/code`.
+
+ Aquí es donde pondremos el archivo `requirements.txt` y el directorio `app`.
+
+3. Copiar el archivo con los requisitos al directorio `/code`.
+
+ Copiar **solo** el archivo con los requisitos primero, no el resto del código.
+
+ Como este archivo **no cambia a menudo**, Docker lo detectará y usará la **caché** para este paso, habilitando la caché para el siguiente paso también.
+
+4. Instalar las dependencias de los paquetes en el archivo de requisitos.
+
+ La opción `--no-cache-dir` le dice a `pip` que no guarde los paquetes descargados localmente, ya que eso solo sería si `pip` fuese a ejecutarse de nuevo para instalar los mismos paquetes, pero ese no es el caso al trabajar con contenedores.
+
+ /// note | Nota
+
+ El `--no-cache-dir` está relacionado solo con `pip`, no tiene nada que ver con Docker o contenedores.
+
+ ///
+
+ La opción `--upgrade` le dice a `pip` que actualice los paquetes si ya están instalados.
+
+ Debido a que el paso anterior de copiar el archivo podría ser detectado por la **caché de Docker**, este paso también **usará la caché de Docker** cuando esté disponible.
+
+ Usar la caché en este paso te **ahorrará** mucho **tiempo** al construir la imagen una y otra vez durante el desarrollo, en lugar de **descargar e instalar** todas las dependencias **cada vez**.
+
+5. Copiar el directorio `./app` dentro del directorio `/code`.
+
+ Como esto contiene todo el código, que es lo que **cambia con más frecuencia**, la **caché de Docker** no se utilizará para este u otros **pasos siguientes** fácilmente.
+
+ Así que es importante poner esto **cerca del final** del `Dockerfile`, para optimizar los tiempos de construcción de la imagen del contenedor.
+
+6. Establecer el **comando** para usar `fastapi run`, que utiliza Uvicorn debajo.
+
+ `CMD` toma una lista de cadenas, cada una de estas cadenas es lo que escribirías en la línea de comandos separado por espacios.
+
+ Este comando se ejecutará desde el **directorio de trabajo actual**, el mismo directorio `/code` que estableciste antes con `WORKDIR /code`.
+
+/// tip | Consejo
+
+Revisa qué hace cada línea haciendo clic en cada número en la burbuja del código. 👆
+
+///
+
+/// warning | Advertencia
+
+Asegúrate de **siempre** usar la **forma exec** de la instrucción `CMD`, como se explica a continuación.
+
+///
+
+#### Usar `CMD` - Forma Exec
+
+La instrucción Docker
+
+```console
+// Podrías crear una env var MY_NAME con
+$ export MY_NAME="Wade Wilson"
+
+// Luego podrías usarla con otros programas, como
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Crea una env var MY_NAME
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Úsala con otros programas, como
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## Leer Variables de Entorno en Python
+
+También podrías crear variables de entorno **fuera** de Python, en la terminal (o con cualquier otro método), y luego **leerlas en Python**.
+
+Por ejemplo, podrías tener un archivo `main.py` con:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip | Consejo
+
+El segundo argumento de
+
+```console
+// Aquí todavía no configuramos la env var
+$ python main.py
+
+// Como no configuramos la env var, obtenemos el valor por defecto
+
+Hello World from Python
+
+// Pero si creamos una variable de entorno primero
+$ export MY_NAME="Wade Wilson"
+
+// Y luego llamamos al programa nuevamente
+$ python main.py
+
+// Ahora puede leer la variable de entorno
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Aquí todavía no configuramos la env var
+$ python main.py
+
+// Como no configuramos la env var, obtenemos el valor por defecto
+
+Hello World from Python
+
+// Pero si creamos una variable de entorno primero
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Y luego llamamos al programa nuevamente
+$ python main.py
+
+// Ahora puede leer la variable de entorno
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+Dado que las variables de entorno pueden configurarse fuera del código, pero pueden ser leídas por el código, y no tienen que ser almacenadas (committed en `git`) con el resto de los archivos, es común usarlas para configuraciones o **ajustes**.
+
+También puedes crear una variable de entorno solo para una **invocación específica de un programa**, que está disponible solo para ese programa, y solo durante su duración.
+
+Para hacer eso, créala justo antes del programa en sí, en la misma línea:
+
+
+
+```console
+// Crea una env var MY_NAME en línea para esta llamada del programa
+$ MY_NAME="Wade Wilson" python main.py
+
+// Ahora puede leer la variable de entorno
+
+Hello Wade Wilson from Python
+
+// La env var ya no existe después
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip | Consejo
+
+Puedes leer más al respecto en
```console
-$ pip install "uvicorn[standard]"
+$ pip install "fastapi[standard]"
---> 100%
```
+**Nota**: Asegúrate de poner `"fastapi[standard]"` entre comillas para asegurar que funcione en todas las terminales.
+
## Ejemplo
### Créalo
@@ -144,9 +149,10 @@ $ pip install "uvicorn[standard]"
* Crea un archivo `main.py` con:
```Python
-from fastapi import FastAPI
from typing import Union
+from fastapi import FastAPI
+
app = FastAPI()
@@ -165,10 +171,11 @@ def read_item(item_id: int, q: Union[str, None] = None):
Si tu código usa `async` / `await`, usa `async def`:
-```Python hl_lines="7 12"
-from fastapi import FastAPI
+```Python hl_lines="9 14"
from typing import Union
+from fastapi import FastAPI
+
app = FastAPI()
@@ -184,7 +191,7 @@ async def read_item(item_id: int, q: Union[str, None] = None):
**Nota**:
-Si no lo sabes, revisa la sección _"¿Con prisa?"_ sobre
```console
-$ uvicorn main:app --reload
-
+$ fastapi dev main.py
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
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: Started reloader process [2248755] using WatchFiles
+INFO: Started server process [2248757]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
@@ -207,13 +227,13 @@ INFO: Application startup complete.
+Aquí la variable `app` será una "instance" de la clase `FastAPI`.
-```console
-$ uvicorn main:app --reload
+Este será el punto principal de interacción para crear toda tu API.
-INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
-
-
-
-Si creas un app como:
-
-```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial002.py!}
-```
-
-y lo guardas en un archivo `main.py`, entonces ejecutarías `uvicorn` así:
-
-
```console
-$ pip install "fastapi[all]"
+$ pip install "fastapi[standard]"
---> 100%
```
-...eso también incluye `uvicorn` que puedes usar como el servidor que ejecuta tu código.
-
-!!! nota
- También puedes instalarlo parte por parte.
-
- Esto es lo que probablemente harías una vez que desees implementar tu aplicación en producción:
-
- ```
- pip install fastapi
- ```
+/// note | Nota
- También debes instalar `uvicorn` para que funcione como tu servidor:
+Cuando instalas con `pip install "fastapi[standard]"` viene con algunas dependencias opcionales estándar por defecto.
- ```
- pip install "uvicorn[standard]"
- ```
+Si no quieres tener esas dependencias opcionales, en su lugar puedes instalar `pip install fastapi`.
- Y lo mismo para cada una de las dependencias opcionales que quieras utilizar.
+///
-## Guía Avanzada de Usuario
+## Guía Avanzada del Usuario
-También hay una **Guía Avanzada de Usuario** que puedes leer luego de este **Tutorial - Guía de Usuario**.
+También hay una **Guía Avanzada del Usuario** que puedes leer después de esta **Tutorial - Guía del Usuario**.
-La **Guía Avanzada de Usuario**, se basa en este tutorial, utiliza los mismos conceptos y enseña algunas características adicionales.
+La **Guía Avanzada del Usuario** se basa en esta, utiliza los mismos conceptos y te enseña algunas funcionalidades adicionales.
-Pero primero deberías leer el **Tutorial - Guía de Usuario** (lo que estas leyendo ahora mismo).
+Pero primero deberías leer la **Tutorial - Guía del Usuario** (lo que estás leyendo ahora mismo).
-La guía esa diseñada para que puedas crear una aplicación completa con solo el **Tutorial - Guía de Usuario**, y luego extenderlo de diferentes maneras, según tus necesidades, utilizando algunas de las ideas adicionales de la **Guía Avanzada de Usuario**.
+Está diseñada para que puedas construir una aplicación completa solo con la **Tutorial - Guía del Usuario**, y luego extenderla de diferentes maneras, dependiendo de tus necesidades, utilizando algunas de las ideas adicionales de la **Guía Avanzada del Usuario**.
diff --git a/docs/es/docs/tutorial/metadata.md b/docs/es/docs/tutorial/metadata.md
new file mode 100644
index 000000000..1561e4ae3
--- /dev/null
+++ b/docs/es/docs/tutorial/metadata.md
@@ -0,0 +1,120 @@
+# Metadata y URLs de Docs
+
+Puedes personalizar varias configuraciones de metadata en tu aplicación **FastAPI**.
+
+## Metadata para la API
+
+Puedes establecer los siguientes campos que se usan en la especificación OpenAPI y en las interfaces automáticas de documentación de la API:
+
+| Parámetro | Tipo | Descripción |
+|------------|------|-------------|
+| `title` | `str` | El título de la API. |
+| `summary` | `str` | Un resumen corto de la API.
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+
+
+Y copia el resultado a la variable `SECRET_KEY` (no uses la del ejemplo).
+
+Crea una variable `ALGORITHM` con el algoritmo usado para firmar el token JWT y configúralo a `"HS256"`.
+
+Crea una variable para la expiración del token.
+
+Define un Modelo de Pydantic que se usará en el endpoint de token para el response.
+
+Crea una función de utilidad para generar un nuevo token de acceso.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
+
+## Actualizar las dependencias
+
+Actualiza `get_current_user` para recibir el mismo token que antes, pero esta vez, usando tokens JWT.
+
+Decodifica el token recibido, verifícalo y devuelve el usuario actual.
+
+Si el token es inválido, devuelve un error HTTP de inmediato.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
+
+## Actualizar la *path operation* `/token`
+
+Crea un `timedelta` con el tiempo de expiración del token.
+
+Crea un verdadero token de acceso JWT y devuélvelo.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
+
+### Detalles técnicos sobre el "sujeto" `sub` de JWT
+
+La especificación de JWT dice que hay una clave `sub`, con el sujeto del token.
+
+Es opcional usarlo, pero ahí es donde pondrías la identificación del usuario, por lo que lo estamos usando aquí.
+
+JWT podría ser usado para otras cosas aparte de identificar un usuario y permitirle realizar operaciones directamente en tu API.
+
+Por ejemplo, podrías identificar un "coche" o un "artículo de blog".
+
+Luego, podrías agregar permisos sobre esa entidad, como "conducir" (para el coche) o "editar" (para el blog).
+
+Y luego, podrías darle ese token JWT a un usuario (o bot), y ellos podrían usarlo para realizar esas acciones (conducir el coche, o editar el artículo del blog) sin siquiera necesitar tener una cuenta, solo con el token JWT que tu API generó para eso.
+
+Usando estas ideas, JWT puede ser utilizado para escenarios mucho más sofisticados.
+
+En esos casos, varias de esas entidades podrían tener el mismo ID, digamos `foo` (un usuario `foo`, un coche `foo`, y un artículo del blog `foo`).
+
+Entonces, para evitar colisiones de ID, cuando crees el token JWT para el usuario, podrías prefijar el valor de la clave `sub`, por ejemplo, con `username:`. Así, en este ejemplo, el valor de `sub` podría haber sido: `username:johndoe`.
+
+Lo importante a tener en cuenta es que la clave `sub` debería tener un identificador único a lo largo de toda la aplicación, y debería ser un string.
+
+## Revisa
+
+Ejecuta el servidor y ve a la documentación:
+
+```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/es/docs/virtual-environments.md b/docs/es/docs/virtual-environments.md
new file mode 100644
index 000000000..71d450e09
--- /dev/null
+++ b/docs/es/docs/virtual-environments.md
@@ -0,0 +1,842 @@
+# Entornos Virtuales
+
+Cuando trabajas en proyectos de Python probablemente deberías usar un **entorno virtual** (o un mecanismo similar) para aislar los paquetes que instalas para cada proyecto.
+
+/// info | Información
+
+Si ya sabes sobre entornos virtuales, cómo crearlos y usarlos, podrías querer saltar esta sección. 🤓
+
+///
+
+/// tip | Consejo
+
+Un **entorno virtual** es diferente de una **variable de entorno**.
+
+Una **variable de entorno** es una variable en el sistema que puede ser usada por programas.
+
+Un **entorno virtual** es un directorio con algunos archivos en él.
+
+///
+
+/// info | Información
+
+Esta página te enseñará cómo usar **entornos virtuales** y cómo funcionan.
+
+Si estás listo para adoptar una **herramienta que gestiona todo** por ti (incluyendo la instalación de Python), prueba
+
+```console
+// Ve al directorio principal
+$ cd
+// Crea un directorio para todos tus proyectos de código
+$ mkdir code
+// Entra en ese directorio de código
+$ cd code
+// Crea un directorio para este proyecto
+$ mkdir awesome-project
+// Entra en ese directorio del proyecto
+$ cd awesome-project
+```
+
+
+
+## Crea un Entorno Virtual
+
+Cuando empiezas a trabajar en un proyecto de Python **por primera vez**, crea un entorno virtual **
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+Si muestra el binario de `python` en `.venv/bin/python`, dentro de tu proyecto (en este caso `awesome-project`), entonces funcionó. 🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+Si muestra el binario de `python` en `.venv\Scripts\python`, dentro de tu proyecto (en este caso `awesome-project`), entonces funcionó. 🎉
+
+////
+
+## Actualiza `pip`
+
+/// tip | Consejo
+
+Si usas
+
+```console
+// No ejecutes esto ahora, solo es un ejemplo 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+Eso descargará un archivo comprimido con el código de FastAPI, normalmente desde
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+Eso significa que el programa `python` que se utilizará es el que está **en el entorno virtual**.
+
+Usas `which` en Linux y macOS y `Get-Command` en Windows PowerShell.
+
+La forma en que funciona ese comando es que irá y revisará la variable de entorno `PATH`, pasando por **cada path en orden**, buscando el programa llamado `python`. Una vez que lo encuentre, te **mostrará el path** a ese programa.
+
+La parte más importante es que cuando llamas a `python`, ese es el exacto "`python`" que será ejecutado.
+
+Así que, puedes confirmar si estás en el entorno virtual correcto.
+
+/// tip | Consejo
+
+Es fácil activar un entorno virtual, obtener un Python, y luego **ir a otro proyecto**.
+
+Y el segundo proyecto **no funcionaría** porque estás usando el **Python incorrecto**, de un entorno virtual para otro proyecto.
+
+Es útil poder revisar qué `python` se está usando. 🤓
+
+///
+
+## Por qué Desactivar un Entorno Virtual
+
+Por ejemplo, podrías estar trabajando en un proyecto `philosophers-stone`, **activar ese entorno virtual**, instalar paquetes y trabajar con ese entorno.
+
+Y luego quieres trabajar en **otro proyecto** `prisoner-of-azkaban`.
+
+Vas a ese proyecto:
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+$ python main.py
+
+// Error importando sirius, no está instalado 😱
+Traceback (most recent call last):
+ File "main.py", line 1, in
+ import sirius
+```
+
+
+
+Pero si desactivas el entorno virtual y activas el nuevo para `prisoner-of-askaban` entonces cuando ejecutes `python` utilizará el Python del entorno virtual en `prisoner-of-azkaban`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// No necesitas estar en el directorio antiguo para desactivar, puedes hacerlo donde sea que estés, incluso después de ir al otro proyecto 😎
+$ deactivate
+
+// Activa el entorno virtual en prisoner-of-azkaban/.venv 🚀
+$ source .venv/bin/activate
+
+// Ahora cuando ejecutes python, encontrará el paquete sirius instalado en este entorno virtual ✨
+$ python main.py
+
+I solemnly swear 🐺
+```
+
+
+
+## Alternativas
+
+Esta es una guía simple para comenzar y enseñarte cómo funciona todo **por debajo**.
+
+Hay muchas **alternativas** para gestionar entornos virtuales, dependencias de paquetes (requisitos), proyectos.
+
+Una vez que estés listo y quieras usar una herramienta para **gestionar todo el proyecto**, dependencias de paquetes, entornos virtuales, etc. Te sugeriría probar
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+
+
+E copie a saída para a variável `SECRET_KEY` (não use a do exemplo).
+
+Crie uma variável `ALGORITHM` com o algoritmo usado para assinar o token JWT e defina como `"HS256"`.
+
+Crie uma variável para a expiração do token.
+
+Defina um modelo Pydantic que será usado no endpoint de token para a resposta.
+
+Crie uma função utilitária para gerar um novo token de acesso.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
+
+## Atualize as dependências
+
+Atualize `get_current_user` para receber o mesmo token de antes, mas desta vez, usando tokens JWT.
+
+Decodifique o token recebido, verifique-o e retorne o usuário atual.
+
+Se o token for inválido, retorne um erro HTTP imediatamente.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
+
+## Atualize a *operação de rota* `/token`
+
+Crie um `timedelta` com o tempo de expiração do token.
+
+Crie um token de acesso JWT real e o retorne.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
+
+### Detalhes técnicos sobre o "sujeito" `sub` do JWT
+
+A especificação JWT diz que existe uma chave `sub`, com o sujeito do token.
+
+É opcional usá-la, mas é onde você colocaria a identificação do usuário, então nós estamos usando aqui.
+
+O JWT pode ser usado para outras coisas além de identificar um usuário e permitir que ele execute operações diretamente na sua API.
+
+Por exemplo, você poderia identificar um "carro" ou uma "postagem de blog".
+
+Depois, você poderia adicionar permissões sobre essa entidade, como "dirigir" (para o carro) ou "editar" (para o blog).
+
+E então, poderia dar esse token JWT para um usuário (ou bot), e ele poderia usá-lo para realizar essas ações (dirigir o carro ou editar o blog) sem sequer precisar ter uma conta, apenas com o token JWT que sua API gerou para isso.
+
+Usando essas ideias, o JWT pode ser usado para cenários muito mais sofisticados.
+
+Nesses casos, várias dessas entidades poderiam ter o mesmo ID, digamos `foo` (um usuário `foo`, um carro `foo` e uma postagem de blog `foo`).
+
+Então, para evitar colisões de ID, ao criar o token JWT para o usuário, você poderia prefixar o valor da chave `sub`, por exemplo, com `username:`. Assim, neste exemplo, o valor de `sub` poderia ser: `username:johndoe`.
+
+O importante a se lembrar é que a chave `sub` deve ter um identificador único em toda a aplicação e deve ser uma string.
+
+## Testando
+
+Execute o servidor e vá para a documentação:
+
+```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/pt/docs/virtual-environments.md b/docs/pt/docs/virtual-environments.md
new file mode 100644
index 000000000..5fc1a8866
--- /dev/null
+++ b/docs/pt/docs/virtual-environments.md
@@ -0,0 +1,844 @@
+# Ambientes Virtuais
+
+Ao trabalhar em projetos Python, você provavelmente deve usar um **ambiente virtual** (ou um mecanismo similar) para isolar os pacotes que você instala para cada projeto.
+
+/// info | Informação
+
+Se você já sabe sobre ambientes virtuais, como criá-los e usá-los, talvez seja melhor pular esta seção. 🤓
+
+///
+
+/// tip | Dica
+
+Um **ambiente virtual** é diferente de uma **variável de ambiente**.
+
+Uma **variável de ambiente** é uma variável no sistema que pode ser usada por programas.
+
+Um **ambiente virtual** é um diretório com alguns arquivos.
+
+///
+
+/// info | Informação
+
+Esta página lhe ensinará como usar **ambientes virtuais** e como eles funcionam.
+
+Se você estiver pronto para adotar uma **ferramenta que gerencia tudo** para você (incluindo a instalação do Python), experimente
+
+```console
+// Vá para o diretório inicial
+$ cd
+// Crie um diretório para todos os seus projetos de código
+$ mkdir code
+// Entre nesse diretório de código
+$ cd code
+// Crie um diretório para este projeto
+$ mkdir awesome-project
+// Entre no diretório do projeto
+$ cd awesome-project
+```
+
+
+
+## Crie um ambiente virtual
+
+Ao começar a trabalhar em um projeto Python **pela primeira vez**, crie um ambiente virtual **
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+Se ele mostrar o binário `python` em `.venv/bin/python`, dentro do seu projeto (neste caso `awesome-project`), então funcionou. 🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+Se ele mostrar o binário `python` em `.venv\Scripts\python`, dentro do seu projeto (neste caso `awesome-project`), então funcionou. 🎉
+
+////
+
+## Atualizar `pip`
+
+/// tip | Dica
+
+Se você usar
+
+```console
+// Não execute isso agora, é apenas um exemplo 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+Isso fará o download de um arquivo compactado com o código FastAPI, normalmente do
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+Isso significa que o programa `python` que será usado é aquele **no ambiente virtual**.
+
+você usa `which` no Linux e macOS e `Get-Command` no Windows PowerShell.
+
+A maneira como esse comando funciona é que ele vai e verifica na variável de ambiente `PATH`, passando por **cada caminho em ordem**, procurando pelo programa chamado `python`. Uma vez que ele o encontre, ele **mostrará o caminho** para esse programa.
+
+A parte mais importante é que quando você chama ``python`, esse é exatamente o "`python`" que será executado.
+
+Assim, você pode confirmar se está no ambiente virtual correto.
+
+/// tip | Dica
+
+É fácil ativar um ambiente virtual, obter um Python e então **ir para outro projeto**.
+
+E o segundo projeto **não funcionaria** porque você está usando o **Python incorreto**, de um ambiente virtual para outro projeto.
+
+É útil poder verificar qual `python` está sendo usado. 🤓
+
+///
+
+## Por que desativar um ambiente virtual
+
+Por exemplo, você pode estar trabalhando em um projeto `philosophers-stone`, **ativar esse ambiente virtual**, instalar pacotes e trabalhar com esse ambiente.
+
+E então você quer trabalhar em **outro projeto** `prisoner-of-azkaban`.
+
+Você vai para aquele projeto:
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+$ python main.py
+
+// Erro ao importar o Sirius, ele não está instalado 😱
+Traceback (most recent call last):
+ File "main.py", line 1, in
+ import sirius
+```
+
+
+
+Mas se você desativar o ambiente virtual e ativar o novo para `prisoner-of-askaban`, quando você executar `python`, ele usará o Python do ambiente virtual em `prisoner-of-azkaban`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// Você não precisa estar no diretório antigo para desativar, você pode fazer isso de onde estiver, mesmo depois de ir para o outro projeto 😎
+$ deactivate
+
+// Ative o ambiente virtual em prisoner-of-azkaban/.venv 🚀
+$ source .venv/bin/activate
+
+// Agora, quando você executar o python, ele encontrará o pacote sirius instalado neste ambiente virtual ✨
+$ python main.py
+
+Eu juro solenemente 🐺
+```
+
+
+
+## Alternativas
+
+Este é um guia simples para você começar e lhe ensinar como tudo funciona **por baixo**.
+
+Existem muitas **alternativas** para gerenciar ambientes virtuais, dependências de pacotes (requisitos) e projetos.
+
+Quando estiver pronto e quiser usar uma ferramenta para **gerenciar todo o projeto**, dependências de pacotes, ambientes virtuais, etc., sugiro que você experimente o
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic uvicorn
+```
+
+
+
+/// info | Информация
+
+Существуют и другие инструменты управления зависимостями.
+
+В этом же разделе, но позже, я покажу вам пример использования Poetry. 👇
+
+///
+
+### Создать приложение **FastAPI**
+
+* Создайте директорию `app` и перейдите в неё.
+* Создайте пустой файл `__init__.py`.
+* Создайте файл `main.py` и заполните его:
+
+```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}
+```
+
+### Dockerfile
+
+В этой же директории создайте файл `Dockerfile` и заполните его:
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9
+
+# (2)
+WORKDIR /code
+
+# (3)
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)
+COPY ./app /code/app
+
+# (6)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. Начните с официального образа Python, который будет основой для образа приложения.
+
+2. Укажите, что в дальнейшем команды запускаемые в контейнере, будут выполняться в директории `/code`.
+
+ Инструкция создаст эту директорию внутри контейнера и мы поместим в неё файл `requirements.txt` и директорию `app`.
+
+3. Скопируете файл с зависимостями из текущей директории в `/code`.
+
+ Сначала копируйте **только** файл с зависимостями.
+
+ Этот файл **изменяется довольно редко**, Docker ищет изменения при постройке образа и если не находит, то использует **кэш**, в котором хранятся предыдущие версии сборки образа.
+
+4. Установите библиотеки перечисленные в файле с зависимостями.
+
+ Опция `--no-cache-dir` указывает `pip` не сохранять загружаемые библиотеки на локальной машине для использования их в случае повторной загрузки. В контейнере, в случае пересборки этого шага, они всё равно будут удалены.
+
+ /// note | Заметка
+
+ Опция `--no-cache-dir` нужна только для `pip`, она никак не влияет на Docker или контейнеры.
+
+ ///
+
+ Опция `--upgrade` указывает `pip` обновить библиотеки, емли они уже установлены.
+
+ Как и в предыдущем шаге с копированием файла, этот шаг также будет использовать **кэш Docker** в случае отсутствия изменений.
+
+ Использование кэша, особенно на этом шаге, позволит вам **сэкономить** кучу времени при повторной сборке образа, так как зависимости будут сохранены в кеше, а не **загружаться и устанавливаться каждый раз**.
+
+5. Скопируйте директорию `./app` внутрь директории `/code` (в контейнере).
+
+ Так как в этой директории расположен код, который **часто изменяется**, то использование **кэша** на этом шаге будет наименее эффективно, а значит лучше поместить этот шаг **ближе к концу** `Dockerfile`, дабы не терять выгоду от оптимизации предыдущих шагов.
+
+6. Укажите **команду**, запускающую сервер `uvicorn`.
+
+ `CMD` принимает список строк, разделённых запятыми, но при выполнении объединит их через пробел, собрав из них одну команду, которую вы могли бы написать в терминале.
+
+ Эта команда будет выполнена в **текущей рабочей директории**, а именно в директории `/code`, которая указана в команде `WORKDIR /code`.
+
+ Так как команда выполняется внутри директории `/code`, в которую мы поместили папку `./app` с приложением, то **Uvicorn** сможет найти и **импортировать** объект `app` из файла `app.main`.
+
+/// tip | Подсказка
+
+Если ткнёте на кружок с плюсом, то увидите пояснения. 👆
+
+///
+
+На данном этапе структура проекта должны выглядеть так:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ └── main.py
+├── Dockerfile
+└── requirements.txt
+```
+
+#### Использование прокси-сервера
+
+Если вы запускаете контейнер за прокси-сервером завершения TLS (балансирующего нагрузку), таким как Nginx или Traefik, добавьте опцию `--proxy-headers`, которая укажет Uvicorn, что он работает позади прокси-сервера и может доверять заголовкам отправляемым им.
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+#### Кэш Docker'а
+
+В нашем `Dockerfile` использована полезная хитрость, когда сначала копируется **только файл с зависимостями**, а не вся папка с кодом приложения.
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+Docker и подобные ему инструменты **создают** образы контейнеров **пошагово**, добавляя **один слой над другим**, начиная с первой строки `Dockerfile` и добавляя файлы, создаваемые при выполнении каждой инструкции из `Dockerfile`.
+
+При создании образа используется **внутренний кэш** и если в файлах нет изменений с момента последней сборки образа, то будет **переиспользован** ранее созданный слой образа, а не повторное копирование файлов и создание слоя с нуля.
+Заметьте, что так как слой следующего шага зависит от слоя предыдущего, то изменения внесённые в промежуточный слой, также повлияют на последующие.
+
+Избегание копирования файлов не обязательно улучшит ситуацию, но использование кэша на одном шаге, позволит **использовать кэш и на следующих шагах**. Например, можно использовать кэш при установке зависимостей:
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+```
+
+Файл со списком зависимостей **изменяется довольно редко**. Так что выполнив команду копирования только этого файла, Docker сможет **использовать кэш** на этом шаге.
+
+А затем **использовать кэш и на следующем шаге**, загружающем и устанавливающем зависимости. И вот тут-то мы и **сэкономим много времени**. ✨ ...а не будем томиться в тягостном ожидании. 😪😆
+
+Для загрузки и установки необходимых библиотек **может понадобиться несколько минут**, но использование **кэша** занимает несколько **секунд** максимум.
+
+И так как во время разработки вы будете часто пересобирать контейнер для проверки работоспособности внесённых изменений, то сэкономленные минуты сложатся в часы, а то и дни.
+
+Так как папка с кодом приложения **изменяется чаще всего**, то мы расположили её в конце `Dockerfile`, ведь после внесённых в код изменений кэш не будет использован на этом и следующих шагах.
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### Создать Docker-образ
+
+Теперь, когда все файлы на своих местах, давайте создадим образ контейнера.
+
+* Перейдите в директорию проекта (в ту, где расположены `Dockerfile` и папка `app` с приложением).
+* Создай образ приложения FastAPI:
+
+
+
+```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** основаны на
+
+```console
+// Вы можете создать переменную окружения MY_NAME с помощью
+$ export MY_NAME="Wade Wilson"
+
+// Затем её можно использовать в других программах, например
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Создайте переменную окружения MY_NAME
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Используйте её с другими программами, например
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## Чтение переменных окружения в python
+
+Так же существует возможность создания переменных окружения **вне** Python, в терминале (или любым другим способом), а затем **чтения их в Python**.
+
+Например, у вас есть файл `main.py`:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+Второй аргумент
+
+```console
+// Здесь мы еще не устанавливаем переменную окружения
+$ python main.py
+
+// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию
+
+Hello World from Python
+
+// Но если мы сначала создадим переменную окружения
+$ export MY_NAME="Wade Wilson"
+
+// А затем снова запустим программу
+$ python main.py
+
+// Теперь она прочитает переменную окружения
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Здесь мы еще не устанавливаем переменную окружения
+$ python main.py
+
+// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию
+
+Hello World from Python
+
+// Но если мы сначала создадим переменную окружения
+$ $Env:MY_NAME = "Wade Wilson"
+
+// А затем снова запустим программу
+$ python main.py
+
+// Теперь она может прочитать переменную окружения
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+Поскольку переменные окружения могут быть установлены вне кода, но могут быть прочитаны кодом, и их не нужно хранить (фиксировать в `git`) вместе с остальными файлами, их принято использовать для конфигураций или **настроек**.
+
+Вы также можете создать переменную окружения только для **конкретного вызова программы**, которая будет доступна только для этой программы и только на время ее выполнения.
+
+Для этого создайте её непосредственно перед самой программой, в той же строке:
+
+
+
+```console
+// Создайте переменную окружения MY_NAME в строке для этого вызова программы
+$ MY_NAME="Wade Wilson" python main.py
+
+// Теперь она может прочитать переменную окружения
+
+Hello Wade Wilson from Python
+
+// После этого переменная окружения больше не существует
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip
+
+Подробнее об этом можно прочитать на сайте
@@ -321,11 +325,11 @@ def update_item(item_id: int, item: Item):
Таким образом, вы объявляете **один раз** типы параметров, тело и т. д. в качестве параметров функции.
-Вы делаете это испльзуя стандартную современную типизацию Python.
+Вы делаете это используя стандартную современную типизацию Python.
Вам не нужно изучать новый синтаксис, методы или классы конкретной библиотеки и т. д.
-Только стандартный **Python 3.6+**.
+Только стандартный **Python**.
Например, для `int`:
@@ -439,22 +443,21 @@ item: Item
Используется Pydantic:
-*
ujson
- для более быстрого JSON
"парсинга".
-*
email_validator
- для проверки электронной почты.
+*
email-validator
- для проверки электронной почты.
Используется Starlette:
*
HTTPX
- Обязательно, если вы хотите использовать `TestClient`.
*
jinja2
- Обязательно, если вы хотите использовать конфигурацию шаблона по умолчанию.
-*
python-multipart
- Обязательно, если вы хотите поддерживать форму
"парсинга" с помощью `request.form()`.
+*
python-multipart
- Обязательно, если вы хотите поддерживать форму
"парсинга" с помощью `request.form()`.
*
itsdangerous
- Обязательно, для поддержки `SessionMiddleware`.
*
pyyaml
- Обязательно, для поддержки `SchemaGenerator` Starlette (возможно, вам это не нужно с FastAPI).
-*
ujson
- Обязательно, если вы хотите использовать `UJSONResponse`.
Используется FastAPI / Starlette:
*
uvicorn
- сервер, который загружает и обслуживает ваше приложение.
*
orjson
- Обязательно, если вы хотите использовать `ORJSONResponse`.
+*
ujson
- Обязательно, если вы хотите использовать `UJSONResponse`.
Вы можете установить все это с помощью `pip install "fastapi[all]"`.
diff --git a/docs/ru/docs/learn/index.md b/docs/ru/docs/learn/index.md
new file mode 100644
index 000000000..b2e4cabc7
--- /dev/null
+++ b/docs/ru/docs/learn/index.md
@@ -0,0 +1,5 @@
+# Обучение
+
+Здесь представлены вводные разделы и учебные пособия для изучения **FastAPI**.
+
+Вы можете считать это **книгой**, **курсом**, **официальным** и рекомендуемым способом изучения FastAPI. 😎
diff --git a/docs/ru/docs/project-generation.md b/docs/ru/docs/project-generation.md
new file mode 100644
index 000000000..efd6794ad
--- /dev/null
+++ b/docs/ru/docs/project-generation.md
@@ -0,0 +1,84 @@
+# Генераторы проектов - Шаблоны
+
+Чтобы начать работу быстрее, Вы можете использовать "генераторы проектов", в которые включены множество начальных настроек для функций безопасности, баз данных и некоторые
эндпоинты API.
+
+В генераторе проектов всегда будут предустановлены какие-то настройки, которые Вам следует обновить и подогнать под свои нужды, но это может быть хорошей отправной точкой для Вашего проекта.
+
+## Full Stack FastAPI PostgreSQL
+
+GitHub:
https://github.com/tiangolo/full-stack-fastapi-postgresql
+
+### Full Stack FastAPI PostgreSQL - Особенности
+
+* Полностью интегрирован с **Docker** (основан на Docker).
+* Развёртывается в режиме Docker Swarm.
+* Интегрирован с **Docker Compose** и оптимизирован для локальной разработки.
+* **Готовый к реальной работе** веб-сервер Python использующий Uvicorn и Gunicorn.
+* Бэкенд построен на фреймворке
**FastAPI**:
+ * **Быстрый**: Высокопроизводительный, на уровне **NodeJS** и **Go** (благодаря Starlette и Pydantic).
+ * **Интуитивно понятный**: Отличная поддержка редактора.
Автодополнение кода везде. Меньше времени на отладку.
+ * **Простой**: Разработан так, чтоб быть простым в использовании и изучении. Меньше времени на чтение документации.
+ * **Лаконичный**: Минимизировано повторение кода. Каждый объявленный параметр определяет несколько функций.
+ * **Надёжный**: Получите готовый к работе код. С автоматической интерактивной документацией.
+ * **Стандартизированный**: Основан на открытых стандартах API (
OpenAPI и
JSON Schema) и полностью совместим с ними.
+ *
**Множество других возможностей** включая автоматическую проверку и сериализацию данных, интерактивную документацию, аутентификацию с помощью OAuth2 JWT-токенов и т.д.
+* **Безопасное хранение паролей**, которые хэшируются по умолчанию.
+* Аутентификация посредством **JWT-токенов**.
+*
Модели **SQLAlchemy** (независящие от расширений Flask, а значит могут быть непосредственно использованы процессами Celery).
+* Базовая модель пользователя (измените или удалите её по необходимости).
+* **Alembic** для организации миграций.
+* **CORS** (Совместное использование ресурсов из разных источников).
+* **Celery**, процессы которого могут выборочно импортировать и использовать модели и код из остальной части бэкенда.
+* Тесты, на основе **Pytest**, интегрированные в Docker, чтобы Вы могли полностью проверить Ваше API, независимо от базы данных. Так как тесты запускаются в Docker, для них может создаваться новое хранилище данных каждый раз (Вы можете, по своему желанию, использовать ElasticSearch, MongoDB, CouchDB или другую СУБД, только лишь для проверки - будет ли Ваше API работать с этим хранилищем).
+* Простая интеграция Python с **Jupyter Kernels** для разработки удалённо или в Docker с расширениями похожими на Atom Hydrogen или Visual Studio Code Jupyter.
+* Фронтенд построен на фреймворке **Vue**:
+ * Сгенерирован с помощью Vue CLI.
+ * Поддерживает **аутентификацию с помощью JWT-токенов**.
+ * Страница логина.
+ * Перенаправление на страницу главной панели мониторинга после логина.
+ * Главная страница мониторинга с возможностью создания и изменения пользователей.
+ * Пользователь может изменять свои данные.
+ * **Vuex**.
+ * **Vue-router**.
+ * **Vuetify** для конструирования красивых компонентов страниц.
+ * **TypeScript**.
+ * Сервер Docker основан на **Nginx** (настроен для удобной работы с Vue-router).
+ * Многоступенчатая сборка Docker, то есть Вам не нужно сохранять или коммитить скомпилированный код.
+ * Тесты фронтенда запускаются во время сборки (можно отключить).
+ * Сделан настолько модульно, насколько возможно, поэтому работает "из коробки", но Вы можете повторно сгенерировать фронтенд с помощью Vue CLI или создать то, что Вам нужно и повторно использовать то, что захотите.
+* **PGAdmin** для СУБД PostgreSQL, которые легко можно заменить на PHPMyAdmin и MySQL.
+* **Flower** для отслеживания работы Celery.
+* Балансировка нагрузки между фронтендом и бэкендом с помощью **Traefik**, а значит, Вы можете расположить их на одном домене, разделив url-пути, так как они обслуживаются разными контейнерами.
+* Интеграция с Traefik включает автоматическую генерацию сертификатов Let's Encrypt для поддержки протокола **HTTPS**.
+* GitLab **CI** (непрерывная интеграция), которая включает тестирование фронтенда и бэкенда.
+
+## Full Stack FastAPI Couchbase
+
+GitHub:
https://github.com/tiangolo/full-stack-fastapi-couchbase
+
+⚠️ **ПРЕДУПРЕЖДЕНИЕ** ⚠️
+
+Если Вы начинаете новый проект, ознакомьтесь с представленными здесь альтернативами.
+
+Например, генератор проектов
Full Stack FastAPI PostgreSQL может быть более подходящей альтернативой, так как он активно поддерживается и используется. И он включает в себя все новые возможности и улучшения.
+
+Но никто не запрещает Вам использовать генератор с СУБД Couchbase, возможно, он всё ещё работает нормально. Или у Вас уже есть проект, созданный с помощью этого генератора ранее, и Вы, вероятно, уже обновили его в соответствии со своими потребностями.
+
+Вы можете прочитать о нём больше в документации соответствующего репозитория.
+
+## Full Stack FastAPI MongoDB
+
+...может быть когда-нибудь появится, в зависимости от наличия у меня свободного времени и прочих факторов. 😅 🎉
+
+## Модели машинного обучения на основе spaCy и FastAPI
+
+GitHub:
https://github.com/microsoft/cookiecutter-spacy-fastapi
+
+### Модели машинного обучения на основе spaCy и FastAPI - Особенности
+
+* Интеграция с моделями **spaCy** NER.
+* Встроенный формат запросов к **когнитивному поиску Azure**.
+* **Готовый к реальной работе** веб-сервер Python использующий Uvicorn и Gunicorn.
+* Встроенное развёртывание на основе **Azure DevOps** Kubernetes (AKS) CI/CD.
+* **Многоязычность**. Лёгкий выбор одного из встроенных в spaCy языков во время настройки проекта.
+* **Легко подключить** модели из других фреймворков (Pytorch, Tensorflow) не ограничиваясь spaCy.
diff --git a/docs/ru/docs/python-types.md b/docs/ru/docs/python-types.md
index 7523083c8..b1d4715fd 100644
--- a/docs/ru/docs/python-types.md
+++ b/docs/ru/docs/python-types.md
@@ -12,16 +12,18 @@ Python имеет поддержку необязательных аннотац
Но даже если вы никогда не используете **FastAPI**, вам будет полезно немного узнать о них.
-!!! note
- Если вы являетесь экспертом в Python и уже знаете всё об аннотациях типов, переходите к следующему разделу.
+/// note
+
+Если вы являетесь экспертом в Python и уже знаете всё об аннотациях типов, переходите к следующему разделу.
+
+///
## Мотивация
Давайте начнем с простого примера:
-```Python
-{!../../../docs_src/python_types/tutorial001.py!}
-```
+{* ../../docs_src/python_types/tutorial001.py *}
+
Вызов этой программы выводит:
@@ -35,9 +37,8 @@ John Doe
* Преобразует первую букву содержимого каждой переменной в верхний регистр с `title()`.
*
Соединяет их через пробел.
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
-```
+{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+
### Отредактируем пример
@@ -79,9 +80,8 @@ John Doe
Это аннотации типов:
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
-```
+{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+
Это не то же самое, что объявление значений по умолчанию, например:
@@ -109,9 +109,8 @@ John Doe
Проверьте эту функцию, она уже имеет аннотации типов:
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
-```
+{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+
Поскольку редактор знает типы переменных, вы получаете не только дополнение, но и проверки ошибок:
@@ -119,9 +118,8 @@ John Doe
Теперь вы знаете, что вам нужно исправить, преобразовав `age` в строку с `str(age)`:
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
-```
+{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+
## Объявление типов
@@ -140,9 +138,8 @@ John Doe
* `bool`
* `bytes`
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
-```
+{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+
### Generic-типы с параметрами типов
@@ -158,9 +155,8 @@ John Doe
Импортируйте `List` из `typing` (с заглавной `L`):
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial006.py!}
-```
+{* ../../docs_src/python_types/tutorial006.py hl[1] *}
+
Объявите переменную с тем же синтаксисом двоеточия (`:`).
@@ -168,14 +164,16 @@ John Doe
Поскольку список является типом, содержащим некоторые внутренние типы, вы помещаете их в квадратные скобки:
-```Python hl_lines="4"
-{!../../../docs_src/python_types/tutorial006.py!}
-```
+{* ../../docs_src/python_types/tutorial006.py hl[4] *}
+
-!!! tip
- Эти внутренние типы в квадратных скобках называются «параметрами типов».
+/// tip
- В этом случае `str` является параметром типа, передаваемым в `List`.
+Эти внутренние типы в квадратных скобках называются «параметрами типов».
+
+В этом случае `str` является параметром типа, передаваемым в `List`.
+
+///
Это означает: "переменная `items` является `list`, и каждый из элементов этого списка является `str`".
@@ -193,9 +191,8 @@ John Doe
Вы бы сделали то же самое, чтобы объявить `tuple` и `set`:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial007.py!}
-```
+{* ../../docs_src/python_types/tutorial007.py hl[1,4] *}
+
Это означает:
@@ -210,9 +207,8 @@ John Doe
Второй параметр типа предназначен для значений `dict`:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial008.py!}
-```
+{* ../../docs_src/python_types/tutorial008.py hl[1,4] *}
+
Это означает:
@@ -225,7 +221,7 @@ John Doe
Вы также можете использовать `Optional`, чтобы объявить, что переменная имеет тип, например, `str`, но это является «необязательным», что означает, что она также может быть `None`:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009.py!}
```
Использование `Optional[str]` вместо просто `str` позволит редактору помочь вам в обнаружении ошибок, в которых вы могли бы предположить, что значение всегда является `str`, хотя на самом деле это может быть и `None`.
@@ -249,15 +245,13 @@ John Doe
Допустим, у вас есть класс `Person` с полем `name`:
-```Python hl_lines="1-3"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+
Тогда вы можете объявить переменную типа `Person`:
-```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+
И снова вы получаете полную поддержку редактора:
@@ -265,7 +259,7 @@ John Doe
## Pydantic-модели
-
Pydantic является Python-библиотекой для выполнения валидации данных.
+
Pydantic является Python-библиотекой для выполнения валидации данных.
Вы объявляете «форму» данных как классы с атрибутами.
@@ -277,12 +271,14 @@ John Doe
Взято из официальной документации Pydantic:
-```Python
-{!../../../docs_src/python_types/tutorial011.py!}
-```
+{* ../../docs_src/python_types/tutorial011.py *}
+
-!!! info
- Чтобы узнать больше о
Pydantic, читайте его документацию.
+/// info
+
+Чтобы узнать больше о
Pydantic, читайте его документацию.
+
+///
**FastAPI** целиком основан на Pydantic.
@@ -310,5 +306,8 @@ John Doe
Важно то, что при использовании стандартных типов Python в одном месте (вместо добавления дополнительных классов, декораторов и т.д.) **FastAPI** сделает за вас большую часть работы.
-!!! info
- Если вы уже прошли всё руководство и вернулись, чтобы узнать больше о типах, хорошим ресурсом является
«шпаргалка» от `mypy`.
+/// info
+
+Если вы уже прошли всё руководство и вернулись, чтобы узнать больше о типах, хорошим ресурсом является
«шпаргалка» от `mypy`.
+
+///
diff --git a/docs/ru/docs/tutorial/background-tasks.md b/docs/ru/docs/tutorial/background-tasks.md
index e608f6c8f..bf2e9dec3 100644
--- a/docs/ru/docs/tutorial/background-tasks.md
+++ b/docs/ru/docs/tutorial/background-tasks.md
@@ -15,9 +15,7 @@
Сначала импортируйте `BackgroundTasks`, потом добавьте в функцию параметр с типом `BackgroundTasks`:
-```Python hl_lines="1 13"
-{!../../../docs_src/background_tasks/tutorial001.py!}
-```
+{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
**FastAPI** создаст объект класса `BackgroundTasks` для вас и запишет его в параметр.
@@ -33,17 +31,13 @@
Так как операция записи не использует `async` и `await`, мы определим ее как обычную `def`:
-```Python hl_lines="6-9"
-{!../../../docs_src/background_tasks/tutorial001.py!}
-```
+{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
## Добавление фоновой задачи
Внутри функции вызовите метод `.add_task()` у объекта *background tasks* и передайте ему функцию, которую хотите выполнить в фоне:
-```Python hl_lines="14"
-{!../../../docs_src/background_tasks/tutorial001.py!}
-```
+{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
`.add_task()` принимает следующие аргументы:
@@ -57,21 +51,11 @@
**FastAPI** знает, что нужно сделать в каждом случае и как переиспользовать тот же объект `BackgroundTasks`, так чтобы все фоновые задачи собрались и запустились вместе в фоне:
-=== "Python 3.6 и выше"
-
- ```Python hl_lines="13 15 22 25"
- {!> ../../../docs_src/background_tasks/tutorial002.py!}
- ```
-
-=== "Python 3.10 и выше"
-
- ```Python hl_lines="11 13 20 23"
- {!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
- ```
+{* ../../docs_src/background_tasks/tutorial002_py310.py hl[11,13,20,23] *}
В этом примере сообщения будут записаны в `log.txt` *после* того, как ответ сервера был отправлен.
-Если бы в запросе была очередь `q`, она бы первой записалась в `log.txt` фоновой задачей (потому что вызывается в зависимости `get_query`).
+Если бы в запрос был передан query-параметр `q`, он бы первыми записался в `log.txt` фоновой задачей (потому что вызывается в зависимости `get_query`).
После другая фоновая задача, которая была сгенерирована в функции, запишет сообщение из параметра `email`.
@@ -93,8 +77,6 @@
Их тяжелее настраивать, также им нужен брокер сообщений наподобие RabbitMQ или Redis, но зато они позволяют вам запускать фоновые задачи в нескольких процессах и даже на нескольких серверах.
-Для примера, посмотрите [Project Generators](../project-generation.md){.internal-link target=_blank}, там есть проект с уже настроенным Celery.
-
Но если вам нужен доступ к общим переменным и объектам вашего **FastAPI** приложения или вам нужно выполнять простые фоновые задачи (наподобие отправки письма из примера) вы можете просто использовать `BackgroundTasks`.
## Резюме
diff --git a/docs/ru/docs/tutorial/bigger-applications.md b/docs/ru/docs/tutorial/bigger-applications.md
new file mode 100644
index 000000000..8b9080d39
--- /dev/null
+++ b/docs/ru/docs/tutorial/bigger-applications.md
@@ -0,0 +1,556 @@
+# Большие приложения, в которых много файлов
+
+При построении приложения или веб-API нам редко удается поместить всё в один файл.
+
+**FastAPI** предоставляет удобный инструментарий, который позволяет нам структурировать приложение, сохраняя при этом всю необходимую гибкость.
+
+/// info | Примечание
+
+Если вы раньше использовали Flask, то это аналог шаблонов Flask (Flask's Blueprints).
+
+///
+
+## Пример структуры приложения
+
+Давайте предположим, что наше приложение имеет следующую структуру:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ ├── dependencies.py
+│ └── routers
+│ │ ├── __init__.py
+│ │ ├── items.py
+│ │ └── users.py
+│ └── internal
+│ ├── __init__.py
+│ └── admin.py
+```
+
+/// tip | Подсказка
+
+Обратите внимание, что в каждом каталоге и подкаталоге имеется файл `__init__.py`
+
+Это как раз то, что позволяет импортировать код из одного файла в другой.
+
+Например, в файле `app/main.py` может быть следующая строка:
+
+```
+from app.routers import items
+```
+
+///
+
+* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией модулей Python).
+* Он содержит файл `app/main.py`. Данный файл является частью пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем пакета: `app.main`.
+* Он также содержит файл `app/dependencies.py`, который также, как и `app/main.py`, является модулем: `app.dependencies`.
+* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`. Он является суб-пакетом: `app.routers`.
+* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является суб-модулем: `app.routers.items`.
+* Точно также `app/routers/users.py` является ещё одним суб-модулем: `app.routers.users`.
+* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним суб-пакетом: `app.internal`.
+* А файл `app/internal/admin.py` является ещё одним суб-модулем: `app.internal.admin`.
+
+

+
+Та же самая файловая структура приложения, но с комментариями:
+
+```
+.
+├── app # "app" пакет
+│ ├── __init__.py # этот файл превращает "app" в "Python-пакет"
+│ ├── main.py # модуль "main", напр.: import app.main
+│ ├── dependencies.py # модуль "dependencies", напр.: import app.dependencies
+│ └── routers # суб-пакет "routers"
+│ │ ├── __init__.py # превращает "routers" в суб-пакет
+│ │ ├── items.py # суб-модуль "items", напр.: import app.routers.items
+│ │ └── users.py # суб-модуль "users", напр.: import app.routers.users
+│ └── internal # суб-пакет "internal"
+│ ├── __init__.py # превращает "internal" в суб-пакет
+│ └── admin.py # суб-модуль "admin", напр.: import app.internal.admin
+```
+
+## `APIRouter`
+
+Давайте предположим, что для работы с пользователями используется отдельный файл (суб-модуль) `/app/routers/users.py`.
+
+Для лучшей организации приложения, вы хотите отделить операции пути, связанные с пользователями, от остального кода.
+
+Но так, чтобы эти операции по-прежнему оставались частью **FastAPI** приложения/веб-API (частью одного пакета)
+
+С помощью `APIRouter` вы можете создать *операции пути* (*эндпоинты*) для данного модуля.
+
+
+### Импорт `APIRouter`
+
+Точно также, как и в случае с классом `FastAPI`, вам нужно импортировать и создать объект класса `APIRouter`.
+
+```Python hl_lines="1 3" title="app/routers/users.py"
+{!../../docs_src/bigger_applications/app/routers/users.py!}
+```
+
+### Создание *эндпоинтов* с помощью `APIRouter`
+
+В дальнейшем используйте `APIRouter` для объявления *эндпоинтов*, точно также, как вы используете класс `FastAPI`:
+
+```Python hl_lines="6 11 16" title="app/routers/users.py"
+{!../../docs_src/bigger_applications/app/routers/users.py!}
+```
+
+Вы можете думать об `APIRouter` как об "уменьшенной версии" класса FastAPI`.
+
+`APIRouter` поддерживает все те же самые опции.
+
+`APIRouter` поддерживает все те же самые параметры, такие как `parameters`, `responses`, `dependencies`, `tags`, и т. д.
+
+/// tip | Подсказка
+
+В данном примере, в качестве названия переменной используется `router`, но вы можете использовать любое другое имя.
+
+///
+
+Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и создадим ещё один модуль с `APIRouter`.
+
+## Зависимости
+
+Нам понадобятся некоторые зависимости, которые мы будем использовать в разных местах нашего приложения.
+
+Мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`).
+
+Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомизированный `X-Token` из заголовка:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="3 6-8" title="app/dependencies.py"
+{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 5-7" title="app/dependencies.py"
+{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Подсказка
+
+Мы рекомендуем использовать версию `Annotated`, когда это возможно.
+
+///
+
+```Python hl_lines="1 4-6" title="app/dependencies.py"
+{!> ../../docs_src/bigger_applications/app/dependencies.py!}
+```
+
+////
+
+/// tip | Подсказка
+
+Для простоты мы воспользовались неким воображаемым заголовоком.
+
+В реальных случаях для получения наилучших результатов используйте интегрированные утилиты обеспечения безопасности [Security utilities](security/index.md){.internal-link target=_blank}.
+
+///
+
+## Ещё один модуль с `APIRouter`
+
+Давайте также предположим, что у вас есть *эндпоинты*, отвечающие за обработку "items", и они находятся в модуле `app/routers/items.py`.
+
+У вас определены следующие *операции пути* (*эндпоинты*):
+
+* `/items/`
+* `/items/{item_id}`
+
+Тут всё точно также, как и в ситуации с `app/routers/users.py`.
+
+Но теперь мы хотим поступить немного умнее и слегка упростить код.
+
+Мы знаем, что все *эндпоинты* данного модуля имеют некоторые общие свойства:
+
+* Префикс пути: `/items`.
+* Теги: (один единственный тег: `items`).
+* Дополнительные ответы (responses)
+* Зависимости: использование созданной нами зависимости `X-token`
+
+Таким образом, вместо того чтобы добавлять все эти свойства в функцию каждого отдельного *эндпоинта*,
+мы добавим их в `APIRouter`.
+
+```Python hl_lines="5-10 16 21" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
+```
+
+Так как каждый *эндпоинт* начинается с символа `/`:
+
+```Python hl_lines="1"
+@router.get("/{item_id}")
+async def read_item(item_id: str):
+ ...
+```
+
+...то префикс не должен заканчиваться символом `/`.
+
+В нашем случае префиксом является `/items`.
+
+Мы также можем добавить в наш маршрутизатор (router) список `тегов` (`tags`) и дополнительных `ответов` (`responses`), которые являются общими для каждого *эндпоинта*.
+
+И ещё мы можем добавить в наш маршрутизатор список `зависимостей`, которые должны вызываться при каждом обращении к *эндпоинтам*.
+
+/// tip | Подсказка
+
+Обратите внимание, что также, как и в случае с зависимостями в декораторах *эндпоинтов* ([dependencies in *path operation decorators*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), никакого значения в *функцию эндпоинта* передано не будет.
+
+///
+
+В результате мы получим следующие эндпоинты:
+
+* `/items/`
+* `/items/{item_id}`
+
+...как мы и планировали.
+
+* Они будут помечены тегами из заданного списка, в нашем случае это `"items"`.
+ * Эти теги особенно полезны для системы автоматической интерактивной документации (с использованием OpenAPI).
+* Каждый из них будет включать предопределенные ответы `responses`.
+* Каждый *эндпоинт* будет иметь список зависимостей (`dependencies`), исполняемых перед вызовом *эндпоинта*.
+ * Если вы определили зависимости в самой операции пути, **то она также будет выполнена**.
+ * Сначала выполняются зависимости маршрутизатора, затем вызываются зависимости, определенные в декораторе *эндпоинта* ([`dependencies` in the decorator](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), и, наконец, обычные параметрические зависимости.
+ * Вы также можете добавить зависимости безопасности с областями видимости (`scopes`) [`Security` dependencies with `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
+
+/// tip | Подсказка
+
+Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *эндпоинтов*, не указывая зависимости для каждой отдельной функции *эндпоинта*.
+
+///
+
+/// check | Заметка
+
+Параметры `prefix`, `tags`, `responses` и `dependencies` относятся к функционалу **FastAPI**, помогающему избежать дублирования кода.
+
+///
+
+### Импорт зависимостей
+
+Наш код находится в модуле `app.routers.items` (файл `app/routers/items.py`).
+
+И нам нужно вызвать функцию зависимости из модуля `app.dependencies` (файл `app/dependencies.py`).
+
+Мы используем операцию относительного импорта `..` для импорта зависимости:
+
+```Python hl_lines="3" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
+```
+
+#### Как работает относительный импорт?
+
+/// tip | Подсказка
+
+Если вы прекрасно знаете, как работает импорт в Python, то переходите к следующему разделу.
+
+///
+
+Одна точка `.`, как в данном примере:
+
+```Python
+from .dependencies import get_token_header
+```
+означает:
+
+* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` расположен в каталоге `app/routers/`)...
+* ... найдите модуль `dependencies` (файл `app/routers/dependencies.py`)...
+* ... и импортируйте из него функцию `get_token_header`.
+
+К сожалению, такого файла не существует, и наши зависимости находятся в файле `app/dependencies.py`.
+
+Вспомните, как выглядит файловая структура нашего приложения:
+
+

+
+---
+
+Две точки `..`, как в данном примере:
+
+```Python
+from ..dependencies import get_token_header
+```
+
+означают:
+
+* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)...
+* ... перейдите в родительский пакет (каталог `app/`)...
+* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
+* ... и импортируйте из него функцию `get_token_header`.
+
+Это работает верно! 🎉
+
+---
+
+Аналогично, если бы мы использовали три точки `...`, как здесь:
+
+```Python
+from ...dependencies import get_token_header
+```
+
+то это бы означало:
+
+* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)...
+* ... перейдите в родительский пакет (каталог `app/`)...
+* ... затем перейдите в родительский пакет текущего пакета (такого пакета не существует, `app` находится на самом верхнем уровне 😱)...
+* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
+* ... и импортируйте из него функцию `get_token_header`.
+
+Это будет относиться к некоторому пакету, находящемуся на один уровень выше чем `app/` и содержащему свой собственный файл `__init__.py`. Но ничего такого у нас нет. Поэтому это приведет к ошибке в нашем примере. 🚨
+
+Теперь вы знаете, как работает импорт в Python, и сможете использовать относительное импортирование в своих собственных приложениях любого уровня сложности. 🤓
+
+### Добавление пользовательских тегов (`tags`), ответов (`responses`) и зависимостей (`dependencies`)
+
+Мы не будем добавлять префикс `/items` и список тегов `tags=["items"]` для каждого *эндпоинта*, т.к. мы уже их добавили с помощью `APIRouter`.
+
+Но помимо этого мы можем добавить новые теги для каждого отдельного *эндпоинта*, а также некоторые дополнительные ответы (`responses`), характерные для данного *эндпоинта*:
+
+```Python hl_lines="30-31" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
+```
+
+/// tip | Подсказка
+
+Последний *эндпоинт* будет иметь следующую комбинацию тегов: `["items", "custom"]`.
+
+А также в его документации будут содержаться оба ответа: один для `404` и другой для `403`.
+
+///
+
+## Модуль main в `FastAPI`
+
+Теперь давайте посмотрим на модуль `app/main.py`.
+
+Именно сюда вы импортируете и именно здесь вы используете класс `FastAPI`.
+
+Это основной файл вашего приложения, который объединяет всё в одно целое.
+
+И теперь, когда большая часть логики приложения разделена на отдельные модули, основной файл `app/main.py` будет достаточно простым.
+
+### Импорт `FastAPI`
+
+Вы импортируете и создаете класс `FastAPI` как обычно.
+
+Мы даже можем объявить глобальные зависимости [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого отдельного маршрутизатора:
+
+```Python hl_lines="1 3 7" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+### Импорт `APIRouter`
+
+Теперь мы импортируем другие суб-модули, содержащие `APIRouter`:
+
+```Python hl_lines="4-5" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`.
+
+### Как работает импорт?
+
+Данная строка кода:
+
+```Python
+from .routers import items, users
+```
+
+означает:
+
+* Начните с пакета, в котором содержится данный модуль (файл `app/main.py` содержится в каталоге `app/`)...
+* ... найдите суб-пакет `routers` (каталог `app/routers/`)...
+* ... и из него импортируйте суб-модули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)...
+
+В модуле `items` содержится переменная `router` (`items.router`), та самая, которую мы создали в файле `app/routers/items.py`, она является объектом класса `APIRouter`.
+
+И затем мы сделаем то же самое для модуля `users`.
+
+Мы также могли бы импортировать и другим методом:
+
+```Python
+from app.routers import items, users
+```
+
+/// info | Примечание
+
+Первая версия является примером относительного импорта:
+
+```Python
+from .routers import items, users
+```
+
+Вторая версия является примером абсолютного импорта:
+
+```Python
+from app.routers import items, users
+```
+
+Узнать больше о пакетах и модулях в Python вы можете из
официальной документации Python о модулях
+
+///
+
+### Избегайте конфликтов имен
+
+Вместо того чтобы импортировать только переменную `router`, мы импортируем непосредственно суб-модуль `items`.
+
+Мы делаем это потому, что у нас есть ещё одна переменная `router` в суб-модуле `users`.
+
+Если бы мы импортировали их одну за другой, как показано в примере:
+
+```Python
+from .routers.items import router
+from .routers.users import router
+```
+
+то переменная `router` из `users` переписал бы переменную `router` из `items`, и у нас не было бы возможности использовать их одновременно.
+
+Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули:
+
+```Python hl_lines="5" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+### Подключение маршрутизаторов (`APIRouter`) для `users` и для `items`
+
+Давайте подключим маршрутизаторы (`router`) из суб-модулей `users` и `items`:
+
+```Python hl_lines="10-11" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+/// info | Примечание
+
+`users.router` содержит `APIRouter` из файла `app/routers/users.py`.
+
+А `items.router` содержит `APIRouter` из файла `app/routers/items.py`.
+
+///
+
+С помощью `app.include_router()` мы можем добавить каждый из маршрутизаторов (`APIRouter`) в основное приложение `FastAPI`.
+
+Он подключит все маршруты заданного маршрутизатора к нашему приложению.
+
+/// note | Технические детали
+
+Фактически, внутри он создаст все *операции пути* для каждой операции пути объявленной в `APIRouter`.
+
+И под капотом всё будет работать так, как будто бы мы имеем дело с одним файлом приложения.
+
+///
+
+/// check | Заметка
+
+При подключении маршрутизаторов не стоит беспокоиться о производительности.
+
+Операция подключения займёт микросекунды и понадобится только при запуске приложения.
+
+Таким образом, это не повлияет на производительность. ⚡
+
+///
+
+### Подключение `APIRouter` с пользовательскими префиксом (`prefix`), тегами (`tags`), ответами (`responses`), и зависимостями (`dependencies`)
+
+Теперь давайте представим, что ваша организация передала вам файл `app/internal/admin.py`.
+
+Он содержит `APIRouter` с некоторыми *эндпоитами* администрирования, которые ваша организация использует для нескольких проектов.
+
+В данном примере это сделать очень просто. Но давайте предположим, что поскольку файл используется для нескольких проектов,
+то мы не можем модифицировать его, добавляя префиксы (`prefix`), зависимости (`dependencies`), теги (`tags`), и т.д. непосредственно в `APIRouter`:
+
+```Python hl_lines="3" title="app/internal/admin.py"
+{!../../docs_src/bigger_applications/app/internal/admin.py!}
+```
+
+Но, несмотря на это, мы хотим использовать кастомный префикс (`prefix`) для подключенного маршрутизатора (`APIRouter`), в результате чего, каждая *операция пути* будет начинаться с `/admin`. Также мы хотим защитить наш маршрутизатор с помощью зависимостей, созданных для нашего проекта. И ещё мы хотим включить теги (`tags`) и ответы (`responses`).
+
+Мы можем применить все вышеперечисленные настройки, не изменяя начальный `APIRouter`. Нам всего лишь нужно передать нужные параметры в `app.include_router()`.
+
+```Python hl_lines="14-17" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
+
+В результате, в нашем приложении каждый *эндпоинт* модуля `admin` будет иметь:
+
+* Префикс `/admin`.
+* Тег `admin`.
+* Зависимость `get_token_header`.
+* Ответ `418`. 🍵
+
+Это будет иметь место исключительно для `APIRouter` в нашем приложении, и не затронет любой другой код, использующий его.
+
+Например, другие проекты, могут использовать тот же самый `APIRouter` с другими методами аутентификации.
+
+### Подключение отдельного *эндпоинта*
+
+Мы также можем добавить *эндпоинт* непосредственно в основное приложение `FastAPI`.
+
+Здесь мы это делаем ... просто, чтобы показать, что это возможно 🤷:
+
+```Python hl_lines="21-23" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`.
+
+/// info | Сложные технические детали
+
+**Примечание**: это сложная техническая деталь, которую, скорее всего, **вы можете пропустить**.
+
+---
+
+Маршрутизаторы (`APIRouter`) не "монтируются" по-отдельности и не изолируются от остального приложения.
+
+Это происходит потому, что нужно включить их *эндпоинты* в OpenAPI схему и в интерфейс пользователя.
+
+В силу того, что мы не можем их изолировать и "примонтировать" независимо от остальных, *эндпоинты* клонируются (пересоздаются) и не подключаются напрямую.
+
+///
+
+## Проверка автоматической документации API
+
+Теперь запустите приложение:
+
+
+
+```console
+$ fastapi dev app/main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Откройте документацию по адресу
http://127.0.0.1:8000/docs.
+
+Вы увидите автоматическую API документацию. Она включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги:
+
+

+
+## Подключение существующего маршрута через новый префикс (`prefix`)
+
+Вы можете использовать `.include_router()` несколько раз с одним и тем же маршрутом, применив различные префиксы.
+
+Это может быть полезным, если нужно предоставить доступ к одному и тому же API через различные префиксы, например, `/api/v1` и `/api/latest`.
+
+Это продвинутый способ, который вам может и не пригодится. Мы приводим его на случай, если вдруг вам это понадобится.
+
+## Включение одного маршрутизатора (`APIRouter`) в другой
+
+Точно так же, как вы включаете `APIRouter` в приложение `FastAPI`, вы можете включить `APIRouter` в другой `APIRouter`:
+
+```Python
+router.include_router(other_router)
+```
+
+Удостоверьтесь, что вы сделали это до того, как подключить маршрутизатор (`router`) к вашему `FastAPI` приложению, и *эндпоинты* маршрутизатора `other_router` были также подключены.
diff --git a/docs/ru/docs/tutorial/body-fields.md b/docs/ru/docs/tutorial/body-fields.md
new file mode 100644
index 000000000..5ed5f59fc
--- /dev/null
+++ b/docs/ru/docs/tutorial/body-fields.md
@@ -0,0 +1,61 @@
+# Body - Поля
+
+Таким же способом, как вы объявляете дополнительную валидацию и метаданные в параметрах *функции обработки пути* с помощью функций `Query`, `Path` и `Body`, вы можете объявлять валидацию и метаданные внутри Pydantic моделей, используя функцию `Field` из Pydantic.
+
+## Импорт `Field`
+
+Сначала вы должны импортировать его:
+
+{* ../../docs_src/body_fields/tutorial001_py310.py hl[2] *}
+
+/// warning | Внимание
+
+Обратите внимание, что функция `Field` импортируется непосредственно из `pydantic`, а не из `fastapi`, как все остальные функции (`Query`, `Path`, `Body` и т.д.).
+
+///
+
+## Объявление атрибутов модели
+
+Вы можете использовать функцию `Field` с атрибутами модели:
+
+{* ../../docs_src/body_fields/tutorial001_py310.py hl[9:12] *}
+
+Функция `Field` работает так же, как `Query`, `Path` и `Body`, у неё такие же параметры и т.д.
+
+/// note | Технические детали
+
+На самом деле, `Query`, `Path` и другие функции, которые вы увидите в дальнейшем, создают объекты подклассов общего класса `Param`, который сам по себе является подклассом `FieldInfo` из Pydantic.
+
+И `Field` (из Pydantic), и `Body`, оба возвращают объекты подкласса `FieldInfo`.
+
+У класса `Body` есть и другие подклассы, с которыми вы ознакомитесь позже.
+
+Помните, что когда вы импортируете `Query`, `Path` и другое из `fastapi`, это фактически функции, которые возвращают специальные классы.
+
+///
+
+/// tip | Подсказка
+
+Обратите внимание, что каждый атрибут модели с типом, значением по умолчанию и `Field` имеет ту же структуру, что и параметр *функции обработки пути* с `Field` вместо `Path`, `Query` и `Body`.
+
+///
+
+## Добавление дополнительной информации
+
+Вы можете объявлять дополнительную информацию в `Field`, `Query`, `Body` и т.п. Она будет включена в сгенерированную JSON схему.
+
+Вы узнаете больше о добавлении дополнительной информации позже в документации, когда будете изучать, как задавать примеры принимаемых данных.
+
+
+/// warning | Внимание
+
+Дополнительные ключи, переданные в функцию `Field`, также будут присутствовать в сгенерированной OpenAPI схеме вашего приложения.
+Поскольку эти ключи не являются обязательной частью спецификации OpenAPI, некоторые инструменты OpenAPI, например, [валидатор OpenAPI](https://validator.swagger.io/), могут не работать с вашей сгенерированной схемой.
+
+///
+
+## Резюме
+
+Вы можете использовать функцию `Field` из Pydantic, чтобы задавать дополнительную валидацию и метаданные для атрибутов модели.
+
+Вы также можете использовать дополнительные ключевые аргументы, чтобы добавить метаданные JSON схемы.
diff --git a/docs/ru/docs/tutorial/body-multiple-params.md b/docs/ru/docs/tutorial/body-multiple-params.md
new file mode 100644
index 000000000..9300aa1bd
--- /dev/null
+++ b/docs/ru/docs/tutorial/body-multiple-params.md
@@ -0,0 +1,171 @@
+# Body - Множество параметров
+
+Теперь, когда мы увидели, как использовать `Path` и `Query` параметры, давайте рассмотрим более продвинутые примеры обьявления тела запроса.
+
+## Обьединение `Path`, `Query` и параметров тела запроса
+
+Во-первых, конечно, вы можете объединять параметры `Path`, `Query` и объявления тела запроса в своих функциях обработки, **FastAPI** автоматически определит, что с ними нужно делать.
+
+Вы также можете объявить параметры тела запроса как необязательные, установив значение по умолчанию, равное `None`:
+
+{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
+
+/// note | Заметка
+
+Заметьте, что в данном случае параметр `item`, который будет взят из тела запроса, необязателен. Так как было установлено значение `None` по умолчанию.
+
+///
+
+## Несколько параметров тела запроса
+
+В предыдущем примере, *операции пути* ожидали тело запроса в формате JSON-тело с параметрами, соответствующими атрибутам `Item`, например:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+}
+```
+
+Но вы также можете объявить множество параметров тела запроса, например `item` и `user`:
+
+{* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
+
+В этом случае **FastAPI** заметит, что в функции есть более одного параметра тела (два параметра, которые являются моделями Pydantic).
+
+Таким образом, имена параметров будут использоваться в качестве ключей (имён полей) в теле запроса, и будет ожидаться запрос следующего формата:
+
+```JSON
+{
+ "item": {
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+ },
+ "user": {
+ "username": "dave",
+ "full_name": "Dave Grohl"
+ }
+}
+```
+
+/// note | Внимание
+
+Обратите внимание, что хотя параметр `item` был объявлен таким же способом, как и раньше, теперь предпологается, что он находится внутри тела с ключом `item`.
+
+///
+
+**FastAPI** сделает автоматические преобразование из запроса, так что параметр `item` получит своё конкретное содержимое, и то же самое происходит с пользователем `user`.
+
+Произойдёт проверка составных данных, и создание документации в схеме OpenAPI и автоматических документах.
+
+## Отдельные значения в теле запроса
+
+Точно так же, как `Query` и `Path` используются для определения дополнительных данных для query и path параметров, **FastAPI** предоставляет аналогичный инструмент - `Body`.
+
+Например, расширяя предыдущую модель, вы можете решить, что вам нужен еще один ключ `importance` в том же теле запроса, помимо параметров `item` и `user`.
+
+Если вы объявите его без указания, какой именно объект (Path, Query, Body и .т.п.) ожидаете, то, поскольку это является простым типом данных, **FastAPI** будет считать, что это query-параметр.
+
+Но вы можете указать **FastAPI** обрабатывать его, как ещё один ключ тела запроса, используя `Body`:
+
+{* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
+
+В этом случае, **FastAPI** будет ожидать тело запроса в формате:
+
+```JSON
+{
+ "item": {
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+ },
+ "user": {
+ "username": "dave",
+ "full_name": "Dave Grohl"
+ },
+ "importance": 5
+}
+```
+
+И всё будет работать так же - преобразование типов данных, валидация, документирование и т.д.
+
+## Множество body и query параметров
+
+Конечно, вы также можете объявлять query-параметры в любое время, дополнительно к любым body-параметрам.
+
+Поскольку по умолчанию, отдельные значения интерпретируются как query-параметры, вам не нужно явно добавлять `Query`, вы можете просто сделать так:
+
+```Python
+q: Union[str, None] = None
+```
+
+Или в Python 3.10 и выше:
+
+```Python
+q: str | None = None
+```
+
+Например:
+
+{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[27] *}
+
+/// info | Информация
+
+`Body` также имеет все те же дополнительные параметры валидации и метаданных, как у `Query`,`Path` и других, которые вы увидите позже.
+
+///
+
+## Добавление одного body-параметра
+
+Предположим, у вас есть только один body-параметр `item` из Pydantic модели `Item`.
+
+По умолчанию, **FastAPI** ожидает получить тело запроса напрямую.
+
+Но если вы хотите чтобы он ожидал JSON с ключом `item` с содержимым модели внутри, также как это происходит при объявлении дополнительных body-параметров, вы можете использовать специальный параметр `embed` у типа `Body`:
+
+```Python
+item: Item = Body(embed=True)
+```
+
+так же, как в этом примере:
+
+{* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
+
+В этом случае **FastAPI** будет ожидать тело запроса в формате:
+
+```JSON hl_lines="2"
+{
+ "item": {
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+ }
+}
+```
+
+вместо этого:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+}
+```
+
+## Резюме
+
+Вы можете добавлять несколько body-параметров вашей *функции операции пути*, несмотря даже на то, что запрос может содержать только одно тело.
+
+Но **FastAPI** справится с этим, предоставит правильные данные в вашей функции, а также сделает валидацию и документацию правильной схемы *операции пути*.
+
+Вы также можете объявить отдельные значения для получения в рамках тела запроса.
+
+И вы можете настроить **FastAPI** таким образом, чтобы включить тело запроса в ключ, даже если объявлен только один параметр.
diff --git a/docs/ru/docs/tutorial/body-nested-models.md b/docs/ru/docs/tutorial/body-nested-models.md
new file mode 100644
index 000000000..430092892
--- /dev/null
+++ b/docs/ru/docs/tutorial/body-nested-models.md
@@ -0,0 +1,247 @@
+# Body - Вложенные модели
+
+С помощью **FastAPI**, вы можете определять, валидировать, документировать и использовать модели произвольной вложенности (благодаря библиотеке Pydantic).
+
+## Определение полей содержащих списки
+
+Вы можете определять атрибут как подтип. Например, тип `list` в Python:
+
+{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
+
+Это приведёт к тому, что обьект `tags` преобразуется в список, несмотря на то что тип его элементов не объявлен.
+
+## Определение полей содержащих список с определением типов его элементов
+
+Однако в Python есть способ объявления списков с указанием типов для вложенных элементов:
+
+### Импортируйте `List` из модуля typing
+
+В Python 3.9 и выше вы можете использовать стандартный тип `list` для объявления аннотаций типов, как мы увидим ниже. 💡
+
+Но в версиях Python до 3.9 (начиная с 3.6) сначала вам необходимо импортировать `List` из стандартного модуля `typing` в Python:
+
+{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
+
+### Объявление `list` с указанием типов для вложенных элементов
+
+Объявление типов для элементов (внутренних типов) вложенных в такие типы как `list`, `dict`, `tuple`:
+
+* Если у вас Python версии ниже чем 3.9, импортируйте их аналог из модуля `typing`
+* Передайте внутренний(ие) тип(ы) как "параметры типа", используя квадратные скобки: `[` и `]`
+
+В Python версии 3.9 это будет выглядеть так:
+
+```Python
+my_list: list[str]
+```
+
+В версиях Python до 3.9 это будет выглядеть так:
+
+```Python
+from typing import List
+
+my_list: List[str]
+```
+
+Это всё стандартный синтаксис Python для объявления типов.
+
+Используйте этот же стандартный синтаксис для атрибутов модели с внутренними типами.
+
+Таким образом, в нашем примере мы можем явно указать тип данных для поля `tags` как "список строк":
+
+{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
+
+## Типы множеств
+
+Но затем мы подумали и поняли, что теги не должны повторяться и, вероятно, они должны быть уникальными строками.
+
+И в Python есть специальный тип данных для множеств уникальных элементов - `set`.
+
+Тогда мы можем обьявить поле `tags` как множество строк:
+
+{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
+
+С помощью этого, даже если вы получите запрос с повторяющимися данными, они будут преобразованы в множество уникальных элементов.
+
+И когда вы выводите эти данные, даже если исходный набор содержал дубликаты, они будут выведены в виде множества уникальных элементов.
+
+И они также будут соответствующим образом аннотированы / задокументированы.
+
+## Вложенные Модели
+
+У каждого атрибута Pydantic-модели есть тип.
+
+Но этот тип может сам быть другой моделью Pydantic.
+
+Таким образом вы можете объявлять глубоко вложенные JSON "объекты" с определёнными именами атрибутов, типами и валидацией.
+
+Всё это может быть произвольно вложенным.
+
+### Определение подмодели
+
+Например, мы можем определить модель `Image`:
+
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
+
+### Использование вложенной модели в качестве типа
+
+Также мы можем использовать эту модель как тип атрибута:
+
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
+
+Это означает, что **FastAPI** будет ожидать тело запроса, аналогичное этому:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2,
+ "tags": ["rock", "metal", "bar"],
+ "image": {
+ "url": "http://example.com/baz.jpg",
+ "name": "The Foo live"
+ }
+}
+```
+
+Ещё раз: сделав такое объявление, с помощью **FastAPI** вы получите:
+
+* Поддержку редакторов IDE (автодополнение и т.д), даже для вложенных моделей
+* Преобразование данных
+* Валидацию данных
+* Автоматическую документацию
+
+## Особые типы и валидация
+
+Помимо обычных простых типов, таких как `str`, `int`, `float`, и т.д. Вы можете использовать более сложные базовые типы, которые наследуются от типа `str`.
+
+Чтобы увидеть все варианты, которые у вас есть, ознакомьтесь с документацией
по необычным типам Pydantic. Вы увидите некоторые примеры в следующей главе.
+
+Например, так как в модели `Image` у нас есть поле `url`, то мы можем объявить его как тип `HttpUrl` из модуля Pydantic вместо типа `str`:
+
+{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
+
+Строка будет проверена на соответствие допустимому URL-адресу и задокументирована в JSON схему / OpenAPI.
+
+## Атрибуты, содержащие списки подмоделей
+
+Вы также можете использовать модели Pydantic в качестве типов вложенных в `list`, `set` и т.д:
+
+{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
+
+Такая реализация будет ожидать (конвертировать, валидировать, документировать и т.д) JSON-содержимое в следующем формате:
+
+```JSON hl_lines="11"
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2,
+ "tags": [
+ "rock",
+ "metal",
+ "bar"
+ ],
+ "images": [
+ {
+ "url": "http://example.com/baz.jpg",
+ "name": "The Foo live"
+ },
+ {
+ "url": "http://example.com/dave.jpg",
+ "name": "The Baz"
+ }
+ ]
+}
+```
+
+/// info | Информация
+
+Заметьте, что теперь у ключа `images` есть список объектов изображений.
+
+///
+
+## Глубоко вложенные модели
+
+Вы можете определять модели с произвольным уровнем вложенности:
+
+{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
+
+/// info | Информация
+
+Заметьте, что у объекта `Offer` есть список объектов `Item`, которые, в свою очередь, могут содержать необязательный список объектов `Image`
+
+///
+
+## Тела с чистыми списками элементов
+
+Если верхний уровень значения тела JSON-объекта представляет собой JSON `array` (в Python - `list`), вы можете объявить тип в параметре функции, так же, как в моделях Pydantic:
+
+```Python
+images: List[Image]
+```
+
+в Python 3.9 и выше:
+
+```Python
+images: list[Image]
+```
+
+например так:
+
+{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
+
+## Универсальная поддержка редактора
+
+И вы получаете поддержку редактора везде.
+
+Даже для элементов внутри списков:
+
+

+
+Вы не могли бы получить такую поддержку редактора, если бы работали напрямую с `dict`, а не с моделями Pydantic.
+
+Но вы также не должны беспокоиться об этом, входящие словари автоматически конвертируются, а ваш вывод также автоматически преобразуется в формат JSON.
+
+## Тела запросов с произвольными словарями (`dict` )
+
+Вы также можете объявить тело запроса как `dict` с ключами определенного типа и значениями другого типа данных.
+
+Без необходимости знать заранее, какие значения являются допустимыми для имён полей/атрибутов (как это было бы в случае с моделями Pydantic).
+
+Это было бы полезно, если вы хотите получить ключи, которые вы еще не знаете.
+
+---
+
+Другой полезный случай - когда вы хотите чтобы ключи были другого типа данных, например, `int`.
+
+Именно это мы сейчас и увидим здесь.
+
+В этом случае вы принимаете `dict`, пока у него есть ключи типа `int` со значениями типа `float`:
+
+{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
+
+/// tip | Совет
+
+Имейте в виду, что JSON поддерживает только ключи типа `str`.
+
+Но Pydantic обеспечивает автоматическое преобразование данных.
+
+Это значит, что даже если пользователи вашего API могут отправлять только строки в качестве ключей, при условии, что эти строки содержат целые числа, Pydantic автоматический преобразует и валидирует эти данные.
+
+А `dict`, с именем `weights`, который вы получите в качестве ответа Pydantic, действительно будет иметь ключи типа `int` и значения типа `float`.
+
+///
+
+## Резюме
+
+С помощью **FastAPI** вы получаете максимальную гибкость, предоставляемую моделями Pydantic, сохраняя при этом простоту, краткость и элегантность вашего кода.
+
+И дополнительно вы получаете:
+
+* Поддержку редактора (автодополнение доступно везде!)
+* Преобразование данных (также известно как парсинг / сериализация)
+* Валидацию данных
+* Документацию схемы данных
+* Автоматическую генерацию документации
diff --git a/docs/ru/docs/tutorial/body-updates.md b/docs/ru/docs/tutorial/body-updates.md
new file mode 100644
index 000000000..99f475a41
--- /dev/null
+++ b/docs/ru/docs/tutorial/body-updates.md
@@ -0,0 +1,98 @@
+# Body - Обновления
+
+## Полное обновление с помощью `PUT`
+
+Для полного обновления элемента можно воспользоваться операцией
HTTP `PUT`.
+
+Вы можете использовать функцию `jsonable_encoder` для преобразования входных данных в JSON, так как нередки случаи, когда работать можно только с простыми типами данных (например, для хранения в NoSQL-базе данных).
+
+{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
+
+`PUT` используется для получения данных, которые должны полностью заменить существующие данные.
+
+### Предупреждение о замене
+
+Это означает, что если вы хотите обновить элемент `bar`, используя `PUT` с телом, содержащим:
+
+```Python
+{
+ "name": "Barz",
+ "price": 3,
+ "description": None,
+}
+```
+
+поскольку оно не включает уже сохраненный атрибут `"tax": 20.2`, входная модель примет значение по умолчанию `"tax": 10.5`.
+
+И данные будут сохранены с этим "новым" `tax`, равным `10,5`.
+
+## Частичное обновление с помощью `PATCH`
+
+Также можно использовать
HTTP `PATCH` операцию для *частичного* обновления данных.
+
+Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми.
+
+/// note | Технические детали
+
+`PATCH` менее распространен и известен, чем `PUT`.
+
+А многие команды используют только `PUT`, даже для частичного обновления.
+
+Вы можете **свободно** использовать их как угодно, **FastAPI** не накладывает никаких ограничений.
+
+Но в данном руководстве более или менее понятно, как они должны использоваться.
+
+///
+
+### Использование параметра `exclude_unset` в Pydantic
+
+Если необходимо выполнить частичное обновление, то очень полезно использовать параметр `exclude_unset` в методе `.dict()` модели Pydantic.
+
+Например, `item.dict(exclude_unset=True)`.
+
+В результате будет сгенерирован словарь, содержащий только те данные, которые были заданы при создании модели `item`, без учета значений по умолчанию. Затем вы можете использовать это для создания словаря только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию:
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
+
+### Использование параметра `update` в Pydantic
+
+Теперь можно создать копию существующей модели, используя `.copy()`, и передать параметр `update` с `dict`, содержащим данные для обновления.
+
+Например, `stored_item_model.copy(update=update_data)`:
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
+
+### Кратко о частичном обновлении
+
+В целом, для применения частичных обновлений необходимо:
+
+* (Опционально) использовать `PATCH` вместо `PUT`.
+* Извлечь сохранённые данные.
+* Поместить эти данные в Pydantic модель.
+* Сгенерировать `dict` без значений по умолчанию из входной модели (с использованием `exclude_unset`).
+ * Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять значения, уже сохраненные в модели по умолчанию.
+* Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметра `update`).
+* Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощью `jsonable_encoder`).
+ * Это сравнимо с повторным использованием метода модели `.dict()`, но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например, `datetime` в `str`.
+* Сохранить данные в своей БД.
+* Вернуть обновленную модель.
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
+
+/// tip | Подсказка
+
+Эту же технику можно использовать и для операции HTTP `PUT`.
+
+Но в приведенном примере используется `PATCH`, поскольку он был создан именно для таких случаев использования.
+
+///
+
+/// note | Технические детали
+
+Обратите внимание, что входная модель по-прежнему валидируется.
+
+Таким образом, если вы хотите получать частичные обновления, в которых могут быть опущены все атрибуты, вам необходимо иметь модель, в которой все атрибуты помечены как необязательные (со значениями по умолчанию или `None`).
+
+Чтобы отличить модели со всеми необязательными значениями для **обновления** от моделей с обязательными значениями для **создания**, можно воспользоваться идеями, описанными в [Дополнительные модели](extra-models.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/ru/docs/tutorial/body.md b/docs/ru/docs/tutorial/body.md
new file mode 100644
index 000000000..2c9110226
--- /dev/null
+++ b/docs/ru/docs/tutorial/body.md
@@ -0,0 +1,162 @@
+# Тело запроса
+
+Когда вам необходимо отправить данные из клиента (допустим, браузера) в ваш API, вы отправляете их как **тело запроса**.
+
+Тело **запроса** --- это данные, отправляемые клиентом в ваш API. Тело **ответа** --- это данные, которые ваш API отправляет клиенту.
+
+Ваш API почти всегда отправляет тело **ответа**. Но клиентам не обязательно всегда отправлять тело **запроса**.
+
+Чтобы объявить тело **запроса**, необходимо использовать модели
Pydantic, со всей их мощью и преимуществами.
+
+/// info | Информация
+
+Чтобы отправить данные, необходимо использовать один из методов: `POST` (обычно), `PUT`, `DELETE` или `PATCH`.
+
+Отправка тела с запросом `GET` имеет неопределенное поведение в спецификациях, тем не менее, оно поддерживается FastAPI только для очень сложных/экстремальных случаев использования.
+
+Поскольку это не рекомендуется, интерактивная документация со Swagger UI не будет отображать информацию для тела при использовании метода GET, а промежуточные прокси-серверы могут не поддерживать такой вариант запроса.
+
+///
+
+## Импортирование `BaseModel` из Pydantic
+
+Первое, что вам необходимо сделать, это импортировать `BaseModel` из пакета `pydantic`:
+
+{* ../../docs_src/body/tutorial001.py hl[4] *}
+
+## Создание вашей собственной модели
+
+После этого вы описываете вашу модель данных как класс, наследующий от `BaseModel`.
+
+Используйте аннотации типов Python для всех атрибутов:
+
+{* ../../docs_src/body/tutorial001.py hl[7:11] *}
+
+Также как и при описании параметров запроса, когда атрибут модели имеет значение по умолчанию, он является необязательным. Иначе он обязателен. Используйте `None`, чтобы сделать его необязательным без использования конкретных значений по умолчанию.
+
+Например, модель выше описывает вот такой JSON "объект" (или словарь Python):
+
+```JSON
+{
+ "name": "Foo",
+ "description": "An optional description",
+ "price": 45.2,
+ "tax": 3.5
+}
+```
+
+...поскольку `description` и `tax` являются необязательными (с `None` в качестве значения по умолчанию), вот такой JSON "объект" также подходит:
+
+```JSON
+{
+ "name": "Foo",
+ "price": 45.2
+}
+```
+
+## Объявление как параметра функции
+
+Чтобы добавить параметр к вашему *обработчику*, объявите его также, как вы объявляли параметры пути или параметры запроса:
+
+{* ../../docs_src/body/tutorial001.py hl[18] *}
+
+...и укажите созданную модель в качестве типа параметра, `Item`.
+
+## Результаты
+
+Всего лишь с помощью аннотации типов Python, **FastAPI**:
+
+* Читает тело запроса как JSON.
+* Приводит к соответствующим типам (если есть необходимость).
+* Проверяет корректность данных.
+ * Если данные некорректны, будет возращена читаемая и понятная ошибка, показывающая что именно и в каком месте некорректно в данных.
+* Складывает полученные данные в параметр `item`.
+ * Поскольку внутри функции вы объявили его с типом `Item`, то теперь у вас есть поддержка со стороны редактора (автодополнение и т.п.) для всех атрибутов и их типов.
+* Генерирует декларативное описание модели в виде
JSON Schema, так что вы можете его использовать где угодно, если это имеет значение для вашего проекта.
+* Эти схемы являются частью сгенерированной схемы OpenAPI и используются для автоматического документирования
UI.
+
+## Автоматическое документирование
+
+Схема JSON ваших моделей будет частью сгенерированной схемы OpenAPI и будет отображена в интерактивной документации API:
+
+

+
+Также она будет указана в документации по API внутри каждой *операции пути*, в которой используются:
+
+

+
+## Поддержка редактора
+
+В вашем редакторе внутри вашей функции у вас будут подсказки по типам и автодополнение (это не будет работать, если вы получаете словарь вместо модели Pydantic):
+
+

+
+Также вы будете получать ошибки в случае несоответствия типов:
+
+

+
+Это не случайно, весь фреймворк построен вокруг такого дизайна.
+
+И это все тщательно протестировано еще на этапе разработки дизайна, до реализации, чтобы это работало со всеми редакторами.
+
+Для поддержки этого даже были внесены некоторые изменения в сам Pydantic.
+
+На всех предыдущих скриншотах используется
Visual Studio Code.
+
+Но у вас будет такая же поддержка и с
PyCharm, и вообще с любым редактором Python:
+
+

+
+/// tip | Подсказка
+
+Если вы используете
PyCharm в качестве редактора, то вам стоит попробовать плагин
Pydantic PyCharm Plugin.
+
+Он улучшает поддержку редактором моделей Pydantic в части:
+
+* автодополнения,
+* проверки типов,
+* рефакторинга,
+* поиска,
+* инспектирования.
+
+///
+
+## Использование модели
+
+Внутри функции вам доступны все атрибуты объекта модели напрямую:
+
+{* ../../docs_src/body/tutorial002.py hl[21] *}
+
+## Тело запроса + параметры пути
+
+Вы можете одновременно объявлять параметры пути и тело запроса.
+
+**FastAPI** распознает, какие параметры функции соответствуют параметрам пути и должны быть **получены из пути**, а какие параметры функции, объявленные как модели Pydantic, должны быть **получены из тела запроса**.
+
+{* ../../docs_src/body/tutorial003.py hl[17:18] *}
+
+## Тело запроса + параметры пути + параметры запроса
+
+Вы также можете одновременно объявить параметры для **пути**, **запроса** и **тела запроса**.
+
+**FastAPI** распознает каждый из них и возьмет данные из правильного источника.
+
+{* ../../docs_src/body/tutorial004.py hl[18] *}
+
+Параметры функции распознаются следующим образом:
+
+* Если параметр также указан в **пути**, то он будет использоваться как параметр пути.
+* Если аннотация типа параметра содержит **примитивный тип** (`int`, `float`, `str`, `bool` и т.п.), он будет интерпретирован как параметр **запроса**.
+* Если аннотация типа параметра представляет собой **модель Pydantic**, он будет интерпретирован как параметр **тела запроса**.
+
+/// note | Заметка
+
+FastAPI понимает, что значение параметра `q` не является обязательным, потому что имеет значение по умолчанию `= None`.
+
+Аннотация `Optional` в `Optional[str]` не используется FastAPI, но помогает вашему редактору лучше понимать ваш код и обнаруживать ошибки.
+
+///
+
+## Без Pydantic
+
+Если вы не хотите использовать модели Pydantic, вы все еще можете использовать параметры **тела запроса**. Читайте в документации раздел [Тело - Несколько параметров: Единичные значения в теле](body-multiple-params.md#_2){.internal-link target=_blank}.
diff --git a/docs/ru/docs/tutorial/cookie-param-models.md b/docs/ru/docs/tutorial/cookie-param-models.md
new file mode 100644
index 000000000..3a57443bb
--- /dev/null
+++ b/docs/ru/docs/tutorial/cookie-param-models.md
@@ -0,0 +1,76 @@
+# Модели параметров cookie
+
+Если у вас есть группа **cookies**, которые связаны между собой, вы можете создать **Pydantic-модель** для их объявления. 🍪
+
+Это позволит вам **переиспользовать модель** в **разных местах**, а также объявить проверки и метаданные сразу для всех параметров. 😎
+
+/// note | Заметка
+
+Этот функционал доступен с версии `0.115.0`. 🤓
+
+///
+
+/// tip | Совет
+
+Такой же подход применяется для `Query`, `Cookie`, и `Header`. 😎
+
+///
+
+## Pydantic-модель для cookies
+
+Объявите параметры **cookie**, которые вам нужны, в **Pydantic-модели**, а затем объявите параметр как `Cookie`:
+
+{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
+
+**FastAPI** **извлечёт** данные для **каждого поля** из **cookies**, полученных в запросе, и выдаст вам объявленную Pydantic-модель.
+
+## Проверка сгенерированной документации
+
+Вы можете посмотреть объявленные cookies в графическом интерфейсе Документации по пути `/docs`:
+
+
+

+
+
+/// info | Дополнительная информация
+
+Имейте в виду, что, поскольку **браузеры обрабатывают cookies** особым образом и под капотом, они **не** позволят **JavaScript** легко получить доступ к ним.
+
+Если вы перейдёте к **графическому интерфейсу документации API** по пути `/docs`, то сможете увидеть **документацию** по cookies для ваших *операций путей*.
+
+Но даже если вы **заполните данные** и нажмёте "Execute", поскольку графический интерфейс Документации работает с **JavaScript**, cookies не будут отправлены, и вы увидите сообщение об **ошибке** как будто не указывали никаких значений.
+
+///
+
+## Запрет дополнительных cookies
+
+В некоторых случаях (не особо часто встречающихся) вам может понадобиться **ограничить** cookies, которые вы хотите получать.
+
+Теперь ваш API сам решает,
принимать ли cookies. 🤪🍪
+
+Вы можете сконфигурировать Pydantic-модель так, чтобы запретить (`forbid`) любые дополнительные (`extra`) поля:
+
+{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
+
+Если клиент попробует отправить **дополнительные cookies**, то в ответ он получит **ошибку**.
+
+Бедные баннеры cookies, они всеми силами пытаются получить ваше согласие — и всё ради того, чтобы
API его отклонил. 🍪
+
+Например, если клиент попытается отправить cookie `santa_tracker` со значением `good-list-please`, то в ответ он получит **ошибку**, сообщающую ему, что cookie `santa_tracker`
не разрешён:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["cookie", "santa_tracker"],
+ "msg": "Extra inputs are not permitted",
+ "input": "good-list-please"
+ }
+ ]
+}
+```
+
+## Заключение
+
+Вы можете использовать **Pydantic-модели** для объявления
**cookies** в **FastAPI**. 😎
diff --git a/docs/ru/docs/tutorial/cookie-params.md b/docs/ru/docs/tutorial/cookie-params.md
new file mode 100644
index 000000000..d1ed943d7
--- /dev/null
+++ b/docs/ru/docs/tutorial/cookie-params.md
@@ -0,0 +1,35 @@
+# Параметры Cookie
+
+Вы можете задать параметры Cookie таким же способом, как `Query` и `Path` параметры.
+
+## Импорт `Cookie`
+
+Сначала импортируйте `Cookie`:
+
+{* ../../docs_src/cookie_params/tutorial001_py310.py hl[1] *}
+
+## Объявление параметров `Cookie`
+
+Затем объявляйте параметры cookie, используя ту же структуру, что и с `Path` и `Query`.
+
+Первое значение - это значение по умолчанию, вы можете передать все дополнительные параметры проверки или аннотации:
+
+{* ../../docs_src/cookie_params/tutorial001_py310.py hl[7] *}
+
+/// note | Технические детали
+
+`Cookie` - это класс, родственный `Path` и `Query`. Он также наследуется от общего класса `Param`.
+
+Но помните, что когда вы импортируете `Query`, `Path`, `Cookie` и другое из `fastapi`, это фактически функции, которые возвращают специальные классы.
+
+///
+
+/// info | Дополнительная информация
+
+Для объявления cookies, вам нужно использовать `Cookie`, иначе параметры будут интерпретированы как параметры запроса.
+
+///
+
+## Резюме
+
+Объявляйте cookies с помощью `Cookie`, используя тот же общий шаблон, что и `Query`, и `Path`.
diff --git a/docs/ru/docs/tutorial/cors.md b/docs/ru/docs/tutorial/cors.md
new file mode 100644
index 000000000..e8bf04576
--- /dev/null
+++ b/docs/ru/docs/tutorial/cors.md
@@ -0,0 +1,85 @@
+# CORS (Cross-Origin Resource Sharing)
+
+
Понятие CORS или "Cross-Origin Resource Sharing" относится к ситуациям, при которых запущенный в браузере фронтенд содержит JavaScript-код, который взаимодействует с бэкендом, находящимся на другом "источнике" ("origin").
+
+## Источник
+
+Источник - это совокупность протокола (`http`, `https`), домена (`myapp.com`, `localhost`, `localhost.tiangolo.com`) и порта (`80`, `443`, `8080`).
+
+Поэтому это три разных источника:
+
+* `http://localhost`
+* `https://localhost`
+* `http://localhost:8080`
+
+Даже если они все расположены в `localhost`, они используют разные протоколы и порты, а значит, являются разными источниками.
+
+## Шаги
+
+Допустим, у вас есть фронтенд, запущенный в браузере по адресу `http://localhost:8080`, и его JavaScript-код пытается взаимодействовать с бэкендом, запущенным по адресу `http://localhost` (поскольку мы не указали порт, браузер по умолчанию будет использовать порт `80`).
+
+Затем браузер отправит бэкенду HTTP-запрос `OPTIONS`, и если бэкенд вернёт соответствующие заголовки для авторизации взаимодействия с другим источником (`http://localhost:8080`), то браузер разрешит JavaScript-коду на фронтенде отправить запрос на этот бэкенд.
+
+Чтобы это работало, у бэкенда должен быть список "разрешённых источников" ("allowed origins").
+
+В таком случае этот список должен содержать `http://localhost:8080`, чтобы фронтенд работал корректно.
+
+## Подстановочный символ `"*"`
+
+В качестве списка источников можно указать подстановочный символ `"*"` ("wildcard"), чтобы разрешить любые источники.
+
+Но тогда не будут разрешены некоторые виды взаимодействия, включая всё связанное с учётными данными: куки, заголовки Authorization с Bearer-токенами наподобие тех, которые мы использовали ранее и т.п.
+
+Поэтому, чтобы всё работало корректно, лучше явно указывать список разрешённых источников.
+
+## Использование `CORSMiddleware`
+
+Вы можете настроить этот механизм в вашем **FastAPI** приложении, используя `CORSMiddleware`.
+
+* Импортируйте `CORSMiddleware`.
+* Создайте список разрешённых источников (в виде строк).
+* Добавьте его как "middleware" к вашему **FastAPI** приложению.
+
+Вы также можете указать, разрешает ли ваш бэкенд использование:
+
+* Учётных данных (включая заголовки Authorization, куки и т.п.).
+* Отдельных HTTP-методов (`POST`, `PUT`) или всех вместе, используя `"*"`.
+* Отдельных HTTP-заголовков или всех вместе, используя `"*"`.
+
+{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+
+`CORSMiddleware` использует для параметров "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте.
+
+Поддерживаются следующие аргументы:
+
+* `allow_origins` - Список источников, на которые разрешено выполнять кросс-доменные запросы. Например, `['https://example.org', 'https://www.example.org']`. Можно использовать `['*']`, чтобы разрешить любые источники.
+* `allow_origin_regex` - Регулярное выражение для определения источников, на которые разрешено выполнять кросс-доменные запросы. Например, `'https://.*\.example\.org'`.
+* `allow_methods` - Список HTTP-методов, которые разрешены для кросс-доменных запросов. По умолчанию равно `['GET']`. Можно использовать `['*']`, чтобы разрешить все стандартные методы.
+* `allow_headers` - Список HTTP-заголовков, которые должны поддерживаться при кросс-доменных запросах. По умолчанию равно `[]`. Можно использовать `['*']`, чтобы разрешить все заголовки. Заголовки `Accept`, `Accept-Language`, `Content-Language` и `Content-Type` всегда разрешены для
простых CORS-запросов.
+* `allow_credentials` - указывает, что куки разрешены в кросс-доменных запросах. По умолчанию равно `False`. Также, `allow_origins` нельзя присвоить `['*']`, если разрешено использование учётных данных. В таком случае должен быть указан список источников.
+* `expose_headers` - Указывает любые заголовки ответа, которые должны быть доступны браузеру. По умолчанию равно `[]`.
+* `max_age` - Устанавливает максимальное время в секундах, в течение которого браузер кэширует CORS-ответы. По умолчанию равно `600`.
+
+`CORSMiddleware` отвечает на два типа HTTP-запросов...
+
+### CORS-запросы с предварительной проверкой
+
+Это любые `OPTIONS` запросы с заголовками `Origin` и `Access-Control-Request-Method`.
+
+В этом случае middleware перехватит входящий запрос и отправит соответствующие CORS-заголовки в ответе, а также ответ `200` или `400` в информационных целях.
+
+### Простые запросы
+
+Любые запросы с заголовком `Origin`. В этом случае middleware передаст запрос дальше как обычно, но добавит соответствующие CORS-заголовки к ответу.
+
+## Больше информации
+
+Для получения более подробной информации о
CORS, обратитесь к
Документации CORS от Mozilla.
+
+/// note | Технические детали
+
+Вы также можете использовать `from starlette.middleware.cors import CORSMiddleware`.
+
+**FastAPI** предоставляет несколько middleware в `fastapi.middleware` только для вашего удобства как разработчика. Но большинство доступных middleware взяты напрямую из Starlette.
+
+///
diff --git a/docs/ru/docs/tutorial/debugging.md b/docs/ru/docs/tutorial/debugging.md
new file mode 100644
index 000000000..05806f087
--- /dev/null
+++ b/docs/ru/docs/tutorial/debugging.md
@@ -0,0 +1,113 @@
+# Отладка
+
+Вы можете подключить отладчик в своем редакторе, например, в Visual Studio Code или PyCharm.
+
+## Вызов `uvicorn`
+
+В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую:
+
+{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+
+### Описание `__name__ == "__main__"`
+
+Главная цель использования `__name__ == "__main__"` в том, чтобы код выполнялся при запуске файла с помощью:
+
+
+
+```console
+$ python myapp.py
+```
+
+
+
+но не вызывался, когда другой файл импортирует это, например:
+
+```Python
+from myapp import app
+```
+
+#### Больше деталей
+
+Давайте назовём ваш файл `myapp.py`.
+
+Если вы запустите его с помощью:
+
+
+
+```console
+$ python myapp.py
+```
+
+
+
+то встроенная переменная `__name__`, автоматически создаваемая Python в вашем файле, будет иметь значение строкового типа `"__main__"`.
+
+Тогда выполнится условие и эта часть кода:
+
+```Python
+ uvicorn.run(app, host="0.0.0.0", port=8000)
+```
+
+будет запущена.
+
+---
+
+Но этого не произойдет, если вы импортируете этот модуль (файл).
+
+Таким образом, если у вас есть файл `importer.py` с таким импортом:
+
+```Python
+from myapp import app
+
+# Some more code
+```
+
+то автоматическая создаваемая внутри файла `myapp.py` переменная `__name__` будет иметь значение отличающееся от `"__main__"`.
+
+Следовательно, строка:
+
+```Python
+ uvicorn.run(app, host="0.0.0.0", port=8000)
+```
+
+не будет выполнена.
+
+/// info | Информация
+
+Для получения дополнительной информации, ознакомьтесь с
официальной документацией Python.
+
+///
+
+## Запуск вашего кода с помощью отладчика
+
+Так как вы запускаете сервер Uvicorn непосредственно из вашего кода, вы можете вызвать Python программу (ваше FastAPI приложение) напрямую из отладчика.
+
+---
+
+Например, в Visual Studio Code вы можете выполнить следующие шаги:
+
+* Перейдите на панель "Debug".
+* Выберите "Add configuration...".
+* Выберите "Python"
+* Запустите отладчик "`Python: Current File (Integrated Terminal)`".
+
+Это запустит сервер с вашим **FastAPI** кодом, остановится на точках останова, и т.д.
+
+Вот как это может выглядеть:
+
+

+
+---
+
+Если используете Pycharm, вы можете выполнить следующие шаги:
+
+* Открыть "Run" меню.
+* Выбрать опцию "Debug...".
+* Затем в появившемся контекстном меню.
+* Выбрать файл для отладки (в данном случае, `main.py`).
+
+Это запустит сервер с вашим **FastAPI** кодом, остановится на точках останова, и т.д.
+
+Вот как это может выглядеть:
+
+

diff --git a/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
new file mode 100644
index 000000000..8037872b9
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -0,0 +1,285 @@
+# Классы как зависимости
+
+Прежде чем углубиться в систему **Внедрения Зависимостей**, давайте обновим предыдущий пример.
+
+## `Словарь` из предыдущего примера
+
+В предыдущем примере мы возвращали `словарь` из нашей зависимости:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *}
+
+Но затем мы получаем `словарь` в параметре `commons` *функции операции пути*. И мы знаем, что редакторы не могут обеспечить достаточную поддержку для `словаря`, поскольку они не могут знать их ключи и типы значений.
+
+Мы можем сделать лучше...
+
+## Что делает зависимость
+
+До сих пор вы видели зависимости, объявленные как функции.
+
+Но это не единственный способ объявления зависимостей (хотя, вероятно, более распространенный).
+
+Ключевым фактором является то, что зависимость должна быть "вызываемой".
+
+В Python "**вызываемый**" - это все, что Python может "вызвать", как функцию.
+
+Так, если у вас есть объект `something` (который может _не_ быть функцией) и вы можете "вызвать" его (выполнить) как:
+
+```Python
+something()
+```
+
+или
+
+```Python
+something(some_argument, some_keyword_argument="foo")
+```
+
+в таком случае он является "вызываемым".
+
+## Классы как зависимости
+
+Вы можете заметить, что для создания экземпляра класса в Python используется тот же синтаксис.
+
+Например:
+
+```Python
+class Cat:
+ def __init__(self, name: str):
+ self.name = name
+
+
+fluffy = Cat(name="Mr Fluffy")
+```
+
+В данном случае `fluffy` является экземпляром класса `Cat`.
+
+А чтобы создать `fluffy`, вы "вызываете" `Cat`.
+
+Таким образом, класс в Python также является **вызываемым**.
+
+Тогда в **FastAPI** в качестве зависимости можно использовать класс Python.
+
+На самом деле FastAPI проверяет, что переданный объект является "вызываемым" (функция, класс или что-либо еще) и указаны необходимые для его вызова параметры.
+
+Если вы передаёте что-то, что можно "вызывать" в качестве зависимости в **FastAPI**, то он будет анализировать параметры, необходимые для "вызова" этого объекта и обрабатывать их так же, как параметры *функции операции пути*. Включая подзависимости.
+
+Это относится и к вызываемым объектам без параметров. Работа с ними происходит точно так же, как и для *функций операции пути* без параметров.
+
+Теперь мы можем изменить зависимость `common_parameters`, указанную выше, на класс `CommonQueryParams`:
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[11:15] *}
+
+Обратите внимание на метод `__init__`, используемый для создания экземпляра класса:
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[12] *}
+
+...имеет те же параметры, что и ранее используемая функция `common_parameters`:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8] *}
+
+Эти параметры и будут использоваться **FastAPI** для "решения" зависимости.
+
+В обоих случаях она будет иметь:
+
+* Необязательный параметр запроса `q`, представляющий собой `str`.
+* Параметр запроса `skip`, представляющий собой `int`, по умолчанию `0`.
+* Параметр запроса `limit`, представляющий собой `int`, по умолчанию равный `100`.
+
+В обоих случаях данные будут конвертированы, валидированы, документированы по схеме OpenAPI и т.д.
+
+## Как это использовать
+
+Теперь вы можете объявить свою зависимость, используя этот класс.
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[19] *}
+
+**FastAPI** вызывает класс `CommonQueryParams`. При этом создается "экземпляр" этого класса, который будет передан в качестве параметра `commons` в вашу функцию.
+
+## Аннотация типа или `Depends`
+
+Обратите внимание, что в приведенном выше коде мы два раза пишем `CommonQueryParams`:
+
+//// tab | Python 3.6+ без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+//// tab | Python 3.6+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+Последний параметр `CommonQueryParams`, в:
+
+```Python
+... Depends(CommonQueryParams)
+```
+
+...это то, что **FastAPI** будет использовать, чтобы узнать, что является зависимостью.
+
+Из него FastAPI извлечёт объявленные параметры и именно их будет вызывать.
+
+---
+
+В этом случае первый `CommonQueryParams`, в:
+
+//// tab | Python 3.6+
+
+```Python
+commons: Annotated[CommonQueryParams, ...
+```
+
+////
+
+//// tab | Python 3.6+ без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python
+commons: CommonQueryParams ...
+```
+
+////
+
+...не имеет никакого специального значения для **FastAPI**. FastAPI не будет использовать его для преобразования данных, валидации и т.д. (поскольку для этого используется `Depends(CommonQueryParams)`).
+
+На самом деле можно написать просто:
+
+//// tab | Python 3.6+
+
+```Python
+commons: Annotated[Any, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.6+ без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python
+commons = Depends(CommonQueryParams)
+```
+
+////
+
+...как тут:
+
+{* ../../docs_src/dependencies/tutorial003_an_py310.py hl[19] *}
+
+Но объявление типа приветствуется, так как в этом случае ваш редактор будет знать, что будет передано в качестве параметра `commons`, и тогда он сможет помочь вам с автодополнением, проверкой типов и т.д:
+
+

+
+## Сокращение
+
+Но вы видите, что здесь мы имеем некоторое повторение кода, дважды написав `CommonQueryParams`:
+
+//// tab | Python 3.6+ без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+//// tab | Python 3.6+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+Для случаев, когда зависимостью является *конкретный* класс, который **FastAPI** "вызовет" для создания экземпляра этого класса, можно использовать укороченную запись.
+
+
+Вместо того чтобы писать:
+
+//// tab | Python 3.6+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.6+ без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+...следует написать:
+
+//// tab | Python 3.6+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends()]
+```
+
+////
+
+//// tab | Python 3.6 без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends()
+```
+
+////
+
+Вы объявляете зависимость как тип параметра и используете `Depends()` без какого-либо параметра, вместо того чтобы *снова* писать полный класс внутри `Depends(CommonQueryParams)`.
+
+Аналогичный пример будет выглядеть следующим образом:
+
+{* ../../docs_src/dependencies/tutorial004_an_py310.py hl[19] *}
+
+...и **FastAPI** будет знать, что делать.
+
+/// tip | Подсказка
+
+Если это покажется вам более запутанным, чем полезным, не обращайте внимания, это вам не *нужно*.
+
+Это просто сокращение. Потому что **FastAPI** заботится о том, чтобы помочь вам свести к минимуму повторение кода.
+
+///
diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
new file mode 100644
index 000000000..0e4eb95be
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -0,0 +1,69 @@
+# Зависимости в декораторах операции пути
+
+В некоторых случаях, возвращаемое значение зависимости не используется внутри *функции операции пути*.
+
+Или же зависимость не возвращает никакого значения.
+
+Но вам всё-таки нужно, чтобы она выполнилась.
+
+Для таких ситуаций, вместо объявления *функции операции пути* с параметром `Depends`, вы можете добавить список зависимостей `dependencies` в *декоратор операции пути*.
+
+## Добавление `dependencies` в *декоратор операции пути*
+
+*Декоратор операции пути* получает необязательный аргумент `dependencies`.
+
+Это должен быть `list` состоящий из `Depends()`:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
+
+Зависимости из dependencies выполнятся так же, как и обычные зависимости. Но их значения (если они были) не будут переданы в *функцию операции пути*.
+
+/// tip | Подсказка
+
+Некоторые редакторы кода определяют неиспользуемые параметры функций и подсвечивают их как ошибку.
+
+Использование `dependencies` в *декораторе операции пути* гарантирует выполнение зависимостей, избегая при этом предупреждений редактора кода и других инструментов.
+
+Это также должно помочь предотвратить путаницу у начинающих разработчиков, которые видят неиспользуемые параметры в коде и могут подумать что в них нет необходимости.
+
+///
+
+/// info | Примечание
+
+В этом примере мы используем выдуманные пользовательские заголовки `X-Key` и `X-Token`.
+
+Но в реальных проектах, при внедрении системы безопасности, вы получите больше пользы используя интегрированные [средства защиты (следующая глава)](../security/index.md){.internal-link target=_blank}.
+
+///
+
+## Исключения в dependencies и возвращаемые значения
+
+Вы можете использовать те же *функции* зависимостей, что и обычно.
+
+### Требования к зависимостям
+
+Они могут объявлять требования к запросу (например заголовки) или другие подзависимости:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
+
+### Вызов исключений
+
+Зависимости из dependencies могут вызывать исключения с помощью `raise`, как и обычные зависимости:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
+
+### Возвращаемые значения
+
+И они могут возвращать значения или нет, эти значения использоваться не будут.
+
+Таким образом, вы можете переиспользовать обычную зависимость (возвращающую значение), которую вы уже используете где-то в другом месте, и хотя значение не будет использоваться, зависимость будет выполнена:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
+
+## Dependencies для группы *операций путей*
+
+Позже, читая о том как структурировать большие приложения ([Bigger Applications - Multiple Files](../../tutorial/bigger-applications.md){.internal-link target=_blank}), возможно, многофайловые, вы узнаете как объявить единый параметр `dependencies` для всей группы *операций путей*.
+
+## Глобальный Dependencies
+
+Далее мы увидим, как можно добавить dependencies для всего `FastAPI` приложения, так чтобы они применялись к каждой *операции пути*.
diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
new file mode 100644
index 000000000..e64f6777c
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -0,0 +1,259 @@
+# Зависимости с yield
+
+FastAPI поддерживает зависимости, которые выполняют некоторые
дополнительные действия после завершения работы.
+
+Для этого используйте `yield` вместо `return`, а дополнительный код напишите после него.
+
+/// tip | Подсказка
+
+Обязательно используйте `yield` один-единственный раз.
+
+///
+
+/// note | Технические детали
+
+Любая функция, с которой может работать:
+
+*
`@contextlib.contextmanager` или
+*
`@contextlib.asynccontextmanager`
+
+будет корректно использоваться в качестве **FastAPI**-зависимости.
+
+На самом деле, FastAPI использует эту пару декораторов "под капотом".
+
+///
+
+## Зависимость базы данных с помощью `yield`
+
+Например, с его помощью можно создать сессию работы с базой данных и закрыть его после завершения.
+
+Перед созданием ответа будет выполнен только код до и включая `yield`.
+
+{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
+
+Полученное значение и есть то, что будет внедрено в функцию операции пути и другие зависимости:
+
+{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+
+Код, следующий за оператором `yield`, выполняется после доставки ответа:
+
+{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+
+/// tip | Подсказка
+
+Можно использовать как `async` так и обычные функции.
+
+**FastAPI** это корректно обработает, и в обоих случаях будет делать то же самое, что и с обычными зависимостями.
+
+///
+
+## Зависимость с `yield` и `try` одновременно
+
+Если использовать блок `try` в зависимости с `yield`, то будет получено всякое исключение, которое было выброшено при использовании зависимости.
+
+Например, если какой-то код в какой-то момент в середине, в другой зависимости или в *функции операции пути*, сделал "откат" транзакции базы данных или создал любую другую ошибку, то вы получите исключение в своей зависимости.
+
+Таким образом, можно искать конкретное исключение внутри зависимости с помощью `except SomeException`.
+
+Таким же образом можно использовать `finally`, чтобы убедиться, что обязательные шаги при выходе выполнены, независимо от того, было ли исключение или нет.
+
+{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+
+## Подзависимости с `yield`
+
+Вы можете иметь подзависимости и "деревья" подзависимостей любого размера и формы, и любая из них или все они могут использовать `yield`.
+
+**FastAPI** будет следить за тем, чтобы "код по выходу" в каждой зависимости с `yield` выполнялся в правильном порядке.
+
+Например, `dependency_c` может иметь зависимость от `dependency_b`, а `dependency_b` от `dependency_a`:
+
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
+
+И все они могут использовать `yield`.
+
+В этом случае `dependency_c` для выполнения своего кода выхода нуждается в том, чтобы значение из `dependency_b` (здесь `dep_b`) было еще доступно.
+
+И, в свою очередь, `dependency_b` нуждается в том, чтобы значение из `dependency_a` (здесь `dep_a`) было доступно для ее завершающего кода.
+
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
+
+Точно так же можно иметь часть зависимостей с `yield`, часть с `return`, и какие-то из них могут зависеть друг от друга.
+
+Либо у вас может быть одна зависимость, которая требует несколько других зависимостей с `yield` и т.д.
+
+Комбинации зависимостей могут быть какими вам угодно.
+
+**FastAPI** проследит за тем, чтобы все выполнялось в правильном порядке.
+
+/// note | Технические детали
+
+Это работает благодаря
Контекстным менеджерам в Python.
+
+///
+
+ **FastAPI** использует их "под капотом" с этой целью.
+
+## Зависимости с `yield` и `HTTPException`
+
+Вы видели, что можно использовать зависимости с `yield` совместно с блоком `try`, отлавливающие исключения.
+
+Таким же образом вы можете поднять исключение `HTTPException` или что-то подобное в завершающем коде, после `yield`.
+
+Код выхода в зависимостях с `yield` выполняется *после* отправки ответа, поэтому [Обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} уже будет запущен. В коде выхода (после `yield`) нет ничего, перехватывающего исключения, брошенные вашими зависимостями.
+
+Таким образом, если после `yield` возникает `HTTPException`, то стандартный (или любой пользовательский) обработчик исключений, который перехватывает `HTTPException` и возвращает ответ HTTP 400, уже не сможет перехватить это исключение.
+
+Благодаря этому все, что установлено в зависимости (например, сеанс работы с БД), может быть использовано, например, фоновыми задачами.
+
+Фоновые задачи выполняются *после* отправки ответа. Поэтому нет возможности поднять `HTTPException`, так как нет даже возможности изменить уже отправленный ответ.
+
+Но если фоновая задача создает ошибку в БД, то, по крайней мере, можно сделать откат или чисто закрыть сессию в зависимости с помощью `yield`, а также, возможно, занести ошибку в журнал или сообщить о ней в удаленную систему отслеживания.
+
+Если у вас есть код, который, как вы знаете, может вызвать исключение, сделайте самую обычную/"питонячью" вещь и добавьте блок `try` в этот участок кода.
+
+Если у вас есть пользовательские исключения, которые вы хотите обрабатывать *до* возврата ответа и, возможно, модифицировать ответ, даже вызывая `HTTPException`, создайте [Cобственный обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+
+/// tip | Подсказка
+
+Вы все еще можете вызывать исключения, включая `HTTPException`, *до* `yield`. Но не после.
+
+///
+
+Последовательность выполнения примерно такая, как на этой схеме. Время течет сверху вниз. А каждый столбец - это одна из частей, взаимодействующих с кодом или выполняющих код.
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant handler as Exception handler
+participant dep as Dep with yield
+participant operation as Path Operation
+participant tasks as Background tasks
+
+ Note over client,tasks: Can raise exception for dependency, handled after response is sent
+ Note over client,operation: Can raise HTTPException and can change the response
+ client ->> dep: Start request
+ Note over dep: Run code up to yield
+ opt raise
+ dep -->> handler: Raise HTTPException
+ handler -->> client: HTTP error response
+ dep -->> dep: Raise other exception
+ end
+ dep ->> operation: Run dependency, e.g. DB session
+ opt raise
+ operation -->> dep: Raise HTTPException
+ dep -->> handler: Auto forward exception
+ handler -->> client: HTTP error response
+ operation -->> dep: Raise other exception
+ dep -->> handler: Auto forward exception
+ end
+ operation ->> client: Return response to client
+ Note over client,operation: Response is already sent, can't change it anymore
+ opt Tasks
+ operation -->> tasks: Send background tasks
+ end
+ opt Raise other exception
+ tasks -->> dep: Raise other exception
+ end
+ Note over dep: After yield
+ opt Handle other exception
+ dep -->> dep: Handle exception, can't change response. E.g. close DB session.
+ end
+```
+
+/// info | Дополнительная информация
+
+Клиенту будет отправлен только **один ответ**. Это может быть один из ответов об ошибке или это будет ответ от *операции пути*.
+
+После отправки одного из этих ответов никакой другой ответ не может быть отправлен.
+
+///
+
+/// tip | Подсказка
+
+На этой диаграмме показано "HttpException", но вы также можете вызвать любое другое исключение, для которого вы создаете [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+
+Если вы создадите какое-либо исключение, оно будет передано зависимостям с yield, включая `HttpException`, а затем **снова** обработчикам исключений. Если для этого исключения нет обработчика исключений, то оно будет обработано внутренним "ServerErrorMiddleware" по умолчанию, возвращающим код состояния HTTP 500, чтобы уведомить клиента, что на сервере произошла ошибка.
+
+///
+
+## Зависимости с `yield`, `HTTPException` и фоновыми задачами
+
+/// warning | Внимание
+
+Скорее всего, вам не нужны эти технические подробности, вы можете пропустить этот раздел и продолжить ниже.
+
+Эти подробности полезны, главным образом, если вы использовали версию FastAPI до 0.106.0 и использовали ресурсы из зависимостей с `yield` в фоновых задачах.
+
+///
+
+До версии FastAPI 0.106.0 вызывать исключения после `yield` было невозможно, код выхода в зависимостях с `yield` выполнялся *после* отправки ответа, поэтому [Обработчик Ошибок](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} уже был бы запущен.
+
+Это было сделано главным образом для того, чтобы позволить использовать те же объекты, "отданные" зависимостями, внутри фоновых задач, поскольку код выхода будет выполняться после завершения фоновых задач.
+
+Тем не менее, поскольку это означало бы ожидание ответа в сети, а также ненужное удержание ресурса в зависимости от доходности (например, соединение с базой данных), это было изменено в FastAPI 0.106.0.
+
+/// tip | Подсказка
+
+Кроме того, фоновая задача обычно представляет собой независимый набор логики, который должен обрабатываться отдельно, со своими собственными ресурсами (например, собственным подключением к базе данных).
+Таким образом, вы, вероятно, получите более чистый код.
+
+///
+
+Если вы полагались на это поведение, то теперь вам следует создавать ресурсы для фоновых задач внутри самой фоновой задачи, а внутри использовать только те данные, которые не зависят от ресурсов зависимостей с `yield`.
+
+Например, вместо того чтобы использовать ту же сессию базы данных, вы создадите новую сессию базы данных внутри фоновой задачи и будете получать объекты из базы данных с помощью этой новой сессии. А затем, вместо того чтобы передавать объект из базы данных в качестве параметра в функцию фоновой задачи, вы передадите идентификатор этого объекта, а затем снова получите объект в функции фоновой задачи.
+
+## Контекстные менеджеры
+
+### Что такое "контекстные менеджеры"
+
+"Контекстные менеджеры" - это любые объекты Python, которые можно использовать в операторе `with`.
+
+Например,
можно использовать `with` для чтения файла:
+
+```Python
+with open("./somefile.txt") as f:
+ contents = f.read()
+ print(contents)
+```
+
+Под капотом" open("./somefile.txt") создаёт объект называемый "контекстным менеджером".
+
+Когда блок `with` завершается, он обязательно закрывает файл, даже если были исключения.
+
+Когда вы создаете зависимость с помощью `yield`, **FastAPI** внутренне преобразует ее в контекстный менеджер и объединяет с некоторыми другими связанными инструментами.
+
+### Использование менеджеров контекста в зависимостях с помощью `yield`
+
+/// warning | Внимание
+
+Это более или менее "продвинутая" идея.
+
+Если вы только начинаете работать с **FastAPI**, то лучше пока пропустить этот пункт.
+
+///
+
+В Python для создания менеджеров контекста можно
создать класс с двумя методами: `__enter__()` и `__exit__()`.
+
+Вы также можете использовать их внутри зависимостей **FastAPI** с `yield`, используя операторы
+`with` или `async with` внутри функции зависимости:
+
+{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
+
+/// tip | Подсказка
+
+Другой способ создания контекстного менеджера - с помощью:
+
+*
`@contextlib.contextmanager` или
+*
`@contextlib.asynccontextmanager`
+
+используйте их для оформления функции с одним `yield`.
+
+Это то, что **FastAPI** использует внутри себя для зависимостей с `yield`.
+
+Но использовать декораторы для зависимостей FastAPI не обязательно (да и не стоит).
+
+FastAPI сделает это за вас на внутреннем уровне.
+
+///
diff --git a/docs/ru/docs/tutorial/dependencies/global-dependencies.md b/docs/ru/docs/tutorial/dependencies/global-dependencies.md
new file mode 100644
index 000000000..5d2e70f6e
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/global-dependencies.md
@@ -0,0 +1,15 @@
+# Глобальные зависимости
+
+Для некоторых типов приложений может потребоваться добавить зависимости ко всему приложению.
+
+Подобно тому, как вы можете [добавлять зависимости через параметр `dependencies` в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, вы можете добавлять зависимости сразу ко всему `FastAPI` приложению.
+
+В этом случае они будут применяться ко всем *операциям пути* в приложении:
+
+{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
+
+Все способы [добавления зависимостей в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} по-прежнему применимы, но в данном случае зависимости применяются ко всем *операциям пути* приложения.
+
+## Зависимости для групп *операций пути*
+
+Позднее, читая о том, как структурировать более крупные [приложения, содержащие много файлов](../../tutorial/bigger-applications.md){.internal-link target=_blank}, вы узнаете, как объявить один параметр dependencies для целой группы *операций пути*.
diff --git a/docs/ru/docs/tutorial/dependencies/index.md b/docs/ru/docs/tutorial/dependencies/index.md
new file mode 100644
index 000000000..28790bd5a
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/index.md
@@ -0,0 +1,244 @@
+# Зависимости
+
+**FastAPI** имеет очень мощную и интуитивную систему **
Dependency Injection**.
+
+Она проектировалась таким образом, чтобы быть простой в использовании и облегчить любому разработчику интеграцию других компонентов с **FastAPI**.
+
+## Что такое "Dependency Injection" (инъекция зависимости)
+
+**"Dependency Injection"** в программировании означает, что у вашего кода (в данном случае, вашей *функции обработки пути*) есть способы объявить вещи, которые запрашиваются для работы и использования: "зависимости".
+
+И потом эта система (в нашем случае **FastAPI**) организует всё, что требуется, чтобы обеспечить ваш код этой зависимостью (сделать "инъекцию" зависимости).
+
+Это очень полезно, когда вам нужно:
+
+* Обеспечить общую логику (один и тот же алгоритм снова и снова).
+* Общее соединение с базой данных.
+* Обеспечение безопасности, аутентификации, запроса роли и т.п.
+* И многое другое.
+
+Всё это минимизирует повторение кода.
+
+## Первые шаги
+
+Давайте рассмотрим очень простой пример. Он настолько простой, что на данный момент почти бесполезный.
+
+Но таким способом мы можем сфокусироваться на том, как же всё таки работает система **Dependency Injection**.
+
+### Создание зависимости или "зависимого"
+Давайте для начала сфокусируемся на зависимостях.
+
+Это просто функция, которая может принимать все те же параметры, что и *функции обработки пути*:
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *}
+
+**И всё.**
+
+**2 строки.**
+
+И теперь она той же формы и структуры, что и все ваши *функции обработки пути*.
+
+Вы можете думать об *функции обработки пути* как о функции без "декоратора" (без `@app.get("/some-path")`).
+
+И она может возвращать всё, что требуется.
+
+В этом случае, эта зависимость ожидает:
+
+* Необязательный query-параметр `q` с типом `str`
+* Необязательный query-параметр `skip` с типом `int`, и значением по умолчанию `0`
+* Необязательный query-параметр `limit` с типом `int`, и значением по умолчанию `100`
+
+И в конце она возвращает `dict`, содержащий эти значения.
+
+/// info | Информация
+
+**FastAPI** добавил поддержку для `Annotated` (и начал её рекомендовать) в версии 0.95.0.
+
+ Если у вас более старая версия, будут ошибки при попытке использовать `Annotated`.
+
+Убедитесь, что вы [Обновили FastAPI версию](../../deployment/versions.md#fastapi_2){.internal-link target=_blank} до, как минимум 0.95.1, перед тем как использовать `Annotated`.
+
+///
+
+### Import `Depends`
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *}
+
+### Объявите зависимость в "зависимом"
+
+Точно так же, как вы использовали `Body`, `Query` и т.д. с вашей *функцией обработки пути* для параметров, используйте `Depends` с новым параметром:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
+
+`Depends` работает немного иначе. Вы передаёте в `Depends` одиночный параметр, который будет похож на функцию.
+
+Вы **не вызываете его** на месте (не добавляете скобочки в конце: 👎 *your_best_func()*👎), просто передаёте как параметр в `Depends()`.
+
+И потом функция берёт параметры так же, как *функция обработки пути*.
+
+/// tip | Подсказка
+
+В следующей главе вы увидите, какие другие вещи, помимо функций, можно использовать в качестве зависимостей.
+
+///
+
+Каждый раз, когда новый запрос приходит, **FastAPI** позаботится о:
+
+* Вызове вашей зависимости ("зависимого") функции с корректными параметрами.
+* Получении результата из вашей функции.
+* Назначении результата в параметр в вашей *функции обработки пути*.
+
+```mermaid
+graph TB
+
+common_parameters(["common_parameters"])
+read_items["/items/"]
+read_users["/users/"]
+
+common_parameters --> read_items
+common_parameters --> read_users
+```
+
+Таким образом, вы пишете общий код один раз, и **FastAPI** позаботится о его вызове для ваших *операций с путями*.
+
+/// check | Проверка
+
+Обратите внимание, что вы не создаёте специальный класс и не передаёте его куда-то в **FastAPI** для регистрации, или что-то в этом роде.
+
+Вы просто передаёте это в `Depends`, и **FastAPI** знает, что делать дальше.
+
+///
+
+## Объединяем с `Annotated` зависимостями
+
+В приведенном выше примере есть небольшое **повторение кода**.
+
+Когда вам нужно использовать `common_parameters()` зависимость, вы должны написать весь параметр с аннотацией типов и `Depends()`:
+
+```Python
+commons: Annotated[dict, Depends(common_parameters)]
+```
+
+Но потому что мы используем `Annotated`, мы можем хранить `Annotated` значение в переменной и использовать его в нескольких местах:
+
+{* ../../docs_src/dependencies/tutorial001_02_an_py310.py hl[12,16,21] *}
+
+/// tip | Подсказка
+
+Это стандартный синтаксис python и называется "type alias", это не особенность **FastAPI**.
+
+Но потому что **FastAPI** базируется на стандартах Python, включая `Annotated`, вы можете использовать этот трюк в вашем коде. 😎
+
+///
+
+Зависимости продолжат работу как ожидалось, и **лучшая часть** в том, что **информация о типе будет сохранена**. Это означает, что ваш редактор кода будет корректно обрабатывать **автодополнения**, **встроенные ошибки** и так далее. То же самое относится и к инструментам, таким как `mypy`.
+
+Это очень полезно, когда вы интегрируете это в **большую кодовую базу**, используя **одинаковые зависимости** снова и снова во **многих** ***операциях пути***.
+
+## Использовать `async` или не `async`
+
+Для зависимостей, вызванных **FastAPI** (то же самое, что и ваши *функции обработки пути*), те же правила, что приняты для определения ваших функций.
+
+Вы можете использовать `async def` или обычное `def`.
+
+Вы также можете объявить зависимости с `async def` внутри обычной `def` *функции обработки пути*, или `def` зависимости внутри `async def` *функции обработки пути*, и так далее.
+
+Это всё не важно. **FastAPI** знает, что нужно сделать. 😎
+
+/// note | Информация
+
+Если вам эта тема не знакома, прочтите [Async: *"In a hurry?"*](../../async.md){.internal-link target=_blank} раздел о `async` и `await` в документации.
+
+///
+
+## Интеграция с OpenAPI
+
+Все заявления о запросах, валидаторы, требования ваших зависимостей (и подзависимостей) будут интегрированы в соответствующую OpenAPI-схему.
+
+В интерактивной документации будет вся информация по этим зависимостям тоже:
+
+

+
+## Простое использование
+
+Если вы посмотрите на фото, *функция обработки пути* объявляется каждый раз, когда вычисляется путь, и тогда **FastAPI** позаботится о вызове функции с корректными параметрами, извлекая информацию из запроса.
+
+На самом деле, все (или большинство) веб-фреймворков работают по схожему сценарию.
+
+Вы никогда не вызываете эти функции на месте. Их вызовет ваш фреймворк (в нашем случае, **FastAPI**).
+
+С системой Dependency Injection, вы можете сообщить **FastAPI**, что ваша *функция обработки пути* "зависит" от чего-то ещё, что должно быть извлечено перед вашей *функцией обработки пути*, и **FastAPI** позаботится об извлечении и инъекции результата.
+
+Другие распространённые термины для описания схожей идеи "dependency injection" являются:
+
+- ресурсность
+- доставка
+- сервисность
+- инъекция
+- компонентность
+
+## **FastAPI** подключаемые модули
+
+Инъекции и модули могут быть построены с использованием системы **Dependency Injection**. Но на самом деле, **нет необходимости создавать новые модули**, просто используя зависимости, можно объявить бесконечное количество интеграций и взаимодействий, которые доступны вашей *функции обработки пути*.
+
+И зависимости могут быть созданы очень простым и интуитивным способом, что позволяет вам просто импортировать нужные пакеты Python и интегрировать их в API функции за пару строк.
+
+Вы увидите примеры этого в следующих главах о реляционных и NoSQL базах данных, безопасности и т.д.
+
+## Совместимость с **FastAPI**
+
+Простота Dependency Injection делает **FastAPI** совместимым с:
+
+- всеми реляционными базами данных
+- NoSQL базами данных
+- внешними пакетами
+- внешними API
+- системами авторизации, аутентификации
+- системами мониторинга использования API
+- системами ввода данных ответов
+- и так далее.
+
+## Просто и сильно
+
+Хотя иерархическая система Dependency Injection очень проста для описания и использования, она по-прежнему очень мощная.
+
+Вы можете описывать зависимости в очередь, и они уже будут вызываться друг за другом.
+
+Когда иерархическое дерево построено, система **Dependency Injection** берет на себя решение всех зависимостей для вас (и их подзависимостей) и обеспечивает (инъектирует) результат на каждом шаге.
+
+Например, у вас есть 4 API-эндпоинта (*операции пути*):
+
+- `/items/public/`
+- `/items/private/`
+- `/users/{user_id}/activate`
+- `/items/pro/`
+
+Тогда вы можете требовать разные права для каждого из них, используя зависимости и подзависимости:
+
+```mermaid
+graph TB
+
+current_user(["current_user"])
+active_user(["active_user"])
+admin_user(["admin_user"])
+paying_user(["paying_user"])
+
+public["/items/public/"]
+private["/items/private/"]
+activate_user["/users/{user_id}/activate"]
+pro_items["/items/pro/"]
+
+current_user --> active_user
+active_user --> admin_user
+active_user --> paying_user
+
+current_user --> public
+active_user --> private
+admin_user --> activate_user
+paying_user --> pro_items
+```
+
+## Интегрировано с **OpenAPI**
+
+Все эти зависимости, объявляя свои требования, также добавляют параметры, проверки и т.д. к вашим операциям *path*.
+
+**FastAPI** позаботится о добавлении всего этого в схему открытого API, чтобы это отображалось в системах интерактивной документации.
diff --git a/docs/ru/docs/tutorial/dependencies/sub-dependencies.md b/docs/ru/docs/tutorial/dependencies/sub-dependencies.md
new file mode 100644
index 000000000..5e8de0c4a
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/sub-dependencies.md
@@ -0,0 +1,105 @@
+# Подзависимости
+
+Вы можете создавать зависимости, которые имеют **подзависимости**.
+
+Их **вложенность** может быть любой глубины.
+
+**FastAPI** сам займётся их управлением.
+
+## Провайдер зависимости
+
+Можно создать первую зависимость следующим образом:
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
+
+Она объявляет необязательный параметр запроса `q` как строку, а затем возвращает его.
+
+Это довольно просто (хотя и не очень полезно), но поможет нам сосредоточиться на том, как работают подзависимости.
+
+## Вторая зависимость
+
+Затем можно создать еще одну функцию зависимости, которая в то же время содержит внутри себя первую зависимость (таким образом, она тоже является "зависимой"):
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
+
+Остановимся на объявленных параметрах:
+
+* Несмотря на то, что эта функция сама является зависимостью, она также является зависимой от чего-то другого.
+ * Она зависит от `query_extractor` и присваивает возвращаемое ей значение параметру `q`.
+* Она также объявляет необязательный куки-параметр `last_query` в виде строки.
+ * Если пользователь не указал параметр `q` в запросе, то мы используем последний использованный запрос, который мы ранее сохранили в куки-параметре `last_query`.
+
+## Использование зависимости
+
+Затем мы можем использовать зависимость вместе с:
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
+
+/// info | Дополнительная информация
+
+Обратите внимание, что мы объявляем только одну зависимость в *функции операции пути* - `query_or_cookie_extractor`.
+
+Но **FastAPI** будет знать, что сначала он должен выполнить `query_extractor`, чтобы передать результаты этого в `query_or_cookie_extractor` при его вызове.
+
+///
+
+```mermaid
+graph TB
+
+query_extractor(["query_extractor"])
+query_or_cookie_extractor(["query_or_cookie_extractor"])
+
+read_query["/items/"]
+
+query_extractor --> query_or_cookie_extractor --> read_query
+```
+
+## Использование одной и той же зависимости несколько раз
+
+Если одна из ваших зависимостей объявлена несколько раз для одной и той же *функции операции пути*, например, несколько зависимостей имеют общую подзависимость, **FastAPI** будет знать, что вызывать эту подзависимость нужно только один раз за запрос.
+
+При этом возвращаемое значение будет сохранено в
"кэш" и будет передано всем "зависимым" функциям, которые нуждаются в нем внутри этого конкретного запроса, вместо того, чтобы вызывать зависимость несколько раз для одного и того же запроса.
+
+В расширенном сценарии, когда вы знаете, что вам нужно, чтобы зависимость вызывалась на каждом шаге (возможно, несколько раз) в одном и том же запросе, вместо использования "кэшированного" значения, вы можете установить параметр `use_cache=False` при использовании `Depends`:
+
+//// tab | Python 3.6+
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
+ return {"fresh_value": fresh_value}
+```
+
+////
+
+//// tab | Python 3.6+ без Annotated
+
+/// tip | Подсказка
+
+Предпочтительнее использовать версию с аннотацией, если это возможно.
+
+///
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
+ return {"fresh_value": fresh_value}
+```
+
+////
+
+## Резюме
+
+Помимо всех этих умных слов, используемых здесь, система внедрения зависимостей довольно проста.
+
+Это просто функции, которые выглядят так же, как *функции операций путей*.
+
+Но, тем не менее, эта система очень мощная и позволяет вам объявлять вложенные графы (деревья) зависимостей сколь угодно глубоко.
+
+/// tip | Подсказка
+
+Все это может показаться не столь полезным на этих простых примерах.
+
+Но вы увидите как это пригодится в главах посвященных безопасности.
+
+И вы также увидите, сколько кода это вам сэкономит.
+
+///
diff --git a/docs/ru/docs/tutorial/encoder.md b/docs/ru/docs/tutorial/encoder.md
new file mode 100644
index 000000000..4ed5039b3
--- /dev/null
+++ b/docs/ru/docs/tutorial/encoder.md
@@ -0,0 +1,35 @@
+# JSON кодировщик
+
+В некоторых случаях может потребоваться преобразование типа данных (например, Pydantic-модели) в тип, совместимый с JSON (например, `dict`, `list` и т.д.).
+
+Например, если необходимо хранить его в базе данных.
+
+Для этого **FastAPI** предоставляет функцию `jsonable_encoder()`.
+
+## Использование `jsonable_encoder`
+
+Представим, что у вас есть база данных `fake_db`, которая принимает только JSON-совместимые данные.
+
+Например, он не принимает объекты `datetime`, так как они не совместимы с JSON.
+
+В таком случае объект `datetime` следует преобразовать в строку соответствующую
формату ISO.
+
+Точно так же эта база данных не может принять Pydantic модель (объект с атрибутами), а только `dict`.
+
+Для этого можно использовать функцию `jsonable_encoder`.
+
+Она принимает объект, например, модель Pydantic, и возвращает его версию, совместимую с JSON:
+
+{* ../../docs_src/encoder/tutorial001_py310.py hl[4,21] *}
+
+В данном примере она преобразует Pydantic модель в `dict`, а `datetime` - в `str`.
+
+Результатом её вызова является объект, который может быть закодирован с помощью функции из стандартной библиотеки Python –
`json.dumps()`.
+
+Функция не возвращает большой `str`, содержащий данные в формате JSON (в виде строки). Она возвращает стандартную структуру данных Python (например, `dict`) со значениями и подзначениями, которые совместимы с JSON.
+
+/// note | Технические детали
+
+`jsonable_encoder` фактически используется **FastAPI** внутри системы для преобразования данных. Однако он полезен и во многих других сценариях.
+
+///
diff --git a/docs/ru/docs/tutorial/extra-data-types.md b/docs/ru/docs/tutorial/extra-data-types.md
new file mode 100644
index 000000000..6d6d4aa9f
--- /dev/null
+++ b/docs/ru/docs/tutorial/extra-data-types.md
@@ -0,0 +1,62 @@
+# Дополнительные типы данных
+
+До сих пор вы использовали простые типы данных, такие как:
+
+* `int`
+* `float`
+* `str`
+* `bool`
+
+Но вы также можете использовать и более сложные типы.
+
+При этом у вас останутся те же возможности , что и до сих пор:
+
+* Отличная поддержка редактора.
+* Преобразование данных из входящих запросов.
+* Преобразование данных для ответа.
+* Валидация данных.
+* Автоматическая аннотация и документация.
+
+## Другие типы данных
+
+Ниже перечислены некоторые из дополнительных типов данных, которые вы можете использовать:
+
+* `UUID`:
+ * Стандартный "Универсальный уникальный идентификатор", используемый в качестве идентификатора во многих базах данных и системах.
+ * В запросах и ответах будет представлен как `str`.
+* `datetime.datetime`:
+ * Встроенный в Python `datetime.datetime`.
+ * В запросах и ответах будет представлен как `str` в формате ISO 8601, например: `2008-09-15T15:53:00+05:00`.
+* `datetime.date`:
+ * Встроенный в Python `datetime.date`.
+ * В запросах и ответах будет представлен как `str` в формате ISO 8601, например: `2008-09-15`.
+* `datetime.time`:
+ * Встроенный в Python `datetime.time`.
+ * В запросах и ответах будет представлен как `str` в формате ISO 8601, например: `14:23:55.003`.
+* `datetime.timedelta`:
+ * Встроенный в Python `datetime.timedelta`.
+ * В запросах и ответах будет представлен в виде общего количества секунд типа `float`.
+ * Pydantic также позволяет представить его как "Кодировку разницы во времени ISO 8601",
см. документацию для получения дополнительной информации.
+* `frozenset`:
+ * В запросах и ответах обрабатывается так же, как и `set`:
+ * В запросах будет прочитан список, исключены дубликаты и преобразован в `set`.
+ * В ответах `set` будет преобразован в `list`.
+ * В сгенерированной схеме будет указано, что значения `set` уникальны (с помощью JSON-схемы `uniqueItems`).
+* `bytes`:
+ * Встроенный в Python `bytes`.
+ * В запросах и ответах будет рассматриваться как `str`.
+ * В сгенерированной схеме будет указано, что это `str` в формате `binary`.
+* `Decimal`:
+ * Встроенный в Python `Decimal`.
+ * В запросах и ответах обрабатывается так же, как и `float`.
+* Вы можете проверить все допустимые типы данных pydantic здесь:
Типы данных Pydantic.
+
+## Пример
+
+Вот пример *операции пути* с параметрами, который демонстрирует некоторые из вышеперечисленных типов.
+
+{* ../../docs_src/extra_data_types/tutorial001.py hl[1,3,12:16] *}
+
+Обратите внимание, что параметры внутри функции имеют свой естественный тип данных, и вы, например, можете выполнять обычные манипуляции с датами, такие как:
+
+{* ../../docs_src/extra_data_types/tutorial001.py hl[18:19] *}
diff --git a/docs/ru/docs/tutorial/extra-models.md b/docs/ru/docs/tutorial/extra-models.md
new file mode 100644
index 000000000..5b51aa402
--- /dev/null
+++ b/docs/ru/docs/tutorial/extra-models.md
@@ -0,0 +1,211 @@
+# Дополнительные модели
+
+В продолжение прошлого примера будет уже обычным делом иметь несколько связанных между собой моделей.
+
+Это особенно применимо в случае моделей пользователя, потому что:
+
+* **Модель для ввода** должна иметь возможность содержать пароль.
+* **Модель для вывода** не должна содержать пароль.
+* **Модель для базы данных**, возможно, должна содержать хэшированный пароль.
+
+/// danger | Внимание
+
+Никогда не храните пароли пользователей в чистом виде. Всегда храните "безопасный хэш", который вы затем сможете проверить.
+
+Если вам это не знакомо, вы можете узнать про "хэш пароля" в [главах о безопасности](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
+
+///
+
+## Множественные модели
+
+Ниже изложена основная идея того, как могут выглядеть эти модели с полями для паролей, а также описаны места, где они используются:
+
+{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
+
+### Про `**user_in.dict()`
+
+#### `.dict()` из Pydantic
+
+`user_in` - это Pydantic-модель класса `UserIn`.
+
+У Pydantic-моделей есть метод `.dict()`, который возвращает `dict` с данными модели.
+
+Поэтому, если мы создадим Pydantic-объект `user_in` таким способом:
+
+```Python
+user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
+```
+
+и затем вызовем:
+
+```Python
+user_dict = user_in.dict()
+```
+
+то теперь у нас есть `dict` с данными модели в переменной `user_dict` (это `dict` вместо объекта Pydantic-модели).
+
+И если мы вызовем:
+
+```Python
+print(user_dict)
+```
+
+мы можем получить `dict` с такими данными:
+
+```Python
+{
+ 'username': 'john',
+ 'password': 'secret',
+ 'email': 'john.doe@example.com',
+ 'full_name': None,
+}
+```
+
+#### Распаковка `dict`
+
+Если мы возьмём `dict` наподобие `user_dict` и передадим его в функцию (или класс), используя `**user_dict`, Python распакует его. Он передаст ключи и значения `user_dict` напрямую как аргументы типа ключ-значение.
+
+Поэтому, продолжая описанный выше пример с `user_dict`, написание такого кода:
+
+```Python
+UserInDB(**user_dict)
+```
+
+Будет работать так же, как примерно такой код:
+
+```Python
+UserInDB(
+ username="john",
+ password="secret",
+ email="john.doe@example.com",
+ full_name=None,
+)
+```
+
+Или, если для большей точности мы напрямую используем `user_dict` с любым потенциальным содержимым, то этот пример будет выглядеть так:
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ password = user_dict["password"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+)
+```
+
+#### Pydantic-модель из содержимого другой модели
+
+Как в примере выше мы получили `user_dict` из `user_in.dict()`, этот код:
+
+```Python
+user_dict = user_in.dict()
+UserInDB(**user_dict)
+```
+
+будет равнозначен такому:
+
+```Python
+UserInDB(**user_in.dict())
+```
+
+...потому что `user_in.dict()` - это `dict`, и затем мы указываем, чтобы Python его "распаковал", когда передаём его в `UserInDB` и ставим перед ним `**`.
+
+Таким образом мы получаем Pydantic-модель на основе данных из другой Pydantic-модели.
+
+#### Распаковка `dict` и дополнительные именованные аргументы
+
+И затем, если мы добавим дополнительный именованный аргумент `hashed_password=hashed_password` как здесь:
+
+```Python
+UserInDB(**user_in.dict(), hashed_password=hashed_password)
+```
+
+... то мы получим что-то подобное:
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ password = user_dict["password"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+ hashed_password = hashed_password,
+)
+```
+
+/// warning | Предупреждение
+
+Цель использованных в примере вспомогательных функций - не более чем демонстрация возможных операций с данными, но, конечно, они не обеспечивают настоящую безопасность.
+
+///
+
+## Сократите дублирование
+
+Сокращение дублирования кода - это одна из главных идей **FastAPI**.
+
+Поскольку дублирование кода повышает риск появления багов, проблем с безопасностью, проблем десинхронизации кода (когда вы обновляете код в одном месте, но не обновляете в другом), и т.д.
+
+А все описанные выше модели используют много общих данных и дублируют названия атрибутов и типов.
+
+Мы можем это улучшить.
+
+Мы можем определить модель `UserBase`, которая будет базовой для остальных моделей. И затем мы можем создать подклассы этой модели, которые будут наследовать её атрибуты (объявления типов, валидацию, и т.п.).
+
+Все операции конвертации, валидации, документации, и т.п. будут по-прежнему работать нормально.
+
+В этом случае мы можем определить только различия между моделями (с `password` в чистом виде, с `hashed_password` и без пароля):
+
+{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
+
+## `Union` или `anyOf`
+
+Вы можете определить ответ как `Union` из двух типов. Это означает, что ответ должен соответствовать одному из них.
+
+Он будет определён в OpenAPI как `anyOf`.
+
+Для этого используйте стандартные аннотации типов в Python
`typing.Union`:
+
+/// note | Примечание
+
+При объявлении
`Union`, сначала указывайте наиболее детальные типы, затем менее детальные. В примере ниже более детальный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
+
+///
+
+{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
+
+### `Union` в Python 3.10
+
+В этом примере мы передаём `Union[PlaneItem, CarItem]` в качестве значения аргумента `response_model`.
+
+Поскольку мы передаём его как **значение аргумента** вместо того, чтобы поместить его в **аннотацию типа**, нам придётся использовать `Union` даже в Python 3.10.
+
+Если оно было бы указано в аннотации типа, то мы могли бы использовать вертикальную черту как в примере:
+
+```Python
+some_variable: PlaneItem | CarItem
+```
+
+Но если мы помещаем его в `response_model=PlaneItem | CarItem` мы получим ошибку, потому что Python попытается произвести **некорректную операцию** между `PlaneItem` и `CarItem` вместо того, чтобы интерпретировать это как аннотацию типа.
+
+## Список моделей
+
+Таким же образом вы можете определять ответы как списки объектов.
+
+Для этого используйте `typing.List` из стандартной библиотеки Python (или просто `list` в Python 3.9 и выше):
+
+{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
+
+## Ответ с произвольным `dict`
+
+Вы также можете определить ответ, используя произвольный одноуровневый `dict` и определяя только типы ключей и значений без использования Pydantic-моделей.
+
+Это полезно, если вы заранее не знаете корректных названий полей/атрибутов (которые будут нужны при использовании Pydantic-модели).
+
+В этом случае вы можете использовать `typing.Dict` (или просто `dict` в Python 3.9 и выше):
+
+{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
+
+## Резюме
+
+Используйте несколько Pydantic-моделей и свободно применяйте наследование для каждой из них.
+
+Вам не обязательно иметь единственную модель данных для каждой сущности, если эта сущность должна иметь возможность быть в разных "состояниях". Как в случае с "сущностью" пользователя, у которого есть состояния с полями `password`, `password_hash` и без пароля.
diff --git a/docs/ru/docs/tutorial/first-steps.md b/docs/ru/docs/tutorial/first-steps.md
new file mode 100644
index 000000000..cb3d19a71
--- /dev/null
+++ b/docs/ru/docs/tutorial/first-steps.md
@@ -0,0 +1,335 @@
+# Первые шаги
+
+Самый простой FastAPI файл может выглядеть так:
+
+{* ../../docs_src/first_steps/tutorial001.py *}
+
+Скопируйте в файл `main.py`.
+
+Запустите сервер в режиме реального времени:
+
+
+
+```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.
+```
+
+
+
+/// note | Технические детали
+
+Команда `uvicorn main:app` обращается к:
+
+* `main`: файл `main.py` (модуль Python).
+* `app`: объект, созданный внутри файла `main.py` в строке `app = FastAPI()`.
+* `--reload`: перезапускает сервер после изменения кода. Используйте только для разработки.
+
+///
+
+В окне вывода появится следующая строка:
+
+```hl_lines="4"
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+Эта строка показывает URL-адрес, по которому приложение доступно на локальной машине.
+
+### Проверьте
+
+Откройте браузер по адресу:
http://127.0.0.1:8000.
+
+Вы увидите JSON-ответ следующего вида:
+
+```JSON
+{"message": "Hello World"}
+```
+
+### Интерактивная документация API
+
+Перейдите по адресу:
http://127.0.0.1:8000/docs.
+
+Вы увидите автоматически сгенерированную, интерактивную документацию по API (предоставленную
Swagger UI):
+
+
+
+### Альтернативная документация API
+
+Теперь перейдите по адресу
http://127.0.0.1:8000/redoc.
+
+Вы увидите альтернативную автоматически сгенерированную документацию (предоставленную
ReDoc):
+
+
+
+### OpenAPI
+
+**FastAPI** генерирует "схему" всего API, используя стандарт **OpenAPI**.
+
+#### "Схема"
+
+"Схема" - это определение или описание чего-либо. Не код, реализующий это, а только абстрактное описание.
+
+#### API "схема"
+
+
OpenAPI - это спецификация, которая определяет, как описывать схему API.
+
+Определение схемы содержит пути (paths) API, их параметры и т.п.
+
+#### "Схема" данных
+
+Термин "схема" также может относиться к формату или структуре некоторых данных, например, JSON.
+
+Тогда, подразумеваются атрибуты JSON, их типы данных и т.п.
+
+#### OpenAPI и JSON Schema
+
+OpenAPI описывает схему API. Эта схема содержит определения (или "схемы") данных, отправляемых и получаемых API. Для описания структуры данных в JSON используется стандарт **JSON Schema**.
+
+#### Рассмотрим `openapi.json`
+
+Если Вас интересует, как выглядит исходная схема OpenAPI, то FastAPI автоматически генерирует JSON-схему со всеми описаниями API.
+
+Можете посмотреть здесь:
http://127.0.0.1:8000/openapi.json.
+
+Вы увидите примерно такой JSON:
+
+```JSON
+{
+ "openapi": "3.0.2",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+
+
+
+...
+```
+
+#### Для чего нужен OpenAPI
+
+Схема OpenAPI является основой для обеих систем интерактивной документации.
+
+Существуют десятки альтернативных инструментов, основанных на OpenAPI. Вы можете легко добавить любой из них к **FastAPI** приложению.
+
+Вы также можете использовать OpenAPI для автоматической генерации кода для клиентов, которые взаимодействуют с API. Например, для фронтенд-, мобильных или IoT-приложений.
+
+## Рассмотрим поэтапно
+
+### Шаг 1: импортируйте `FastAPI`
+
+{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+
+`FastAPI` это класс в Python, который предоставляет всю функциональность для API.
+
+/// note | Технические детали
+
+`FastAPI` это класс, который наследуется непосредственно от `Starlette`.
+
+Вы можете использовать всю функциональность
Starlette в `FastAPI`.
+
+///
+
+### Шаг 2: создайте экземпляр `FastAPI`
+
+{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+
+Переменная `app` является экземпляром класса `FastAPI`.
+
+Это единая точка входа для создания и взаимодействия с API.
+
+Именно к этой переменной `app` обращается `uvicorn` в команде:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Если создать такое приложение:
+
+{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
+
+И поместить его в `main.py`, тогда вызов `uvicorn` будет таким:
+
+
+
+```console
+$ uvicorn main:my_awesome_api --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### Шаг 3: определите *операцию пути (path operation)*
+
+#### Путь (path)
+
+"Путь" это часть URL, после первого символа `/`, следующего за именем домена.
+
+Для URL:
+
+```
+https://example.com/items/foo
+```
+
+...путь выглядит так:
+
+```
+/items/foo
+```
+
+/// info | Дополнительная иформация
+
+Термин "path" также часто называется "endpoint" или "route".
+
+///
+
+При создании API, "путь" является основным способом разделения "задач" и "ресурсов".
+
+#### Операция (operation)
+
+"Операция" это один из "методов" HTTP.
+
+Таких, как:
+
+* `POST`
+* `GET`
+* `PUT`
+* `DELETE`
+
+...и более экзотических:
+
+* `OPTIONS`
+* `HEAD`
+* `PATCH`
+* `TRACE`
+
+По протоколу HTTP можно обращаться к каждому пути, используя один (или несколько) из этих "методов".
+
+---
+
+При создании API принято использовать конкретные HTTP-методы для выполнения определенных действий.
+
+Обычно используют:
+
+* `POST`: создать данные.
+* `GET`: прочитать.
+* `PUT`: изменить (обновить).
+* `DELETE`: удалить.
+
+В OpenAPI каждый HTTP метод называется "**операция**".
+
+Мы также будем придерживаться этого термина.
+
+#### Определите *декоратор операции пути (path operation decorator)*
+
+{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+
+Декоратор `@app.get("/")` указывает **FastAPI**, что функция, прямо под ним, отвечает за обработку запросов, поступающих по адресу:
+
+* путь `/`
+* использующих
get
операцию
+
+/// info | `@decorator` Дополнительная информация
+
+Синтаксис `@something` в Python называется "декоратор".
+
+Вы помещаете его над функцией. Как красивую декоративную шляпу (думаю, что оттуда и происходит этот термин).
+
+"Декоратор" принимает функцию ниже и выполняет с ней какое-то действие.
+
+В нашем случае, этот декоратор сообщает **FastAPI**, что функция ниже соответствует **пути** `/` и **операции** `get`.
+
+Это и есть "**декоратор операции пути**".
+
+///
+
+Можно также использовать операции:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+И более экзотические:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+/// tip | Подсказка
+
+Вы можете использовать каждую операцию (HTTP-метод) по своему усмотрению.
+
+**FastAPI** не навязывает определенного значения для каждого метода.
+
+Информация здесь представлена как рекомендация, а не требование.
+
+Например, при использовании GraphQL обычно все действия выполняются только с помощью POST операций.
+
+///
+
+### Шаг 4: определите **функцию операции пути**
+
+Вот "**функция операции пути**":
+
+* **путь**: `/`.
+* **операция**: `get`.
+* **функция**: функция ниже "декоратора" (ниже `@app.get("/")`).
+
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+
+Это обычная Python функция.
+
+**FastAPI** будет вызывать её каждый раз при получении `GET` запроса к URL "`/`".
+
+В данном случае это асинхронная функция.
+
+---
+
+Вы также можете определить ее как обычную функцию вместо `async def`:
+
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+
+/// note | Технические детали
+
+Если не знаете в чём разница, посмотрите [Конкурентность: *"Нет времени?"*](../async.md#_1){.internal-link target=_blank}.
+
+///
+
+### Шаг 5: верните результат
+
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+
+Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д.
+
+Также можно вернуть модели Pydantic (рассмотрим это позже).
+
+Многие объекты и модели будут автоматически преобразованы в JSON (включая ORM). Пробуйте использовать другие объекты, которые предпочтительней для Вас, вероятно, они уже поддерживаются.
+
+## Резюме
+
+* Импортируем `FastAPI`.
+* Создаём экземпляр `app`.
+* Пишем **декоратор операции пути** (такой как `@app.get("/")`).
+* Пишем **функцию операции пути** (`def root(): ...`).
+* Запускаем сервер в режиме разработки (`uvicorn main:app --reload`).
diff --git a/docs/ru/docs/tutorial/handling-errors.md b/docs/ru/docs/tutorial/handling-errors.md
new file mode 100644
index 000000000..c596abe1f
--- /dev/null
+++ b/docs/ru/docs/tutorial/handling-errors.md
@@ -0,0 +1,257 @@
+# Обработка ошибок
+
+Существует множество ситуаций, когда необходимо сообщить об ошибке клиенту, использующему ваш API.
+
+Таким клиентом может быть браузер с фронтендом, чужой код, IoT-устройство и т.д.
+
+Возможно, вам придется сообщить клиенту о следующем:
+
+* Клиент не имеет достаточных привилегий для выполнения данной операции.
+* Клиент не имеет доступа к данному ресурсу.
+* Элемент, к которому клиент пытался получить доступ, не существует.
+* и т.д.
+
+В таких случаях обычно возвращается **HTTP-код статуса ответа** в диапазоне **400** (от 400 до 499).
+
+Они похожи на двухсотые HTTP статус-коды (от 200 до 299), которые означают, что запрос обработан успешно.
+
+Четырёхсотые статус-коды означают, что ошибка произошла по вине клиента.
+
+Помните ли ошибки **"404 Not Found "** (и шутки) ?
+
+## Использование `HTTPException`
+
+Для возврата клиенту HTTP-ответов с ошибками используется `HTTPException`.
+
+### Импортируйте `HTTPException`
+
+{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+
+### Вызовите `HTTPException` в своем коде
+
+`HTTPException` - это обычное исключение Python с дополнительными данными, актуальными для API.
+
+Поскольку это исключение Python, то его не `возвращают`, а `вызывают`.
+
+Это также означает, что если вы находитесь внутри функции, которая вызывается внутри вашей *функции операции пути*, и вы поднимаете `HTTPException` внутри этой функции, то она не будет выполнять остальной код в *функции операции пути*, а сразу завершит запрос и отправит HTTP-ошибку из `HTTPException` клиенту.
+
+О том, насколько выгоднее `вызывать` исключение, чем `возвращать` значение, будет рассказано в разделе, посвященном зависимостям и безопасности.
+
+В данном примере, когда клиент запрашивает элемент по несуществующему ID, возникает исключение со статус-кодом `404`:
+
+{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+
+### Возвращаемый ответ
+
+Если клиент запросит `http://example.com/items/foo` (`item_id` `"foo"`), то он получит статус-код 200 и ответ в формате JSON:
+
+```JSON
+{
+ "item": "The Foo Wrestlers"
+}
+```
+
+Но если клиент запросит `http://example.com/items/bar` (несуществующий `item_id` `"bar"`), то он получит статус-код 404 (ошибка "не найдено") и JSON-ответ в виде:
+
+```JSON
+{
+ "detail": "Item not found"
+}
+```
+
+/// tip | Подсказка
+
+При вызове `HTTPException` в качестве параметра `detail` можно передавать любое значение, которое может быть преобразовано в JSON, а не только `str`.
+
+Вы можете передать `dict`, `list` и т.д.
+
+Они автоматически обрабатываются **FastAPI** и преобразуются в JSON.
+
+///
+
+## Добавление пользовательских заголовков
+
+В некоторых ситуациях полезно иметь возможность добавлять пользовательские заголовки к ошибке HTTP. Например, для некоторых типов безопасности.
+
+Скорее всего, вам не потребуется использовать его непосредственно в коде.
+
+Но в случае, если это необходимо для продвинутого сценария, можно добавить пользовательские заголовки:
+
+{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+
+## Установка пользовательских обработчиков исключений
+
+Вы можете добавить пользовательские обработчики исключений с помощью
то же самое исключение - утилиты от Starlette.
+
+Допустим, у вас есть пользовательское исключение `UnicornException`, которое вы (или используемая вами библиотека) можете `вызвать`.
+
+И вы хотите обрабатывать это исключение глобально с помощью FastAPI.
+
+Можно добавить собственный обработчик исключений с помощью `@app.exception_handler()`:
+
+{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
+
+Здесь, если запросить `/unicorns/yolo`, то *операция пути* вызовет `UnicornException`.
+
+Но оно будет обработано `unicorn_exception_handler`.
+
+Таким образом, вы получите чистую ошибку с кодом состояния HTTP `418` и содержимым JSON:
+
+```JSON
+{"message": "Oops! yolo did something. There goes a rainbow..."}
+```
+
+/// note | Технические детали
+
+Также можно использовать `from starlette.requests import Request` и `from starlette.responses import JSONResponse`.
+
+**FastAPI** предоставляет тот же `starlette.responses`, что и `fastapi.responses`, просто для удобства разработчика. Однако большинство доступных ответов поступает непосредственно из Starlette. То же самое касается и `Request`.
+
+///
+
+## Переопределение стандартных обработчиков исключений
+
+**FastAPI** имеет некоторые обработчики исключений по умолчанию.
+
+Эти обработчики отвечают за возврат стандартных JSON-ответов при `вызове` `HTTPException` и при наличии в запросе недопустимых данных.
+
+Вы можете переопределить эти обработчики исключений на свои собственные.
+
+### Переопределение исключений проверки запроса
+
+Когда запрос содержит недопустимые данные, **FastAPI** внутренне вызывает ошибку `RequestValidationError`.
+
+А также включает в себя обработчик исключений по умолчанию.
+
+Чтобы переопределить его, импортируйте `RequestValidationError` и используйте его с `@app.exception_handler(RequestValidationError)` для создания обработчика исключений.
+
+Обработчик исключения получит объект `Request` и исключение.
+
+{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
+
+Теперь, если перейти к `/items/foo`, то вместо стандартной JSON-ошибки с:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+вы получите текстовую версию:
+
+```
+1 validation error
+path -> item_id
+ value is not a valid integer (type=type_error.integer)
+```
+
+#### `RequestValidationError` или `ValidationError`
+
+/// warning | Внимание
+
+Это технические детали, которые можно пропустить, если они не важны для вас сейчас.
+
+///
+
+`RequestValidationError` является подклассом Pydantic
`ValidationError`.
+
+**FastAPI** использует его для того, чтобы, если вы используете Pydantic-модель в `response_model`, и ваши данные содержат ошибку, вы увидели ошибку в журнале.
+
+Но клиент/пользователь этого не увидит. Вместо этого клиент получит сообщение "Internal Server Error" с кодом состояния HTTP `500`.
+
+Так и должно быть, потому что если в вашем *ответе* или где-либо в вашем коде (не в *запросе* клиента) возникает Pydantic `ValidationError`, то это действительно ошибка в вашем коде.
+
+И пока вы не устраните ошибку, ваши клиенты/пользователи не должны иметь доступа к внутренней информации о ней, так как это может привести к уязвимости в системе безопасности.
+
+### Переопределите обработчик ошибок `HTTPException`
+
+Аналогичным образом можно переопределить обработчик `HTTPException`.
+
+Например, для этих ошибок можно вернуть обычный текстовый ответ вместо JSON:
+
+{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
+
+/// note | Технические детали
+
+Можно также использовать `from starlette.responses import PlainTextResponse`.
+
+**FastAPI** предоставляет тот же `starlette.responses`, что и `fastapi.responses`, просто для удобства разработчика. Однако большинство доступных ответов поступает непосредственно из Starlette.
+
+///
+
+### Используйте тело `RequestValidationError`
+
+Ошибка `RequestValidationError` содержит полученное `тело` с недопустимыми данными.
+
+Вы можете использовать его при разработке приложения для регистрации тела и его отладки, возврата пользователю и т.д.
+
+{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+
+Теперь попробуйте отправить недействительный элемент, например:
+
+```JSON
+{
+ "title": "towel",
+ "size": "XL"
+}
+```
+
+Вы получите ответ о том, что данные недействительны, содержащий следующее тело:
+
+```JSON hl_lines="12-15"
+{
+ "detail": [
+ {
+ "loc": [
+ "body",
+ "size"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ],
+ "body": {
+ "title": "towel",
+ "size": "XL"
+ }
+}
+```
+
+#### `HTTPException` в FastAPI или в Starlette
+
+**FastAPI** имеет собственный `HTTPException`.
+
+Класс ошибок **FastAPI** `HTTPException` наследует от класса ошибок Starlette `HTTPException`.
+
+Единственное отличие заключается в том, что `HTTPException` от **FastAPI** позволяет добавлять заголовки, которые будут включены в ответ.
+
+Он необходим/используется внутри системы для OAuth 2.0 и некоторых утилит безопасности.
+
+Таким образом, вы можете продолжать вызывать `HTTPException` от **FastAPI** как обычно в своем коде.
+
+Но когда вы регистрируете обработчик исключений, вы должны зарегистрировать его для `HTTPException` от Starlette.
+
+Таким образом, если какая-либо часть внутреннего кода Starlette, расширение или плагин Starlette вызовет исключение Starlette `HTTPException`, ваш обработчик сможет перехватить и обработать его.
+
+В данном примере, чтобы иметь возможность использовать оба `HTTPException` в одном коде, исключения Starlette переименованы в `StarletteHTTPException`:
+
+```Python
+from starlette.exceptions import HTTPException as StarletteHTTPException
+```
+
+### Переиспользование обработчиков исключений **FastAPI**
+
+Если вы хотите использовать исключение вместе с теми же обработчиками исключений по умолчанию из **FastAPI**, вы можете импортировать и повторно использовать обработчики исключений по умолчанию из `fastapi.exception_handlers`:
+
+{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
+
+В этом примере вы просто `выводите в терминал` ошибку с очень выразительным сообщением, но идея вам понятна. Вы можете использовать исключение, а затем просто повторно использовать стандартные обработчики исключений.
diff --git a/docs/ru/docs/tutorial/header-param-models.md b/docs/ru/docs/tutorial/header-param-models.md
new file mode 100644
index 000000000..4f54e3e15
--- /dev/null
+++ b/docs/ru/docs/tutorial/header-param-models.md
@@ -0,0 +1,72 @@
+# Модели Header-параметров
+
+Если у вас есть группа связанных **header-параметров**, то вы можете объединить их в одну **Pydantic-модель**.
+
+Это позволит вам **переиспользовать модель** в **разных местах**, а также задать валидацию и метаданные сразу для всех параметров. 😎
+
+/// note | Заметка
+
+Этот функционал доступен в FastAPI начиная с версии `0.115.0`. 🤓
+
+///
+
+## Header-параметры в виде Pydantic-модели
+
+Объявите нужные **header-параметры** в **Pydantic-модели** и затем аннотируйте параметр как `Header`:
+
+{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
+
+**FastAPI** **извлечёт** данные для **каждого поля** из **заголовков** запроса и выдаст заданную вами Pydantic-модель.
+
+## Проверьте документацию
+
+Вы можете посмотреть нужные header-параметры в графическом интерфейсе сгенерированной документации по пути `/docs`:
+
+
+

+
+
+## Как запретить дополнительные заголовки
+
+В некоторых случаях (не особо часто встречающихся) вам может понадобиться **ограничить** заголовки, которые вы хотите получать.
+
+Вы можете использовать возможности конфигурации Pydantic-модели для того, чтобы запретить (`forbid`) любые дополнительные (`extra`) поля:
+
+{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
+
+Если клиент попробует отправить **дополнительные заголовки**, то в ответ он получит **ошибку**.
+
+Например, если клиент попытается отправить заголовок `tool` со значением `plumbus`, то в ответ он получит ошибку, сообщающую ему, что header-параметр `tool` не разрешен:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["header", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ ]
+}
+```
+
+## Как отключить автоматическое преобразование подчеркиваний
+
+Как и в случае с обычными заголовками, если у вас в именах параметров имеются символы подчеркивания, они **автоматически преобразовываются в дефис**.
+
+Например, если в коде есть header-параметр `save_data`, то ожидаемый HTTP-заголовок будет `save-data` и именно так он будет отображаться в документации.
+
+Если по каким-то причинам вам нужно отключить данное автоматическое преобразование, это можно сделать и для Pydantic-моделей для header-параметров.
+
+{* ../../docs_src/header_param_models/tutorial003_an_py310.py hl[19] *}
+
+/// warning | Внимание
+
+Перед тем как устанавливать для параметра `convert_underscores` значение `False`, имейте в виду, что некоторые HTTP-прокси и серверы не разрешают использовать заголовки с символами подчеркивания.
+
+///
+
+## Резюме
+
+Вы можете использовать **Pydantic-модели** для объявления **header-параметров** в **FastAPI**. 😎
diff --git a/docs/ru/docs/tutorial/header-params.md b/docs/ru/docs/tutorial/header-params.md
new file mode 100644
index 000000000..e892cfc07
--- /dev/null
+++ b/docs/ru/docs/tutorial/header-params.md
@@ -0,0 +1,91 @@
+# Header-параметры
+
+Вы можете определить параметры заголовка таким же образом, как вы определяете параметры `Query`, `Path` и `Cookie`.
+
+## Импорт `Header`
+
+Сперва импортируйте `Header`:
+
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
+
+## Объявление параметров `Header`
+
+Затем объявите параметры заголовка, используя ту же структуру, что и с `Path`, `Query` и `Cookie`.
+
+Первое значение является значением по умолчанию, вы можете передать все дополнительные параметры валидации или аннотации:
+
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | Технические детали
+
+`Header` - это "родственный" класс `Path`, `Query` и `Cookie`. Он также наследуется от того же общего класса `Param`.
+
+Но помните, что когда вы импортируете `Query`, `Path`, `Header` и другие из `fastapi`, на самом деле это функции, которые возвращают специальные классы.
+
+///
+
+/// info | Дополнительная информация
+
+Чтобы объявить заголовки, важно использовать `Header`, иначе параметры интерпретируются как query-параметры.
+
+///
+
+## Автоматическое преобразование
+
+`Header` обладает небольшой дополнительной функциональностью в дополнение к тому, что предоставляют `Path`, `Query` и `Cookie`.
+
+Большинство стандартных заголовков разделены символом "дефис", также известным как "минус" (`-`).
+
+Но переменная вроде `user-agent` недопустима в Python.
+
+По умолчанию `Header` преобразует символы имен параметров из символа подчеркивания (`_`) в дефис (`-`) для извлечения и документирования заголовков.
+
+Кроме того, HTTP-заголовки не чувствительны к регистру, поэтому вы можете объявить их в стандартном стиле Python (также известном как "snake_case").
+
+Таким образом вы можете использовать `user_agent`, как обычно, в коде Python, вместо того, чтобы вводить заглавные буквы как `User_Agent` или что-то подобное.
+
+Если по какой-либо причине вам необходимо отключить автоматическое преобразование подчеркиваний в дефисы, установите для параметра `convert_underscores` в `Header` значение `False`:
+
+{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
+
+/// warning | Внимание
+
+Прежде чем установить для `convert_underscores` значение `False`, имейте в виду, что некоторые HTTP-прокси и серверы запрещают использование заголовков с подчеркиванием.
+
+///
+
+## Повторяющиеся заголовки
+
+Есть возможность получать несколько заголовков с одним и тем же именем, но разными значениями.
+
+Вы можете определить эти случаи, используя список в объявлении типа.
+
+Вы получите все значения из повторяющегося заголовка в виде `list` Python.
+
+Например, чтобы объявить заголовок `X-Token`, который может появляться более одного раза, вы можете написать:
+
+{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
+
+Если вы взаимодействуете с этой *операцией пути*, отправляя два HTTP-заголовка, таких как:
+
+```
+X-Token: foo
+X-Token: bar
+```
+
+Ответ был бы таким:
+
+```JSON
+{
+ "X-Token values": [
+ "bar",
+ "foo"
+ ]
+}
+```
+
+## Резюме
+
+Объявляйте заголовки с помощью `Header`, используя тот же общий шаблон, как при `Query`, `Path` и `Cookie`.
+
+И не беспокойтесь о символах подчеркивания в ваших переменных, **FastAPI** позаботится об их преобразовании.
diff --git a/docs/ru/docs/tutorial/index.md b/docs/ru/docs/tutorial/index.md
new file mode 100644
index 000000000..ddca2fbb1
--- /dev/null
+++ b/docs/ru/docs/tutorial/index.md
@@ -0,0 +1,83 @@
+# Учебник - Руководство пользователя
+
+В этом руководстве шаг за шагом показано, как использовать **FastApi** с большинством его функций.
+
+Каждый раздел постепенно основывается на предыдущих, но он структурирован по отдельным темам, так что вы можете перейти непосредственно к конкретной теме для решения ваших конкретных потребностей в API.
+
+Он также создан для использования в качестве будущего справочника.
+
+Так что вы можете вернуться и посмотреть именно то, что вам нужно.
+
+## Запустите код
+
+Все блоки кода можно копировать и использовать напрямую (на самом деле это проверенные файлы Python).
+
+Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `uvicorn` с параметрами:
+
+
+
+```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.
+```
+
+
+
+**НАСТОЯТЕЛЬНО рекомендуется**, чтобы вы написали или скопировали код, отредактировали его и запустили локально.
+
+Использование кода в вашем редакторе — это то, что действительно показывает вам преимущества FastAPI, видя, как мало кода вам нужно написать, все проверки типов, автодополнение и т.д.
+
+---
+
+## Установка FastAPI
+
+Первый шаг — установить FastAPI.
+
+Для руководства вы, возможно, захотите установить его со всеми дополнительными зависимостями и функциями:
+
+
+
+```console
+$ pip install "fastapi[all]"
+
+---> 100%
+```
+
+
+
+...это также включает `uvicorn`, который вы можете использовать в качестве сервера, который запускает ваш код.
+
+/// note | Технические детали
+
+Вы также можете установить его по частям.
+
+Это то, что вы, вероятно, сделаете, когда захотите развернуть свое приложение в рабочей среде:
+
+```
+pip install fastapi
+```
+
+Также установите `uvicorn` для работы в качестве сервера:
+
+```
+pip install "uvicorn[standard]"
+```
+
+И то же самое для каждой из необязательных зависимостей, которые вы хотите использовать.
+
+///
+
+## Продвинутое руководство пользователя
+
+Существует также **Продвинутое руководство пользователя**, которое вы сможете прочитать после руководства **Учебник - Руководство пользователя**.
+
+**Продвинутое руководство пользователя** основано на этом, использует те же концепции и учит вас некоторым дополнительным функциям.
+
+Но вы должны сначала прочитать **Учебник - Руководство пользователя** (то, что вы читаете прямо сейчас).
+
+Он разработан таким образом, что вы можете создать полноценное приложение, используя только **Учебник - Руководство пользователя**, а затем расширить его различными способами, в зависимости от ваших потребностей, используя некоторые дополнительные идеи из **Продвинутого руководства пользователя**.
diff --git a/docs/ru/docs/tutorial/metadata.md b/docs/ru/docs/tutorial/metadata.md
new file mode 100644
index 000000000..f07073508
--- /dev/null
+++ b/docs/ru/docs/tutorial/metadata.md
@@ -0,0 +1,110 @@
+# URL-адреса метаданных и документации
+
+Вы можете настроить несколько конфигураций метаданных в вашем **FastAPI** приложении.
+
+## Метаданные для API
+
+Вы можете задать следующие поля, которые используются в спецификации OpenAPI и в UI автоматической документации API:
+
+| Параметр | Тип | Описание |
+|------------|--|-------------|
+| `title` | `str` | Заголовок API. |
+| `description` | `str` | Краткое описание API. Может быть использован Markdown. |
+| `version` | `string` | Версия API. Версия вашего собственного приложения, а не OpenAPI. К примеру `2.5.0`. |
+| `terms_of_service` | `str` | Ссылка к условиям пользования API. Если указано, то это должен быть URL-адрес. |
+| `contact` | `dict` | Контактная информация для открытого API. Может содержать несколько полей.
поля contact
Параметр | Тип | Описание |
---|
name | str | Идентификационное имя контактного лица/организации. |
url | str | URL указывающий на контактную информацию. ДОЛЖЕН быть в формате URL. |
email | str | Email адрес контактного лица/организации. ДОЛЖЕН быть в формате email адреса. |
|
+| `license_info` | `dict` | Информация о лицензии открытого API. Может содержать несколько полей.
поля license_info
Параметр | Тип | Описание |
---|
name | str | ОБЯЗАТЕЛЬНО (если установлен параметр license_info ). Название лицензии, используемой для API |
url | str | URL, указывающий на лицензию, используемую для API. ДОЛЖЕН быть в формате URL. |
|
+
+Вы можете задать их следующим образом:
+
+{* ../../docs_src/metadata/tutorial001.py hl[3:16,19:31] *}
+
+/// tip | Подсказка
+
+Вы можете использовать Markdown в поле `description`, и оно будет отображено в выводе.
+
+///
+
+С этой конфигурацией автоматическая документация API будут выглядеть так:
+
+

+
+## Метаданные для тегов
+
+Вы также можете добавить дополнительные метаданные для различных тегов, используемых для группировки ваших операций пути с помощью параметра `openapi_tags`.
+
+Он принимает список, содержащий один словарь для каждого тега.
+
+Каждый словарь может содержать в себе:
+
+* `name` (**обязательно**): `str`-значение с тем же именем тега, которое вы используете в параметре `tags` в ваших *операциях пути* и `APIRouter`ах.
+* `description`: `str`-значение с кратким описанием для тега. Может содержать Markdown и будет отображаться в UI документации.
+* `externalDocs`: `dict`-значение описывающее внешнюю документацию. Включает в себя:
+ * `description`: `str`-значение с кратким описанием для внешней документации.
+ * `url` (**обязательно**): `str`-значение с URL-адресом для внешней документации.
+
+### Создание метаданных для тегов
+
+Давайте попробуем сделать это на примере с тегами для `users` и `items`.
+
+Создайте метаданные для ваших тегов и передайте их в параметре `openapi_tags`:
+
+{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+
+Помните, что вы можете использовать Markdown внутри описания, к примеру "login" будет отображен жирным шрифтом (**login**) и "fancy" будет отображаться курсивом (_fancy_).
+
+/// tip | Подсказка
+
+Вам необязательно добавлять метаданные для всех используемых тегов
+
+///
+
+### Используйте собственные теги
+Используйте параметр `tags` с вашими *операциями пути* (и `APIRouter`ами), чтобы присвоить им различные теги:
+
+{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+
+/// info | Дополнительная информация
+
+Узнайте больше о тегах в [Конфигурации операции пути](path-operation-configuration.md#_3){.internal-link target=_blank}.
+
+///
+
+### Проверьте документацию
+
+Теперь, если вы проверите документацию, вы увидите всю дополнительную информацию:
+
+

+
+### Порядок расположения тегов
+
+Порядок расположения словарей метаданных для каждого тега определяет также порядок, отображаемый в документах UI
+
+К примеру, несмотря на то, что `users` будут идти после `items` в алфавитном порядке, они отображаются раньше, потому что мы добавляем свои метаданные в качестве первого словаря в списке.
+
+## URL-адреса OpenAPI
+
+По умолчанию схема OpenAPI отображена по адресу `/openapi.json`.
+
+Но вы можете изменить это с помощью параметра `openapi_url`.
+
+К примеру, чтобы задать её отображение по адресу `/api/v1/openapi.json`:
+
+{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+
+Если вы хотите отключить схему OpenAPI полностью, вы можете задать `openapi_url=None`, это также отключит пользовательские интерфейсы документации, которые его использует.
+
+## URL-адреса документации
+
+Вы можете изменить конфигурацию двух пользовательских интерфейсов документации, среди которых
+
+* **Swagger UI**: отображаемый по адресу `/docs`.
+ * Вы можете задать его URL с помощью параметра `docs_url`.
+ * Вы можете отключить это с помощью настройки `docs_url=None`.
+* **ReDoc**: отображаемый по адресу `/redoc`.
+ * Вы можете задать его URL с помощью параметра `redoc_url`.
+ * Вы можете отключить это с помощью настройки `redoc_url=None`.
+
+К примеру, чтобы задать отображение Swagger UI по адресу `/documentation` и отключить ReDoc:
+
+{* ../../docs_src/metadata/tutorial003.py hl[3] *}
diff --git a/docs/ru/docs/tutorial/middleware.md b/docs/ru/docs/tutorial/middleware.md
new file mode 100644
index 000000000..845e881e1
--- /dev/null
+++ b/docs/ru/docs/tutorial/middleware.md
@@ -0,0 +1,74 @@
+# Middleware (Промежуточный слой)
+
+Вы можете добавить промежуточный слой (middleware) в **FastAPI** приложение.
+
+"Middleware" это функция, которая выполняется с каждым запросом до его обработки какой-либо конкретной *операцией пути*.
+А также с каждым ответом перед его возвращением.
+
+
+* Она принимает каждый поступающий **запрос**.
+* Может что-то сделать с этим **запросом** или выполнить любой нужный код.
+* Затем передает **запрос** для последующей обработки (какой-либо *операцией пути*).
+* Получает **ответ** (от *операции пути*).
+* Может что-то сделать с этим **ответом** или выполнить любой нужный код.
+* И возвращает **ответ**.
+
+/// note | Технические детали
+
+Если у вас есть зависимости с `yield`, то код выхода (код после `yield`) будет выполняться *после* middleware.
+
+Если у вас имеются некие фоновые задачи (см. документацию), то они будут запущены после middleware.
+
+///
+
+## Создание middleware
+
+Для создания middleware используйте декоратор `@app.middleware("http")`.
+
+Функция middleware получает:
+
+* `request` (объект запроса).
+* Функцию `call_next`, которая получает `request` в качестве параметра.
+ * Эта функция передаёт `request` соответствующей *операции пути*.
+ * Затем она возвращает ответ `response`, сгенерированный *операцией пути*.
+* Также имеется возможность видоизменить `response`, перед тем как его вернуть.
+
+{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+
+/// tip | Примечание
+
+Имейте в виду, что можно добавлять свои собственные заголовки
при помощи префикса 'X-'.
+
+Если же вы хотите добавить собственные заголовки, которые клиент сможет увидеть в браузере, то вам потребуется добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}), используя параметр `expose_headers`, см. документацию
Starlette's CORS docs.
+
+///
+
+/// note | Технические детали
+
+Вы также можете использовать `from starlette.requests import Request`.
+
+**FastAPI** предоставляет такой доступ для удобства разработчиков. Но, на самом деле, это `Request` из Starlette.
+
+///
+
+### До и после `response`
+
+Вы можете добавить код, использующий `request` до передачи его какой-либо *операции пути*.
+
+А также после формирования `response`, до того, как вы его вернёте.
+
+Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:
+
+{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+
+/// tip | Примечание
+
+Мы используем
`time.perf_counter()` вместо `time.time()` для обеспечения большей точности наших примеров. 🤓
+
+///
+
+## Другие middleware
+
+О других middleware вы можете узнать больше в разделе [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank}.
+
+В следующем разделе вы можете прочитать, как настроить
CORS с помощью middleware.
diff --git a/docs/ru/docs/tutorial/path-operation-configuration.md b/docs/ru/docs/tutorial/path-operation-configuration.md
new file mode 100644
index 000000000..af471ca69
--- /dev/null
+++ b/docs/ru/docs/tutorial/path-operation-configuration.md
@@ -0,0 +1,107 @@
+# Конфигурация операций пути
+
+Существует несколько параметров, которые вы можете передать вашему *декоратору операций пути* для его настройки.
+
+/// warning | Внимание
+
+Помните, что эти параметры передаются непосредственно *декоратору операций пути*, а не вашей *функции-обработчику операций пути*.
+
+///
+
+## Коды состояния
+
+Вы можете определить (HTTP) `status_code`, который будет использован в ответах вашей *операции пути*.
+
+Вы можете передать только `int`-значение кода, например `404`.
+
+Но если вы не помните, для чего нужен каждый числовой код, вы можете использовать сокращенные константы в параметре `status`:
+
+{* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
+
+Этот код состояния будет использован в ответе и будет добавлен в схему OpenAPI.
+
+/// note | Технические детали
+
+Вы также можете использовать `from starlette import status`.
+
+**FastAPI** предоставляет тот же `starlette.status` под псевдонимом `fastapi.status` для удобства разработчика. Но его источник - это непосредственно Starlette.
+
+///
+
+## Теги
+
+Вы можете добавлять теги к вашим *операциям пути*, добавив параметр `tags` с `list` заполненным `str`-значениями (обычно в нём только одна строка):
+
+{* ../../docs_src/path_operation_configuration/tutorial002_py310.py hl[15,20,25] *}
+
+Они будут добавлены в схему OpenAPI и будут использованы в автоматической документации интерфейса:
+
+

+
+### Теги с перечислениями
+
+Если у вас большое приложение, вы можете прийти к необходимости добавить **несколько тегов**, и возможно, вы захотите убедиться в том, что всегда используете **один и тот же тег** для связанных *операций пути*.
+
+В этих случаях, имеет смысл хранить теги в классе `Enum`.
+
+**FastAPI** поддерживает это так же, как и в случае с обычными строками:
+
+{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
+
+## Краткое и развёрнутое содержание
+
+Вы можете добавить параметры `summary` и `description`:
+
+{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *}
+
+## Описание из строк документации
+
+Так как описания обычно длинные и содержат много строк, вы можете объявить описание *операции пути* в функции
строки документации и **FastAPI** прочитает её отсюда.
+
+Вы можете использовать
Markdown в строке документации, и он будет интерпретирован и отображён корректно (с учетом отступа в строке документации).
+
+{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
+
+Он будет использован в интерактивной документации:
+
+

+
+## Описание ответа
+
+Вы можете указать описание ответа с помощью параметра `response_description`:
+
+{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *}
+
+/// info | Дополнительная информация
+
+Помните, что `response_description` относится конкретно к ответу, а `description` относится к *операции пути* в целом.
+
+///
+
+/// check | Технические детали
+
+OpenAPI указывает, что каждой *операции пути* необходимо описание ответа.
+
+Если вдруг вы не укажете его, то **FastAPI** автоматически сгенерирует это описание с текстом "Successful response".
+
+///
+
+

+
+## Обозначение *операции пути* как устаревшей
+
+Если вам необходимо пометить *операцию пути* как
устаревшую, при этом не удаляя её, передайте параметр `deprecated`:
+
+{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+
+Он будет четко помечен как устаревший в интерактивной документации:
+
+

+
+Проверьте, как будут выглядеть устаревшие и не устаревшие *операции пути*:
+
+

+
+## Резюме
+
+Вы можете легко конфигурировать и добавлять метаданные в ваши *операции пути*, передавая параметры *декораторам операций пути*.
diff --git a/docs/ru/docs/tutorial/path-params-numeric-validations.md b/docs/ru/docs/tutorial/path-params-numeric-validations.md
new file mode 100644
index 000000000..dca267f78
--- /dev/null
+++ b/docs/ru/docs/tutorial/path-params-numeric-validations.md
@@ -0,0 +1,168 @@
+# Path-параметры и валидация числовых данных
+
+Так же, как с помощью `Query` вы можете добавлять валидацию и метаданные для query-параметров, так и с помощью `Path` вы можете добавлять такую же валидацию и метаданные для path-параметров.
+
+## Импорт Path
+
+Сначала импортируйте `Path` из `fastapi`, а также импортируйте `Annotated`:
+
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
+
+/// info | Информация
+
+Поддержка `Annotated` была добавлена в FastAPI начиная с версии 0.95.0 (и с этой версии рекомендуется использовать этот подход).
+
+Если вы используете более старую версию, вы столкнётесь с ошибками при попытке использовать `Annotated`.
+
+Убедитесь, что вы [обновили версию FastAPI](../deployment/versions.md#fastapi_2){.internal-link target=_blank} как минимум до 0.95.1 перед тем, как использовать `Annotated`.
+
+///
+
+## Определите метаданные
+
+Вы можете указать все те же параметры, что и для `Query`.
+
+Например, чтобы указать значение метаданных `title` для path-параметра `item_id`, вы можете написать:
+
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
+
+/// note | Примечание
+
+Path-параметр всегда является обязательным, поскольку он составляет часть пути.
+
+Поэтому следует объявить его с помощью `...`, чтобы обозначить, что этот параметр обязательный.
+
+Тем не менее, даже если вы объявите его как `None` или установите для него значение по умолчанию, это ни на что не повлияет и параметр останется обязательным.
+
+///
+
+## Задайте нужный вам порядок параметров
+
+/// tip | Подсказка
+
+Это не имеет большого значения, если вы используете `Annotated`.
+
+///
+
+Допустим, вы хотите объявить query-параметр `q` как обязательный параметр типа `str`.
+
+И если вам больше ничего не нужно указывать для этого параметра, то нет необходимости использовать `Query`.
+
+Но вам по-прежнему нужно использовать `Path` для path-параметра `item_id`. И если по какой-либо причине вы не хотите использовать `Annotated`, то могут возникнуть небольшие сложности.
+
+Если вы поместите параметр со значением по умолчанию перед другим параметром, у которого нет значения по умолчанию, то Python укажет на ошибку.
+
+Но вы можете изменить порядок параметров, чтобы параметр без значения по умолчанию (query-параметр `q`) шёл первым.
+
+Это не имеет значения для **FastAPI**. Он распознает параметры по их названиям, типам и значениям по умолчанию (`Query`, `Path`, и т.д.), ему не важен их порядок.
+
+Поэтому вы можете определить функцию так:
+
+//// tab | Python 3.8 без Annotated
+
+/// tip | Подсказка
+
+Рекомендуется использовать версию с `Annotated` если возможно.
+
+///
+
+```Python hl_lines="7"
+{!> ../../docs_src/path_params_numeric_validations/tutorial002.py!}
+```
+
+////
+
+Но имейте в виду, что если вы используете `Annotated`, вы не столкнётесь с этой проблемой, так как вы не используете `Query()` или `Path()` в качестве значения по умолчанию для параметра функции.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py hl[10] *}
+
+## Задайте нужный вам порядок параметров, полезные приёмы
+
+/// tip | Подсказка
+
+Это не имеет большого значения, если вы используете `Annotated`.
+
+///
+
+Здесь описан **небольшой приём**, который может оказаться удобным, хотя часто он вам не понадобится.
+
+Если вы хотите:
+
+* объявить query-параметр `q` без `Query` и без значения по умолчанию
+* объявить path-параметр `item_id` с помощью `Path`
+* указать их в другом порядке
+* не использовать `Annotated`
+
+...то вы можете использовать специальную возможность синтаксиса Python.
+
+Передайте `*` в качестве первого параметра функции.
+
+Python не будет ничего делать с `*`, но он будет знать, что все следующие параметры являются именованными аргументами (парами ключ-значение), также известными как
kwargs
, даже если у них нет значений по умолчанию.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+
+### Лучше с `Annotated`
+
+Имейте в виду, что если вы используете `Annotated`, то, поскольку вы не используете значений по умолчанию для параметров функции, то у вас не возникнет подобной проблемы и вам не придётся использовать `*`.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
+
+## Валидация числовых данных: больше или равно
+
+С помощью `Query` и `Path` (и других классов, которые мы разберём позже) вы можете добавлять ограничения для числовых данных.
+
+В этом примере при указании `ge=1`, параметр `item_id` должен быть больше или равен `1` ("`g`reater than or `e`qual").
+
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
+
+## Валидация числовых данных: больше и меньше или равно
+
+То же самое применимо к:
+
+* `gt`: больше (`g`reater `t`han)
+* `le`: меньше или равно (`l`ess than or `e`qual)
+
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
+
+## Валидация числовых данных: числа с плавающей точкой, больше и меньше
+
+Валидация также применима к значениям типа `float`.
+
+В этом случае становится важной возможность добавить ограничение
gt
, вместо
ge
, поскольку в таком случае вы можете, например, создать ограничение, чтобы значение было больше `0`, даже если оно меньше `1`.
+
+Таким образом, `0.5` будет корректным значением. А `0.0` или `0` — нет.
+
+То же самое справедливо и для
lt
.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
+
+## Резюме
+
+С помощью `Query`, `Path` (и других классов, которые мы пока не затронули) вы можете добавлять метаданные и строковую валидацию тем же способом, как и в главе [Query-параметры и валидация строк](query-params-str-validations.md){.internal-link target=_blank}.
+
+А также вы можете добавить валидацию числовых данных:
+
+* `gt`: больше (`g`reater `t`han)
+* `ge`: больше или равно (`g`reater than or `e`qual)
+* `lt`: меньше (`l`ess `t`han)
+* `le`: меньше или равно (`l`ess than or `e`qual)
+
+/// info | Информация
+
+`Query`, `Path` и другие классы, которые мы разберём позже, являются наследниками общего класса `Param`.
+
+Все они используют те же параметры для дополнительной валидации и метаданных, которые вы видели ранее.
+
+///
+
+/// note | Технические детали
+
+`Query`, `Path` и другие "классы", которые вы импортируете из `fastapi`, на самом деле являются функциями, которые при вызове возвращают экземпляры одноимённых классов.
+
+Объект `Query`, который вы импортируете, является функцией. И при вызове она возвращает экземпляр одноимённого класса `Query`.
+
+Использование функций (вместо использования классов напрямую) нужно для того, чтобы ваш редактор не подсвечивал ошибки, связанные с их типами.
+
+Таким образом вы можете использовать привычный вам редактор и инструменты разработки, не добавляя дополнительных конфигураций для игнорирования подобных ошибок.
+
+///
diff --git a/docs/ru/docs/tutorial/path-params.md b/docs/ru/docs/tutorial/path-params.md
new file mode 100644
index 000000000..5c2d82a65
--- /dev/null
+++ b/docs/ru/docs/tutorial/path-params.md
@@ -0,0 +1,255 @@
+# Path-параметры
+
+Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python:
+
+{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+
+Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
+
+Если запустите этот пример и перейдёте по адресу:
http://127.0.0.1:8000/items/foo, то увидите ответ:
+
+```JSON
+{"item_id":"foo"}
+```
+
+## Параметры пути с типами
+
+Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python.
+
+{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+
+Здесь, `item_id` объявлен типом `int`.
+
+/// check | Заметка
+
+Это обеспечит поддержку редактора внутри функции (проверка ошибок, автодополнение и т.п.).
+
+///
+
+##
Преобразование данных
+
+Если запустите этот пример и перейдёте по адресу:
http://127.0.0.1:8000/items/3, то увидите ответ:
+
+```JSON
+{"item_id":3}
+```
+
+/// check | Заметка
+
+Обратите внимание на значение `3`, которое получила (и вернула) функция. Это целочисленный Python `int`, а не строка `"3"`.
+
+Используя определения типов, **FastAPI** выполняет автоматический
"парсинг" запросов.
+
+///
+
+##
Проверка данных
+
+Если откроете браузер по адресу
http://127.0.0.1:8000/items/foo, то увидите интересную HTTP-ошибку:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+из-за того, что параметр пути `item_id` имеет значение `"foo"`, которое не является типом `int`.
+
+Та же ошибка возникнет, если вместо `int` передать `float` , например:
http://127.0.0.1:8000/items/4.2
+
+/// check | Заметка
+
+**FastAPI** обеспечивает проверку типов, используя всё те же определения типов.
+
+Обратите внимание, что в тексте ошибки явно указано место не прошедшее проверку.
+
+Это очень полезно при разработке и отладке кода, который взаимодействует с API.
+
+///
+
+## Документация
+
+И теперь, когда откроете браузер по адресу:
http://127.0.0.1:8000/docs, то увидите вот такую автоматически сгенерированную документацию API:
+
+

+
+/// check | Заметка
+
+Ещё раз, просто используя определения типов, **FastAPI** обеспечивает автоматическую интерактивную документацию (с интеграцией Swagger UI).
+
+Обратите внимание, что параметр пути объявлен целочисленным.
+
+///
+
+## Преимущества стандартизации, альтернативная документация
+
+Поскольку сгенерированная схема соответствует стандарту
OpenAPI, её можно использовать со множеством совместимых инструментов.
+
+Именно поэтому, FastAPI сам предоставляет альтернативную документацию API (используя ReDoc), которую можно получить по адресу:
http://127.0.0.1:8000/redoc.
+
+

+
+По той же причине, есть множество совместимых инструментов, включая инструменты генерации кода для многих языков.
+
+## Pydantic
+
+Вся проверка данных выполняется под капотом с помощью
Pydantic. Поэтому вы можете быть уверены в качестве обработки данных.
+
+Вы можете использовать в аннотациях как простые типы данных, вроде `str`, `float`, `bool`, так и более сложные типы.
+
+Некоторые из них рассматриваются в следующих главах данного руководства.
+
+## Порядок имеет значение
+
+При создании *операций пути* можно столкнуться с ситуацией, когда путь является фиксированным.
+
+Например, `/users/me`. Предположим, что это путь для получения данных о текущем пользователе.
+
+У вас также может быть путь `/users/{user_id}`, чтобы получить данные о конкретном пользователе по его ID.
+
+Поскольку *операции пути* выполняются в порядке их объявления, необходимо, чтобы путь для `/users/me` был объявлен раньше, чем путь для `/users/{user_id}`:
+
+
+{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+
+Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
+
+Аналогично, вы не можете переопределить операцию с путем:
+
+{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+
+Первый будет выполняться всегда, так как путь совпадает первым.
+
+## Предопределенные значения
+
+Что если нам нужно заранее определить допустимые *параметры пути*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление
`Enum` Python.
+
+### Создание класса `Enum`
+
+Импортируйте `Enum` и создайте подкласс, который наследуется от `str` и `Enum`.
+
+Мы наследуемся от `str`, чтобы документация API могла понять, что значения должны быть типа `string` и отображалась правильно.
+
+Затем создайте атрибуты класса с фиксированными допустимыми значениями:
+
+{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
+
+/// info | Дополнительная информация
+
+
Перечисления (enum) доступны в Python начиная с версии 3.4.
+
+///
+
+/// tip | Подсказка
+
+Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия
моделей машинного обучения.
+
+///
+
+### Определение *параметра пути*
+
+Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
+
+{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+
+### Проверьте документацию
+
+Поскольку доступные значения *параметра пути* определены заранее, интерактивная документация может наглядно их отображать:
+
+

+
+### Работа с *перечислениями* в Python
+
+Значение *параметра пути* будет *элементом перечисления*.
+
+#### Сравнение *элементов перечисления*
+
+Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`:
+
+{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+
+#### Получение *значения перечисления*
+
+Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`:
+
+{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+
+/// tip | Подсказка
+
+Значение `"lenet"` также можно получить с помощью `ModelName.lenet.value`.
+
+///
+
+#### Возврат *элементов перечисления*
+
+Из *операции пути* можно вернуть *элементы перечисления*, даже вложенные в тело JSON (например в `dict`).
+
+Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
+
+{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+Вы отправите клиенту такой JSON-ответ:
+
+```JSON
+{
+ "model_name": "alexnet",
+ "message": "Deep Learning FTW!"
+}
+```
+
+## Path-параметры, содержащие пути
+
+Предположим, что есть *операция пути* с путем `/files/{file_path}`.
+
+Но вам нужно, чтобы `file_path` сам содержал *путь*, например, `home/johndoe/myfile.txt`.
+
+Тогда URL для этого файла будет такой: `/files/home/johndoe/myfile.txt`.
+
+### Поддержка OpenAPI
+
+OpenAPI не поддерживает способов объявления *параметра пути*, содержащего внутри *путь*, так как это может привести к сценариям, которые сложно определять и тестировать.
+
+Тем не менее это можно сделать в **FastAPI**, используя один из внутренних инструментов Starlette.
+
+Документация по-прежнему будет работать, хотя и не добавит никакой информации о том, что параметр должен содержать путь.
+
+### Конвертер пути
+
+Благодаря одной из опций Starlette, можете объявить *параметр пути*, содержащий *путь*, используя URL вроде:
+
+```
+/files/{file_path:path}
+```
+
+В этом случае `file_path` - это имя параметра, а часть `:path`, указывает, что параметр должен соответствовать любому *пути*.
+
+Можете использовать так:
+
+{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+
+/// tip | Подсказка
+
+Возможно, вам понадобится, чтобы параметр содержал `/home/johndoe/myfile.txt` с ведущим слэшем (`/`).
+
+В этом случае URL будет таким: `/files//home/johndoe/myfile.txt`, с двойным слэшем (`//`) между `files` и `home`.
+
+///
+
+## Резюме
+Используя **FastAPI** вместе со стандартными объявлениями типов Python (короткими и интуитивно понятными), вы получаете:
+
+* Поддержку редактора (проверку ошибок, автозаполнение и т.п.)
+* "
Парсинг" данных
+* Валидацию данных
+* Автоматическую документацию API с указанием типов параметров.
+
+И объявлять типы достаточно один раз.
+
+Это, вероятно, является главным заметным преимуществом **FastAPI** по сравнению с альтернативными фреймворками (кроме
сырой производительности).
diff --git a/docs/ru/docs/tutorial/query-param-models.md b/docs/ru/docs/tutorial/query-param-models.md
new file mode 100644
index 000000000..4d76d09e8
--- /dev/null
+++ b/docs/ru/docs/tutorial/query-param-models.md
@@ -0,0 +1,68 @@
+# Модели Query-Параметров
+
+Если у вас есть группа связанных **query-параметров**, то вы можете объединить их в одну **Pydantic-модель**.
+
+Это позволит вам **переиспользовать модель** в **разных местах**, устанавливать валидаторы и метаданные, в том числе для сразу всех параметров, в одном месте. 😎
+
+/// note | Заметка
+
+Этот функционал доступен с версии `0.115.0`. 🤓
+
+///
+
+## Pydantic-Модель для Query-Параметров
+
+Объявите нужные **query-параметры** в **Pydantic-модели**, а после аннотируйте параметр как `Query`:
+
+{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
+
+**FastAPI извлечёт** данные соответствующие **каждому полю модели** из **query-параметров** запроса и выдаст вам объявленную Pydantic-модель заполненную ими.
+
+## Проверьте Сгенерированную Документацию
+
+Вы можете посмотреть query-параметры в графическом интерфейсе сгенерированной документации по пути `/docs`:
+
+
+

+
+
+## Запретить Дополнительные Query-Параметры
+
+В некоторых случаях (не особо часто встречающихся) вам может понадобиться **ограничить** query-параметры, которые вы хотите получить.
+
+Вы можете сконфигурировать Pydantic-модель так, чтобы запретить (`forbid`) все дополнительные (`extra`) поля.
+
+{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
+
+Если клиент попробует отправить **дополнительные** данные в **query-параметрах**, то в ответ он получит **ошибку**.
+
+Например, если клиент попытается отправить query-параметр `tool` с значением `plumbus`, в виде:
+
+```http
+https://example.com/items/?limit=10&tool=plumbus
+```
+
+То в ответ он получит **ошибку**, сообщающую ему, что query-параметр `tool` не разрешен:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["query", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus"
+ }
+ ]
+}
+```
+
+## Заключение
+
+Вы можете использовать **Pydantic-модели** для объявления **query-параметров** в **FastAPI**. 😎
+
+/// tip | Совет
+
+Спойлер: вы также можете использовать Pydantic-модели для группировки кук (cookies) и заголовков (headers), но об этом вы прочитаете позже. 🤫
+
+///
diff --git a/docs/ru/docs/tutorial/query-params-str-validations.md b/docs/ru/docs/tutorial/query-params-str-validations.md
new file mode 100644
index 000000000..13b7015db
--- /dev/null
+++ b/docs/ru/docs/tutorial/query-params-str-validations.md
@@ -0,0 +1,464 @@
+# Query-параметры и валидация строк
+
+**FastAPI** позволяет определять дополнительную информацию и валидацию для ваших параметров.
+
+Давайте рассмотрим следующий пример:
+
+{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
+
+Query-параметр `q` имеет тип `Union[str, None]` (или `str | None` в Python 3.10). Это означает, что входной параметр будет типа `str`, но может быть и `None`. Ещё параметр имеет значение по умолчанию `None`, из-за чего FastAPI определит параметр как необязательный.
+
+/// note | Технические детали
+
+FastAPI определит параметр `q` как необязательный, потому что его значение по умолчанию `= None`.
+
+`Union` в `Union[str, None]` позволит редактору кода оказать вам лучшую поддержку и найти ошибки.
+
+///
+
+## Расширенная валидация
+
+Добавим дополнительное условие валидации параметра `q` - **длина строки не более 50 символов** (условие проверяется всякий раз, когда параметр `q` не является `None`).
+
+### Импорт `Query` и `Annotated`
+
+Чтобы достичь этого, первым делом нам нужно импортировать:
+
+* `Query` из пакета `fastapi`:
+* `Annotated` из пакета `typing` (или из `typing_extensions` для Python ниже 3.9)
+
+//// tab | Python 3.10+
+
+В Python 3.9 или выше, `Annotated` является частью стандартной библиотеки, таким образом вы можете импортировать его из `typing`.
+
+```Python hl_lines="1 3"
+{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+В версиях Python ниже Python 3.9 `Annotation` импортируется из `typing_extensions`.
+
+Эта библиотека будет установлена вместе с FastAPI.
+
+```Python hl_lines="3-4"
+{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
+```
+
+////
+
+## `Annotated` как тип для query-параметра `q`
+
+Помните, как ранее я говорил об Annotated? Он может быть использован для добавления метаданных для ваших параметров в разделе [Введение в аннотации типов Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}?
+
+Пришло время использовать их в FastAPI. 🚀
+
+У нас была аннотация следующего типа:
+
+//// tab | Python 3.10+
+
+```Python
+q: str | None = None
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+q: Union[str, None] = None
+```
+
+////
+
+Вот что мы получим, если обернём это в `Annotated`:
+
+//// tab | Python 3.10+
+
+```Python
+q: Annotated[str | None] = None
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+q: Annotated[Union[str, None]] = None
+```
+
+////
+
+Обе эти версии означают одно и тоже. `q` - это параметр, который может быть `str` или `None`, и по умолчанию он будет принимать `None`.
+
+Давайте повеселимся. 🎉
+
+## Добавим `Query` в `Annotated` для query-параметра `q`
+
+Теперь, когда у нас есть `Annotated`, где мы можем добавить больше метаданных, добавим `Query` со значением параметра `max_length` равным 50:
+
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
+
+Обратите внимание, что значение по умолчанию всё ещё `None`, так что параметр остаётся необязательным.
+
+Однако теперь, имея `Query(max_length=50)` внутри `Annotated`, мы говорим FastAPI, что мы хотим извлечь это значение из параметров query-запроса (что произойдёт в любом случае 🤷), и что мы хотим иметь **дополнительные условия валидации** для этого значения (для чего мы и делаем это - чтобы получить дополнительную валидацию). 😎
+
+Теперь FastAPI:
+
+* **Валидирует** (проверяет), что полученные данные состоят максимум из 50 символов
+* Показывает **исчерпывающую ошибку** (будет описание местонахождения ошибки и её причины) для клиента в случаях, когда данные не валидны
+* **Задокументирует** параметр в схему OpenAPI *операции пути* (что будет отображено в **UI автоматической документации**)
+
+## Альтернативный (устаревший) способ задать `Query` как значение по умолчанию
+
+В предыдущих версиях FastAPI (ниже
0.95.0) необходимо было использовать `Query` как значение по умолчанию для query-параметра. Так было вместо размещения его в `Annotated`, так что велика вероятность, что вам встретится такой код. Сейчас объясню.
+
+/// tip | Подсказка
+
+При написании нового кода и везде где это возможно, используйте `Annotated`, как было описано ранее. У этого способа есть несколько преимуществ (о них дальше) и никаких недостатков. 🍰
+
+///
+
+Вот как вы могли бы использовать `Query()` в качестве значения по умолчанию параметра вашей функции, установив для параметра `max_length` значение 50:
+
+{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
+
+В таком случае (без использования `Annotated`), мы заменили значение по умолчанию с `None` на `Query()` в функции. Теперь нам нужно установить значение по умолчанию для query-параметра `Query(default=None)`, что необходимо для тех же целей, как когда ранее просто указывалось значение по умолчанию (по крайней мере, для FastAPI).
+
+Таким образом:
+
+```Python
+q: Union[str, None] = Query(default=None)
+```
+
+...делает параметр необязательным со значением по умолчанию `None`, также как это делает:
+
+```Python
+q: Union[str, None] = None
+```
+
+И для Python 3.10 и выше:
+
+```Python
+q: str | None = Query(default=None)
+```
+
+...делает параметр необязательным со значением по умолчанию `None`, также как это делает:
+
+```Python
+q: str | None = None
+```
+
+Но он явно объявляет его как query-параметр.
+
+/// info | Дополнительная информация
+
+Запомните, важной частью объявления параметра как необязательного является:
+
+```Python
+= None
+```
+
+или:
+
+```Python
+= Query(default=None)
+```
+
+так как `None` указан в качестве значения по умолчанию, параметр будет **необязательным**.
+
+`Union[str, None]` позволит редактору кода оказать вам лучшую поддержку. Но это не то, на что обращает внимание FastAPI для определения необязательности параметра.
+
+///
+
+Теперь, мы можем указать больше параметров для `Query`. В данном случае, параметр `max_length` применяется к строкам:
+
+```Python
+q: Union[str, None] = Query(default=None, max_length=50)
+```
+
+Входные данные будут проверены. Если данные недействительны, тогда будет указано на ошибку в запросе (будет описание местонахождения ошибки и её причины). Кроме того, параметр задокументируется в схеме OpenAPI данной *операции пути*.
+
+### Использовать `Query` как значение по умолчанию или добавить в `Annotated`
+
+Когда `Query` используется внутри `Annotated`, вы не можете использовать параметр `default` у `Query`.
+
+Вместо этого, используйте обычное указание значения по умолчанию для параметра функции. Иначе, это будет несовместимо.
+
+Следующий пример не рабочий:
+
+```Python
+q: Annotated[str, Query(default="rick")] = "morty"
+```
+
+...потому что нельзя однозначно определить, что именно должно быть значением по умолчанию: `"rick"` или `"morty"`.
+
+Вам следует использовать (предпочтительно):
+
+```Python
+q: Annotated[str, Query()] = "rick"
+```
+
+...или как в старом коде, который вам может попасться:
+
+```Python
+q: str = Query(default="rick")
+```
+
+### Преимущества `Annotated`
+
+**Рекомендуется использовать `Annotated`** вместо значения по умолчанию в параметрах функции, потому что так **лучше** по нескольким причинам. 🤓
+
+Значение **по умолчанию** у **параметров функции** - это **действительно значение по умолчанию**, что более интуитивно понятно для пользователей Python. 😌
+
+Вы можете **вызвать** ту же функцию в **иных местах** без FastAPI, и она **сработает как ожидается**. Если это **обязательный** параметр (без значения по умолчанию), ваш **редактор кода** сообщит об ошибке. **Python** также укажет на ошибку, если вы вызовете функцию без передачи ей обязательного параметра.
+
+Если вы вместо `Annotated` используете **(устаревший) стиль значений по умолчанию**, тогда при вызове этой функции без FastAPI в **другом месте** вам необходимо **помнить** о передаче аргументов функции, чтобы она работала корректно. В противном случае, значения будут отличаться от тех, что вы ожидаете (например, `QueryInfo` или что-то подобное вместо `str`). И ни ваш редактор кода, ни Python не будут жаловаться на работу этой функции, только когда вычисления внутри дадут сбой.
+
+Так как `Annotated` может принимать более одной аннотации метаданных, то теперь вы можете использовать ту же функцию с другими инструментами, например
Typer. 🚀
+
+## Больше валидации
+
+Вы также можете добавить параметр `min_length`:
+
+{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
+
+## Регулярные выражения
+
+Вы можете определить
регулярное выражение, которому должен соответствовать параметр:
+
+{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
+
+Данное регулярное выражение проверяет, что полученное значение параметра:
+
+* `^`: начало строки.
+* `fixedquery`: в точности содержит строку `fixedquery`.
+* `$`: конец строки, не имеет символов после `fixedquery`.
+
+Не переживайте, если **"регулярное выражение"** вызывает у вас трудности. Это достаточно сложная тема для многих людей. Вы можете сделать множество вещей без использования регулярных выражений.
+
+Но когда они вам понадобятся, и вы закончите их освоение, то не будет проблемой использовать их в **FastAPI**.
+
+## Значения по умолчанию
+
+Вы точно также можете указать любое значение `по умолчанию`, как ранее указывали `None`.
+
+Например, вы хотите для параметра запроса `q` указать, что он должен состоять минимум из 3 символов (`min_length=3`) и иметь значение по умолчанию `"fixedquery"`:
+
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
+
+/// note | Технические детали
+
+Наличие значения по умолчанию делает параметр необязательным.
+
+///
+
+## Обязательный параметр
+
+Когда вам не требуется дополнительная валидация или дополнительные метаданные для параметра запроса, вы можете сделать параметр `q` обязательным просто не указывая значения по умолчанию. Например:
+
+```Python
+q: str
+```
+
+вместо:
+
+```Python
+q: Union[str, None] = None
+```
+
+Но у нас query-параметр определён как `Query`. Например:
+
+//// tab | Annotated
+
+```Python
+q: Annotated[Union[str, None], Query(min_length=3)] = None
+```
+
+////
+
+//// tab | без Annotated
+
+```Python
+q: Union[str, None] = Query(default=None, min_length=3)
+```
+
+////
+
+В таком случае, чтобы сделать query-параметр `Query` обязательным, вы можете просто не указывать значение по умолчанию:
+
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
+
+### Обязательный параметр с `None`
+
+Вы можете определить, что параметр может принимать `None`, но всё ещё является обязательным. Это может потребоваться для того, чтобы пользователи явно указали параметр, даже если его значение будет `None`.
+
+Чтобы этого добиться, вам нужно определить `None` как валидный тип для параметра запроса, но также указать `default=...`:
+
+{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
+
+/// tip | Подсказка
+
+Pydantic, мощь которого используется в FastAPI для валидации и сериализации, имеет специальное поведение для `Optional` или `Union[Something, None]` без значения по умолчанию. Вы можете узнать об этом больше в документации Pydantic, раздел
Обязательные Опциональные поля.
+
+///
+
+## Множество значений для query-параметра
+
+Для query-параметра `Query` можно указать, что он принимает список значений (множество значений).
+
+Например, query-параметр `q` может быть указан в URL несколько раз. И если вы ожидаете такой формат запроса, то можете указать это следующим образом:
+
+{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
+
+Затем, получив такой URL:
+
+```
+http://localhost:8000/items/?q=foo&q=bar
+```
+
+вы бы получили несколько значений (`foo` и `bar`), которые относятся к параметру `q`, в виде Python `list` внутри вашей *функции обработки пути*, в *параметре функции* `q`.
+
+Таким образом, ответ на этот URL будет:
+
+```JSON
+{
+ "q": [
+ "foo",
+ "bar"
+ ]
+}
+```
+
+/// tip | Подсказка
+
+Чтобы объявить query-параметр типом `list`, как в примере выше, вам нужно явно использовать `Query`, иначе он будет интерпретирован как тело запроса.
+
+///
+
+Интерактивная документация API будет обновлена соответствующим образом, где будет разрешено множество значений:
+
+

+
+### Query-параметр со множеством значений по умолчанию
+
+Вы также можете указать тип `list` со списком значений по умолчанию на случай, если вам их не предоставят:
+
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
+
+Если вы перейдёте по ссылке:
+
+```
+http://localhost:8000/items/
+```
+
+значение по умолчанию для `q` будет: `["foo", "bar"]` и ответом для вас будет:
+
+```JSON
+{
+ "q": [
+ "foo",
+ "bar"
+ ]
+}
+```
+
+#### Использование `list`
+
+Вы также можете использовать `list` напрямую вместо `List[str]` (или `list[str]` в Python 3.9+):
+
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
+
+/// note | Технические детали
+
+Запомните, что в таком случае, FastAPI не будет проверять содержимое списка.
+
+Например, для List[int] список будет провалидирован (и задокументирован) на содержание только целочисленных элементов. Но для простого `list` такой проверки не будет.
+
+///
+
+## Больше метаданных
+
+Вы можете добавить больше информации об query-параметре.
+
+Указанная информация будет включена в генерируемую OpenAPI документацию и использована в пользовательском интерфейсе и внешних инструментах.
+
+/// note | Технические детали
+
+Имейте в виду, что разные инструменты могут иметь разные уровни поддержки OpenAPI.
+
+Некоторые из них могут не отображать (на данный момент) всю заявленную дополнительную информацию, хотя в большинстве случаев отсутствующая функция уже запланирована к разработке.
+
+///
+
+Вы можете указать название query-параметра, используя параметр `title`:
+
+{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
+
+Добавить описание, используя параметр `description`:
+
+{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
+
+## Псевдонимы параметров
+
+Представьте, что вы хотите использовать query-параметр с названием `item-query`.
+
+Например:
+
+```
+http://127.0.0.1:8000/items/?item-query=foobaritems
+```
+
+Но `item-query` является невалидным именем переменной в Python.
+
+Наиболее похожее валидное имя `item_query`.
+
+Но вам всё равно необходим `item-query`...
+
+Тогда вы можете объявить `псевдоним`, и этот псевдоним будет использоваться для поиска значения параметра запроса:
+
+{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
+
+## Устаревшие параметры
+
+Предположим, вы больше не хотите использовать какой-либо параметр.
+
+Вы решили оставить его, потому что клиенты всё ещё им пользуются. Но вы хотите отобразить это в документации как
устаревший функционал.
+
+Тогда для `Query` укажите параметр `deprecated=True`:
+
+{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
+
+В документации это будет отображено следующим образом:
+
+

+
+## Исключить из OpenAPI
+
+Чтобы исключить query-параметр из генерируемой OpenAPI схемы (а также из системы автоматической генерации документации), укажите в `Query` параметр `include_in_schema=False`:
+
+{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
+
+## Резюме
+
+Вы можете объявлять дополнительные правила валидации и метаданные для ваших параметров запроса.
+
+Общие метаданные:
+
+* `alias`
+* `title`
+* `description`
+* `deprecated`
+* `include_in_schema`
+
+Специфичные правила валидации для строк:
+
+* `min_length`
+* `max_length`
+* `regex`
+
+В рассмотренных примерах показано объявление правил валидации для строковых значений `str`.
+
+В следующих главах вы увидете, как объявлять правила валидации для других типов (например, чисел).
diff --git a/docs/ru/docs/tutorial/query-params.md b/docs/ru/docs/tutorial/query-params.md
new file mode 100644
index 000000000..547d9831d
--- /dev/null
+++ b/docs/ru/docs/tutorial/query-params.md
@@ -0,0 +1,187 @@
+# Query-параметры
+
+Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
+
+{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+
+Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`.
+
+Например, в этом URL-адресе:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+...параметры запроса такие:
+
+* `skip`: со значением `0`
+* `limit`: со значением `10`
+
+Будучи частью URL-адреса, они "по умолчанию" являются строками.
+
+Но когда вы объявляете их с использованием аннотаций (в примере выше, как `int`), они конвертируются в указанный тип данных и проходят проверку на соответствие ему.
+
+Все те же правила, которые применяются к path-параметрам, также применяются и query-параметрам:
+
+* Поддержка от редактора кода (очевидно)
+*
"Парсинг" данных
+* Проверка на соответствие данных (Валидация)
+* Автоматическая документация
+
+## Значения по умолчанию
+
+Поскольку query-параметры не являются фиксированной частью пути, они могут быть не обязательными и иметь значения по умолчанию.
+
+В примере выше значения по умолчанию равны `skip=0` и `limit=10`.
+
+Таким образом, результат перехода по URL-адресу:
+
+```
+http://127.0.0.1:8000/items/
+```
+
+будет таким же, как если перейти используя параметры по умолчанию:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+Но если вы введёте, например:
+
+```
+http://127.0.0.1:8000/items/?skip=20
+```
+
+Значения параметров в вашей функции будут:
+
+* `skip=20`: потому что вы установили это в URL-адресе
+* `limit=10`: т.к это было значение по умолчанию
+
+## Необязательные параметры
+
+Аналогично, вы можете объявлять необязательные query-параметры, установив их значение по умолчанию, равное `None`:
+
+{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
+
+В этом случае, параметр `q` будет не обязательным и будет иметь значение `None` по умолчанию.
+
+/// check | Важно
+
+Также обратите внимание, что **FastAPI** достаточно умён чтобы заметить, что параметр `item_id` является path-параметром, а `q` нет, поэтому, это параметр запроса.
+
+///
+
+## Преобразование типа параметра запроса
+
+Вы также можете объявлять параметры с типом `bool`, которые будут преобразованы соответственно:
+
+{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
+
+В этом случае, если вы сделаете запрос:
+
+```
+http://127.0.0.1:8000/items/foo?short=1
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=True
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=true
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=on
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=yes
+```
+
+или в любом другом варианте написания (в верхнем регистре, с заглавной буквой, и т.п), внутри вашей функции параметр `short` будет иметь значение `True` типа данных `bool` . В противном случае - `False`.
+
+
+## Смешивание query-параметров и path-параметров
+
+Вы можете объявлять несколько query-параметров и path-параметров одновременно,**FastAPI** сам разберётся, что чем является.
+
+И вы не обязаны объявлять их в каком-либо определенном порядке.
+
+Они будут обнаружены по именам:
+
+{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
+
+## Обязательные query-параметры
+
+Когда вы объявляете значение по умолчанию для параметра, который не является path-параметром (в этом разделе, мы пока что познакомились только с path-параметрами), то это значение не является обязательным.
+
+Если вы не хотите задавать конкретное значение, но хотите сделать параметр необязательным, вы можете установить значение по умолчанию равным `None`.
+
+Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
+
+{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+
+Здесь параметр запроса `needy` является обязательным параметром с типом данных `str`.
+
+Если вы откроете в браузере URL-адрес, например:
+
+```
+http://127.0.0.1:8000/items/foo-item
+```
+
+...без добавления обязательного параметра `needy`, вы увидите подобного рода ошибку:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "query",
+ "needy"
+ ],
+ "msg": "field required",
+ "type": "value_error.missing"
+ }
+ ]
+}
+```
+
+Поскольку `needy` является обязательным параметром, вам необходимо указать его в URL-адресе:
+
+```
+http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
+```
+
+...это будет работать:
+
+```JSON
+{
+ "item_id": "foo-item",
+ "needy": "sooooneedy"
+}
+```
+
+Конечно, вы можете определить некоторые параметры как обязательные, некоторые - со значением по умполчанию, а некоторые - полностью необязательные:
+
+{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
+
+В этом примере, у нас есть 3 параметра запроса:
+
+* `needy`, обязательный `str`.
+* `skip`, типа `int` и со значением по умолчанию `0`.
+* `limit`, необязательный `int`.
+
+/// tip | Подсказка
+
+Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#_7){.internal-link target=_blank}.
+
+///
diff --git a/docs/ru/docs/tutorial/request-files.md b/docs/ru/docs/tutorial/request-files.md
new file mode 100644
index 000000000..2cfa4e1dc
--- /dev/null
+++ b/docs/ru/docs/tutorial/request-files.md
@@ -0,0 +1,172 @@
+# Загрузка файлов
+
+Используя класс `File`, мы можем позволить клиентам загружать файлы.
+
+/// info | Дополнительная информация
+
+Чтобы получать загруженные файлы, сначала установите
`python-multipart`.
+
+Например: `pip install python-multipart`.
+
+Это связано с тем, что загружаемые файлы передаются как данные формы.
+
+///
+
+## Импорт `File`
+
+Импортируйте `File` и `UploadFile` из модуля `fastapi`:
+
+{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
+
+## Определите параметры `File`
+
+Создайте параметры `File` так же, как вы это делаете для `Body` или `Form`:
+
+{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
+
+/// info | Дополнительная информация
+
+`File` - это класс, который наследуется непосредственно от `Form`.
+
+Но помните, что когда вы импортируете `Query`, `Path`, `File` и другие из `fastapi`, на самом деле это функции, которые возвращают специальные классы.
+
+///
+
+/// tip | Подсказка
+
+Для объявления тела файла необходимо использовать `File`, поскольку в противном случае параметры будут интерпретироваться как параметры запроса или параметры тела (JSON).
+
+///
+
+Файлы будут загружены как данные формы.
+
+Если вы объявите тип параметра у *функции операции пути* как `bytes`, то **FastAPI** прочитает файл за вас, и вы получите его содержимое в виде `bytes`.
+
+Следует иметь в виду, что все содержимое будет храниться в памяти. Это хорошо подходит для небольших файлов.
+
+Однако возможны случаи, когда использование `UploadFile` может оказаться полезным.
+
+## Загрузка файла с помощью `UploadFile`
+
+Определите параметр файла с типом `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
+
+Использование `UploadFile` имеет ряд преимуществ перед `bytes`:
+
+* Использовать `File()` в значении параметра по умолчанию не обязательно.
+* При этом используется "буферный" файл:
+ * Файл, хранящийся в памяти до максимального предела размера, после преодоления которого он будет храниться на диске.
+* Это означает, что он будет хорошо работать с большими файлами, такими как изображения, видео, большие бинарные файлы и т.д., не потребляя при этом всю память.
+* Из загруженного файла можно получить метаданные.
+* Он реализует
file-like `async` интерфейс.
+* Он предоставляет реальный объект Python
`SpooledTemporaryFile` который вы можете передать непосредственно другим библиотекам, которые ожидают файл в качестве объекта.
+
+### `UploadFile`
+
+`UploadFile` имеет следующие атрибуты:
+
+* `filename`: Строка `str` с исходным именем файла, который был загружен (например, `myimage.jpg`).
+* `content_type`: Строка `str` с типом содержимого (MIME type / media type) (например, `image/jpeg`).
+* `file`:
`SpooledTemporaryFile` (a
file-like объект). Это фактический файл Python, который можно передавать непосредственно другим функциям или библиотекам, ожидающим файл в качестве объекта.
+
+`UploadFile` имеет следующие методы `async`. Все они вызывают соответствующие файловые методы (используя внутренний SpooledTemporaryFile).
+
+* `write(data)`: Записать данные `data` (`str` или `bytes`) в файл.
+* `read(size)`: Прочитать количество `size` (`int`) байт/символов из файла.
+* `seek(offset)`: Перейти к байту на позиции `offset` (`int`) в файле.
+ * Наример, `await myfile.seek(0)` перейдет к началу файла.
+ * Это особенно удобно, если вы один раз выполнили команду `await myfile.read()`, а затем вам нужно прочитать содержимое файла еще раз.
+* `close()`: Закрыть файл.
+
+Поскольку все эти методы являются `async` методами, вам следует использовать "await" вместе с ними.
+
+Например, внутри `async` *функции операции пути* можно получить содержимое с помощью:
+
+```Python
+contents = await myfile.read()
+```
+
+Если вы находитесь внутри обычной `def` *функции операции пути*, можно получить прямой доступ к файлу `UploadFile.file`, например:
+
+```Python
+contents = myfile.file.read()
+```
+
+/// note | Технические детали `async`
+
+При использовании методов `async` **FastAPI** запускает файловые методы в пуле потоков и ожидает их.
+
+///
+
+/// note | Технические детали Starlette
+
+**FastAPI** наследует `UploadFile` непосредственно из **Starlette**, но добавляет некоторые детали для совместимости с **Pydantic** и другими частями FastAPI.
+
+///
+
+## Про данные формы ("Form Data")
+
+Способ, которым HTML-формы (`
`) отправляют данные на сервер, обычно использует "специальную" кодировку для этих данных, отличную от JSON.
+
+**FastAPI** позаботится о том, чтобы считать эти данные из нужного места, а не из JSON.
+
+/// note | Технические детали
+
+Данные из форм обычно кодируются с использованием "media type" `application/x-www-form-urlencoded` когда он не включает файлы.
+
+Но когда форма включает файлы, она кодируется как multipart/form-data. Если вы используете `File`, **FastAPI** будет знать, что ему нужно получить файлы из нужной части тела.
+
+Если вы хотите узнать больше об этих кодировках и полях форм, перейдите по ссылке
MDN web docs for POST
.
+
+///
+
+/// warning | Внимание
+
+В операции *функции операции пути* можно объявить несколько параметров `File` и `Form`, но нельзя также объявлять поля `Body`, которые предполагается получить в виде JSON, поскольку тело запроса будет закодировано с помощью `multipart/form-data`, а не `application/json`.
+
+Это не является ограничением **FastAPI**, это часть протокола HTTP.
+
+///
+
+## Необязательная загрузка файлов
+
+Вы можете сделать загрузку файла необязательной, используя стандартные аннотации типов и установив значение по умолчанию `None`:
+
+{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
+
+## `UploadFile` с дополнительными метаданными
+
+Вы также можете использовать `File()` вместе с `UploadFile`, например, для установки дополнительных метаданных:
+
+{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
+
+## Загрузка нескольких файлов
+
+Можно одновременно загружать несколько файлов.
+
+Они будут связаны с одним и тем же "полем формы", отправляемым с помощью данных формы.
+
+Для этого необходимо объявить список `bytes` или `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
+
+Вы получите, как и было объявлено, список `list` из `bytes` или `UploadFile`.
+
+/// note | Technical Details
+
+Можно также использовать `from starlette.responses import HTMLResponse`.
+
+**FastAPI** предоставляет тот же `starlette.responses`, что и `fastapi.responses`, просто для удобства разработчика. Однако большинство доступных ответов поступает непосредственно из Starlette.
+
+///
+
+### Загрузка нескольких файлов с дополнительными метаданными
+
+Так же, как и раньше, вы можете использовать `File()` для задания дополнительных параметров, даже для `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
+
+## Резюме
+
+Используйте `File`, `bytes` и `UploadFile` для работы с файлами, которые будут загружаться и передаваться в виде данных формы.
diff --git a/docs/ru/docs/tutorial/request-form-models.md b/docs/ru/docs/tutorial/request-form-models.md
new file mode 100644
index 000000000..1034ed27f
--- /dev/null
+++ b/docs/ru/docs/tutorial/request-form-models.md
@@ -0,0 +1,78 @@
+# Модели форм
+
+Вы можете использовать **Pydantic-модели** для объявления **полей форм** в FastAPI.
+
+/// info | Дополнительная информация
+
+Чтобы использовать формы, сначала установите
`python-multipart`.
+
+Убедитесь, что вы создали и активировали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, а затем установите пакет, например:
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+/// note | Заметка
+
+Этот функционал доступен с версии `0.113.0`. 🤓
+
+///
+
+## Pydantic-модель для формы
+
+Вам просто нужно объявить **Pydantic-модель** с полями, которые вы хотите получить как **поля формы**, а затем объявить параметр как `Form`:
+
+{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
+
+**FastAPI** **извлечёт** данные для **каждого поля** из **данных формы** в запросе и выдаст вам объявленную Pydantic-модель.
+
+## Проверка сгенерированной документации
+
+Вы можете посмотреть поля формы в графическом интерфейсе Документации по пути `/docs`:
+
+
+

+
+
+## Запрет дополнительных полей формы
+
+В некоторых случаях (не особо часто встречающихся) вам может понадобиться **ограничить** поля формы только теми, которые объявлены в Pydantic-модели. И **запретить** любые **дополнительные** поля.
+
+/// note | Заметка
+
+Этот функционал доступен с версии `0.114.0`. 🤓
+
+///
+
+Вы можете сконфигурировать Pydantic-модель так, чтобы запретить (`forbid`) все дополнительные (`extra`) поля:
+
+{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
+
+Если клиент попробует отправить дополнительные данные, то в ответ он получит **ошибку**.
+
+Например, если клиент попытается отправить поля формы:
+
+* `username`: `Rick`
+* `password`: `Portal Gun`
+* `extra`: `Mr. Poopybutthole`
+
+То в ответ он получит **ошибку**, сообщающую ему, что поле `extra` не разрешено:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "Mr. Poopybutthole"
+ }
+ ]
+}
+```
+
+## Заключение
+
+Вы можете использовать Pydantic-модели для объявления полей форм в FastAPI. 😎
diff --git a/docs/ru/docs/tutorial/request-forms-and-files.md b/docs/ru/docs/tutorial/request-forms-and-files.md
new file mode 100644
index 000000000..116c0cdb1
--- /dev/null
+++ b/docs/ru/docs/tutorial/request-forms-and-files.md
@@ -0,0 +1,37 @@
+# Файлы и формы в запросе
+
+Вы можете определять файлы и поля формы одновременно, используя `File` и `Form`.
+
+/// info | Дополнительная информация
+
+Чтобы получать загруженные файлы и/или данные форм, сначала установите
`python-multipart`.
+
+Например: `pip install python-multipart`.
+
+///
+
+## Импортируйте `File` и `Form`
+
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
+
+## Определите параметры `File` и `Form`
+
+Создайте параметры файла и формы таким же образом, как для `Body` или `Query`:
+
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
+
+Файлы и поля формы будут загружены в виде данных формы, и вы получите файлы и поля формы.
+
+Вы можете объявить некоторые файлы как `bytes`, а некоторые - как `UploadFile`.
+
+/// warning | Внимание
+
+Вы можете объявить несколько параметров `File` и `Form` в операции *path*, но вы не можете также объявить поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с помощью `multipart/form-data` вместо `application/json`.
+
+Это не ограничение **Fast API**, это часть протокола HTTP.
+
+///
+
+## Резюме
+
+Используйте `File` и `Form` вместе, когда необходимо получить данные и файлы в одном запросе.
diff --git a/docs/ru/docs/tutorial/request-forms.md b/docs/ru/docs/tutorial/request-forms.md
new file mode 100644
index 000000000..b33ea044b
--- /dev/null
+++ b/docs/ru/docs/tutorial/request-forms.md
@@ -0,0 +1,69 @@
+# Данные формы
+
+Когда вам нужно получить поля формы вместо JSON, вы можете использовать `Form`.
+
+/// info | Дополнительная информация
+
+Чтобы использовать формы, сначала установите
`python-multipart`.
+
+Например, выполните команду `pip install python-multipart`.
+
+///
+
+## Импорт `Form`
+
+Импортируйте `Form` из `fastapi`:
+
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
+
+## Определение параметров `Form`
+
+Создайте параметры формы так же, как это делается для `Body` или `Query`:
+
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
+
+Например, в одном из способов использования спецификации OAuth2 (называемом "потоком пароля") требуется отправить `username` и `password` в виде полей формы.
+
+Данный способ требует отправку данных для авторизации посредством формы (а не JSON) и обязательного наличия в форме строго именованных полей `username` и `password`.
+
+Вы можете настроить `Form` точно так же, как настраиваете и `Body` ( `Query`, `Path`, `Cookie`), включая валидации, примеры, псевдонимы (например, `user-name` вместо `username`) и т.д.
+
+/// info | Дополнительная информация
+
+`Form` - это класс, который наследуется непосредственно от `Body`.
+
+///
+
+/// tip | Подсказка
+
+Вам необходимо явно указывать параметр `Form` при объявлении каждого поля, иначе поля будут интерпретироваться как параметры запроса или параметры тела (JSON).
+
+///
+
+## О "полях формы"
+
+Обычно способ, которым HTML-формы (`
`) отправляют данные на сервер, использует "специальное" кодирование для этих данных, отличное от JSON.
+
+**FastAPI** гарантирует правильное чтение этих данных из соответствующего места, а не из JSON.
+
+/// note | Технические детали
+
+Данные из форм обычно кодируются с использованием "типа медиа" `application/x-www-form-urlencoded`.
+
+Но когда форма содержит файлы, она кодируется как `multipart/form-data`. Вы узнаете о работе с файлами в следующей главе.
+
+Если вы хотите узнать больше про кодировки и поля формы, ознакомьтесь с
документацией MDN для `POST` на веб-сайте.
+
+///
+
+/// warning | Предупреждение
+
+Вы можете объявлять несколько параметров `Form` в *операции пути*, но вы не можете одновременно с этим объявлять поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с использованием `application/x-www-form-urlencoded`, а не `application/json`.
+
+Это не ограничение **FastAPI**, это часть протокола HTTP.
+
+///
+
+## Резюме
+
+Используйте `Form` для объявления входных параметров данных формы.
diff --git a/docs/ru/docs/tutorial/response-model.md b/docs/ru/docs/tutorial/response-model.md
new file mode 100644
index 000000000..b3c29281c
--- /dev/null
+++ b/docs/ru/docs/tutorial/response-model.md
@@ -0,0 +1,339 @@
+# Модель ответа - Возвращаемый тип
+
+Вы можете объявить тип ответа, указав аннотацию **возвращаемого значения** для *функции операции пути*.
+
+FastAPI позволяет использовать **аннотации типов** таким же способом, как и для ввода данных в **параметры** функции, вы можете использовать модели Pydantic, списки, словари, скалярные типы (такие, как int, bool и т.д.).
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+FastAPI будет использовать этот возвращаемый тип для:
+
+* **Валидации** ответа.
+ * Если данные невалидны (например, отсутствует одно из полей), это означает, что код *вашего* приложения работает некорректно и функция возвращает не то, что вы ожидаете. В таком случае приложение вернет server error вместо того, чтобы отправить неправильные данные. Таким образом, вы и ваши пользователи можете быть уверены, что получите корректные данные в том виде, в котором они ожидаются.
+* Добавьте **JSON схему** для ответа внутри *операции пути* OpenAPI.
+ * Она будет использована для **автоматически генерируемой документации**.
+ * А также - для автоматической кодогенерации пользователями.
+
+Но самое важное:
+
+* Ответ будет **ограничен и отфильтрован** - т.е. в нем останутся только те данные, которые определены в возвращаемом типе.
+ * Это особенно важно для **безопасности**, далее мы рассмотрим эту тему подробнее.
+
+## Параметр `response_model`
+
+Бывают случаи, когда вам необходимо (или просто хочется) возвращать данные, которые не полностью соответствуют объявленному типу.
+
+Допустим, вы хотите, чтобы ваша функция **возвращала словарь (dict)** или объект из базы данных, но при этом **объявляете выходной тип как модель Pydantic**. Тогда именно указанная модель будет использована для автоматической документации, валидации и т.п. для объекта, который вы вернули (например, словаря или объекта из базы данных).
+
+Но если указать аннотацию возвращаемого типа, статическая проверка типов будет выдавать ошибку (абсолютно корректную в данном случае). Она будет говорить о том, что ваша функция должна возвращать данные одного типа (например, dict), а в аннотации вы объявили другой тип (например, модель Pydantic).
+
+В таком случае можно использовать параметр `response_model` внутри *декоратора операции пути* вместо аннотации возвращаемого значения функции.
+
+Параметр `response_model` может быть указан для любой *операции пути*:
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* и др.
+
+{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
+
+/// note | Технические детали
+
+Помните, что параметр `response_model` является параметром именно декоратора http-методов (`get`, `post`, и т.п.). Не следует его указывать для *функций операций пути*, как вы бы поступили с другими параметрами или с телом запроса.
+
+///
+
+`response_model` принимает те же типы, которые можно указать для какого-либо поля в модели Pydantic. Таким образом, это может быть как одиночная модель Pydantic, так и `список (list)` моделей Pydantic. Например, `List[Item]`.
+
+FastAPI будет использовать значение `response_model` для того, чтобы автоматически генерировать документацию, производить валидацию и т.п. А также для **конвертации и фильтрации выходных данных** в объявленный тип.
+
+/// tip | Подсказка
+
+Если вы используете анализаторы типов со строгой проверкой (например, mypy), можно указать `Any` в качестве типа возвращаемого значения функции.
+
+Таким образом вы информируете ваш редактор кода, что намеренно возвращаете данные неопределенного типа. Но возможности FastAPI, такие как автоматическая генерация документации, валидация, фильтрация и т.д. все так же будут работать, просто используя параметр `response_model`.
+
+///
+
+### Приоритет `response_model`
+
+Если одновременно указать аннотацию типа для ответа функции и параметр `response_model` - последний будет иметь больший приоритет и FastAPI будет использовать именно его.
+
+Таким образом вы можете объявить корректные аннотации типов к вашим функциям, даже если они возвращают тип, отличающийся от указанного в `response_model`. Они будут считаны во время статической проверки типов вашими помощниками, например, mypy. При этом вы все так же используете возможности FastAPI для автоматической документации, валидации и т.д. благодаря `response_model`.
+
+Вы можете указать значение `response_model=None`, чтобы отключить создание модели ответа для данной *операции пути*. Это может понадобиться, если вы добавляете аннотации типов для данных, не являющихся валидными полями Pydantic. Мы увидим пример кода для такого случая в одном из разделов ниже.
+
+## Получить и вернуть один и тот же тип данных
+
+Здесь мы объявили модель `UserIn`, которая хранит пользовательский пароль в открытом виде:
+
+{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
+
+/// info | Информация
+
+Чтобы использовать `EmailStr`, прежде необходимо установить
`email-validator`.
+Используйте `pip install email-validator`
+или `pip install pydantic[email]`.
+
+///
+
+Далее мы используем нашу модель в аннотациях типа как для аргумента функции, так и для выходного значения:
+
+{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}
+
+Теперь всякий раз, когда клиент создает пользователя с паролем, API будет возвращать его пароль в ответе.
+
+В данном случае это не такая уж большая проблема, поскольку ответ получит тот же самый пользователь, который и создал пароль.
+
+Но что если мы захотим использовать эту модель для какой-либо другой *операции пути*? Мы можем, сами того не желая, отправить пароль любому другому пользователю.
+
+/// danger | Осторожно
+
+Никогда не храните пароли пользователей в открытом виде, а также никогда не возвращайте их в ответе, как в примере выше. В противном случае - убедитесь, что вы хорошо продумали и учли все возможные риски такого подхода и вам известно, что вы делаете.
+
+///
+
+## Создание модели для ответа
+
+Вместо этого мы можем создать входную модель, хранящую пароль в открытом виде и выходную модель без пароля:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
+
+В таком случае, даже несмотря на то, что наша *функция операции пути* возвращает тот же самый объект пользователя с паролем, полученным на вход:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
+
+...мы указали в `response_model` модель `UserOut`, в которой отсутствует поле, содержащее пароль - и он будет исключен из ответа:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
+
+Таким образом **FastAPI** позаботится о фильтрации ответа и исключит из него всё, что не указано в выходной модели (при помощи Pydantic).
+
+### `response_model` или возвращаемый тип данных
+
+В нашем примере модели входных данных и выходных данных различаются. И если мы укажем аннотацию типа выходного значения функции как `UserOut` - проверка типов выдаст ошибку из-за того, что мы возвращаем некорректный тип. Поскольку это 2 разных класса.
+
+Поэтому в нашем примере мы можем объявить тип ответа только в параметре `response_model`.
+
+...но продолжайте читать дальше, чтобы узнать как можно это обойти.
+
+## Возвращаемый тип и Фильтрация данных
+
+Продолжим рассматривать предыдущий пример. Мы хотели **аннотировать входные данные одним типом**, а выходное значение - **другим типом**.
+
+Мы хотим, чтобы FastAPI продолжал **фильтровать** данные, используя `response_model`.
+
+В прошлом примере, т.к. входной и выходной типы являлись разными классами, мы были вынуждены использовать параметр `response_model`. И как следствие, мы лишались помощи статических анализаторов для проверки ответа функции.
+
+Но в подавляющем большинстве случаев мы будем хотеть, чтобы модель ответа лишь **фильтровала/удаляла** некоторые данные из ответа, как в нашем примере.
+
+И в таких случаях мы можем использовать классы и наследование, чтобы пользоваться преимуществами **аннотаций типов** и получать более полную статическую проверку типов. Но при этом все так же получать **фильтрацию ответа** от FastAPI.
+
+{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
+
+Таким образом, мы получаем поддержку редактора кода и mypy в части типов, сохраняя при этом фильтрацию данных от FastAPI.
+
+Как это возможно? Давайте разберемся. 🤓
+
+### Аннотации типов и инструменты для их проверки
+
+Для начала давайте рассмотрим как наш редактор кода, mypy и другие помощники разработчика видят аннотации типов.
+
+У модели `BaseUser` есть некоторые поля. Затем `UserIn` наследуется от `BaseUser` и добавляет новое поле `password`. Таким образом модель будет включать в себя все поля из первой модели (родителя), а также свои собственные.
+
+Мы аннотируем возвращаемый тип функции как `BaseUser`, но фактически мы будем возвращать объект типа `UserIn`.
+
+Редакторы, mypy и другие инструменты не будут иметь возражений против такого подхода, поскольку `UserIn` является подклассом `BaseUser`. Это означает, что такой тип будет *корректным*, т.к. ответ может быть чем угодно, если это будет `BaseUser`.
+
+### Фильтрация Данных FastAPI
+
+FastAPI знает тип ответа функции, так что вы можете быть уверены, что на выходе будут **только** те поля, которые вы указали.
+
+FastAPI совместно с Pydantic выполнит некоторую магию "под капотом", чтобы убедиться, что те же самые правила наследования классов не используются для фильтрации возвращаемых данных, в противном случае вы могли бы в конечном итоге вернуть гораздо больше данных, чем ожидали.
+
+Таким образом, вы можете получить все самое лучшее из обоих миров: аннотации типов с **поддержкой инструментов для разработки** и **фильтрацию данных**.
+
+## Автоматическая документация
+
+Если посмотреть на сгенерированную документацию, вы можете убедиться, что в ней присутствуют обе JSON схемы - как для входной модели, так и для выходной:
+
+

+
+И также обе модели будут использованы в интерактивной документации API:
+
+

+
+## Другие аннотации типов
+
+Бывают случаи, когда вы возвращаете что-то, что не является валидным типом для Pydantic и вы указываете аннотацию ответа функции только для того, чтобы работала поддержка различных инструментов (редактор кода, mypy и др.).
+
+### Возвращаем Response
+
+Самый частый сценарий использования - это [возвращать Response напрямую, как описано в расширенной документации](../advanced/response-directly.md){.internal-link target=_blank}.
+
+{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
+
+Это поддерживается FastAPI по-умолчанию, т.к. аннотация проставлена в классе (или подклассе) `Response`.
+
+И ваши помощники разработки также будут счастливы, т.к. оба класса `RedirectResponse` и `JSONResponse` являются подклассами `Response`. Таким образом мы получаем корректную аннотацию типа.
+
+### Подкласс Response в аннотации типа
+
+Вы также можете указать подкласс `Response` в аннотации типа:
+
+{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
+
+Это сработает, потому что `RedirectResponse` является подклассом `Response` и FastAPI автоматически обработает этот простейший случай.
+
+### Некорректные аннотации типов
+
+Но когда вы возвращаете какой-либо другой произвольный объект, который не является допустимым типом Pydantic (например, объект из базы данных), и вы аннотируете его подобным образом для функции, FastAPI попытается создать из этого типа модель Pydantic и потерпит неудачу.
+
+То же самое произошло бы, если бы у вас было что-то вроде
Union различных типов и один или несколько из них не являлись бы допустимыми типами для Pydantic. Например, такой вариант приведет к ошибке 💥:
+
+{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
+
+...такой код вызовет ошибку, потому что в аннотации указан неподдерживаемый Pydantic тип. А также этот тип не является классом или подклассом `Response`.
+
+### Возможно ли отключить генерацию модели ответа?
+
+Продолжим рассматривать предыдущий пример. Допустим, что вы хотите отказаться от автоматической валидации ответа, документации, фильтрации и т.д.
+
+Но в то же время, хотите сохранить аннотацию возвращаемого типа для функции, чтобы обеспечить работу помощников и анализаторов типов (например, mypy).
+
+В таком случае, вы можете отключить генерацию модели ответа, указав `response_model=None`:
+
+{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
+
+Тогда FastAPI не станет генерировать модель ответа и вы сможете сохранить такую аннотацию типа, которая вам требуется, никак не влияя на работу FastAPI. 🤓
+
+## Параметры модели ответа
+
+Модель ответа может иметь значения по умолчанию, например:
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}
+
+* `description: Union[str, None] = None` (или `str | None = None` в Python 3.10), где `None` является значением по умолчанию.
+* `tax: float = 10.5`, где `10.5` является значением по умолчанию.
+* `tags: List[str] = []`, где пустой список `[]` является значением по умолчанию.
+
+но вы, возможно, хотели бы исключить их из ответа, если данные поля не были заданы явно.
+
+Например, у вас есть модель с множеством необязательных полей в NoSQL базе данных, но вы не хотите отправлять в качестве ответа очень длинный JSON с множеством значений по умолчанию.
+
+### Используйте параметр `response_model_exclude_unset`
+
+Установите для *декоратора операции пути* параметр `response_model_exclude_unset=True`:
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}
+
+и тогда значения по умолчанию не будут включены в ответ. В нем будут только те поля, значения которых фактически были установлены.
+
+Итак, если вы отправите запрос на данную *операцию пути* для элемента, с ID = `Foo` - ответ (с исключенными значениями по-умолчанию) будет таким:
+
+```JSON
+{
+ "name": "Foo",
+ "price": 50.2
+}
+```
+
+/// info | Информация
+
+"Под капотом" FastAPI использует метод `.dict()` у объектов моделей Pydantic
с параметром `exclude_unset`, чтобы достичь такого эффекта.
+
+///
+
+/// info | Информация
+
+Вы также можете использовать:
+
+* `response_model_exclude_defaults=True`
+* `response_model_exclude_none=True`
+
+как описано в
документации Pydantic для параметров `exclude_defaults` и `exclude_none`.
+
+///
+
+#### Если значение поля отличается от значения по-умолчанию
+
+Если для некоторых полей модели, имеющих значения по-умолчанию, значения были явно установлены - как для элемента с ID = `Bar`, ответ будет таким:
+
+```Python hl_lines="3 5"
+{
+ "name": "Bar",
+ "description": "The bartenders",
+ "price": 62,
+ "tax": 20.2
+}
+```
+
+они не будут исключены из ответа.
+
+#### Если значение поля совпадает с его значением по умолчанию
+
+Если данные содержат те же значения, которые являются для этих полей по умолчанию, но были установлены явно - как для элемента с ID = `baz`, ответ будет таким:
+
+```Python hl_lines="3 5-6"
+{
+ "name": "Baz",
+ "description": None,
+ "price": 50.2,
+ "tax": 10.5,
+ "tags": []
+}
+```
+
+FastAPI достаточно умен (на самом деле, это заслуга Pydantic), чтобы понять, что, хотя `description`, `tax` и `tags` хранят такие же данные, какие должны быть по умолчанию - для них эти значения были установлены явно (а не получены из значений по умолчанию).
+
+И поэтому, они также будут включены в JSON ответа.
+
+/// tip | Подсказка
+
+Значением по умолчанию может быть что угодно, не только `None`.
+
+Им может быть и список (`[]`), значение 10.5 типа `float`, и т.п.
+
+///
+
+### `response_model_include` и `response_model_exclude`
+
+Вы также можете использовать параметры *декоратора операции пути*, такие, как `response_model_include` и `response_model_exclude`.
+
+Они принимают аргументы типа `set`, состоящий из строк (`str`) с названиями атрибутов, которые либо требуется включить в ответ (при этом исключив все остальные), либо наоборот исключить (оставив в ответе все остальные поля).
+
+Это можно использовать как быстрый способ исключить данные из ответа, не создавая отдельную модель Pydantic.
+
+/// tip | Подсказка
+
+Но по-прежнему рекомендуется следовать изложенным выше советам и использовать несколько моделей вместо данных параметров.
+
+Потому как JSON схема OpenAPI, генерируемая вашим приложением (а также документация) все еще будет содержать все поля, даже если вы использовали `response_model_include` или `response_model_exclude` и исключили некоторые атрибуты.
+
+То же самое применимо к параметру `response_model_by_alias`.
+
+///
+
+{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}
+
+/// tip | Подсказка
+
+При помощи кода `{"name","description"}` создается объект множества (`set`) с двумя строковыми значениями.
+
+Того же самого можно достичь используя `set(["name", "description"])`.
+
+///
+
+#### Что если использовать `list` вместо `set`?
+
+Если вы забыли про `set` и использовали структуру `list` или `tuple`, FastAPI автоматически преобразует этот объект в `set`, чтобы обеспечить корректную работу:
+
+{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
+
+## Резюме
+
+Используйте параметр `response_model` у *декоратора операции пути* для того, чтобы задать модель ответа и в большей степени для того, чтобы быть уверенным, что приватная информация будет отфильтрована.
+
+А также используйте `response_model_exclude_unset`, чтобы возвращать только те значения, которые были заданы явно.
diff --git a/docs/ru/docs/tutorial/response-status-code.md b/docs/ru/docs/tutorial/response-status-code.md
new file mode 100644
index 000000000..b46f656f3
--- /dev/null
+++ b/docs/ru/docs/tutorial/response-status-code.md
@@ -0,0 +1,101 @@
+# HTTP коды статуса ответа
+
+Вы можете задать HTTP код статуса ответа с помощью параметра `status_code` подобно тому, как вы определяете схему ответа в любой из *операций пути*:
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* и других.
+
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+
+/// note | Примечание
+
+Обратите внимание, что `status_code` является атрибутом метода-декоратора (`get`, `post` и т.д.), а не *функции-обработчика пути* в отличие от всех остальных параметров и тела запроса.
+
+///
+
+Параметр `status_code` принимает число, обозначающее HTTP код статуса ответа.
+
+/// info | Информация
+
+В качестве значения параметра `status_code` также может использоваться `IntEnum`, например, из библиотеки
`http.HTTPStatus` в Python.
+
+///
+
+Это позволит:
+
+* Возвращать указанный код статуса в ответе.
+* Документировать его как код статуса ответа в OpenAPI схеме (а значит, и в пользовательском интерфейсе):
+
+

+
+/// note | Примечание
+
+Некоторые коды статуса ответа (см. следующий раздел) указывают на то, что ответ не имеет тела.
+
+FastAPI знает об этом и создаст документацию OpenAPI, в которой будет указано, что тело ответа отсутствует.
+
+///
+
+## Об HTTP кодах статуса ответа
+
+/// note | Примечание
+
+Если вы уже знаете, что представляют собой HTTP коды статуса ответа, можете перейти к следующему разделу.
+
+///
+
+В протоколе HTTP числовой код состояния из 3 цифр отправляется как часть ответа.
+
+У кодов статуса есть названия, чтобы упростить их распознавание, но важны именно числовые значения.
+
+Кратко о значениях кодов:
+
+* `1XX` – статус-коды информационного типа. Они редко используются разработчиками напрямую. Ответы с этими кодами не могут иметь тела.
+* **`2XX`** – статус-коды, сообщающие об успешной обработке запроса. Они используются чаще всего.
+ * `200` – это код статуса ответа по умолчанию, который означает, что все прошло "OK".
+ * Другим примером может быть статус `201`, "Created". Он обычно используется после создания новой записи в базе данных.
+ * Особый случай – `204`, "No Content". Этот статус ответа используется, когда нет содержимого для возврата клиенту, и поэтому ответ не должен иметь тела.
+* **`3XX`** – статус-коды, сообщающие о перенаправлениях. Ответы с этими кодами статуса могут иметь или не иметь тело, за исключением ответов со статусом `304`, "Not Modified", у которых не должно быть тела.
+* **`4XX`** – статус-коды, сообщающие о клиентской ошибке. Это ещё одна наиболее часто используемая категория.
+ * Пример – код `404` для статуса "Not Found".
+ * Для общих ошибок со стороны клиента можно просто использовать код `400`.
+* `5XX` – статус-коды, сообщающие о серверной ошибке. Они почти никогда не используются разработчиками напрямую. Когда что-то идет не так в какой-то части кода вашего приложения или на сервере, он автоматически вернёт один из 5XX кодов.
+
+/// tip | Подсказка
+
+Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с
документацией MDN об HTTP кодах статуса ответа.
+
+///
+
+## Краткие обозначения для запоминания названий кодов
+
+Рассмотрим предыдущий пример еще раз:
+
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+
+`201` – это код статуса "Создано".
+
+Но вам не обязательно запоминать, что означает каждый из этих кодов.
+
+Для удобства вы можете использовать переменные из `fastapi.status`.
+
+{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+
+Они содержат те же числовые значения, но позволяют использовать подсказки редактора для выбора кода статуса:
+
+

+
+/// note | Технические детали
+
+Вы также можете использовать `from starlette import status` вместо `from fastapi import status`.
+
+**FastAPI** позволяет использовать как `starlette.status`, так и `fastapi.status` исключительно для удобства разработчиков. Но поставляется fastapi.status непосредственно из Starlette.
+
+///
+
+## Изменение кода статуса по умолчанию
+
+Позже, в [Руководстве для продвинутых пользователей](../advanced/response-change-status-code.md){.internal-link target=_blank}, вы узнаете, как возвращать HTTP коды статуса, отличные от используемого здесь кода статуса по умолчанию.
diff --git a/docs/ru/docs/tutorial/schema-extra-example.md b/docs/ru/docs/tutorial/schema-extra-example.md
new file mode 100644
index 000000000..f17b24349
--- /dev/null
+++ b/docs/ru/docs/tutorial/schema-extra-example.md
@@ -0,0 +1,110 @@
+# Объявление примера запроса данных
+
+Вы можете объявлять примеры данных, которые ваше приложение может получать.
+
+Вот несколько способов, как это можно сделать.
+
+## Pydantic `schema_extra`
+
+Вы можете объявить ключ `example` для модели Pydantic, используя класс `Config` и переменную `schema_extra`, как описано в
Pydantic документации: Настройка схемы:
+
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:21] *}
+
+Эта дополнительная информация будет включена в **JSON Schema** выходных данных для этой модели, и она будет использоваться в документации к API.
+
+/// tip | Подсказка
+
+Вы можете использовать тот же метод для расширения JSON-схемы и добавления своей собственной дополнительной информации.
+
+Например, вы можете использовать это для добавления дополнительной информации для пользовательского интерфейса в вашем веб-приложении и т.д.
+
+///
+
+## Дополнительные аргументы поля `Field`
+
+При использовании `Field()` с моделями Pydantic, вы также можете объявлять дополнительную информацию для **JSON Schema**, передавая любые другие произвольные аргументы в функцию.
+
+Вы можете использовать это, чтобы добавить аргумент `example` для каждого поля:
+
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
+
+/// warning | Внимание
+
+Имейте в виду, что эти дополнительные переданные аргументы не добавляют никакой валидации, только дополнительную информацию для документации.
+
+///
+
+## Использование `example` и `examples` в OpenAPI
+
+При использовании любой из этих функций:
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+вы также можете добавить аргумент, содержащий `example` или группу `examples` с дополнительной информацией, которая будет добавлена в **OpenAPI**.
+
+### Параметр `Body` с аргументом `example`
+
+Здесь мы передаём аргумент `example`, как пример данных ожидаемых в параметре `Body()`:
+
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:27] *}
+
+### Аргумент "example" в UI документации
+
+С любым из вышеуказанных методов это будет выглядеть так в `/docs`:
+
+

+
+### `Body` с аргументом `examples`
+
+В качестве альтернативы одному аргументу `example`, вы можете передавать `examples` используя тип данных `dict` с **несколькими примерами**, каждый из которых содержит дополнительную информацию, которая также будет добавлена в **OpenAPI**.
+
+Ключи `dict` указывают на каждый пример, а значения для каждого из них - на еще один тип `dict` с дополнительной информацией.
+
+Каждый конкретный пример типа `dict` в аргументе `examples` может содержать:
+
+* `summary`: Краткое описание для примера.
+* `description`: Полное описание, которое может содержать текст в формате Markdown.
+* `value`: Это конкретный пример, который отображается, например, в виде типа `dict`.
+* `externalValue`: альтернатива параметру `value`, URL-адрес, указывающий на пример. Хотя это может не поддерживаться таким же количеством инструментов разработки и тестирования API, как параметр `value`.
+
+{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:49] *}
+
+### Аргумент "examples" в UI документации
+
+С аргументом `examples`, добавленным в `Body()`, страница документации `/docs` будет выглядеть так:
+
+

+
+## Технические Детали
+
+/// warning | Внимание
+
+Эти технические детали относятся к стандартам **JSON Schema** и **OpenAPI**.
+
+Если предложенные выше идеи уже работают для вас, возможно этого будет достаточно и эти детали вам не потребуются, можете спокойно их пропустить.
+
+///
+
+Когда вы добавляете пример внутрь модели Pydantic, используя `schema_extra` или `Field(example="something")`, этот пример добавляется в **JSON Schema** для данной модели Pydantic.
+
+И эта **JSON Schema** модели Pydantic включается в **OpenAPI** вашего API, а затем используется в UI документации.
+
+Поля `example` как такового не существует в стандартах **JSON Schema**. В последних версиях JSON-схемы определено поле
`examples`, но OpenAPI 3.0.3 основан на более старой версии JSON-схемы, которая не имела поля `examples`.
+
+Таким образом, OpenAPI 3.0.3 определяет своё собственное поле
`example` для модифицированной версии **JSON Schema**, которую он использует чтобы достичь той же цели (однако это именно поле `example`, а не `examples`), и именно это используется API в UI документации (с интеграцией Swagger UI).
+
+Итак, хотя поле `example` не является частью JSON-схемы, оно является частью настраиваемой версии JSON-схемы в OpenAPI, и именно это поле будет использоваться в UI документации.
+
+Однако, когда вы используете поле `example` или `examples` с любой другой функцией (`Query()`, `Body()`, и т.д.), эти примеры не добавляются в JSON-схему, которая описывает эти данные (даже в собственную версию JSON-схемы OpenAPI), они добавляются непосредственно в объявление *операции пути* в OpenAPI (вне частей OpenAPI, которые используют JSON-схему).
+
+Для функций `Path()`, `Query()`, `Header()`, и `Cookie()`, аргументы `example` или `examples` добавляются в
определение OpenAPI, к объекту `Parameter Object` (в спецификации).
+
+И для функций `Body()`, `File()` и `Form()` аргументы `example` или `examples` аналогично добавляются в
определение OpenAPI, к объекту `Request Body Object`, в поле `content` в объекте `Media Type Object` (в спецификации).
+
+С другой стороны, существует более новая версия OpenAPI: **3.1.0**, недавно выпущенная. Она основана на последней версии JSON-схемы и большинство модификаций из OpenAPI JSON-схемы удалены в обмен на новые возможности из последней версии JSON-схемы, так что все эти мелкие отличия устранены. Тем не менее, Swagger UI в настоящее время не поддерживает OpenAPI 3.1.0, поэтому пока лучше продолжать использовать вышеупомянутые методы.
diff --git a/docs/ru/docs/tutorial/security/first-steps.md b/docs/ru/docs/tutorial/security/first-steps.md
new file mode 100644
index 000000000..375c2d7f6
--- /dev/null
+++ b/docs/ru/docs/tutorial/security/first-steps.md
@@ -0,0 +1,195 @@
+# Безопасность - первые шаги
+
+Представим, что у вас есть свой **бэкенд** API на некотором домене.
+
+И у вас есть **фронтенд** на другом домене или на другом пути того же домена (или в мобильном приложении).
+
+И вы хотите иметь возможность аутентификации фронтенда с бэкендом, используя **имя пользователя** и **пароль**.
+
+Мы можем использовать **OAuth2** для создания такой системы с помощью **FastAPI**.
+
+Но давайте избавим вас от необходимости читать всю длинную спецификацию, чтобы найти те небольшие кусочки информации, которые вам нужны.
+
+Для работы с безопасностью воспользуемся средствами, предоставленными **FastAPI**.
+
+## Как это выглядит
+
+Давайте сначала просто воспользуемся кодом и посмотрим, как он работает, а затем детально разберём, что происходит.
+
+## Создание `main.py`
+
+Скопируйте пример в файл `main.py`:
+
+{* ../../docs_src/security/tutorial001_an_py39.py *}
+
+## Запуск
+
+/// info | Дополнительная информация
+
+Вначале, установите библиотеку
`python-multipart`.
+
+А именно: `pip install python-multipart`.
+
+Это связано с тем, что **OAuth2** использует "данные формы" для передачи `имени пользователя` и `пароля`.
+
+///
+
+Запустите ваш сервер:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+## Проверка
+
+Перейдите к интерактивной документации по адресу:
http://127.0.0.1:8000/docs.
+
+Вы увидите примерно следующее:
+
+

+
+/// check | Кнопка авторизации!
+
+У вас уже появилась новая кнопка "Authorize".
+
+А у *операции пути* теперь появился маленький замочек в правом верхнем углу, на который можно нажать.
+
+///
+
+При нажатии на нее появляется небольшая форма авторизации, в которую нужно ввести `имя пользователя` и `пароль` (и другие необязательные поля):
+
+

+
+/// note | Технические детали
+
+Неважно, что вы введете в форму, она пока не будет работать. Но мы к этому еще придем.
+
+///
+
+Конечно, это не фронтенд для конечных пользователей, но это отличный автоматический инструмент для интерактивного документирования всех ваших API.
+
+Он может использоваться командой фронтенда (которой можете быть и вы сами).
+
+Он может быть использован сторонними приложениями и системами.
+
+Кроме того, его можно использовать самостоятельно для отладки, проверки и тестирования одного и того же приложения.
+
+## Аутентификация по паролю
+
+Теперь давайте вернемся немного назад и разберемся, что же это такое.
+
+Аутентификация по паролю является одним из способов, определенных в OAuth2, для обеспечения безопасности и аутентификации.
+
+OAuth2 был разработан для того, чтобы бэкэнд или API были независимы от сервера, который аутентифицирует пользователя.
+
+Но в нашем случае одно и то же приложение **FastAPI** будет работать с API и аутентификацией.
+
+Итак, рассмотрим его с этой упрощенной точки зрения:
+
+* Пользователь вводит на фронтенде `имя пользователя` и `пароль` и нажимает `Enter`.
+* Фронтенд (работающий в браузере пользователя) отправляет эти `имя пользователя` и `пароль` на определенный URL в нашем API (объявленный с помощью параметра `tokenUrl="token"`).
+* API проверяет эти `имя пользователя` и `пароль` и выдает в ответ "токен" (мы еще не реализовали ничего из этого).
+ * "Токен" - это просто строка с некоторым содержимым, которое мы можем использовать позже для верификации пользователя.
+ * Обычно срок действия токена истекает через некоторое время.
+ * Таким образом, пользователю придется снова войти в систему в какой-то момент времени.
+ * И если токен будет украден, то риск будет меньше, так как он не похож на постоянный ключ, который будет работать вечно (в большинстве случаев).
+* Фронтенд временно хранит этот токен в каком-то месте.
+* Пользователь щелкает мышью на фронтенде, чтобы перейти в другой раздел на фронтенде.
+* Фронтенду необходимо получить дополнительные данные из API.
+ * Но для этого необходима аутентификация для конкретной конечной точки.
+ * Поэтому для аутентификации в нашем API он посылает заголовок `Authorization` со значением `Bearer` плюс сам токен.
+ * Если токен содержит `foobar`, то содержание заголовка `Authorization` будет таким: `Bearer foobar`.
+
+## Класс `OAuth2PasswordBearer` в **FastAPI**
+
+**FastAPI** предоставляет несколько средств на разных уровнях абстракции для реализации этих функций безопасности.
+
+В данном примере мы будем использовать **OAuth2**, с аутентификацией по паролю, используя токен **Bearer**. Для этого мы используем класс `OAuth2PasswordBearer`.
+
+/// info | Дополнительная информация
+
+Токен "bearer" - не единственный вариант, но для нашего случая он является наилучшим.
+
+И это может быть лучшим вариантом для большинства случаев использования, если только вы не являетесь экспертом в области OAuth2 и точно знаете, почему вам лучше подходит какой-то другой вариант.
+
+В этом случае **FastAPI** также предоставляет инструменты для его реализации.
+
+///
+
+При создании экземпляра класса `OAuth2PasswordBearer` мы передаем в него параметр `tokenUrl`. Этот параметр содержит URL, который клиент (фронтенд, работающий в браузере пользователя) будет использовать для отправки `имени пользователя` и `пароля` с целью получения токена.
+
+{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
+
+/// tip | Подсказка
+
+Здесь `tokenUrl="token"` ссылается на относительный URL `token`, который мы еще не создали. Поскольку это относительный URL, он эквивалентен `./token`.
+
+Поскольку мы используем относительный URL, если ваш API расположен по адресу `https://example.com/`, то он будет ссылаться на `https://example.com/token`. Если же ваш API расположен по адресу `https://example.com/api/v1/`, то он будет ссылаться на `https://example.com/api/v1/token`.
+
+Использование относительного URL важно для того, чтобы ваше приложение продолжало работать даже в таких сложных случаях, как оно находится [за прокси-сервером](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+
+///
+
+Этот параметр не создает конечную точку / *операцию пути*, а объявляет, что URL `/token` будет таким, который клиент должен использовать для получения токена. Эта информация используется в OpenAPI, а затем в интерактивных системах документации API.
+
+Вскоре мы создадим и саму операцию пути.
+
+/// info | Дополнительная информация
+
+Если вы очень строгий "питонист", то вам может не понравиться стиль названия параметра `tokenUrl` вместо `token_url`.
+
+Это связано с тем, что тут используется то же имя, что и в спецификации OpenAPI. Таким образом, если вам необходимо более подробно изучить какую-либо из этих схем безопасности, вы можете просто использовать копирование/вставку, чтобы найти дополнительную информацию о ней.
+
+///
+
+Переменная `oauth2_scheme` является экземпляром `OAuth2PasswordBearer`, но она также является "вызываемой".
+
+Ее можно вызвать следующим образом:
+
+```Python
+oauth2_scheme(some, parameters)
+```
+
+Поэтому ее можно использовать вместе с `Depends`.
+
+### Использование
+
+Теперь вы можете передать ваш `oauth2_scheme` в зависимость с помощью `Depends`.
+
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+
+Эта зависимость будет предоставлять `строку`, которая присваивается параметру `token` в *функции операции пути*.
+
+**FastAPI** будет знать, что он может использовать эту зависимость для определения "схемы безопасности" в схеме OpenAPI (и автоматической документации по API).
+
+/// info | Технические детали
+
+**FastAPI** будет знать, что он может использовать класс `OAuth2PasswordBearer` (объявленный в зависимости) для определения схемы безопасности в OpenAPI, поскольку он наследуется от `fastapi.security.oauth2.OAuth2`, который, в свою очередь, наследуется от `fastapi.security.base.SecurityBase`.
+
+Все утилиты безопасности, интегрируемые в OpenAPI (и автоматическая документация по API), наследуются от `SecurityBase`, поэтому **FastAPI** может знать, как интегрировать их в OpenAPI.
+
+///
+
+## Что он делает
+
+Он будет искать в запросе заголовок `Authorization` и проверять, содержит ли он значение `Bearer` с некоторым токеном, и возвращать токен в виде `строки`.
+
+Если он не видит заголовка `Authorization` или значение не имеет токена `Bearer`, то в ответ будет выдана ошибка с кодом состояния 401 (`UNAUTHORIZED`).
+
+Для возврата ошибки даже не нужно проверять, существует ли токен. Вы можете быть уверены, что если ваша функция была выполнена, то в этом токене есть `строка`.
+
+Проверить это можно уже сейчас в интерактивной документации:
+
+

+
+Мы пока не проверяем валидность токена, но для начала неплохо.
+
+## Резюме
+
+Таким образом, всего за 3-4 дополнительные строки вы получаете некую примитивную форму защиты.
diff --git a/docs/ru/docs/tutorial/security/get-current-user.md b/docs/ru/docs/tutorial/security/get-current-user.md
new file mode 100644
index 000000000..05eb290d7
--- /dev/null
+++ b/docs/ru/docs/tutorial/security/get-current-user.md
@@ -0,0 +1,99 @@
+# Данные текущего пользователя
+
+В предыдущей главе система безопасности (основанная на системе внедрения зависимостей) передавала *функции, обрабатывающей эндпоинт,* `токен` в виде `строки`:
+
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+
+Это пока что не слишком нам полезно. Давайте изменим код так, чтобы он возвращал нам данные пользователя, отправившего запрос.
+
+## Создание модели пользователя
+
+Сначала создадим Pydantic-модель пользователя.
+
+Точно так же, как мы использовали Pydantic для объявления тел запросов, мы можем использовать его где угодно:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
+
+## Создание зависимости `get_current_user`
+
+Давайте создадим зависимость `get_current_user`.
+
+Помните, что у зависимостей могут быть подзависимости?
+
+`get_current_user` как раз будет иметь подзависимость `oauth2_scheme`, которую мы создали ранее.
+
+Аналогично тому, как мы делали это ранее в *обработчике эндпоинта* наша новая зависимость `get_current_user` будет получать `token` в виде `строки` от подзависимости `oauth2_scheme`:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
+
+## Получение данных пользователя
+
+`get_current_user` будет использовать созданную нами (ненастоящую) служебную функцию, которая принимает токен в виде `строки` и возвращает нашу Pydantic-модель `User`:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
+
+## Внедрение зависимости текущего пользователя
+
+Теперь мы можем использовать тот же `Depends` с нашей зависимостью `get_current_user` в *функции обрабатывающей эндпоинт*:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
+
+Обратите внимание, что мы объявляем тип переменной `current_user` как Pydantic-модель `User`.
+
+Это поможет выполнить внутри функции все проверки автозаполнения и типа.
+
+/// tip | Подсказка
+Возможно, вы помните, что тело запроса также объявляется с помощью Pydantic-моделей.
+
+В этом месте у **FastAPI** не возникнет проблем, потому что вы используете `Depends`.
+///
+
+/// check | Заметка
+То, как устроена эта система зависимостей, позволяет нам иметь различные зависимости, которые возвращают модель `User`.
+
+Мы не ограничены наличием только одной зависимости, которая может возвращать данные такого типа.
+///
+
+## Другие модели
+
+Теперь вы можете получать информацию о текущем пользователе непосредственно в *функции обрабатывающей эндпоинт* и работать с механизмами безопасности на уровне **Внедрения Зависимостей**, используя `Depends`.
+
+Причем для обеспечения требований безопасности можно использовать любую модель или данные (в данном случае - Pydantic-модель `User`).
+
+Но вы не ограничены использованием какой-то конкретной моделью данных, классом или типом.
+
+Вы хотите использовать в модели `id` и `email`, а `username` вам не нужен? Ну разумеется. Воспользуйтесь тем же инструментарием.
+
+Вам нужны только `строки`? Или только `словари`? Или непосредственно экземпляр модели класса базы данных? Все это работает точно также.
+
+У вас нет пользователей, которые входят в ваше приложение, а только роботы, боты или другие системы, у которых есть только токен доступа? Опять же, все работает одинаково.
+
+Просто используйте любую модель, любой класс, любую базу данных, которые нужны для вашего приложения. Система внедрения зависимостей **FastAPI** поможет вам в этом.
+
+## Размер кода
+
+Этот пример может показаться многословным. Следует иметь в виду, что в одном файле мы смешиваем безопасность, модели данных, служебные функции и *эндпоинты*.
+
+Но вот ключевой момент:
+
+Все, что касается безопасности и внедрения зависимостей, пишется один раз.
+
+И вы можете сделать его настолько сложным, насколько захотите. И все это будет написано только один раз, в одном месте, со всей своей гибкостью.
+
+И у вас могут быть тысячи конечных точек (*эндпоинтов*), использующих одну и ту же систему безопасности.
+
+И все они (или любая их часть по вашему желанию) могут воспользоваться преимуществами повторного использования этих зависимостей или любых других зависимостей, которые вы создадите.
+
+И все эти тысячи *эндпоинтов* могут составлять всего 3 строки:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
+
+## Резюме
+
+Теперь вы можете получать данные о текущем пользователе непосредственно в своей *функции обработчике эндпоинта*.
+
+Мы уже на полпути к этому.
+
+Осталось лишь добавить *эндпоинт* для отправки пользователем/клиентом своих `имени пользователя` и `пароля`.
+
+Это будет рассмотрено в следующем разделе.
diff --git a/docs/ru/docs/tutorial/security/index.md b/docs/ru/docs/tutorial/security/index.md
new file mode 100644
index 000000000..e4969c4cf
--- /dev/null
+++ b/docs/ru/docs/tutorial/security/index.md
@@ -0,0 +1,106 @@
+# Настройка авторизации
+
+Существует множество способов обеспечения безопасности, аутентификации и авторизации.
+
+Обычно эта тема является достаточно сложной и трудной.
+
+Во многих фреймворках и системах только работа с определением доступов к приложению и аутентификацией требует значительных затрат усилий и написания множества кода (во многих случаях его объём может составлять более 50% от всего написанного кода).
+
+**FastAPI** предоставляет несколько инструментов, которые помогут вам настроить **Авторизацию** легко, быстро, стандартным способом, без необходимости изучать все её тонкости.
+
+Но сначала давайте рассмотрим некоторые небольшие концепции.
+
+## Куда-то торопишься?
+
+Если вам не нужна информация о каких-либо из следующих терминов и вам просто нужно добавить защиту с аутентификацией на основе логина и пароля *прямо сейчас*, переходите к следующим главам.
+
+## OAuth2
+
+OAuth2 - это протокол, который определяет несколько способов обработки аутентификации и авторизации.
+
+Он довольно обширен и охватывает несколько сложных вариантов использования.
+
+OAuth2 включает в себя способы аутентификации с использованием "третьей стороны".
+
+Это то, что используют под собой все кнопки "вход с помощью Facebook, Google, Twitter, GitHub" на страницах авторизации.
+
+### OAuth 1
+
+Ранее использовался протокол OAuth 1, который сильно отличается от OAuth2 и является более сложным, поскольку он включал прямые описания того, как шифровать сообщение.
+
+В настоящее время он не очень популярен и не используется.
+
+OAuth2 не указывает, как шифровать сообщение, он ожидает, что ваше приложение будет обслуживаться по протоколу HTTPS.
+
+/// tip | Подсказка
+
+В разделе **Развертывание** вы увидите [как настроить протокол HTTPS бесплатно, используя Traefik и Let's Encrypt.](https://fastapi.tiangolo.com/ru/deployment/https/)
+
+///
+
+## OpenID Connect
+
+OpenID Connect - это еще один протокол, основанный на **OAuth2**.
+
+Он просто расширяет OAuth2, уточняя некоторые вещи, не имеющие однозначного определения в OAuth2, в попытке сделать его более совместимым.
+
+Например, для входа в Google используется OpenID Connect (который под собой использует OAuth2).
+
+Но вход в Facebook не поддерживает OpenID Connect. У него есть собственная вариация OAuth2.
+
+### OpenID (не "OpenID Connect")
+
+Также ранее использовался стандарт "OpenID", который пытался решить ту же проблему, что и **OpenID Connect**, но не был основан на OAuth2.
+
+Таким образом, это была полноценная дополнительная система.
+
+В настоящее время не очень популярен и не используется.
+
+## OpenAPI
+
+OpenAPI (ранее известный как Swagger) - это открытая спецификация для создания API (в настоящее время является частью Linux Foundation).
+
+**FastAPI** основан на **OpenAPI**.
+
+Это то, что делает возможным наличие множества автоматических интерактивных интерфейсов документирования, сгенерированного кода и т.д.
+
+В OpenAPI есть способ использовать несколько "схем" безопасности.
+
+Таким образом, вы можете воспользоваться преимуществами Всех этих стандартных инструментов, включая интерактивные системы документирования.
+
+OpenAPI может использовать следующие схемы авторизации:
+
+* `apiKey`: уникальный идентификатор для приложения, который может быть получен из:
+ * Параметров запроса.
+ * Заголовка.
+ * Cookies.
+* `http`: стандартные системы аутентификации по протоколу HTTP, включая:
+ * `bearer`: заголовок `Authorization` со значением `Bearer {уникальный токен}`. Это унаследовано от OAuth2.
+ * Базовая аутентификация по протоколу HTTP.
+ * HTTP Digest и т.д.
+* `oauth2`: все способы обеспечения безопасности OAuth2 называемые "потоки" (англ. "flows").
+ * Некоторые из этих "потоков" подходят для реализации аутентификации через сторонний сервис использующий OAuth 2.0 (например, Google, Facebook, Twitter, GitHub и т.д.):
+ * `implicit`
+ * `clientCredentials`
+ * `authorizationCode`
+ * Но есть один конкретный "поток", который может быть идеально использован для обработки аутентификации непосредственно в том же приложении:
+ * `password`: в некоторых следующих главах будут рассмотрены примеры этого.
+* `openIdConnect`: способ определить, как автоматически обнаруживать данные аутентификации OAuth2.
+ * Это автоматическое обнаружение определено в спецификации OpenID Connect.
+
+
+/// tip | Подсказка
+
+Интеграция сторонних сервисов для аутентификации/авторизации таких как Google, Facebook, Twitter, GitHub и т.д. осуществляется достаточно легко.
+
+Самой сложной проблемой является создание такого провайдера аутентификации/авторизации, но **FastAPI** предоставляет вам инструменты, позволяющие легко это сделать, выполняя при этом всю тяжелую работу за вас.
+
+///
+
+## Преимущества **FastAPI**
+
+Fast API предоставляет несколько инструментов для каждой из этих схем безопасности в модуле `fastapi.security`, которые упрощают использование этих механизмов безопасности.
+
+В следующих главах вы увидите, как обезопасить свой API, используя инструменты, предоставляемые **FastAPI**.
+
+И вы также увидите, как он автоматически интегрируется в систему интерактивной документации.
diff --git a/docs/ru/docs/tutorial/security/oauth2-jwt.md b/docs/ru/docs/tutorial/security/oauth2-jwt.md
new file mode 100644
index 000000000..1195fad21
--- /dev/null
+++ b/docs/ru/docs/tutorial/security/oauth2-jwt.md
@@ -0,0 +1,261 @@
+# OAuth2 с паролем (и хешированием), Bearer с JWT-токенами
+
+Теперь, когда у нас определен процесс обеспечения безопасности, давайте сделаем приложение действительно безопасным, используя токены
JWT и безопасное хеширование паролей.
+
+Этот код можно реально использовать в своем приложении, сохранять хэши паролей в базе данных и т.д.
+
+Мы продолжим разбираться, начиная с того места, на котором остановились в предыдущей главе.
+
+## Про JWT
+
+JWT означает "JSON Web Tokens".
+
+Это стандарт для кодирования JSON-объекта в виде длинной строки без пробелов. Выглядит это следующим образом:
+
+```
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
+```
+
+Он не зашифрован, поэтому любой человек может восстановить информацию из его содержимого.
+
+Но он подписан. Следовательно, когда вы получаете токен, который вы эмитировали (выдавали), вы можете убедиться, что это именно вы его эмитировали.
+
+Таким образом, можно создать токен со сроком действия, скажем, 1 неделя. А когда пользователь вернется на следующий день с тем же токеном, вы будете знать, что он все еще авторизирован в вашей системе.
+
+Через неделю срок действия токена истечет, пользователь не будет авторизован и ему придется заново входить в систему, чтобы получить новый токен. А если пользователь (или третье лицо) попытается модифицировать токен, чтобы изменить срок действия, вы сможете это обнаружить, поскольку подписи не будут совпадать.
+
+Если вы хотите поиграть с JWT-токенами и посмотреть, как они работают, посмотрите
https://jwt.io.
+
+## Установка `PyJWT`
+
+Нам необходимо установить `pyjwt` для генерации и проверки JWT-токенов на языке Python.
+
+Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md){.internal-link target=_blank}, активируйте его, а затем установите `pyjwt`:
+
+
+
+```console
+$ pip install pyjwt
+
+---> 100%
+```
+
+
+
+/// info | Дополнительная информация
+Если вы планируете использовать алгоритмы цифровой подписи, такие как RSA или ECDSA, вам следует установить зависимость библиотеки криптографии `pyjwt[crypto]`.
+
+Подробнее об этом можно прочитать в
документации по установке PyJWT.
+///
+
+## Хеширование паролей
+
+"Хеширование" означает преобразование некоторого содержимого (в данном случае пароля) в последовательность байтов (просто строку), которая выглядит как тарабарщина.
+
+Каждый раз, когда вы передаете точно такое же содержимое (точно такой же пароль), вы получаете точно такую же тарабарщину.
+
+Но преобразовать тарабарщину обратно в пароль невозможно.
+
+### Для чего нужно хеширование паролей
+
+Если ваша база данных будет украдена, то вор не получит пароли пользователей в открытом виде, а только их хэши.
+
+Таким образом, вор не сможет использовать этот пароль в другой системе (поскольку многие пользователи везде используют один и тот же пароль, это было бы опасно).
+
+## Установка `passlib`
+
+PassLib - это отличный пакет Python для работы с хэшами паролей.
+
+Он поддерживает множество безопасных алгоритмов хеширования и утилит для работы с ними.
+
+Рекомендуемый алгоритм - "Bcrypt".
+
+Убедитесь, что вы создали и активировали виртуальное окружение, и затем установите PassLib вместе с Bcrypt:
+
+
+
+```console
+$ pip install "passlib[bcrypt]"
+
+---> 100%
+```
+
+
+
+/// tip | Подсказка
+С помощью `passlib` можно даже настроить его на чтение паролей, созданных **Django**, плагином безопасности **Flask** или многими другими библиотеками.
+
+Таким образом, вы сможете, например, совместно использовать одни и те же данные из приложения Django в базе данных с приложением FastAPI. Или постепенно мигрировать Django-приложение, используя ту же базу данных.
+
+При этом пользователи смогут одновременно входить в систему как из приложения Django, так и из приложения **FastAPI**.
+///
+
+## Хеширование и проверка паролей
+
+Импортируйте необходимые инструменты из `passlib`.
+
+Создайте "контекст" PassLib. Именно он будет использоваться для хэширования и проверки паролей.
+
+/// tip | Подсказка
+Контекст PassLib также имеет функциональность для использования различных алгоритмов хеширования, в том числе и устаревших, только для возможности их проверки и т.д.
+
+Например, вы можете использовать его для чтения и проверки паролей, сгенерированных другой системой (например, Django), но хэшировать все новые пароли другим алгоритмом, например Bcrypt.
+
+И при этом быть совместимым со всеми этими системами.
+///
+
+Создайте служебную функцию для хэширования пароля, поступающего от пользователя.
+
+А затем создайте другую - для проверки соответствия полученного пароля и хранимого хэша.
+
+И еще одну - для аутентификации и возврата пользователя.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
+
+/// note | Технические детали
+Если проверить новую (фальшивую) базу данных `fake_users_db`, то можно увидеть, как теперь выглядит хэшированный пароль: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
+///
+
+## Работа с JWT токенами
+
+Импортируйте установленные модули.
+
+Создайте случайный секретный ключ, который будет использоваться для подписи JWT-токенов.
+
+Для генерации безопасного случайного секретного ключа используйте команду:
+
+
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+
+
+И скопируйте полученный результат в переменную `SECRET_KEY` (не используйте тот, что в примере).
+
+Создайте переменную `ALGORITHM` с алгоритмом, используемым для подписи JWT-токена, и установите для нее значение `"HS256"`.
+
+Создайте переменную для срока действия токена.
+
+Определите Pydantic Model, которая будет использоваться для формирования ответа на запрос на получение токена.
+
+Создайте служебную функцию для генерации нового токена доступа.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
+
+## Обновление зависимостей
+
+Обновите `get_current_user` для получения того же токена, что и раньше, но на этот раз с использованием JWT-токенов.
+
+Декодируйте полученный токен, проверьте его и верните текущего пользователя.
+
+Если токен недействителен, то сразу же верните HTTP-ошибку.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
+
+## Обновление *операции пути* `/token`
+
+Создайте `timedelta` со временем истечения срока действия токена.
+
+Создайте реальный токен доступа JWT и верните его
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
+
+### Технические подробности о JWT ключе `sub`
+
+В спецификации JWT говорится, что существует ключ `sub`, содержащий субъект токена.
+
+Его использование необязательно, но это именно то место, куда вы должны поместить идентификатор пользователя, и поэтому мы здесь его и используем.
+
+JWT может использоваться и для других целей, помимо идентификации пользователя и предоставления ему возможности выполнять операции непосредственно в вашем API.
+
+Например, вы могли бы определить "автомобиль" или "запись в блоге".
+
+Затем вы могли бы добавить права доступа к этой сущности, например "управлять" (для автомобиля) или "редактировать" (для блога).
+
+Затем вы могли бы передать этот JWT-токен пользователю (или боту), и они использовали бы его для выполнения определенных действий (управление автомобилем или редактирование запись в блоге), даже не имея учетной записи, просто используя JWT-токен, сгенерированный вашим API.
+
+Используя эти идеи, JWT можно применять для гораздо более сложных сценариев.
+
+В отдельных случаях несколько сущностей могут иметь один и тот же идентификатор, скажем, `foo` (пользователь `foo`, автомобиль `foo` и запись в блоге `foo`).
+
+Поэтому, чтобы избежать коллизий идентификаторов, при создании JWT-токена для пользователя можно добавить префикс `username` к значению ключа `sub`. Таким образом, в данном примере значение `sub` было бы `username:johndoe`.
+
+Важно помнить, что ключ `sub` должен иметь уникальный идентификатор для всего приложения и представлять собой строку.
+
+## Проверка в действии
+
+Запустите сервер и перейдите к документации:
http://127.0.0.1:8000/docs.
+
+Вы увидите пользовательский интерфейс вида:
+
+

+
+Пройдите авторизацию так же, как делали раньше.
+
+Используя учетные данные пользователя:
+
+Username: `johndoe`
+Password: `secret`
+
+/// check | Заметка
+Обратите внимание, что нигде в коде не используется открытый текст пароля "`secret`", мы используем только его хэшированную версию.
+///
+
+

+
+Вызвав эндпоинт `/users/me/`, вы получите ответ в виде:
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false
+}
+```
+
+

+
+Если открыть инструменты разработчика, то можно увидеть, что передаваемые данные включают только токен, пароль передается только в первом запросе для аутентификации пользователя и получения токена доступа, но не в последующих:
+
+

+
+/// note | Техническая информация
+Обратите внимание на заголовок `Authorization`, значение которого начинается с `Bearer`.
+///
+
+## Продвинутое использование `scopes`
+
+В OAuth2 существует понятие "диапазоны" ("`scopes`").
+
+С их помощью можно добавить определенный набор разрешений к JWT-токену.
+
+Затем вы можете передать этот токен непосредственно пользователю или третьей стороне для взаимодействия с вашим API с определенным набором ограничений.
+
+О том, как их использовать и как они интегрированы в **FastAPI**, читайте далее в **Руководстве пользователя**.
+
+## Резюме
+
+С учетом того, что вы видели до сих пор, вы можете создать безопасное приложение **FastAPI**, используя такие стандарты, как OAuth2 и JWT.
+
+Практически в любом фреймворке работа с безопасностью довольно быстро превращается в сложную тему.
+
+Многие пакеты, сильно упрощающие эту задачу, вынуждены идти на многочисленные компромиссы с моделью данных, с базой данных и с доступным функционалом. Некоторые из этих пакетов, которые пытаются уж слишком все упростить, имеют даже "дыры" в системе безопасности.
+
+---
+
+**FastAPI** не делает уступок ни одной базе данных, модели данных или инструментарию.
+
+Он предоставляет вам полную свободу действий, позволяя выбирать то, что лучше всего подходит для вашего проекта.
+
+Вы можете напрямую использовать многие хорошо поддерживаемые и широко распространенные пакеты, такие как `passlib` и `PyJWT`, поскольку **FastAPI** не требует сложных механизмов для интеграции внешних пакетов.
+
+Напротив, он предоставляет инструменты, позволяющие максимально упростить этот процесс без ущерба для гибкости, надежности и безопасности.
+
+При этом вы можете использовать и реализовывать безопасные стандартные протоколы, такие как OAuth2, относительно простым способом.
+
+В **Руководстве пользователя** вы можете узнать больше о том, как использовать "диапазоны" ("`scopes`") OAuth2 для создания более точно настроенной системы разрешений в соответствии с теми же стандартами. OAuth2 с диапазонами - это механизм, используемый многими крупными провайдерами сервиса аутентификации, такими как Facebook, Google, GitHub, Microsoft, Twitter и др., для авторизации сторонних приложений на взаимодействие с их API от имени их пользователей.
diff --git a/docs/ru/docs/tutorial/security/simple-oauth2.md b/docs/ru/docs/tutorial/security/simple-oauth2.md
new file mode 100644
index 000000000..9732265cc
--- /dev/null
+++ b/docs/ru/docs/tutorial/security/simple-oauth2.md
@@ -0,0 +1,272 @@
+# Простая авторизация по протоколу OAuth2 с токеном типа Bearer
+
+Теперь, отталкиваясь от предыдущей главы, добавим недостающие части, чтобы получить безопасную систему.
+
+## Получение `имени пользователя` и `пароля`
+
+Для получения `имени пользователя` и `пароля` мы будем использовать утилиты безопасности **FastAPI**.
+
+Протокол OAuth2 определяет, что при использовании "аутентификации по паролю" (которую мы и используем) клиент/пользователь должен передавать поля `username` и `password` в полях формы.
+
+В спецификации сказано, что поля должны быть названы именно так. Поэтому `user-name` или `email` работать не будут.
+
+Но не волнуйтесь, вы можете показать его конечным пользователям во фронтенде в том виде, в котором хотите.
+
+А ваши модели баз данных могут использовать любые другие имена.
+
+Но при авторизации согласно спецификации, требуется использовать именно эти имена, что даст нам возможность воспользоваться встроенной системой документации API.
+
+В спецификации также указано, что `username` и `password` должны передаваться в виде данных формы (так что никакого JSON здесь нет).
+
+### Oбласть видимости (scope)
+
+В спецификации также говорится, что клиент может передать еще одно поле формы "`scope`".
+
+Имя поля формы - `scope` (в единственном числе), но на самом деле это длинная строка, состоящая из отдельных областей видимости (scopes), разделенных пробелами.
+
+Каждая "область видимости" (scope) - это просто строка (без пробелов).
+
+Обычно они используются для указания уровней доступа, например:
+
+* `users:read` или `users:write` являются распространенными примерами.
+* `instagram_basic` используется Facebook / Instagram.
+* `https://www.googleapis.com/auth/drive` используется компанией Google.
+
+/// info | Дополнительнаяя информация
+В OAuth2 "scope" - это просто строка, которая уточняет уровень доступа.
+
+Не имеет значения, содержит ли он другие символы, например `:`, или является ли он URL.
+
+Эти детали зависят от конкретной реализации.
+
+Для OAuth2 это просто строки.
+///
+
+## Код получения `имени пользователя` и `пароля`
+
+Для решения задачи давайте воспользуемся утилитами, предоставляемыми **FastAPI**.
+
+### `OAuth2PasswordRequestForm`
+
+Сначала импортируйте `OAuth2PasswordRequestForm` и затем используйте ее как зависимость с `Depends` в *эндпоинте* `/token`:
+
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[4,78] *}
+
+`OAuth2PasswordRequestForm` - это класс для использования в качестве зависимости для *функции обрабатывающей эндпоинт*, который определяет тело формы со следующими полями:
+
+* `username`.
+* `password`.
+* Необязательное поле `scope` в виде большой строки, состоящей из строк, разделенных пробелами.
+* Необязательное поле `grant_type`.
+
+/// tip | Подсказка
+По спецификации OAuth2 поле `grant_type` является обязательным и содержит фиксированное значение `password`, но `OAuth2PasswordRequestForm` не обеспечивает этого.
+
+Если вам необходимо использовать `grant_type`, воспользуйтесь `OAuth2PasswordRequestFormStrict` вместо `OAuth2PasswordRequestForm`.
+///
+
+* Необязательное поле `client_id` (в нашем примере он не нужен).
+* Необязательное поле `client_secret` (в нашем примере он не нужен).
+
+/// info | Дополнительная информация
+Форма `OAuth2PasswordRequestForm` не является специальным классом для **FastAPI**, как `OAuth2PasswordBearer`.
+
+`OAuth2PasswordBearer` указывает **FastAPI**, что это схема безопасности. Следовательно, она будет добавлена в OpenAPI.
+
+Но `OAuth2PasswordRequestForm` - это всего лишь класс зависимости, который вы могли бы написать самостоятельно или вы могли бы объявить параметры `Form` напрямую.
+
+Но, поскольку это распространённый вариант использования, он предоставляется **FastAPI** напрямую, просто чтобы облегчить задачу.
+///
+
+### Использование данных формы
+
+/// tip | Подсказка
+В экземпляре зависимого класса `OAuth2PasswordRequestForm` атрибут `scope`, состоящий из одной длинной строки, разделенной пробелами, заменен на атрибут `scopes`, состоящий из списка отдельных строк, каждая из которых соответствует определенному уровню доступа.
+
+В данном примере мы не используем `scopes`, но если вам это необходимо, то такая функциональность имеется.
+///
+
+Теперь получим данные о пользователе из (ненастоящей) базы данных, используя `username` из поля формы.
+
+Если такого пользователя нет, то мы возвращаем ошибку "неверное имя пользователя или пароль".
+
+Для ошибки мы используем исключение `HTTPException`:
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[3,79:81] *}
+
+### Проверка пароля
+
+На данный момент у нас есть данные о пользователе из нашей базы данных, но мы еще не проверили пароль.
+
+Давайте сначала поместим эти данные в модель Pydantic `UserInDB`.
+
+Ни в коем случае нельзя сохранять пароли в открытом виде, поэтому мы будем использовать (пока что ненастоящую) систему хеширования паролей.
+
+Если пароли не совпадают, мы возвращаем ту же ошибку.
+
+#### Хеширование паролей
+
+"Хеширование" означает: преобразование некоторого содержимого (в данном случае пароля) в последовательность байтов (просто строку), которая выглядит как тарабарщина.
+
+Каждый раз, когда вы передаете точно такое же содержимое (точно такой же пароль), вы получаете точно такую же тарабарщину.
+
+Но преобразовать тарабарщину обратно в пароль невозможно.
+
+##### Зачем использовать хеширование паролей
+
+Если ваша база данных будет украдена, то у вора не будет паролей пользователей в открытом виде, только хэши.
+
+Таким образом, вор не сможет использовать эти же пароли в другой системе (поскольку многие пользователи используют одни и те же пароли повсеместно, это было бы опасно).
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[82:85] *}
+
+#### Про `**user_dict`
+
+`UserInDB(**user_dict)` означает:
+
+*Передавать ключи и значения `user_dict` непосредственно в качестве аргументов ключ-значение, что эквивалентно:*
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+ disabled = user_dict["disabled"],
+ hashed_password = user_dict["hashed_password"],
+)
+```
+
+/// info | Дополнительная информация
+Более полное объяснение `**user_dict` можно найти в [документации к **Дополнительным моделям**](../extra-models.md#about-user_indict){.internal-link target=_blank}.
+///
+
+## Возврат токена
+
+Ответ эндпоинта `token` должен представлять собой объект в формате JSON.
+
+Он должен иметь `token_type`. В нашем случае, поскольку мы используем токены типа "Bearer", тип токена должен быть "`bearer`".
+
+И в нем должна быть строка `access_token`, содержащая наш токен доступа.
+
+В этом простом примере мы нарушим все правила безопасности, и будем считать, что имя пользователя (username) полностью соответствует токену (token)
+
+/// tip | Подсказка
+В следующей главе мы рассмотрим реальную защищенную реализацию с хешированием паролей и токенами
JWT.
+
+Но пока давайте остановимся на необходимых нам деталях.
+///
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[87] *}
+
+/// tip | Подсказка
+Согласно спецификации, вы должны возвращать JSON с `access_token` и `token_type`, как в данном примере.
+
+Это то, что вы должны сделать сами в своем коде и убедиться, что вы используете эти JSON-ключи.
+
+Это практически единственное, что нужно не забывать делать самостоятельно, чтобы следовать требованиям спецификации.
+
+Все остальное за вас сделает **FastAPI**.
+///
+
+## Обновление зависимостей
+
+Теперь мы обновим наши зависимости.
+
+Мы хотим получить значение `current_user` *только* если этот пользователь активен.
+
+Поэтому мы создаем дополнительную зависимость `get_current_active_user`, которая, в свою очередь, использует в качестве зависимости `get_current_user`.
+
+Обе эти зависимости просто вернут HTTP-ошибку, если пользователь не существует или неактивен.
+
+Таким образом, в нашем эндпоинте мы получим пользователя только в том случае, если он существует, правильно аутентифицирован и активен:
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
+
+/// info | Дополнительная информация
+Дополнительный заголовок `WWW-Authenticate` со значением `Bearer`, который мы здесь возвращаем, также является частью спецификации.
+
+Ответ сервера с HTTP-кодом 401 "UNAUTHORIZED" должен также возвращать заголовок `WWW-Authenticate`.
+
+В случае с bearer-токенами (наш случай) значение этого заголовка должно быть `Bearer`.
+
+На самом деле этот дополнительный заголовок можно пропустить и все будет работать.
+
+Но он приведён здесь для соответствия спецификации.
+
+Кроме того, могут существовать инструменты, которые ожидают его и могут использовать, и это может быть полезно для вас или ваших пользователей сейчас или в будущем.
+
+В этом и заключается преимущество стандартов...
+///
+
+## Посмотим как это работает
+
+Откроем интерактивную документацию:
http://127.0.0.1:8000/docs.
+
+### Аутентификация
+
+Нажмите кнопку "Авторизация".
+
+Используйте учётные данные:
+
+Пользователь: `johndoe`
+
+Пароль: `secret`
+
+

+
+После авторизации в системе вы увидите следующее:
+
+

+
+### Получение собственных пользовательских данных
+
+Теперь, используя операцию `GET` с путем `/users/me`, вы получите данные пользователя, например:
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false,
+ "hashed_password": "fakehashedsecret"
+}
+```
+
+

+
+Если щелкнуть на значке замка и выйти из системы, а затем попытаться выполнить ту же операцию ещё раз, то будет выдана ошибка HTTP 401:
+
+```JSON
+{
+ "detail": "Not authenticated"
+}
+```
+
+### Неактивный пользователь
+
+Теперь попробуйте пройти аутентификацию с неактивным пользователем:
+
+Пользователь: `alice`
+
+Пароль: `secret2`
+
+И попробуйте использовать операцию `GET` с путем `/users/me`.
+
+Вы получите ошибку "Inactive user", как тут:
+
+```JSON
+{
+ "detail": "Inactive user"
+}
+```
+
+## Резюме
+
+Теперь у вас есть инструменты для реализации полноценной системы безопасности на основе `имени пользователя` и `пароля` для вашего API.
+
+Используя эти средства, можно сделать систему безопасности совместимой с любой базой данных, с любым пользователем или моделью данных.
+
+ Единственным недостатком нашей системы является то, что она всё ещё не защищена.
+
+В следующей главе вы увидите, как использовать библиотеку безопасного хеширования паролей и токены
JWT.
diff --git a/docs/ru/docs/tutorial/sql-databases.md b/docs/ru/docs/tutorial/sql-databases.md
new file mode 100644
index 000000000..b127e44d5
--- /dev/null
+++ b/docs/ru/docs/tutorial/sql-databases.md
@@ -0,0 +1,358 @@
+# SQL (реляционные) базы данных
+
+**FastAPI** не требует использования реляционной базы данных. Вы можете воспользоваться любой базой данных, которой хотите.
+
+В этом разделе мы продемонстрируем, как работать с
SQLModel.
+
+Библиотека **SQLModel** построена на основе
SQLAlchemy и Pydantic. Она была разработана автором **FastAPI** специально для приложений на основе FastAPI, которые используют **реляционные базы данных**.
+
+/// tip | Подсказка
+
+Вы можете воспользоваться любой библиотекой для работы с реляционными (SQL) или нереляционными (NoSQL) базами данных. (Их ещё называют
**ORM** библиотеками). FastAPI не принуждает вас к использованию чего-либо конкретного. 😎
+
+///
+
+В основе SQLModel лежит SQLAlchemy, поэтому вы спокойно можете использовать любую базу данных, поддерживаемую SQLAlchemy (и, соответственно, поддерживаемую SQLModel), например:
+
+* PostgreSQL
+* MySQL
+* SQLite
+* Oracle
+* Microsoft SQL Server, и т.д.
+
+В данном примере мы будем использовать базу данных **SQLite**, т.к. она состоит из единственного файла и поддерживается встроенными библиотеками Python. Таким образом, вы сможете скопировать данный пример и запустить его как он есть.
+
+В дальнейшем, для продакшн-версии вашего приложения, возможно, вам стоит использовать серверную базу данных, например, **PostgreSQL**.
+
+/// tip | Подсказка
+
+Существует официальный генератор проектов на **FastAPI** и **PostgreSQL**, который также включает frontend и дополнительные инструменты
https://github.com/fastapi/full-stack-fastapi-template
+
+///
+
+Это очень простое и короткое руководство, поэтому, если вы хотите узнать о базах данных в целом, об SQL, разобраться с более продвинутым функционалом, то воспользуйтесь
документацией SQLModel.
+
+## Установка `SQLModel`
+
+Создайте виртуальное окружение [virtual environment](../virtual-environments.md){.internal-link target=_blank}, активируйте его и установите `sqlmodel`:
+
+
+
+```console
+$ pip install sqlmodel
+---> 100%
+```
+
+
+
+## Создание приложения с единственной моделью
+
+Мы начнем с создания наиболее простой первой версии нашего приложения с одной единственной моделью **SQLModel**.
+
+В дальнейшем с помощью **дополнительных моделей** мы его улучшим и сделаем более безопасным и универсальным. 🤓
+
+### Создание моделей
+
+Импортируйте `SQLModel` и создайте модель базы данных:
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
+
+Класс `Hero` очень напоминает модель Pydantic (фактически, под капотом, *это и есть модель Pydantic*).
+
+Но есть и некоторые различия
+
+* `table=True` для SQLModel означает, что это *модель-таблица*, которая должна представлять **таблицу** в реляционной базе данных. Это не просто *модель данных* (в отличие от обычного класса в Pydantic).
+
+* `Field(primary_key=True)` для SQLModel означает, что поле `id` является первичным ключом в таблице базы данных (вы можете подробнее узнать о первичных ключах баз данных в документации по SQLModel).
+
+ Тип `int | None` сигнализирует для SQLModel, что столбец таблицы базы данных должен иметь тип `INTEGER`, или иметь пустое значение `NULL`.
+
+* `Field(index=True)` для SQLModel означает, что нужно создать **SQL индекс** для данного столбца. Это обеспечит более быстрый поиск при чтении данных, отфильтрованных по данному столбцу.
+
+ SQLModel будет знать, что данные типа `str`, будут представлены в базе данных как `TEXT` (или `VARCHAR`, в зависимости от типа базы данных).
+
+### Создание соединения с базой данных (Engine)
+
+В SQLModel объект соединения `engine` (по сути это `Engine` из SQLAlchemy) **содержит пул соединений** к базе данных.
+
+Для обеспечения всех подключений приложения к одной базе данных нужен только один объект соединения `engine`.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *}
+
+Использование настройки `check_same_thread=False` позволяет FastAPI использовать одну и ту же SQLite базу данных в различных потоках (threads). Это необходимо, когда **один запрос** использует **более одного потока** (например, в зависимостях).
+
+Не беспокойтесь, учитывая структуру кода, мы позже позаботимся о том, чтобы использовать **отдельную SQLModel-сессию на каждый отдельный запрос**, это как раз то, что пытается обеспечить `check_same_thread`.
+
+### Создание таблиц
+
+Далее мы добавляем функцию, использующую `SQLModel.metadata.create_all(engine)`, для того, чтобы создать **таблицы** для каждой из **моделей таблицы**.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *}
+
+### Создание зависимости Session
+
+Сессия базы данных (**`Session`**) хранит **объекты в памяти** и отслеживает любые необходимые изменения в данных, а затем **использует `engine`** для коммуникации с базой данных.
+
+Мы создадим FastAPI-**зависимость** с помощью `yield`, которая будет создавать новую сессию (Session) для каждого запроса. Это как раз и обеспечит использование отдельной сессии на каждый отдельный запрос. 🤓
+
+Затем мы создадим объявленную (`Annotated`) зависимость `SessionDep`. Мы сделаем это для того, чтобы упростить остальной код, который будет использовать эту зависимость.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *}
+
+### Создание таблиц базы данных при запуске приложения
+
+Мы будем создавать таблицы базы данных при запуске приложения.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *}
+
+В данном примере мы создаем таблицы при наступлении события запуска приложения.
+
+В продуктовом приложении вы, скорее всего, будете использовать скрипт для миграции базы данных, который выполняется перед запуском приложения. 🤓
+
+/// tip | Подсказка
+
+В SQLModel будут включены утилиты миграции, входящие в состав Alembic, но на данный момент вы просто можете использовать
+
Alembic напрямую.
+
+///
+
+### Создание героя (Hero)
+
+Каждая модель в SQLModel является также моделью Pydantic, поэтому вы можете использовать её при **объявлении типов**, точно также, как и модели Pydantic.
+
+Например, при объявлении параметра типа `Hero`, она будет считана из **тела JSON**.
+
+Точно также, вы можете использовать её при объявлении типа значения, возвращаемого функцией, и тогда структурированные данные будут отображены через пользовательский интерфейс автоматически сгенерированной документации FastAPI.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *}
+
+Мы используем зависимость `SessionDep` (сессию базы данных) для того, чтобы добавить нового героя `Hero` в объект сессии (`Session`), сохранить изменения в базе данных, обновить данные героя и затем вернуть их.
+
+### Чтение данных о героях
+
+Мы можем **читать** данные героев из базы данных с помощью `select()`. Мы можем включить `limit` и `offset` для постраничного считывания результатов.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *}
+
+### Чтение данных отдельного героя
+
+Мы можем прочитать данные отдельного героя (`Hero`).
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *}
+
+### Удаление данных героя
+
+Мы также можем удалить героя `Hero` из базы данных.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *}
+
+### Запуск приложения
+
+Вы можете запустить приложение следующим образом:
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Далее перейдите в пользовательский интерфейс API `/docs`. Вы увидите, что **FastAPI** использует модели для создания документации API. Эти же модели используются для сериализации и проверки данных.
+
+
+

+
+
+## Добавление в приложение дополнительных (вспомогательных) моделей
+
+Теперь давайте проведём **рефакторинг** нашего приложения, чтобы сделать его более безопасным и более универсальным.
+
+Обратите внимание, что на данном этапе наше приложение позволяет на уровне клиента определять `id` создаваемого героя (`Hero`). 😱
+
+Мы не можем этого допустить, т.к. существует риск переписать уже присвоенные `id` в базе данных. Присвоение `id` должно происходить **на уровне бэкэнда (backend)** или **на уровне базы данных**, но никак **не на уровне клиента**.
+
+Кроме того, мы создаем секретное имя `secret_name` для героя, но пока что, мы возвращаем его повсеместно, и это слабо напоминает **секретность**... 😅
+
+Мы поправим это с помощью нескольких дополнительных (вспомогательных) моделей. Вот где SQLModel по-настоящему покажет себя. ✨
+
+### Создание дополнительных моделей
+
+В **SQLModel**, любая модель с параметром `table=True` является **моделью таблицы**.
+
+Любая модель, не содержащая `table=True` является **моделью данных**, это по сути обычные модели Pydantic (с несколько расширенным функционалом). 🤓
+
+С помощью SQLModel мы можем использовать **наследование**, что поможет нам **избежать дублирования** всех полей.
+
+#### Базовый класс `HeroBase`
+
+Давайте начнём с модели `HeroBase`, которая содержит поля, общие для всех моделей:
+
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *}
+
+#### Модель таблицы `Hero`
+
+Далее давайте создадим **модель таблицы** `Hero` с дополнительными полями, которых может не быть в других моделях:
+
+* `id`
+* `secret_name`
+
+Модель `Hero` наследует от `HeroBase`, и поэтому включает также поля из `HeroBase`. Таким образом, все поля, содержащиеся в `Hero`, будут следующими:
+
+* `id`
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *}
+
+#### Публичная модель данных `HeroPublic`
+
+Далее мы создадим модель `HeroPublic`. Мы будем возвращать её клиентам API.
+
+Она включает в себя те же поля, что и `HeroBase`, и, соответственно, поле `secret_name` в ней отсутствует.
+
+Наконец-то личность наших героев защищена! 🥷
+
+В модели `HeroPublic` также объявляется поле `id: int`. Мы как бы заключаем договоренность с API клиентом, на то, что передаваемые данные всегда должны содержать поле `id`, и это поле должно содержать целое число (и никогда не содержать `None`).
+
+/// tip | Подсказка
+
+Модель ответа, гарантирующая наличие поля со значением типа `int` (не `None`), очень полезна при разработке API клиентов. Определенность в передаваемых данных может обеспечить написание более простого кода.
+
+Также **автоматически генерируемые клиенты** будут иметь более простой интерфейс. И в результате жизнь разработчиков, использующих ваш API, станет значительно легче. 😎
+
+///
+
+`HeroPublic` содержит все поля `HeroBase`, а также поле `id`, объявленное как `int` (не `None`):
+
+* `id`
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *}
+
+#### Модель для создания героя `HeroCreate`
+
+Сейчас мы создадим модель `HeroCreate`. Эта модель будет использоваться для проверки данных, переданных клиентом.
+
+Она содержит те же поля, что и `HeroBase`, а также поле `secret_name`.
+
+Теперь, при создании нового героя, клиенты будут передавать секретное имя `secret_name`, которое будет сохранено в базе данных, но не будет возвращено в ответе API клиентам.
+
+/// tip | Подсказка
+
+Вот как нужно работать с **паролями**: получайте их, но не возвращайте их через API.
+
+Также хэшируйте значения паролей перед тем, как их сохранить. Ни в коем случае не храните пароли в открытом виде, как обычный текст.
+
+///
+
+Поля модели `HeroCreate`:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *}
+
+#### Модель для обновления данных героя `HeroUpdate`
+
+В предыдущих версиях нашей программы мы не могли обновить данные героя, теперь, воспользовавшись дополнительными моделями, мы сможем это сделать. 🎉
+
+Модель данных `HeroUpdate` в некотором смысле особенная. Она содержит все те же поля, что и модель создания героя, но все поля модели являются **необязательными**. (Все они имеют значение по умолчанию.) Таким образом, при обновлении данных героя, вам достаточно передать только те поля, которые требуют изменения.
+
+Поскольку **все поля по сути меняются** (теперь тип каждого поля допускает значение `None` и значение по умолчанию `None`), мы должны их **объявить заново**.
+
+Фактически, нам не нужно наследоваться от `HeroBase`, потому что мы будем заново объявлять все поля. Я оставлю наследование просто для поддержания общего стиля, но оно (наследование) здесь необязательно. 🤷
+
+Поля `HeroUpdate`:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *}
+
+### Создание героя с помощью `HeroCreate` и возвращение результатов с помощью `HeroPublic`
+
+Теперь, когда у нас есть дополнительные модели, мы можем обновить те части приложения, которые их используют.
+
+Вместе c запросом на создание героя мы получаем объект данных `HeroCreate`, и создаем на его основе объект модели таблицы `Hero`.
+
+Созданный объект *модели таблицы* `Hero` будет иметь все поля, переданные клиентом, а также поле `id`, сгенерированное базой данных.
+
+Далее функция вернёт объект *модели таблицы* `Hero`. Но поскольку, мы объявили `HeroPublic` как модель ответа, то **FastAPI** будет использовать именно её для проверки и сериализации данных.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *}
+
+/// tip | Подсказка
+
+Теперь мы используем модель ответа `response_model=HeroPublic`, вместо того, чтобы объявить тип возвращаемого значения как `-> HeroPublic`. Мы это делаем потому, что тип возвращаемого значения не относится к `HeroPublic`.
+
+Если бы мы объявили тип возвращаемого значения как `-> HeroPublic`, то редактор и линтер начали бы ругаться (и вполне справедливо), что возвращаемое значение принадлежит типу `Hero`, а совсем не `HeroPublic`.
+
+Объявляя модель ответа в `response_model`, мы как бы говорим **FastAPI**: делай свое дело, не вмешиваясь в аннотацию типов и не полагаясь на помощь редактора или других инструментов.
+
+///
+
+### Чтение данных героев с помощью `HeroPublic`
+
+Мы можем проделать то же самое **для чтения данных** героев. Мы применим модель ответа `response_model=list[HeroPublic]`, и тем самым обеспечим правильную проверку и сериализацию данных.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *}
+
+### Чтение данных отдельного героя с помощью `HeroPublic`
+
+Мы можем **прочитать** данные отдельного героя:
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *}
+
+### Обновление данных героя с помощью `HeroUpdate`
+
+Мы можем **обновить данные героя**. Для этого мы воспользуемся HTTP методом `PATCH`.
+
+В коде мы получаем объект словаря `dict` с данными, переданными клиентом (т.е. **только c данными, переданными клиентом**, исключая любые значения, которые могли бы быть там только потому, что они являются значениями по умолчанию). Для того чтобы сделать это, мы воспользуемся опцией `exclude_unset=True`. В этом главная хитрость. 🪄
+
+Затем мы применим `hero_db.sqlmodel_update(hero_data)`, и обновим `hero_db`, использовав данные `hero_data`.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *}
+
+### Удалим героя ещё раз
+
+Операция **удаления** героя практически не меняется.
+
+В данном случае желание *`отрефакторить всё`* остаётся неудовлетворенным. 😅
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *}
+
+### Снова запустим приложение
+
+Вы можете снова запустить приложение:
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Если вы перейдете в пользовательский интерфейс API `/docs`, то вы увидите, что он был обновлен, и больше не принимает параметра `id` от клиента при создании нового героя, и т.д.
+
+
+

+
+
+## Резюме
+
+Вы можете использовать
**SQLModel** для взаимодействия с реляционными базами данных, а также для упрощения работы с **моделями данных** и **моделями таблиц**.
+
+Вы можете узнать гораздо больше информации в документации по **SQLModel**. Там вы найдете более подробное
мини-руководство по использованию SQLModel с **FastAPI**. 🚀
diff --git a/docs/ru/docs/tutorial/static-files.md b/docs/ru/docs/tutorial/static-files.md
new file mode 100644
index 000000000..c06eb858b
--- /dev/null
+++ b/docs/ru/docs/tutorial/static-files.md
@@ -0,0 +1,41 @@
+# Статические Файлы
+
+Вы можете предоставлять статические файлы автоматически из директории, используя `StaticFiles`.
+
+## Использование `StaticFiles`
+
+* Импортируйте `StaticFiles`.
+* "Примонтируйте" экземпляр `StaticFiles()` с указанием определенной директории.
+
+{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+
+/// note | Технические детали
+
+Вы также можете использовать `from starlette.staticfiles import StaticFiles`.
+
+**FastAPI** предоставляет `starlette.staticfiles` под псевдонимом `fastapi.staticfiles`, просто для вашего удобства, как разработчика. Но на самом деле это берётся напрямую из библиотеки Starlette.
+
+///
+
+### Что такое "Монтирование"
+
+"Монтирование" означает добавление полноценного "независимого" приложения в определенную директорию, которое затем обрабатывает все подпути.
+
+Это отличается от использования `APIRouter`, так как примонтированное приложение является полностью независимым.
+OpenAPI и документация из вашего главного приложения не будет содержать ничего из примонтированного приложения, и т.д.
+
+Вы можете прочитать больше об этом в **Расширенном руководстве пользователя**.
+
+## Детали
+
+Первый параметр `"/static"` относится к подпути, по которому это "подприложение" будет "примонтировано". Таким образом, любой путь начинающийся со `"/static"` будет обработан этим приложением.
+
+Параметр `directory="static"` относится к имени директории, которая содержит ваши статические файлы.
+
+`name="static"` даёт имя маршруту, которое может быть использовано внутри **FastAPI**.
+
+Все эти параметры могут отличаться от "`static`", настройте их в соответствии с вашими нуждами и конкретными деталями вашего собственного приложения.
+
+## Больше информации
+
+Для получения дополнительной информации о деталях и настройках ознакомьтесь с
Документацией Starlette о статических файлах.
diff --git a/docs/ru/docs/tutorial/testing.md b/docs/ru/docs/tutorial/testing.md
new file mode 100644
index 000000000..2c0f93d48
--- /dev/null
+++ b/docs/ru/docs/tutorial/testing.md
@@ -0,0 +1,237 @@
+# Тестирование
+
+Благодаря
Starlette, тестировать приложения **FastAPI** легко и приятно.
+
+Тестирование основано на библиотеке
HTTPX, которая в свою очередь основана на библиотеке Requests, так что все действия знакомы и интуитивно понятны.
+
+Используя эти инструменты, Вы можете напрямую задействовать
pytest с **FastAPI**.
+
+## Использование класса `TestClient`
+
+/// info | Информация
+
+Для использования класса `TestClient` необходимо установить библиотеку
`httpx`.
+
+Например, так: `pip install httpx`.
+
+///
+
+Импортируйте `TestClient`.
+
+Создайте объект `TestClient`, передав ему в качестве параметра Ваше приложение **FastAPI**.
+
+Создайте функцию, название которой должно начинаться с `test_` (это стандарт из соглашений `pytest`).
+
+Используйте объект `TestClient` так же, как Вы используете `httpx`.
+
+Напишите простое утверждение с `assert` дабы проверить истинность Python-выражения (это тоже стандарт `pytest`).
+
+{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+
+/// 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**:
+
+
+{* ../../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` Вы можете использовать относительный импорт:
+
+{* ../../docs_src/app_testing/test_main.py hl[3] *}
+
+
+...и писать дальше тесты, как и раньше.
+
+## Тестирование: расширенный пример
+
+Теперь давайте расширим наш пример и добавим деталей, чтоб посмотреть, как тестировать различные части приложения.
+
+### Расширенный файл приложения **FastAPI**
+
+Мы продолжим работу с той же файловой структурой, что и ранее:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Предположим, что в файле `main.py` с приложением **FastAPI** есть несколько **операций пути**.
+
+В нём описана операция `GET`, которая может вернуть ошибку.
+
+Ещё есть операция `POST` и она тоже может вернуть ошибку.
+
+Обе *операции пути* требуют наличия в запросе заголовка `X-Token`.
+
+//// tab | Python 3.10+
+
+```Python
+{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python
+{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+{!> ../../docs_src/app_testing/app_b_an/main.py!}
+```
+
+////
+
+//// tab | Python 3.10+ без Annotated
+
+/// tip | Подсказка
+
+По возможности используйте версию с `Annotated`.
+
+///
+
+```Python
+{!> ../../docs_src/app_testing/app_b_py310/main.py!}
+```
+
+////
+
+//// tab | Python 3.8+ без Annotated
+
+/// tip | Подсказка
+
+По возможности используйте версию с `Annotated`.
+
+///
+
+```Python
+{!> ../../docs_src/app_testing/app_b/main.py!}
+```
+
+////
+
+### Расширенный файл тестов
+
+Теперь обновим файл `test_main.py`, добавив в него тестов:
+
+{* ../../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/docs/virtual-environments.md b/docs/ru/docs/virtual-environments.md
new file mode 100644
index 000000000..777adaf22
--- /dev/null
+++ b/docs/ru/docs/virtual-environments.md
@@ -0,0 +1,839 @@
+# Виртуальная среда
+
+При работе с проектами в Python рекомендуется использовать **виртуальную среду разработки** (или какой-нибудь другой подобный механизм). Это нужно для того, чтобы изолировать устанавливаемые пакеты для каждого отдельного проекта.
+
+/// info | Дополнительная информация
+
+Если вы уже знакомы с виртуальными средами разработки, знаете как их создавать и использовать, то вы можете свободно пропустить данный раздел. 🤓
+
+///
+
+/// tip | Подсказка
+
+**Виртуальная среда** и **переменная окружения** это две разные вещи.
+
+**Переменная окружения** это системная переменная, которую могут использовать программы.
+
+**Виртуальная среда** это папка, содержащая файлы.
+
+///
+
+/// info | Дополнительная информация
+
+В этом разделе мы научим вас пользоваться виртуальными средами разработки и расскажем, как они работают.
+
+Если же вы готовы воспользоваться инструментом, **который умеет управлять всем, что касается Python-проектов**,
+(включая установку Python), то попробуйте
uv.
+
+///
+
+## Создание проекта
+
+В первую очередь, создайте директорию для вашего проекта.
+
+Я обычно создаю папку под названием `code` внутри моего домашнего каталога `/home/user`.
+
+Затем внутри данной папки я создаю отдельную директорию под каждый свой проект.
+
+
+
+```console
+// Перейдите в домашний каталог
+$ cd
+// Создайте отдельную папку под все будущие программные проекты (code)
+$ mkdir code
+// Войдите в директорию code
+$ cd code
+// Создайте директрорию под данный проект (awesome-project)
+$ mkdir awesome-project
+// Перейдите в созданную директорию проекта
+$ cd awesome-project
+```
+
+
+
+## Создание виртуальной среды разработки
+
+Начиная работу с Python-проектом, сразу же создавайте виртуальную среду разработки
+**
внутри вашего проекта**.
+
+/// tip | Подсказка
+
+Виртуальная среда разработки создается один раз, и в дальнейшем, работая с проектом, этого больше делать не придется.
+
+///
+
+//// tab | `venv`
+
+Для создания виртуальной среды вы можете воспользоваться модулем `venv`, который является частью встроенной библиотеки Python.
+
+
+
+```console
+$ python -m venv .venv
+```
+
+
+
+/// details | Что делает эта команда?
+
+* `python`: использовать программу под именем `python`
+* `-m`: вызывать модуль как скрипт, в следующей инструкции мы скажем какой именно модуль вызвать
+* `venv`: использовать модуль под названием `venv`, который обычно устанавливается вместе с Python
+* `.venv`: создать виртуальную среду разработки в новой директории `.venv`
+
+///
+
+////
+
+//// tab | `uv`
+
+Если вы установили
`uv`, то вы можете им воспользоваться для создания виртуальной среды разработки.
+
+
+
+```console
+$ uv venv
+```
+
+
+
+/// tip | Подсказка
+
+По умолчанию `uv` создаст виртуальную среду разработки в папке под названием `.venv`.
+
+Но вы можете это изменить, передав дополнительный аргумент с именем директории.
+
+///
+
+////
+
+Данная команда создаст новую виртуальную среду разработки в папке `.venv`.
+
+/// details | `.venv` или другое имя?
+
+Вы можете поместить виртуальную среду разработки в папку с другим именем, но традиционным (конвенциональным) названием является `.venv` .
+
+///
+
+## Активация виртуальной среды разработки
+
+Активируйте виртуальную среду разработки, и тогда любая запускаемая Python-команда или устанавливаемый пакет будут ее использовать.
+
+/// tip | Подсказка
+
+При работе над проектом делайте это **каждый раз** при запуске **новой сессии в терминале**.
+
+///
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+Или при использовании Bash для Windows (напр.
Git Bash):
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+## Проверка активации виртуальной среды
+
+Проверьте, активна ли виртуальная среда (удостоверимся, что предыдущая команда сработала).
+
+/// tip | Подсказка
+
+Убедитесь в том, что все работает так, как нужно и вы используете именно ту виртуальную среду разработки, которую нужно. Делать это необязательно, но желательно.
+
+///
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+Если данная команда показывает, что исполняемый файл `python` (`.venv\bin\python`), находится внутри виртуальной среды вашего проекта (у нас это `awesome-project`), значит все отработало как нужно. 🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+Если данная команда показывает, что исполняемый файл `python` (`.venv\Scripts\python`), находится внутри виртуальной среды вашего проекта (у нас это `awesome-project`), значит все отработало как нужно. 🎉
+
+////
+
+## Обновление `pip`
+
+/// tip | Подсказка
+
+Если вы используете
`uv`, то вы должны будете его использовать для установки пакетов вместо `pip`, поэтому обновлять `pip` вам ненужно. 😎
+
+///
+
+Если для установки пакетов вы используете `pip` (он устанавливается по умолчанию вместе с Python), то обновите `pip` до последней версии.
+
+Большинство экзотических ошибок, возникающих при установке пакетов, устраняется предварительным обновлением `pip`.
+
+/// tip | Подсказка
+
+Обычно это делается только один раз, сразу после создания виртуальной среды разработки.
+
+///
+
+Убедитесь в том, что виртуальная среда активирована (с помощью вышеуказанной команды) и запустите следующую команду:
+
+
+
+```console
+$ python -m pip install --upgrade pip
+
+---> 100%
+```
+
+
+
+## Добавление `.gitignore`
+
+Если вы используете **Git** (а вы должны его использовать), то добавьте файл `.gitignore` и исключите из Git всё, что находится в папке `.venv`.
+
+/// tip | Подсказка
+
+Если для создания виртуальной среды вы используете
`uv`, то для вас все уже сделано и вы можете пропустить этот шаг. 😎
+
+///
+
+/// tip | Подсказка
+
+Это делается один раз, сразу после создания виртуальной среды разработки.
+
+///
+
+
+
+```console
+$ echo "*" > .venv/.gitignore
+```
+
+
+
+/// details | Что делает эта команда?
+
+* `echo "*"`: напечатать `*` в консоли (следующий шаг это слегка изменит)
+* `>`: все что находится слева от `>` не печатать в консоль, но записать в файл находящийся справа от `>`
+* `.gitignore`: имя файла, в который нужно записать текст.
+
+`*` в Git означает "всё". Т.е. будет проигнорировано всё, что содержится в папке `.venv`.
+
+Данная команда создаст файл `.gitignore` следующего содержания:
+
+```gitignore
+*
+```
+
+///
+
+## Установка пакетов
+
+После установки виртуальной среды, вы можете устанавливать в нее пакеты.
+
+/// tip | Подсказка
+
+Сделайте это **один раз**, при установке или обновлении пакетов, нужных вашему проекту.
+
+Если вам понадобится обновить версию пакета или добавить новый пакет, то вы должны будете **сделать это снова**.
+
+///
+
+### Установка пакетов напрямую
+
+Если вы торопитесь и не хотите объявлять зависимости проекта в отдельном файле, то вы можете установить их напрямую.
+
+/// tip | Подсказка
+
+Объявление пакетов, которые использует ваш проект, и их версий в отдельном файле (например, в `requirements.txt` или в `pyproject.toml`) - это отличная идея.
+
+///
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install "fastapi[standard]"
+
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+Если вы используете
`uv`:
+
+
+
+```console
+$ uv pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+////
+
+### Установка из `requirements.txt`
+
+Если у вас есть `requirements.txt`, то вы можете использовать его для установки пакетов.
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+Если вы используете
`uv`:
+
+
+
+```console
+$ uv pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+/// details | `requirements.txt`
+
+`requirements.txt` с парочкой пакетов внутри выглядит приблизительно так:
+
+```requirements.txt
+fastapi[standard]==0.113.0
+pydantic==2.8.0
+```
+
+///
+
+## Запуск программы
+
+После активации виртуальной среды разработки вы можете запустить свою программу и она будет использовать версию Python и пакеты, установленные в виртуальной среде.
+
+
+
+```console
+$ python main.py
+
+Hello World
+```
+
+
+
+## Настройка редактора
+
+Вероятно, вы захотите воспользоваться редактором. Убедитесь, что вы настроили его на использование той самой виртуальной среды, которую вы создали. (Скорее всего, она автоматически будет обнаружена). Это позволит вам использовать авто-завершение и выделение ошибок в редакторе.
+
+Например:
+
+*
VS Code
+*
PyCharm
+
+/// tip | Подсказка
+
+Обычно это делается один раз, при создании виртуальной среды разработки.
+
+///
+
+## Деактивация виртуальной среды разработки
+
+По окончании работы над проектом вы можете деактивировать виртуальную среду.
+
+
+
+```console
+$ deactivate
+```
+
+
+
+Таким образом, при запуске `python`, будет использована версия `python` установленная глобально, а не из этой виртуальной среды вместе с установленными в ней пакетами.
+
+## Все готово к работе
+
+Теперь вы готовы к тому, чтобы начать работу над своим проектом.
+
+
+
+/// tip | Подсказка
+
+Хотите разобраться со всем, что написано выше?
+
+Продолжайте читать. 👇🤓
+
+///
+
+## Зачем использовать виртуальную среду?
+
+Для работы с FastAPI вам потребуется установить
Python.
+
+После этого вам нужно будет **установить** FastAPI и другие **пакеты**, которые вы собираетесь использовать.
+
+Для установки пакетов обычно используют `pip`, который устанавливается вместе с Python (или же используют альтернативные решения).
+
+Тем не менее, если вы просто используете `pip` напрямую, то пакеты будут установлены в **глобальное Python-окружение** (глобально установленный Python).
+
+### Проблема
+
+Так в чем же проблема с установкой пакетов в глобальную среду Python?
+
+В какой-то момент вам, вероятно, придется писать множество разных программ, которые используют различные пакеты. 😱
+
+Например, вы создаете проект `philosophers-stone`, который зависит от пакета под названием **`harry`, версии `1`**. Таким образом, вам нужно установить `harry`.
+
+```mermaid
+flowchart LR
+ stone(philosophers-stone) -->|requires| harry-1[harry v1]
+```
+
+Затем, в какой-то момент, вы создаете другой проект под названием `prisoner-of-azkaban`, и этот проект тоже зависит от `harry`, но он уже использует **`harry` версии `3`**.
+
+```mermaid
+flowchart LR
+ azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
+```
+
+Проблема заключается в том, что при установке в глобальное окружение, а не в локальную виртуальную среду разработки, вам нужно будет выбирать, какую версию пакета `harry` устанавливать.
+
+Если вам нужен `philosophers-stone`, то вам нужно сначала установить `harry` версии `1`:
+
+
+
+```console
+$ pip install "harry==1"
+```
+
+
+
+И тогда в вашем глобальном окружении Python будет установлен `harry` версии `1`:
+
+```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
+```
+
+Но если позднее вы захотите запустить `prisoner-of-azkaban`, то вам нужно будет удалить `harry` версии 1, и установить `harry` версии `3` (при установке пакета версии `3` поверх пакета версии `1`, пакет версии `1` удаляется автоматически).
+
+
+
+```console
+$ pip install "harry==3"
+```
+
+
+
+И тогда, в вашей глобальной среде окружения Python, будет установлен пакет `harry` версии `3`.
+
+И когда вы снова попытаетесь запустить `philosophers-stone`, то существует вероятность того, что он не будет работать, так как он использует `harry` версии `1`.
+
+```mermaid
+flowchart LR
+ subgraph global[global env]
+ harry-1[
harry v1]
+ 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 | Подсказка
+
+В пакетах Python очень часто стараются изо всех сил избегать внесения критических изменений в новые версии, но лучше перестраховаться и планово устанавливать новые версии, а затем запускать тесты, чтобы проверить, все ли работает правильно.
+
+///
+
+Теперь представьте, что это происходит со многими другими пакетами, которые используются в ваших проектах. С этим очень сложно справиться. И скорее всего, в конечном итоге вы будете запускать некоторые проекты с некоторыми несовместимыми зависимостями и не будете знать, почему что-то не работает.
+
+Кроме того, в зависимости от вашей операционной системы (напр. Linux, Windows, macOS), она может поставляться с уже установленным Python. Вероятно, что в этом случае в ней уже установлены системные пакеты определенных версий. Если вы устанавливаете пакеты глобально, то вы можете **поломать** программы, являющиеся частью ОС.
+
+## Куда устанавливаются пакеты?
+
+Когда вы устанавливаете Python, то на вашей машине создается некоторое количество директорий, содержащих некоторое количество файлов.
+
+Среди них есть каталоги, отвечающие за хранение всех устанавливаемых вами пакетов.
+
+Когда вы запустите команду:
+
+
+
+```console
+// Не запускайте эту команду, это просто пример 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+То будет скачан сжатый файл, содержащий код FastAPI, обычно скачивание происходит с
PyPI.
+
+Также будут скачаны файлы, содержащие пакеты, которые использует FastAPI.
+
+Затем все файлы будут извлечены и помещены в директорию на вашем компьютере.
+
+По умолчанию эти файлы будут загружены и извлечены в один из каталогов установки Python, т.е. в глобальную среду.
+
+## Что такое виртуальная среда разработки?
+
+Решением проблемы размещения всех пакетов в глобальной среде будет использование отдельной виртуальной среды под каждый проект, над которым вы работаете.
+
+Виртуальная среда это обычная папка, очень похожая на глобальную, куда вы можете устанавливать пакеты для вашего проекта.
+
+Таким образом, каждый проект будет иметь свою отдельную виртуальную среду разработки (в директории `.venv`) вместе со своими пакетами.
+
+```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
+```
+
+## Что означает активация виртуальной среды?
+
+Когда вы активируете виртуальную среду разработки, например, так:
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+Или если вы воспользуетесь Bash под Windows (напр.
Git Bash):
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+
+Эта команда создаст или изменит некоторые [переменные окружения](environment-variables.md){.internal-link target=_blank}, которые будут доступны для последующих команд.
+
+Одной из таких переменных является `PATH`.
+
+/// tip | Подсказка
+
+Вы можете узнать больше о переменной окружения `PATH` в разделе [Переменные окружения](environment-variables.md#path-environment-variable){.internal-link target=_blank}.
+
+///
+
+При активации виртуальной среды путь `.venv/bin` (для Linux и macOS) или `.venv\Scripts` (для Windows) добавляется в переменную окружения `PATH`.
+
+Предположим, что до активации виртуальной среды переменная `PATH` выглядела так:
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Это означает, что система ищет программы в следующих каталогах:
+
+* `/usr/bin`
+* `/bin`
+* `/usr/sbin`
+* `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Windows\System32
+```
+
+Это означает, что система ищет программы в:
+
+* `C:\Windows\System32`
+
+////
+
+После активации виртуальной среды переменная окружение `PATH` будет выглядеть примерно так:
+
+//// tab | Linux, macOS
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Это означает, что система теперь будет искать программы в:
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin
+```
+
+прежде чем начать искать в других каталогах.
+
+Таким образом, когда вы введете в консоль `python`, система будет искать Python в
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+и будет использовать именно его.
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
+```
+
+Это означает, что система в первую очередь начнет искать программы в:
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts
+```
+
+прежде чем начать искать в других директориях.
+
+Таким образом, если вы введете в консоль команду `python`, то система найдет Python в:
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+и использует его.
+
+////
+
+Очень важной деталью является то, что путь к виртуальной среде будет помещен в самое начало переменной `PATH`. Система обнаружит данный путь к Python раньше, чем какой-либо другой. Таким образом, при запуске команды `python`, будет использован именно Python из виртуальной среды разработки, а не какой-нибудь другой (например, Python из глобальной среды)
+
+Активация виртуальной среды разработки также меняет и несколько других вещей, но данная функция является основной.
+
+## Проверка виртуальной среды
+
+Когда вы проверяете активна ли виртуальная среда разработки, например, так:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+Это означает, что будет использоваться `python` **из виртуальной среды разработки**.
+
+Вы используете `which` для Linux и macOS и `Get-Command` для Windows PowerShell.
+
+Эта команда работает следующим образом: она проверяет переменную окружения `PATH`, проходя по очереди каждый указанный путь в поисках программы под названием `python`. И когда она её находит, то возвращает путь к данной программе.
+
+Основной момент при вызове команды `python` состоит в том, какой именно "`python`" будет запущен.
+
+Таким образом, вы можете убедиться, что используете правильную виртуальную среду разработки.
+
+/// tip | Подсказка
+
+Легко активировать одну виртуальную среду, вызвать один Python и **перейти к следующему проекту**.
+
+И следующий проект не будет работать потому, что вы используете **неправильный Python** из виртуальной среды другого проекта.
+
+Так что, будет нелишним проверить, какой `python` вы используете. 🤓
+
+///
+
+## Зачем деактивируют виртуальную среду?
+
+Предположим, что вы работаете над проектом `philosophers-stone`, **активируете виртуальную среду разработки**, устанавливаете пакеты и работаете с данной средой.
+
+И позже вам понадобилось поработать с **другим проектом** `prisoner-of-azkaban`.
+
+Вы переходите к этому проекту:
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+```
+
+
+
+Если вы не деактивировали виртуальное окружение проекта `philosophers-stone`, то при запуске `python` через консоль будет вызван Python из `philosophers-stone`
+
+
+
+```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
+ import sirius
+```
+
+
+
+Но если вы деактивируете виртуальную среду разработки и активируете новую среду для `prisoner-of-askaban`, то вы тогда запустите Python из виртуального окружения `prisoner-of-azkaban`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// Вам не требуется находится в старой директории для деактивации среды разработки, вы можете это сделать откуда угодно, даже из каталога другого проекта, в который вы перешли. 😎
+$ deactivate
+
+// Активируйте виртуальную среду разработки в prisoner-of-azkaban/.venv 🚀
+$ source .venv/bin/activate
+
+// Тепреь, когда вы запустите python, он найдет пакет sirius, установленный в виртуальной среде ✨
+$ python main.py
+
+Я торжественно клянусь в этом! 🐺
+```
+
+
+
+## Альтернативы
+
+Это простое руководство поможет вам начать работу и научит тому, как всё работает **изнутри**.
+
+Существует много альтернативных решений для работы с виртуальными средами разработки, с программными зависимостями, а также с проектами.
+
+Когда вы будете готовы использовать единый инструмент для управления проектом, программными зависимостями, виртуальными средами разработки и т.д., то я рекомендую вам попробовать
uv.
+
+`uv` может очень многое. Он умеет:
+
+* **Устанавливать Python**, включая установку различных версий
+* Управлять средой виртуального окружения вашего проекта
+* Устанавливать **пакеты**
+* Управлять пакетами и их версиями внутри вашего проекта
+* Удостовериться, что вы используете **точный** набор пакетов и версий при установке, включая зависимости. Таким образом, вы можете быть уверенны, что проект, запускается в production, точно также, как и при разработке, этот механизм называется *locking*
+* Многие другие вещи
+
+## Заключение
+
+Если вы прочитали и поняли всё это, то теперь вы знаете **гораздо больше** о виртуальных средах разработки, чем многие другие разработчики. 🤓
+
+Скорее всего, знание этих деталей будет полезно вам в будущем. Когда вы будете отлаживать что-то, кажущееся сложным, вы будете знать, **как это работает под капотом**. 😎
diff --git a/docs/ru/mkdocs.yml b/docs/ru/mkdocs.yml
index f35ee968c..de18856f4 100644
--- a/docs/ru/mkdocs.yml
+++ b/docs/ru/mkdocs.yml
@@ -1,155 +1 @@
-site_name: FastAPI
-site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
-site_url: https://fastapi.tiangolo.com/ru/
-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: ru
-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/
- - es: /es/
- - fa: /fa/
- - fr: /fr/
- - he: /he/
- - id: /id/
- - it: /it/
- - ja: /ja/
- - ko: /ko/
- - nl: /nl/
- - pl: /pl/
- - pt: /pt/
- - ru: /ru/
- - sq: /sq/
- - sv: /sv/
- - tr: /tr/
- - uk: /uk/
- - zh: /zh/
-- features.md
-- fastapi-people.md
-- python-types.md
-- Учебник - руководство пользователя:
- - tutorial/background-tasks.md
-- async.md
-- Развёртывание:
- - deployment/index.md
- - deployment/versions.md
-- external-links.md
-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: UA-133183413-1
- 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: /es/
- name: es - español
- - link: /fa/
- name: fa
- - link: /fr/
- name: fr - français
- - link: /he/
- name: he
- - link: /id/
- name: id
- - link: /it/
- name: it - italiano
- - link: /ja/
- name: ja - 日本語
- - link: /ko/
- name: ko - 한국어
- - 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: /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
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/sq/docs/index.md b/docs/sq/docs/index.md
deleted file mode 100644
index cff2c2804..000000000
--- a/docs/sq/docs/index.md
+++ /dev/null
@@ -1,466 +0,0 @@
-
-{!../../../docs/missing-translation.md!}
-
-
-
-
-
-
- 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.6+ 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 [...]_"
-
-
-
----
-
-## **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.6+**.
-
-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).
-* Many extra features (thanks to Starlette) as:
- * **WebSockets**
- * **GraphQL**
- * 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).
-*
graphene
- Required for `GraphQLApp` support.
-*
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/sq/mkdocs.yml b/docs/sq/mkdocs.yml
deleted file mode 100644
index b07f3bc63..000000000
--- a/docs/sq/mkdocs.yml
+++ /dev/null
@@ -1,145 +0,0 @@
-site_name: FastAPI
-site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
-site_url: https://fastapi.tiangolo.com/sq/
-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/
- - es: /es/
- - fa: /fa/
- - fr: /fr/
- - he: /he/
- - id: /id/
- - it: /it/
- - ja: /ja/
- - ko: /ko/
- - nl: /nl/
- - pl: /pl/
- - pt: /pt/
- - ru: /ru/
- - sq: /sq/
- - sv: /sv/
- - 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: UA-133183413-1
- 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: /es/
- name: es - español
- - link: /fa/
- name: fa
- - link: /fr/
- name: fr - français
- - link: /he/
- name: he
- - link: /id/
- name: id
- - link: /it/
- name: it - italiano
- - link: /ja/
- name: ja - 日本語
- - link: /ko/
- name: ko - 한국어
- - 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: /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/sv/docs/index.md b/docs/sv/docs/index.md
deleted file mode 100644
index 23143a96f..000000000
--- a/docs/sv/docs/index.md
+++ /dev/null
@@ -1,468 +0,0 @@
-
-{!../../../docs/missing-translation.md!}
-
-
-
-
-
-
- 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.6+ 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 [...]_"
-
-
-
----
-
-## **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.6+**.
-
-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/sv/mkdocs.yml b/docs/sv/mkdocs.yml
deleted file mode 100644
index 3332d232d..000000000
--- a/docs/sv/mkdocs.yml
+++ /dev/null
@@ -1,145 +0,0 @@
-site_name: FastAPI
-site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
-site_url: https://fastapi.tiangolo.com/sv/
-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: sv
-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/
- - es: /es/
- - fa: /fa/
- - fr: /fr/
- - he: /he/
- - id: /id/
- - it: /it/
- - ja: /ja/
- - ko: /ko/
- - nl: /nl/
- - pl: /pl/
- - pt: /pt/
- - ru: /ru/
- - sq: /sq/
- - sv: /sv/
- - 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: UA-133183413-1
- 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: /es/
- name: es - español
- - link: /fa/
- name: fa
- - link: /fr/
- name: fr - français
- - link: /he/
- name: he
- - link: /id/
- name: id
- - link: /it/
- name: it - italiano
- - link: /ja/
- name: ja - 日本語
- - link: /ko/
- name: ko - 한국어
- - 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: /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/sv/overrides/.gitignore b/docs/sv/overrides/.gitignore
deleted file mode 100644
index e69de29bb..000000000
diff --git a/docs/tr/docs/about/index.md b/docs/tr/docs/about/index.md
new file mode 100644
index 000000000..e9dee5217
--- /dev/null
+++ b/docs/tr/docs/about/index.md
@@ -0,0 +1,3 @@
+# Hakkında
+
+FastAPI, tasarımı, ilham kaynağı ve daha fazlası hakkında. 🤓
diff --git a/docs/tr/docs/advanced/index.md b/docs/tr/docs/advanced/index.md
new file mode 100644
index 000000000..836e63c8a
--- /dev/null
+++ b/docs/tr/docs/advanced/index.md
@@ -0,0 +1,36 @@
+# Gelişmiş Kullanıcı Rehberi
+
+## Ek Özellikler
+
+[Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası **FastAPI**'ın tüm ana özelliklerini tanıtmaya yetecektir.
+
+İlerleyen bölümlerde diğer seçenekler, konfigürasyonlar ve ek özellikleri göreceğiz.
+
+/// tip | İpucu
+
+Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
+
+Kullanım şeklinize bağlı olarak, çözümünüz bu bölümlerden birinde olabilir.
+
+///
+
+## Önce Öğreticiyi Okuyun
+
+[Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfasındaki bilgilerle **FastAPI**'nın çoğu özelliğini kullanabilirsiniz.
+
+Sonraki bölümler bu sayfayı okuduğunuzu ve bu ana fikirleri bildiğinizi varsayarak hazırlanmıştır.
+
+## Diğer Kurslar
+
+[Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası ve bu **Gelişmiş Kullanıcı Rehberi**, öğretici bir kılavuz (bir kitap gibi) şeklinde yazılmıştır ve **FastAPI'ı öğrenmek** için yeterli olsa da, ek kurslarla desteklemek isteyebilirsiniz.
+
+Belki de öğrenme tarzınıza daha iyi uyduğu için başka kursları tercih edebilirsiniz.
+
+Bazı kurs sağlayıcıları ✨ [**FastAPI destekçileridir**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, bu FastAPI ve **ekosisteminin** sürekli ve sağlıklı bir şekilde **gelişmesini** sağlar.
+
+Ayrıca, size **iyi bir öğrenme deneyimi** sağlamakla kalmayıp, **iyi ve sağlıklı bir framework** olan FastAPI'a ve ve **topluluğuna** (yani size) olan gerçek bağlılıklarını gösterir.
+
+Onların kurslarını denemek isteyebilirsiniz:
+
+*
Talk Python Training
+*
Test-Driven Development
diff --git a/docs/tr/docs/advanced/security/index.md b/docs/tr/docs/advanced/security/index.md
new file mode 100644
index 000000000..709f74c72
--- /dev/null
+++ b/docs/tr/docs/advanced/security/index.md
@@ -0,0 +1,19 @@
+# Gelişmiş Güvenlik
+
+## Ek Özellikler
+
+[Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
+
+/// tip | İpucu
+
+Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
+
+Kullanım şeklinize bağlı olarak, çözümünüz bu bölümlerden birinde olabilir.
+
+///
+
+## Önce Öğreticiyi Okuyun
+
+Sonraki bölümler [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasını okuduğunuzu varsayarak hazırlanmıştır.
+
+Bu bölümler aynı kavramlara dayanır, ancak bazı ek işlevsellikler sağlar.
diff --git a/docs/tr/docs/advanced/testing-websockets.md b/docs/tr/docs/advanced/testing-websockets.md
new file mode 100644
index 000000000..ddacca449
--- /dev/null
+++ b/docs/tr/docs/advanced/testing-websockets.md
@@ -0,0 +1,13 @@
+# WebSockets'i Test Etmek
+
+WebSockets testi yapmak için `TestClient`'ı kullanabilirsiniz.
+
+Bu işlem için, `TestClient`'ı bir `with` ifadesinde kullanarak WebSocket'e bağlanabilirsiniz:
+
+{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
+
+/// note | Not
+
+Daha fazla detay için Starlette'in
Websockets'i Test Etmek dokümantasyonunu inceleyin.
+
+///
diff --git a/docs/tr/docs/advanced/wsgi.md b/docs/tr/docs/advanced/wsgi.md
new file mode 100644
index 000000000..00815a4b2
--- /dev/null
+++ b/docs/tr/docs/advanced/wsgi.md
@@ -0,0 +1,35 @@
+# WSGI - Flask, Django ve Daha Fazlasını FastAPI ile Kullanma
+
+WSGI uygulamalarını [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank} bölümlerinde gördüğünüz gibi bağlayabilirsiniz.
+
+Bunun için `WSGIMiddleware` ile Flask, Django vb. WSGI uygulamanızı sarmalayabilir ve FastAPI'ya bağlayabilirsiniz.
+
+## `WSGIMiddleware` Kullanımı
+
+`WSGIMiddleware`'ı projenize dahil edin.
+
+Ardından WSGI (örneğin Flask) uygulamanızı middleware ile sarmalayın.
+
+Son olarak da bir yol altında bağlama işlemini gerçekleştirin.
+
+{* ../../docs_src/wsgi/tutorial001.py hl[2:3,23] *}
+
+## Kontrol Edelim
+
+Artık `/v1/` yolunun altındaki her istek Flask uygulaması tarafından işlenecektir.
+
+Geri kalanı ise **FastAPI** tarafından işlenecektir.
+
+Eğer uygulamanızı çalıştırıp
http://localhost:8000/v1/ adresine giderseniz, Flask'tan gelen yanıtı göreceksiniz:
+
+```txt
+Hello, World from Flask!
+```
+
+Eğer
http://localhost:8000/v2/ adresine giderseniz, FastAPI'dan gelen yanıtı göreceksiniz:
+
+```JSON
+{
+ "message": "Hello World"
+}
+```
diff --git a/docs/tr/docs/alternatives.md b/docs/tr/docs/alternatives.md
new file mode 100644
index 000000000..c98b966b5
--- /dev/null
+++ b/docs/tr/docs/alternatives.md
@@ -0,0 +1,483 @@
+# Alternatifler, İlham Kaynakları ve Karşılaştırmalar
+
+**FastAPI**'ya neler ilham verdi? Diğer alternatiflerle karşılaştırıldığında farkları neler? **FastAPI** diğer alternatiflerinden neler öğrendi?
+
+## Giriş
+
+Başkalarının daha önceki çalışmaları olmasaydı, **FastAPI** var olmazdı.
+
+Geçmişte oluşturulan pek çok araç **FastAPI**'a ilham kaynağı olmuştur.
+
+Yıllardır yeni bir framework oluşturmaktan kaçınıyordum. Başlangıçta **FastAPI**'ın çözdüğü sorunları çözebilmek için pek çok farklı framework,
eklenti ve araç kullanmayı denedim.
+
+Ancak bir noktada, geçmişteki diğer araçlardan en iyi fikirleri alarak bütün bu çözümleri kapsayan, ayrıca bütün bunları Python'ın daha önce mevcut olmayan özelliklerini (Python 3.6+ ile gelen
tip belirteçleri) kullanarak yapan bir şey üretmekten başka seçenek kalmamıştı.
+
+## Daha Önce Geliştirilen Araçlar
+
+###
Django
+
+Django geniş çapta güvenilen, Python ekosistemindeki en popüler web framework'üdür. Instagram gibi sistemleri geliştirmede kullanılmıştır.
+
+MySQL ve PostgreSQL gibi ilişkisel veritabanlarıyla nispeten sıkı bir şekilde bağlantılıdır. Bu nedenle Couchbase, MongoDB ve Cassandra gibi NoSQL veritabanlarını ana veritabanı motoru olarak kullanmak pek de kolay değil.
+
+Modern ön uçlarda (React, Vue.js ve Angular gibi) veya diğer sistemler (örneğin
nesnelerin interneti cihazları) tarafından kullanılan API'lar yerine arka uçta HTML üretmek için oluşturuldu.
+
+###
Django REST Framework
+
+Django REST framework'ü, Django'nun API kabiliyetlerini arttırmak için arka planda Django kullanan esnek bir araç grubu olarak oluşturuldu.
+
+Üstelik Mozilla, Red Hat ve Eventbrite gibi pek çok şirket tarafından kullanılıyor.
+
+**Otomatik API dökümantasyonu**nun ilk örneklerinden biri olduğu için, **FastAPI** arayışına ilham veren ilk fikirlerden biri oldu.
+
+/// note | Not
+
+Django REST Framework'ü, aynı zamanda **FastAPI**'ın dayandığı Starlette ve Uvicorn'un da yaratıcısı olan Tom Christie tarafından geliştirildi.
+
+///
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+Kullanıcılar için otomatik API dökümantasyonu sunan bir web arayüzüne sahip olmalı.
+
+///
+
+###
Flask
+
+Flask bir
mikro framework olduğundan Django gibi framework'lerin aksine veritabanı entegrasyonu gibi Django ile gelen pek çok özelliği direkt barındırmaz.
+
+Sağladığı basitlik ve esneklik NoSQL veritabanlarını ana veritabanı sistemi olarak kullanmak gibi şeyler yapmaya olanak sağlar.
+
+Yapısı oldukça basit olduğundan öğrenmesi de nispeten basittir, tabii dökümantasyonu bazı noktalarda biraz teknik hale geliyor.
+
+Ayrıca Django ile birlikte gelen veritabanı, kullanıcı yönetimi ve diğer pek çok özelliğe ihtiyaç duymayan uygulamalarda da yaygın olarak kullanılıyor. Ancak bu tür özelliklerin pek çoğu
eklentiler ile eklenebiliyor.
+
+Uygulama parçalarının böyle ayrılıyor oluşu ve istenilen özelliklerle genişletilebilecek bir
mikro framework olmak tam da benim istediğim bir özellikti.
+
+Flask'ın basitliği göz önünde bulundurulduğu zaman, API geliştirmek için iyi bir seçim gibi görünüyordu. Sıradaki şey ise Flask için bir "Django REST Framework"!
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+Gereken araçları ve parçaları birleştirip eşleştirmeyi kolaylaştıracak bir mikro framework olmalı.
+
+Basit ve kullanması kolay bir
yönlendirme sistemine sahip olmalı.
+
+///
+
+###
Requests
+
+**FastAPI** aslında **Requests**'in bir alternatifi değil. İkisininde kapsamı oldukça farklı.
+
+Aslında Requests'i bir FastAPI uygulamasının *içinde* kullanmak daha olağan olurdu.
+
+Ama yine de, FastAPI, Requests'ten oldukça ilham aldı.
+
+**Requests**,
API'lar ile bir istemci olarak *etkileşime geçmeyi* sağlayan bir kütüphaneyken **FastAPI** bir sunucu olarak
API'lar oluşturmaya yarar.
+
+Öyle ya da böyle zıt uçlarda olmalarına rağmen birbirlerini tamamlıyorlar.
+
+Requests oldukça basit ve sezgisel bir tasarıma sahip, kullanması da mantıklı varsayılan değerlerle oldukça kolay. Ama aynı zamanda çok güçlü ve gayet özelleştirilebilir.
+
+Bu yüzden resmi web sitede de söylendiği gibi:
+
+> Requests, tüm zamanların en çok indirilen Python
paketlerinden biridir.
+
+Kullanım şekli oldukça basit. Örneğin bir `GET` isteği yapmak için aşağıdaki yeterli:
+
+```Python
+response = requests.get("http://example.com/some/url")
+```
+
+Bunun FastAPI'deki API
*yol işlemi* şöyle görünür:
+
+```Python hl_lines="1"
+@app.get("/some/url")
+def read_url():
+ return {"message": "Hello World!"}
+```
+
+`requests.get(...)` ile `@app.get(...)` arasındaki benzerliklere bakın.
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+* Basit ve sezgisel bir API'ya sahip olmalı.
+* HTTP metot isimlerini (işlemlerini) anlaşılır olacak bir şekilde, direkt kullanmalı.
+* Mantıklı varsayılan değerlere ve buna rağmen güçlü bir özelleştirme desteğine sahip olmalı.
+
+///
+
+###
Swagger /
OpenAPI
+
+Benim Django REST Framework'ünden istediğim ana özellik otomatik API dökümantasyonuydu.
+
+Daha sonra API'ları dökümanlamak için Swagger adında JSON (veya JSON'un bir uzantısı olan YAML'ı) kullanan bir standart olduğunu buldum.
+
+Üstelik Swagger API'ları için zaten halihazırda oluşturulmuş bir web arayüzü vardı. Yani, bir API için Swagger dökümantasyonu oluşturmak bu arayüzü otomatik olarak kullanabilmek demekti.
+
+Swagger bir noktada Linux Foundation'a verildi ve adı OpenAPI olarak değiştirildi.
+
+İşte bu yüzden versiyon 2.0 hakkında konuşurken "Swagger", versiyon 3 ve üzeri için ise "OpenAPI" adını kullanmak daha yaygın.
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+API spesifikasyonları için özel bir şema yerine bir
açık standart benimseyip kullanmalı.
+
+Ayrıca standarda bağlı kullanıcı arayüzü araçlarını entegre etmeli:
+
+*
Swagger UI
+*
ReDoc
+
+Yukarıdaki ikisi oldukça popüler ve istikrarlı olduğu için seçildi, ancak hızlı bir araştırma yaparak **FastAPI** ile kullanabileceğiniz pek çok OpenAPI alternatifi arayüz bulabilirsiniz.
+
+///
+
+### Flask REST framework'leri
+
+Pek çok Flask REST framework'ü var, fakat bunları biraz araştırdıktan sonra pek çoğunun artık geliştirilmediğini ve göze batan bazı sorunlarının olduğunu gördüm.
+
+###
Marshmallow
+
+API sistemlerine gereken ana özelliklerden biri de koddan veriyi alıp ağ üzerinde gönderilebilecek bir şeye çevirmek, yani veri
dönüşümü. Bu işleme veritabanındaki veriyi içeren bir objeyi JSON objesine çevirmek, `datetime` objelerini metinlere çevirmek gibi örnekler verilebilir.
+
+API'lara gereken bir diğer büyük özellik ise veri doğrulamadır, yani verinin çeşitli parametrelere bağlı olarak doğru ve tutarlı olduğundan emin olmaktır. Örneğin bir alanın `int` olmasına karar verdiniz, daha sonra rastgele bir metin değeri almasını istemezsiniz. Bu özellikle sisteme dışarıdan gelen veri için kullanışlı bir özellik oluyor.
+
+Bir veri doğrulama sistemi olmazsa bütün bu kontrolleri koda dökerek kendiniz yapmak zorunda kalırdınız.
+
+Marshmallow bu özellikleri sağlamak için geliştirilmişti. Benim de geçmişte oldukça sık kullandığım harika bir kütüphanedir.
+
+Ama... Python'un tip belirteçleri gelmeden önce oluşturulmuştu. Yani her
şemayı tanımlamak için Marshmallow'un sunduğu spesifik araçları ve sınıfları kullanmanız gerekiyordu.
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+Kod kullanarak otomatik olarak veri tipini ve veri doğrulamayı belirten "şemalar" tanımlamalı.
+
+///
+
+###
Webargs
+
+API'ların ihtiyacı olan bir diğer önemli özellik ise gelen isteklerdeki verileri Python objelerine
ayrıştırabilmektir.
+
+Webargs, Flask gibi bir kaç framework'ün üzerinde bunu sağlamak için geliştirilen bir araçtır.
+
+Veri doğrulama için arka planda Marshmallow kullanıyor, hatta aynı geliştiriciler tarafından oluşturuldu.
+
+Webargs da harika bir araç ve onu da geçmişte henüz **FastAPI** yokken çok kullandım.
+
+/// info | Bilgi
+
+Webargs aynı Marshmallow geliştirileri tarafından oluşturuldu.
+
+///
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+Gelen istek verisi için otomatik veri doğrulamaya sahip olmalı.
+
+///
+
+###
APISpec
+
+Marshmallow ve Webargs
eklentiler olarak; veri doğrulama, ayrıştırma ve dönüştürmeyi sağlıyor.
+
+Ancak dökümantasyondan hala ses seda yok. Daha sonrasında ise APISpec geldi.
+
+APISpec pek çok framework için bir
eklenti olarak kullanılıyor (Starlette için de bir
eklentisi var).
+
+Şemanın tanımını
yol'a istek geldiğinde çalışan her bir fonksiyonun
döküman dizesinin içine YAML formatında olacak şekilde yazıyorsunuz o da OpenAPI şemaları üretiyor.
+
+Flask, Starlette, Responder ve benzerlerinde bu şekilde çalışıyor.
+
+Fakat sonrasında yine mikro sözdizimi problemiyle karşılaşıyoruz. Python metinlerinin içinde koskoca bir YAML oluyor.
+
+Editör bu konuda pek yardımcı olamaz. Üstelik eğer parametreleri ya da Marshmallow şemalarını değiştirip YAML kodunu güncellemeyi unutursak artık döküman geçerliliğini yitiriyor.
+
+/// info | Bilgi
+
+APISpec de aynı Marshmallow geliştiricileri tarafından oluşturuldu.
+
+///
+
+/// check | **FastAPI**'a nasıl ilham verdi?
+
+API'lar için açık standart desteği olmalı (OpenAPI gibi).
+
+///
+
+###
Flask-apispec
+
+Flask-apispec ise Webargs, Marshmallow ve APISpec'i birbirine bağlayan bir Flask
eklentisi.
+
+Webargs ve Marshmallow'daki bilgiyi APISpec ile otomatik OpenAPI şemaları üretmek için kullanıyor.
+
+Hak ettiği değeri görmeyen, harika bir araç. Piyasadaki çoğu Flask
eklentisinden çok daha popüler olmalı. Hak ettiği değeri görmüyor oluşunun sebebi ise dökümantasyonun çok kısa ve soyut olması olabilir.
+
+Böylece Flask-apispec, Python döküman dizilerine YAML gibi farklı bir syntax yazma sorununu çözmüş oldu.
+
+**FastAPI**'ı geliştirene dek benim favori arka uç kombinasyonum Flask'in yanında Marshmallow ve Webargs ile birlikte Flask-apispec idi.
+
+Bunu kullanmak, bir kaç
full-stack Flask projesi oluşturucusunun yaratılmasına yol açtı. Bunlar benim (ve bir kaç harici ekibin de) şimdiye kadar kullandığı asıl
stackler:
+
+*
https://github.com/tiangolo/full-stack
+*
https://github.com/tiangolo/full-stack-flask-couchbase
+*
https://github.com/tiangolo/full-stack-flask-couchdb
+
+Aynı full-stack üreticiler [**FastAPI** Proje Üreticileri](project-generation.md){.internal-link target=_blank}'nin de temelini oluşturdu.
+
+/// info | Bilgi
+
+Flask-apispec de aynı Marshmallow geliştiricileri tarafından üretildi.
+
+///
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Veri dönüşümü ve veri doğrulamayı tanımlayan kodu kullanarak otomatik olarak OpenAPI şeması oluşturmalı.
+
+///
+
+###
NestJS (and
Angular)
+
+Bu Python teknolojisi bile değil. NestJS, Angulardan ilham almış olan bir JavaScript (TypeScript) NodeJS framework'ü.
+
+Flask-apispec ile yapılabileceklere nispeten benzeyen bir şey elde ediyor.
+
+Angular 2'den ilham alan, içine gömülü bir
bağımlılık enjeksiyonu sistemi var. Bildiğim diğer tüm bağımlılık enjeksiyonu sistemlerinde olduğu gibi"
bağımlılık"ları önceden kaydetmenizi gerektiriyor. Böylece projeyi daha detaylı hale getiriyor ve kod tekrarını da arttırıyor.
+
+Parametreler TypeScript tipleri (Python tip belirteçlerine benzer) ile açıklandığından editör desteği oldukça iyi.
+
+Ama TypeScript verileri kod JavaScript'e derlendikten sonra korunmadığından, bunlara dayanarak aynı anda veri doğrulaması, veri dönüşümü ve dökümantasyon tanımlanamıyor. Bundan ve bazı tasarım tercihlerinden dolayı veri doğrulaması, dönüşümü ve otomatik şema üretimi için pek çok yere dekorator eklemek gerekiyor. Bu da projeyi oldukça detaylandırıyor.
+
+İç içe geçen derin modelleri pek iyi işleyemiyor. Yani eğer istekteki JSON gövdesi derin bir JSON objesiyse düzgün bir şekilde dökümante edilip doğrulanamıyor.
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Güzel bir editör desteği için Python tiplerini kullanmalı.
+
+Güçlü bir bağımlılık enjeksiyon sistemine sahip olmalı. Kod tekrarını minimuma indirecek bir yol bulmalı.
+
+///
+
+###
Sanic
+
+Sanic, `asyncio`'ya dayanan son derece hızlı Python kütüphanelerinden biriydi. Flask'a epey benzeyecek şekilde geliştirilmişti.
+
+/// note | Teknik detaylar
+
+İçerisinde standart Python `asyncio` döngüsü yerine
`uvloop` kullanıldı. Hızının asıl kaynağı buydu.
+
+Uvicorn ve Starlette'e ilham kaynağı olduğu oldukça açık, şu anda ikisi de açık karşılaştırmalarda Sanicten daha hızlı gözüküyor.
+
+///
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Uçuk performans sağlayacak bir yol bulmalı.
+
+Tam da bu yüzden **FastAPI** Starlette'e dayanıyor, çünkü Starlette şu anda kullanılabilir en hızlı framework. (üçüncü parti karşılaştırmalı testlerine göre)
+
+///
+
+###
Falcon
+
+Falcon ise bir diğer yüksek performanslı Python framework'ü. Minimal olacak şekilde Hug gibi diğer framework'lerin temeli olabilmek için tasarlandı.
+
+İki parametre kabul eden fonksiyonlar şeklinde tasarlandı, biri "istek" ve diğeri ise "cevap". Sonra isteğin çeşitli kısımlarını **okuyor**, cevaba ise bir şeyler **yazıyorsunuz**. Bu tasarımdan dolayı istek parametrelerini ve gövdelerini standart Python tip belirteçlerini kullanarak fonksiyon parametreleriyle belirtmek mümkün değil.
+
+Yani veri doğrulama, veri dönüştürme ve dökümantasyonun hepsi kodda yer almalı, otomatik halledemiyoruz. Ya da Falcon üzerine bir framework olarak uygulanmaları gerekiyor, aynı Hug'da olduğu gibi. Bu ayrım Falcon'un tasarımından esinlenen, istek ve cevap objelerini parametre olarak işleyen diğer kütüphanelerde de yer alıyor.
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Harika bir performans'a sahip olmanın yollarını bulmalı.
+
+Hug ile birlikte (Hug zaten Falcon'a dayandığından) **FastAPI**'ın fonksiyonlarda `cevap` parametresi belirtmesinde ilham kaynağı oldu.
+
+FastAPI'da opsiyonel olmasına rağmen, daha çok header'lar, çerezler ve alternatif durum kodları belirlemede kullanılıyor.
+
+///
+
+###
Molten
+
+**FastAPI**'ı geliştirmenin ilk aşamalarında Molten'ı keşfettim. Pek çok ortak fikrimiz vardı:
+
+* Python'daki tip belirteçlerini baz alıyordu.
+* Bunlara bağlı olarak veri doğrulaması ve dökümantasyon sağlıyordu.
+* Bir
bağımlılık enjeksiyonu sistemi vardı.
+
+Veri doğrulama, veri dönüştürme ve dökümantasyon için Pydantic gibi bir üçüncü parti kütüphane kullanmıyor, kendi içerisinde bunlara sahip. Yani bu veri tipi tanımlarını tekrar kullanmak pek de kolay değil.
+
+Biraz daha detaylı ayarlamalara gerek duyuyor. Ayrıca
ASGI yerine
WSGI'a dayanıyor. Yani Uvicorn, Starlette ve Sanic gibi araçların yüksek performansından faydalanacak şekilde tasarlanmamış.
+
+
Bağımlılık enjeksiyonu sistemi bağımlılıkların önceden kaydedilmesini ve sonrasında belirlenen veri tiplerine göre çözülmesini gerektiriyor. Yani spesifik bir tip, birden fazla bileşen ile belirlenemiyor.
+
+
Yol'lar fonksiyonun üstünde endpoint'i işleyen dekoratörler yerine farklı yerlerde tanımlanan fonksiyonlarla belirlenir. Bu Flask (ve Starlette) yerine daha çok Django'nun yaklaşımına daha yakın bir metot. Bu, kodda nispeten birbiriyle sıkı ilişkili olan şeyleri ayırmaya sebep oluyor.
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Model özelliklerinin "standart" değerlerini kullanarak veri tipleri için ekstra veri doğrulama koşulları tanımlamalı. Bu editör desteğini geliştiriyor ve daha önceden Pydantic'te yoktu.
+
+Bu aslında Pydantic'in de aynı doğrulama stiline geçmesinde ilham kaynağı oldu. Şu anda bütün bu özellikler Pydantic'in yapısında yer alıyor.
+
+///
+
+###
Hug
+
+Hug, Python tip belirteçlerini kullanarak API parametrelerinin tipini belirlemeyi uygulayan ilk framework'lerdendi. Bu, diğer araçlara da ilham kaynağı olan harika bir fikirdi.
+
+Tip belirlerken standart Python veri tipleri yerine kendi özel tiplerini kullandı, yine de bu ileriye dönük devasa bir adımdı.
+
+Hug ayrıca tüm API'ı JSON ile ifade eden özel bir şema oluşturan ilk framework'lerdendir.
+
+OpenAPI veya JSON Şeması gibi bir standarda bağlı değildi. Yani Swagger UI gibi diğer araçlarla entegre etmek kolay olmazdı. Ama yine de, bu oldukça yenilikçi bir fikirdi.
+
+Ayrıca ilginç ve çok rastlanmayan bir özelliği vardı: aynı framework'ü kullanarak hem API'lar hem de
CLI'lar oluşturmak mümkündü.
+
+Senkron çalışan Python web framework'lerinin standardına (WSGI) dayandığından dolayı Websocket'leri ve diğer şeyleri işleyemiyor, ancak yine de yüksek performansa sahip.
+
+/// info | Bilgi
+
+Hug, Python dosyalarında bulunan dahil etme satırlarını otomatik olarak sıralayan harika bir araç olan
`isort`'un geliştiricisi Timothy Crosley tarafından geliştirildi.
+
+///
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Hug, APIStar'ın çeşitli kısımlarında esin kaynağı oldu ve APIStar'la birlikte en umut verici bulduğum araçlardan biriydi.
+
+**FastAPI**, Python tip belirteçlerini kullanarak parametre belirlemede ve API'ı otomatık tanımlayan bir şema üretmede de Hug'a esinlendi.
+
+**FastAPI**'ın header ve çerez tanımlamak için fonksiyonlarda `response` parametresini belirtmesinde de Hug'dan ilham alındı.
+
+///
+
+###
APIStar (<= 0.5)
+
+**FastAPI**'ı geliştirmeye başlamadan hemen önce **APIStar** sunucusunu buldum. Benim aradığım şeylerin neredeyse hepsine sahipti ve harika bir tasarımı vardı.
+
+Benim şimdiye kadar gördüğüm Python tip belirteçlerini kullanarak parametre ve istekler belirlemeyi uygulayan ilk framework'lerdendi (Molten ve NestJS'den önce). APIStar'ı da aşağı yukarı Hug ile aynı zamanlarda buldum. Fakat APIStar OpenAPI standardını kullanıyordu.
+
+Farklı yerlerdeki tip belirteçlerine bağlı olarak otomatik veri doğrulama, veri dönüştürme ve OpenAPI şeması oluşturma desteği sunuyordu.
+
+Gövde şema tanımları Pydantic ile aynı Python tip belirteçlerini kullanmıyordu, biraz daha Marsmallow'a benziyordu. Dolayısıyla editör desteği de o kadar iyi olmazdı ama APIStar eldeki en iyi seçenekti.
+
+O dönemlerde karşılaştırmalarda en iyi performansa sahipti (yalnızca Starlette'e kaybediyordu).
+
+Başlangıçta otomatik API dökümantasyonu sunan bir web arayüzü yoktu, ama ben ona Swagger UI ekleyebileceğimi biliyordum.
+
+Bağımlılık enjeksiyon sistemi vardı. Yukarıda bahsettiğim diğer araçlar gibi bundaki sistem de bileşenlerin önceden kaydedilmesini gerektiriyordu. Yine de harika bir özellikti.
+
+Güvenlik entegrasyonu olmadığından dolayı APIStar'ı hiç bir zaman tam bir projede kullanamadım. Bu yüzden Flask-apispec'e bağlı full-stack proje üreticilerde sahip olduğum özellikleri tamamen değiştiremedim. Bu güvenlik entegrasyonunu ekleyen bir
PR oluşturmak da projelerim arasında yer alıyordu.
+
+Sonrasında ise projenin odağı değişti.
+
+Geliştiricinin Starlette'e odaklanması gerekince proje de artık bir API web framework'ü olmayı bıraktı.
+
+Artık APIStar, OpenAPI özelliklerini doğrulamak için bir dizi araç sunan bir proje haline geldi.
+
+/// info | Bilgi
+
+APIStar, aşağıdaki projeleri de üreten Tom Christie tarafından geliştirildi:
+
+* Django REST Framework
+* **FastAPI**'ın da dayandığı Starlette
+* Starlette ve **FastAPI** tarafından da kullanılan Uvicorn
+
+///
+
+/// check | **FastAPI**'a nasıl ilham oldu?
+
+Var oldu.
+
+Aynı Python veri tipleriyle birden fazla şeyi belirleme (veri doğrulama, veri dönüştürme ve dökümantasyon), bir yandan da harika bir editör desteği sunma, benim muhteşem bulduğum bir fikirdi.
+
+Uzunca bir süre boyunca benzer bir framework arayıp pek çok farklı alternatifi denedikten sonra, APIStar en iyi seçenekti.
+
+Sonra APIStar bir sunucu olmayı bıraktı ve Starlette oluşturuldu. Starlette, böyle bir sunucu sistemi için daha iyi bir temel sunuyordu. Bu da **FastAPI**'ın son esin kaynağıydı.
+
+Ben bu önceki araçlardan öğrendiklerime dayanarak **FastAPI**'ın özelliklerini arttırıp geliştiriyor,
tip desteği sistemi ve diğer kısımları iyileştiriyorum ancak yine de **FastAPI**'ı APIStar'ın "ruhani varisi" olarak görüyorum.
+
+///
+
+## **FastAPI** Tarafından Kullanılanlar
+
+###
Pydantic
+
+Pydantic Python tip belirteçlerine dayanan; veri doğrulama, veri dönüştürme ve dökümantasyon tanımlamak (JSON Şema kullanarak) için bir kütüphanedir.
+
+Tip belirteçleri kullanıyor olması onu aşırı sezgisel yapıyor.
+
+Marshmallow ile karşılaştırılabilir. Ancak karşılaştırmalarda Marshmallowdan daha hızlı görünüyor. Aynı Python tip belirteçlerine dayanıyor ve editör desteği de harika.
+
+/// check | **FastAPI** nerede kullanıyor?
+
+Bütün veri doğrulama, veri dönüştürme ve JSON Şemasına bağlı otomatik model dökümantasyonunu halletmek için!
+
+**FastAPI** yaptığı her şeyin yanı sıra bu JSON Şema verisini alıp daha sonra OpenAPI'ya yerleştiriyor.
+
+///
+
+###
Starlette
+
+Starlette hafif bir
ASGI framework'ü ve yüksek performanslı asyncio servisleri oluşturmak için ideal.
+
+Kullanımı çok kolay ve sezgisel, kolaylıkla genişletilebilecek ve modüler bileşenlere sahip olacak şekilde tasarlandı.
+
+Sahip olduğu bir kaç özellik:
+
+* Cidden etkileyici bir performans.
+* WebSocket desteği.
+* İşlem-içi arka plan görevleri.
+* Başlatma ve kapatma olayları.
+* HTTPX ile geliştirilmiş bir test istemcisi.
+* CORS, GZip, Static Files ve Streaming cevapları desteği.
+* Session ve çerez desteği.
+* Kodun %100'ü test kapsamında.
+* Kodun %100'ü tip belirteçleriyle desteklenmiştir.
+* Yalnızca bir kaç zorunlu bağımlılığa sahip.
+
+Starlette şu anda test edilen en hızlı Python framework'ü. Yalnızca bir sunucu olan Uvicorn'a yeniliyor, o da zaten bir framework değil.
+
+Starlette bütün temel web mikro framework işlevselliğini sağlıyor.
+
+Ancak otomatik veri doğrulama, veri dönüştürme ve dökümantasyon sağlamyor.
+
+Bu, **FastAPI**'ın onun üzerine tamamen Python tip belirteçlerine bağlı olarak eklediği (Pydantic ile) ana şeylerden biri. **FastAPI** bunun yanında artı olarak bağımlılık enjeksiyonu sistemi, güvenlik araçları, OpenAPI şema üretimi ve benzeri özellikler de ekliyor.
+
+/// note | Teknik Detaylar
+
+ASGI, Django'nun ana ekibi tarafından geliştirilen yeni bir "standart". Bir "Python standardı" (PEP) olma sürecinde fakat henüz bir standart değil.
+
+Bununla birlikte, halihazırda birçok araç tarafından bir "standart" olarak kullanılmakta. Bu, Uvicorn'u farklı ASGI sunucularıyla (Daphne veya Hypercorn gibi) değiştirebileceğiniz veya `python-socketio` gibi ASGI ile uyumlu araçları ekleyebileciğiniz için birlikte çalışılabilirliği büyük ölçüde arttırıyor.
+
+///
+
+/// check | **FastAPI** nerede kullanıyor?
+
+Tüm temel web kısımlarında üzerine özellikler eklenerek kullanılmakta.
+
+`FastAPI` sınıfının kendisi direkt olarak `Starlette` sınıfını miras alıyor!
+
+Yani, Starlette ile yapabileceğiniz her şeyi, Starlette'in bir nevi güçlendirilmiş hali olan **FastAPI** ile doğrudan yapabilirsiniz.
+
+///
+
+###
Uvicorn
+
+Uvicorn, uvlook ile httptools üzerine kurulu ışık hzında bir ASGI sunucusudur.
+
+Bir web framework'ünden ziyade bir sunucudur, yani yollara bağlı yönlendirme yapmanızı sağlayan araçları yoktur. Bu daha çok Starlette (ya da **FastAPI**) gibi bir framework'ün sunucuya ek olarak sağladığı bir şeydir.
+
+Starlette ve **FastAPI** için tavsiye edilen sunucu Uvicorndur.
+
+/// check | **FastAPI** neden tavsiye ediyor?
+
+**FastAPI** uygulamalarını çalıştırmak için ana web sunucusu Uvicorn!
+
+Gunicorn ile birleştirdiğinizde asenkron ve çoklu işlem destekleyen bir sunucu elde ediyorsunuz!
+
+Daha fazla detay için [Deployment](deployment/index.md){.internal-link target=_blank} bölümünü inceleyebilirsiniz.
+
+///
+
+## Karşılaştırma ve Hız
+
+Uvicorn, Starlette ve FastAPI arasındakı farkı daha iyi anlamak ve karşılaştırma yapmak için [Kıyaslamalar](benchmarks.md){.internal-link target=_blank} bölümüne bakın!
diff --git a/docs/tr/docs/async.md b/docs/tr/docs/async.md
new file mode 100644
index 000000000..558a79cb7
--- /dev/null
+++ b/docs/tr/docs/async.md
@@ -0,0 +1,407 @@
+# Concurrency ve async / await
+
+*path operasyon fonksiyonu* için `async def `sözdizimi, asenkron kod, eşzamanlılık ve paralellik hakkında bazı ayrıntılar.
+
+## Aceleniz mi var?
+
+
TL;DR:
+
+Eğer `await` ile çağrılması gerektiğini belirten üçüncü taraf kütüphaneleri kullanıyorsanız, örneğin:
+
+```Python
+results = await some_library()
+```
+
+O zaman *path operasyon fonksiyonunu* `async def` ile tanımlayın örneğin:
+
+```Python hl_lines="2"
+@app.get('/')
+async def read_results():
+ results = await some_library()
+ return results
+```
+
+/// note | Not
+
+Sadece `async def` ile tanımlanan fonksiyonlar içinde `await` kullanabilirsiniz.
+
+///
+
+---
+
+Eğer bir veritabanı, bir API, dosya sistemi vb. ile iletişim kuran bir üçüncü taraf bir kütüphane kullanıyorsanız ve `await` kullanımını desteklemiyorsa, (bu şu anda çoğu veritabanı kütüphanesi için geçerli bir durumdur), o zaman *path operasyon fonksiyonunuzu* `def` kullanarak normal bir şekilde tanımlayın, örneğin:
+
+```Python hl_lines="2"
+@app.get('/')
+def results():
+ results = some_library()
+ return results
+```
+
+---
+
+Eğer uygulamanız (bir şekilde) başka bir şeyle iletişim kurmak ve onun cevap vermesini beklemek zorunda değilse, `async def` kullanın.
+
+---
+
+Sadece bilmiyorsanız, normal `def` kullanın.
+
+---
+
+**Not**: *path operasyon fonksiyonlarınızda* `def` ve `async def`'i ihtiyaç duyduğunuz gibi karıştırabilir ve her birini sizin için en iyi seçeneği kullanarak tanımlayabilirsiniz. FastAPI onlarla doğru olanı yapacaktır.
+
+Her neyse, yukarıdaki durumlardan herhangi birinde, FastAPI yine de asenkron olarak çalışacak ve son derece hızlı olacaktır.
+
+Ancak yukarıdaki adımları takip ederek, bazı performans optimizasyonları yapılabilecektir.
+
+## Teknik Detaylar
+
+Python'un modern versiyonlarında **`async` ve `await`** sözdizimi ile **"coroutines"** kullanan **"asenkron kod"** desteğine sahiptir.
+
+Bu ifadeyi aşağıdaki bölümlerde daha da ayrıntılı açıklayalım:
+
+* **Asenkron kod**
+* **`async` ve `await`**
+* **Coroutines**
+
+## Asenkron kod
+
+Asenkron kod programlama dilinin 💬 bilgisayara / programa 🤖 kodun bir noktasında, *başka bir kodun* bir yerde bitmesini 🤖 beklemesi gerektiğini söylemenin bir yoludur. Bu *başka koda* "slow-file" denir 📝.
+
+Böylece, bu süreçte bilgisayar "slow-file" 📝 tamamlanırken gidip başka işler yapabilir.
+
+Sonra bilgisayar / program 🤖 her fırsatı olduğunda o noktada yaptığı tüm işleri 🤖 bitirene kadar geri dönücek. Ve 🤖 yapması gerekeni yaparak, beklediği görevlerden herhangi birinin bitip bitmediğini görecek.
+
+Ardından, 🤖 bitirmek için ilk görevi alır ("slow-file" 📝) ve onunla ne yapması gerekiyorsa onu devam ettirir.
+
+Bu "başka bir şey için bekle" normalde, aşağıdakileri beklemek gibi (işlemcinin ve RAM belleğinin hızına kıyasla) nispeten "yavaş" olan
I/O işlemlerine atıfta bulunur:
+
+* istemci tarafından ağ üzerinden veri göndermek
+* ağ üzerinden istemciye gönderilen veriler
+* sistem tarafından okunacak ve programınıza verilecek bir dosya içeriği
+* programınızın diske yazılmak üzere sisteme verdiği dosya içerikleri
+* uzak bir API işlemi
+* bir veritabanı bitirme işlemi
+* sonuçları döndürmek için bir veritabanı sorgusu
+* vb.
+
+Yürütme süresi çoğunlukla
I/O işlemleri beklenerek tüketildiğinden bunlara "I/O bağlantılı" işlemler denir.
+
+Buna "asenkron" denir, çünkü bilgisayar/program yavaş görevle "senkronize" olmak zorunda değildir, görevin tam olarak biteceği anı bekler, hiçbir şey yapmadan, görev sonucunu alabilmek ve çalışmaya devam edebilmek için .
+
+Bunun yerine, "asenkron" bir sistem olarak, bir kez bittiğinde, bilgisayarın / programın yapması gerekeni bitirmesi için biraz (birkaç mikrosaniye) sırada bekleyebilir ve ardından sonuçları almak için geri gelebilir ve onlarla çalışmaya devam edebilir.
+
+"Senkron" ("asenkron"un aksine) için genellikle "sıralı" terimini de kullanırlar, çünkü bilgisayar/program, bu adımlar beklemeyi içerse bile, farklı bir göreve geçmeden önce tüm adımları sırayla izler.
+
+
+### Eşzamanlılık (Concurrency) ve Burgerler
+
+
+Yukarıda açıklanan bu **asenkron** kod fikrine bazen **"eşzamanlılık"** da denir. **"Paralellikten"** farklıdır.
+
+**Eşzamanlılık** ve **paralellik**, "aynı anda az ya da çok olan farklı işler" ile ilgilidir.
+
+Ancak *eşzamanlılık* ve *paralellik* arasındaki ayrıntılar oldukça farklıdır.
+
+
+Farkı görmek için burgerlerle ilgili aşağıdaki hikayeyi hayal edin:
+
+### Eşzamanlı Burgerler
+
+
+
+Aşkınla beraber 😍 dışarı hamburger yemeye çıktınız 🍔, kasiyer 💁 öndeki insanlardan sipariş alırken siz sıraya girdiniz.
+
+Sıra sizde ve sen aşkın 😍 ve kendin için 2 çılgın hamburger 🍔 söylüyorsun.
+
+Ödemeyi yaptın 💸.
+
+Kasiyer 💁 mutfakdaki aşçıya 👨🍳 hamburgerleri 🍔 hazırlaması gerektiğini söyler ve aşçı bunu bilir (o an önceki müşterilerin siparişlerini hazırlıyor olsa bile).
+
+Kasiyer 💁 size bir sıra numarası verir.
+
+Beklerken askınla 😍 bir masaya oturur ve uzun bir süre konuşursunuz(Burgerleriniz çok çılgın olduğundan ve hazırlanması biraz zaman alıyor ✨🍔✨).
+
+Hamburgeri beklerkenki zamanı 🍔, aşkının ne kadar zeki ve tatlı olduğuna hayran kalarak harcayabilirsin ✨😍✨.
+
+Aşkınla 😍 konuşurken arada sıranın size gelip gelmediğini kontrol ediyorsun.
+
+Nihayet sıra size geldi. Tezgaha gidip hamburgerleri 🍔kapıp masaya geri dönüyorsun.
+
+Aşkınla hamburgerlerinizi yiyor 🍔 ve iyi vakit geçiriyorsunuz ✨.
+
+---
+
+Bu hikayedeki bilgisayar / program 🤖 olduğunuzu hayal edin.
+
+Sırada beklerken boştasın 😴, sıranı beklerken herhangi bir "üretim" yapmıyorsun. Ama bu sıra hızlı çünkü kasiyer sadece siparişleri alıyor (onları hazırlamıyor), burada bir sıknıtı yok.
+
+Sonra sıra size geldiğinde gerçekten "üretken" işler yapabilirsiniz 🤓, menüyü oku, ne istediğine larar ver, aşkının seçimini al 😍, öde 💸, doğru kartı çıkart, ödemeyi kontrol et, faturayı kontrol et, siparişin doğru olup olmadığını kontrol et, vb.
+
+Ama hamburgerler 🍔 hazır olmamasına rağmen Kasiyer 💁 ile işiniz "duraklıyor" ⏸, çünkü hamburgerlerin hazır olmasını bekliyoruz 🕙.
+
+Ama tezgahtan uzaklaşıp sıranız gelene kadarmasanıza dönebilir 🔀 ve dikkatinizi aşkınıza 😍 verebilirsiniz vr bunun üzerine "çalışabilirsiniz" ⏯ 🤓. Artık "üretken" birşey yapıyorsunuz 🤓, sevgilinle 😍 flört eder gibi.
+
+Kasiyer 💁 "Hamburgerler hazır !" 🍔 dediğinde ve görüntülenen numara sizin numaranız olduğunda hemen koşup hamburgerlerinizi almaya çalışmıyorsunuz. Biliyorsunuzki kimse sizin hamburgerlerinizi 🍔 çalmayacak çünkü sıra sizin.
+
+Yani Aşkınızın😍 hikayeyi bitirmesini bekliyorsunuz (çalışmayı bitir ⏯ / görev işleniyor.. 🤓), nazikçe gülümseyin ve hamburger yemeye gittiğinizi söyleyin ⏸.
+
+Ardından tezgaha 🔀, şimdi biten ilk göreve ⏯ gidin, Hamburgerleri 🍔 alın, teşekkür edin ve masaya götürün. sayacın bu adımı tamamlanır ⏹. Bu da yeni bir görev olan "hamburgerleri ye" 🔀 ⏯ görevini başlatırken "hamburgerleri al" ⏹ görevini bitirir.
+
+### Parallel Hamburgerler
+
+Şimdi bunların "Eşzamanlı Hamburger" değil, "Paralel Hamburger" olduğunu düşünelim.
+
+Hamburger 🍔 almak için 😍 aşkınla Paralel fast food'a gidiyorsun.
+
+Birden fazla kasiyer varken (varsayalım 8) sıraya girdiniz👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 ve sıranız gelene kadar bekliyorsunuz.
+
+Sizden önceki herkez ayrılmadan önce hamburgerlerinin 🍔 hazır olmasını bekliyor 🕙. Çünkü kasiyerlerin her biri bir hamburger hazırlanmadan önce bir sonraki siparişe geçmiiyor.
+
+Sonunda senin sıran, aşkın 😍 ve kendin için 2 hamburger 🍔 siparişi verdiniz.
+
+Ödemeyi yaptınız 💸.
+
+Kasiyer mutfağa gider 👨🍳.
+
+Sırada bekliyorsunuz 🕙, kimse sizin burgerinizi 🍔 almaya çalışmıyor çünkü sıra sizin.
+
+Sen ve aşkın 😍 sıranızı korumak ve hamburgerleri almakla o kadar meşgulsünüz ki birbirinize vakit 🕙 ayıramıyorsunuz 😞.
+
+İşte bu "senkron" çalışmadır. Kasiyer/aşçı 👨🍳ile senkron hareket ediyorsunuz. Bu yüzden beklemek 🕙 ve kasiyer/aşçı burgeri 🍔bitirip size getirdiğinde orda olmak zorundasınız yoksa başka biri alabilir.
+
+Sonra kasiyeri/aşçı 👨🍳 nihayet hamburgerlerinizle 🍔, uzun bir süre sonra 🕙 tezgaha geri geliyor.
+
+Burgerlerinizi 🍔 al ve aşkınla masanıza doğru ilerle 😍.
+
+Sadece burgerini yiyorsun 🍔 ve bitti ⏹.
+
+Bekleyerek çok fazla zaman geçtiğinden 🕙 konuşmaya çok fazla vakit kalmadı 😞.
+
+---
+
+Paralel burger senaryosunda ise, siz iki işlemcili birer robotsunuz 🤖 (sen ve sevgilin 😍), Beklıyorsunuz 🕙 hem konuşarak güzel vakit geçirirken ⏯ hem de sıranızı bekliyorsunuz 🕙.
+
+Mağazada ise 8 işlemci bulunuyor (Kasiyer/aşçı) 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳. Eşzamanlı burgerde yalnızca 2 kişi olabiliyordu (bir kasiyer ve bir aşçı) 💁 👨🍳.
+
+Ama yine de bu en iyisi değil 😞.
+
+---
+
+Bu hikaye burgerler 🍔 için paralel.
+
+Bir gerçek hayat örneği verelim. Bir banka hayal edin.
+
+Bankaların çoğunda birkaç kasiyer 👨💼👨💼👨💼👨💼 ve uzun bir sıra var 🕙🕙🕙🕙🕙🕙🕙🕙.
+
+Tüm işi sırayla bir müşteri ile yapan tüm kasiyerler 👨💼⏯.
+
+Ve uzun süre kuyrukta beklemek 🕙 zorundasın yoksa sıranı kaybedersin.
+
+Muhtemelen ayak işlerı yaparken sevgilini 😍 bankaya 🏦 getirmezsin.
+
+### Burger Sonucu
+
+Bu "aşkınla fast food burgerleri" senaryosunda, çok fazla bekleme olduğu için 🕙, eşzamanlı bir sisteme sahip olmak çok daha mantıklı ⏸🔀⏯.
+
+Web uygulamalarının çoğu için durum böyledir.
+
+Pek çok kullanıcı var, ama sunucunuz pek de iyi olmayan bir bağlantı ile istek atmalarını bekliyor.
+
+Ve sonra yanıtların geri gelmesi için tekrar 🕙 bekliyor
+
+Bu "bekleme" 🕙 mikrosaniye cinsinden ölçülür, yine de, hepsini toplarsak çok fazla bekleme var.
+
+Bu nedenle, web API'leri için asenkron ⏸🔀⏯ kod kullanmak çok daha mantıklı.
+
+Mevcut popüler Python frameworklerinin çoğu (Flask ve Django gibi), Python'daki yeni asenkron özellikler mevcut olmadan önce yazıldı. Bu nedenle, dağıtılma biçimleri paralel yürütmeyi ve yenisi kadar güçlü olmayan eski bir eşzamansız yürütme biçimini destekler.
+
+Asenkron web (ASGI) özelliği, WebSockets için destek eklemek için Django'ya eklenmiş olsa da.
+
+Asenkron çalışabilme NodeJS in popüler olmasının sebebi (paralel olamasa bile) ve Go dilini güçlü yapan özelliktir.
+
+Ve bu **FastAPI** ile elde ettiğiniz performans düzeyiyle aynıdır.
+
+Aynı anda paralellik ve asenkronluğa sahip olabildiğiniz için, test edilen NodeJS çerçevelerinin çoğundan daha yüksek performans elde edersiniz ve C'ye daha yakın derlenmiş bir dil olan Go ile eşit bir performans elde edersiniz
(bütün teşekkürler Starlette'e ).
+
+### Eşzamanlılık paralellikten daha mı iyi?
+
+Hayır! Hikayenin ahlakı bu değil.
+
+Eşzamanlılık paralellikten farklıdır. Ve çok fazla bekleme içeren **belirli** senaryolarda daha iyidir. Bu nedenle, genellikle web uygulamaları için paralellikten çok daha iyidir. Ama her şey için değil.
+
+Yanı, bunu aklınızda oturtmak için aşağıdaki kısa hikayeyi hayal edin:
+
+> Büyük, kirli bir evi temizlemelisin.
+
+*Evet, tüm hikaye bu*.
+
+---
+
+Beklemek yok 🕙. Hiçbir yerde. Sadece evin birden fazla yerinde yapılacak fazlasıyla iş var.
+
+You could have turns as in the burgers example, first the living room, then the kitchen, but as you are not waiting 🕙 for anything, just cleaning and cleaning, the turns wouldn't affect anything.
+Hamburger örneğindeki gibi dönüşleriniz olabilir, önce oturma odası, sonra mutfak, ama hiçbir şey için 🕙 beklemediğinizden, sadece temizlik, temizlik ve temizlik, dönüşler hiçbir şeyi etkilemez.
+
+Sıralı veya sırasız (eşzamanlılık) bitirmek aynı zaman alır ve aynı miktarda işi yaparsınız.
+
+Ama bu durumda, 8 eski kasiyer/aşçı - yeni temizlikçiyi getirebilseydiniz 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 ve her birini (artı siz) evin bir bölgesini temizlemek için görevlendirseydiniz, ekstra yardımla tüm işleri **paralel** olarak yapabilir ve çok daha erken bitirebilirdiniz.
+
+Bu senaryoda, temizlikçilerin her biri (siz dahil) birer işlemci olacak ve üzerine düşeni yapacaktır.
+
+Yürütme süresinin çoğu (beklemek yerine) iş yapıldığından ve bilgisayardaki iş bir
CPU tarafından yapıldığından, bu sorunlara "CPU bound" diyorlar".
+
+---
+
+CPU'ya bağlı işlemlerin yaygın örnekleri, karmaşık matematik işlemleri gerektiren işlerdir.
+
+Örneğin:
+
+* **Ses** veya **görüntü işleme**.
+* **Bilgisayar görüsü**: bir görüntü milyonlarca pikselden oluşur, her pikselin 3 değeri / rengi vardır, bu pikseller üzerinde aynı anda bir şeyler hesaplamayı gerektiren işleme.
+* **Makine Öğrenimi**: Çok sayıda "matris" ve "vektör" çarpımı gerektirir. Sayıları olan ve hepsini aynı anda çarpan büyük bir elektronik tablo düşünün.
+* **Derin Öğrenme**: Bu, Makine Öğreniminin bir alt alanıdır, dolayısıyla aynısı geçerlidir. Sadece çarpılacak tek bir sayı tablosu değil, büyük bir sayı kümesi vardır ve çoğu durumda bu modelleri oluşturmak ve/veya kullanmak için özel işlemciler kullanırsınız.
+
+### Eşzamanlılık + Paralellik: Web + Makine Öğrenimi
+
+**FastAPI** ile web geliştirme için çok yaygın olan eşzamanlılıktan yararlanabilirsiniz (NodeJS'in aynı çekiciliği).
+
+Ancak, Makine Öğrenimi sistemlerindekile gibi **CPU'ya bağlı** iş yükleri için paralellik ve çoklu işlemenin (birden çok işlemin paralel olarak çalışması) avantajlarından da yararlanabilirsiniz.
+
+Buna ek olarak Python'un **Veri Bilimi**, Makine Öğrenimi ve özellikle Derin Öğrenme için ana dil olduğu gerçeği, FastAPI'yi Veri Bilimi / Makine Öğrenimi web API'leri ve uygulamaları için çok iyi bir seçenek haline getirir.
+
+Production'da nasıl oldugunu görmek için şu bölüme bakın [Deployment](deployment/index.md){.internal-link target=_blank}.
+
+## `async` ve `await`
+
+Python'un modern sürümleri, asenkron kodu tanımlamanın çok sezgisel bir yoluna sahiptir. Bu, normal "sequentıal" (sıralı) kod gibi görünmesini ve doğru anlarda sizin için "awaıt" ile bekleme yapmasını sağlar.
+
+Sonuçları vermeden önce beklemeyi gerektirecek ve yeni Python özelliklerini destekleyen bir işlem olduğunda aşağıdaki gibi kodlayabilirsiniz:
+
+```Python
+burgers = await get_burgers(2)
+```
+
+Buradaki `await` anahtari Python'a, sonuçları `burgers` degiskenine atamadan önce `get_burgers(2)` kodunun işini bitirmesini 🕙 beklemesi gerektiğini söyler. Bununla Python, bu ara zamanda başka bir şey 🔀 ⏯ yapabileceğini bilecektir (başka bir istek almak gibi).
+
+ `await`kodunun çalışması için, eşzamansızlığı destekleyen bir fonksiyonun içinde olması gerekir. Bunu da yapmak için fonksiyonu `async def` ile tanımlamamız yeterlidir:
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # burgerleri oluşturmak için asenkron birkaç iş
+ return burgers
+```
+
+...`def` yerine:
+
+```Python hl_lines="2"
+# bu kod asenkron değil
+def get_sequential_burgers(number: int):
+ # burgerleri oluşturmak için senkron bırkaç iş
+ return burgers
+```
+
+`async def` ile Python, bu fonksıyonun içinde, `await` ifadelerinin farkında olması gerektiğini ve çalışma zamanı gelmeden önce bu işlevin yürütülmesini "duraklatabileceğini" ve başka bir şey yapabileceğini 🔀 bilir.
+
+`async def` fonksiyonunu çağırmak istediğinizde, onu "awaıt" ıle kullanmanız gerekir. Yani, bu işe yaramaz:
+
+```Python
+# Bu işe yaramaz, çünkü get_burgers, şu şekilde tanımlandı: async def
+burgers = get_burgers(2)
+```
+
+---
+
+Bu nedenle, size onu `await` ile çağırabileceğinizi söyleyen bir kitaplık kullanıyorsanız, onu `async def` ile tanımlanan *path fonksiyonu* içerisinde kullanmanız gerekir, örneğin:
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### Daha fazla teknik detay
+
+`await` in yalnızca `async def` ile tanımlanan fonksıyonların içinde kullanılabileceğini fark etmişsinizdir.
+
+Ama aynı zamanda, `async def` ile tanımlanan fonksiyonların "await" ile beklenmesi gerekir. Bu nedenle, "`async def` içeren fonksiyonlar yalnızca "`async def` ile tanımlanan fonksiyonların içinde çağrılabilir.
+
+
+Yani yumurta mı tavukdan, tavuk mu yumurtadan gibi ilk `async` fonksiyonu nasıl çağırılır?
+
+**FastAPI** ile çalışıyorsanız bunun için endişelenmenize gerek yok, çünkü bu "ilk" fonksiyon sizin *path fonksiyonunuz* olacak ve FastAPI doğru olanı nasıl yapacağını bilecek.
+
+Ancak FastAPI olmadan `async` / `await` kullanmak istiyorsanız,
resmi Python belgelerini kontrol edin.
+
+### Asenkron kodun diğer biçimleri
+
+Bu `async` ve `await` kullanimi oldukça yenidir.
+
+Ancak asenkron kodla çalışmayı çok daha kolay hale getirir.
+
+Aynı sözdizimi (hemen hemen aynı) son zamanlarda JavaScript'in modern sürümlerine de dahil edildi (Tarayıcı ve NodeJS'de).
+
+Ancak bundan önce, asenkron kodu işlemek oldukça karmaşık ve zordu.
+
+Python'un önceki sürümlerinde, threadlerı veya
Gevent kullanıyor olabilirdin. Ancak kodu anlamak, hata ayıklamak ve düşünmek çok daha karmaşık olurdu.
+
+NodeJS / Browser JavaScript'in önceki sürümlerinde, "callback" kullanırdınız. Bu da
callbacks cehennemine yol açar.
+
+## Coroutine'ler
+
+**Coroutine**, bir `async def` fonksiyonu tarafından döndürülen değer için çok süslü bir terimdir. Python bunun bir fonksiyon gibi bir noktada başlayıp biteceğini bilir, ancak içinde bir `await` olduğunda dahili olarak da duraklatılabilir ⏸.
+
+Ancak, `async` ve `await` ile asenkron kod kullanmanın tüm bu işlevselliği, çoğu zaman "Coroutine" kullanmak olarak adlandırılır. Go'nun ana özelliği olan "Goroutines" ile karşılaştırılabilir.
+
+## Sonuç
+
+Aynı ifadeyi yukarıdan görelim:
+
+> Python'ın modern sürümleri, **"async" ve "await"** sözdizimi ile birlikte **"coroutines"** adlı bir özelliği kullanan **"asenkron kod"** desteğine sahiptir.
+
+Şimdi daha mantıklı gelmeli. ✨
+
+FastAPI'ye (Starlette aracılığıyla) güç veren ve bu kadar etkileyici bir performansa sahip olmasını sağlayan şey budur.
+
+## Çok Teknik Detaylar
+
+/// warning
+
+Muhtemelen burayı atlayabilirsiniz.
+
+Bunlar, **FastAPI**'nin altta nasıl çalıştığına dair çok teknik ayrıntılardır.
+
+Biraz teknik bilginiz varsa (co-routines, threads, blocking, vb)ve FastAPI'nin "async def" ile normal "def" arasındaki farkı nasıl işlediğini merak ediyorsanız, devam edin.
+
+///
+
+### Path fonksiyonu
+
+"async def" yerine normal "def" ile bir *yol işlem işlevi* bildirdiğinizde, doğrudan çağrılmak yerine (sunucuyu bloke edeceğinden) daha sonra beklenen harici bir iş parçacığı havuzunda çalıştırılır.
+
+Yukarıda açıklanan şekilde çalışmayan başka bir asenkron framework'den geliyorsanız ve küçük bir performans kazancı (yaklaşık 100 nanosaniye) için "def" ile *path fonksiyonu* tanımlamaya alışkınsanız, **FastAPI**'de tam tersi olacağını unutmayın. Bu durumlarda, *path fonksiyonu*
G/Ç engelleyen durum oluşturmadıkça "async def" kullanmak daha iyidir.
+
+Yine de, her iki durumda da, **FastAPI**'nin önceki frameworkden [hala daha hızlı](index.md#performans){.internal-link target=_blank} (veya en azından karşılaştırılabilir) olma olasılığı vardır.
+
+### Bagımlılıklar
+
+Aynısı bağımlılıklar için de geçerlidir. Bir bağımlılık, "async def" yerine standart bir "def" işleviyse, harici iş parçacığı havuzunda çalıştırılır.
+
+### Alt-bağımlıklar
+
+Birbirini gerektiren (fonksiyonlarin parametreleri olarak) birden fazla bağımlılık ve alt bağımlılıklarınız olabilir, bazıları 'async def' ve bazıları normal 'def' ile oluşturulabilir. Yine de normal 'def' ile oluşturulanlar, "await" kulanilmadan harici bir iş parçacığında (iş parçacığı havuzundan) çağrılır.
+
+### Diğer yardımcı fonksiyonlar
+
+Doğrudan çağırdığınız diğer herhangi bir yardımcı fonksiyonu, normal "def" veya "async def" ile tanimlayabilirsiniz. FastAPI onu çağırma şeklinizi etkilemez.
+
+Bu, FastAPI'nin sizin için çağırdığı fonksiyonlarin tam tersidir: *path fonksiyonu* ve bağımlılıklar.
+
+Yardımcı program fonksiyonunuz 'def' ile normal bir işlevse, bir iş parçacığı havuzunda değil doğrudan (kodunuzda yazdığınız gibi) çağrılır, işlev 'async def' ile oluşturulmuşsa çağırıldığı yerde 'await' ile beklemelisiniz.
+
+---
+
+Yeniden, bunlar, onları aramaya geldiğinizde muhtemelen işinize yarayacak çok teknik ayrıntılardır.
+
+Aksi takdirde, yukarıdaki bölümdeki yönergeleri iyi bilmelisiniz:
Aceleniz mi var?.
diff --git a/docs/tr/docs/benchmarks.md b/docs/tr/docs/benchmarks.md
index 1ce3c758f..eb5472869 100644
--- a/docs/tr/docs/benchmarks.md
+++ b/docs/tr/docs/benchmarks.md
@@ -1,34 +1,34 @@
# Kıyaslamalar
-Bağımsız TechEmpower kıyaslamaları gösteriyor ki Uvicorn'la beraber çalışan **FastAPI** uygulamaları
Python'un en hızlı frameworklerinden birisi , sadece Starlette ve Uvicorn'dan daha düşük sıralamada (FastAPI bu frameworklerin üzerine kurulu). (*)
+Bağımsız TechEmpower kıyaslamaları gösteriyor ki
en hızlı Python frameworklerinden birisi olan Uvicorn ile çalıştırılan **FastAPI** uygulamaları, sadece Starlette ve Uvicorn'dan daha düşük sıralamada (FastAPI bu frameworklerin üzerine kurulu) yer alıyor. (*)
Fakat kıyaslamaları ve karşılaştırmaları incelerken şunları aklınızda bulundurmalısınız.
-## Kıyaslamalar ve hız
+## Kıyaslamalar ve Hız
-Kıyaslamaları incelediğinizde, farklı özelliklere sahip birçok araçların eşdeğer olarak karşılaştırıldığını görmek yaygındır.
+Kıyaslamaları incelediğinizde, farklı özelliklere sahip araçların eşdeğer olarak karşılaştırıldığını yaygın bir şekilde görebilirsiniz.
-Özellikle, Uvicorn, Starlette ve FastAPI'ın birlikte karşılaştırıldığını görmek için (diğer birçok araç arasında).
+Özellikle, (diğer birçok araç arasında) Uvicorn, Starlette ve FastAPI'ın birlikte karşılaştırıldığını görebilirsiniz.
-Araç tarafından çözülen sorun ne kadar basitse, o kadar iyi performans alacaktır. Ve kıyaslamaların çoğu, araç tarafından sağlanan ek özellikleri test etmez.
+Aracın çözdüğü problem ne kadar basitse, performansı o kadar iyi olacaktır. Ancak kıyaslamaların çoğu, aracın sağladığı ek özellikleri test etmez.
Hiyerarşi şöyledir:
* **Uvicorn**: bir ASGI sunucusu
- * **Starlette**: (Uvicorn'u kullanır) bir web microframeworkü
- * **FastAPI**: (Starlette'i kullanır) data validation vb. ile API'lar oluşturmak için çeşitli ek özelliklere sahip bir API frameworkü
+ * **Starlette**: (Uvicorn'u kullanır) bir web mikroframeworkü
+ * **FastAPI**: (Starlette'i kullanır) veri doğrulama vb. çeşitli ek özelliklere sahip, API oluşturmak için kullanılan bir API mikroframeworkü
* **Uvicorn**:
- * Sunucunun kendisi dışında ekstra bir kod içermediği için en iyi performansa sahip olacaktır
- * Direkt olarak Uvicorn'da bir uygulama yazmazsınız. Bu, en azından Starlette tarafından sağlanan tüm kodu (veya **FastAPI**) az çok içermesi gerektiği anlamına gelir. Ve eğer bunu yaptıysanız, son uygulamanız bir framework kullanmak ve uygulama kodlarını ve bugları en aza indirmekle aynı ek yüke sahip olacaktır.
+ * Sunucunun kendisi dışında ekstra bir kod içermediği için en iyi performansa sahip olacaktır.
+ * Doğrudan Uvicorn ile bir uygulama yazmazsınız. Bu, yazdığınız kodun en azından Starlette tarafından sağlanan tüm kodu (veya **FastAPI**) az çok içermesi gerektiği anlamına gelir. Eğer bunu yaptıysanız, son uygulamanız bir framework kullanmak ve uygulama kodlarını ve hataları en aza indirmekle aynı ek yüke sahip olacaktır.
* Eğer Uvicorn'u karşılaştırıyorsanız, Daphne, Hypercorn, uWSGI, vb. uygulama sunucuları ile karşılaştırın.
* **Starlette**:
- * Uvicorn'dan sonraki en iyi performansa sahip olacak. Aslında, Starlette çalışmak için Uvicorn'u kullanıyor. Dolayısıyla, muhtemelen daha fazla kod çalıştırmak zorunda kaldığında Uvicorn'dan sadece "daha yavaş" olabilir.
- * Ancak routing based on paths ile vb. basit web uygulamaları oluşturmak için araçlar sağlar.
- * Eğer Starlette'i karşılaştırıyorsanız, Sanic, Flask, Django, vb. frameworkler (veya microframeworkler) ile karşılaştırın.
+ * Uvicorn'dan sonraki en iyi performansa sahip olacaktır. İşin aslı, Starlette çalışmak için Uvicorn'u kullanıyor. Dolayısıyla, daha fazla kod çalıştırmaası gerektiğinden muhtemelen Uvicorn'dan sadece "daha yavaş" olabilir.
+ * Ancak yol bazlı yönlendirme vb. basit web uygulamaları oluşturmak için araçlar sağlar.
+ * Eğer Starlette'i karşılaştırıyorsanız, Sanic, Flask, Django, vb. frameworkler (veya mikroframeworkler) ile karşılaştırın.
* **FastAPI**:
- * Starlette'in Uvicorn'u kullandığı ve ondan daha hızlı olamayacağı gibi, **FastAPI** da Starlette'i kullanır, bu yüzden ondan daha hızlı olamaz.
- * FastAPI, Starlette'e ek olarak daha fazla özellik sunar. Data validation ve serialization gibi API'lar oluştururken neredeyse ve her zaman ihtiyaç duyduğunuz özellikler. Ve bunu kullanarak, ücretsiz olarak otomatik dokümantasyon elde edersiniz (otomatik dokümantasyon çalışan uygulamalara ek yük getirmez, başlangıçta oluşturulur).
- * FastAPI'ı kullanmadıysanız ve Starlette'i doğrudan kullandıysanız (veya başka bir araç, Sanic, Flask, Responder, vb.) tüm data validation'ı ve serialization'ı kendiniz sağlamanız gerekir. Dolayısıyla, son uygulamanız FastAPI kullanılarak oluşturulmuş gibi hâlâ aynı ek yüke sahip olacaktır. Çoğu durumda, uygulamalarda yazılan kodun büyük çoğunluğunu data validation ve serialization oluşturur.
- * Dolayısıyla, FastAPI'ı kullanarak geliştirme süresinden, buglardan, kod satırlarından tasarruf edersiniz ve muhtemelen kullanmasaydınız aynı performansı (veya daha iyisini) elde edersiniz. (hepsini kodunuza uygulamak zorunda kalacağınız gibi)
- * Eğer FastAPI'ı karşılaştırıyorsanız, Flask-apispec, NestJS, Molten, vb. gibi data validation, serialization ve dokümantasyon sağlayan bir web uygulaması frameworkü ile (veya araç setiyle) karşılaştırın. Entegre otomatik data validation, serialization ve dokümantasyon içeren frameworkler.
+ * Starlette'in Uvicorn'u kullandığı ve ondan daha hızlı olamayacağı gibi, **FastAPI**'da Starlette'i kullanır, dolayısıyla ondan daha hızlı olamaz.
+ * FastAPI, Starlette'e ek olarak daha fazla özellik sunar. Bunlar veri doğrulama ve
dönüşümü gibi API'lar oluştururken neredeyse ve her zaman ihtiyaç duyduğunuz özelliklerdir. Ve bunu kullanarak, ücretsiz olarak otomatik dokümantasyon elde edersiniz (otomatik dokümantasyon çalışan uygulamalara ek yük getirmez, başlangıçta oluşturulur).
+ * FastAPI'ı kullanmadıysanız ve Starlette'i doğrudan kullandıysanız (veya başka bir araç, Sanic, Flask, Responder, vb.) tüm veri doğrulama ve dönüştürme araçlarını kendiniz geliştirmeniz gerekir. Dolayısıyla, son uygulamanız FastAPI kullanılarak oluşturulmuş gibi hâlâ aynı ek yüke sahip olacaktır. Çoğu durumda, uygulamalarda yazılan kodun büyük bir kısmını veri doğrulama ve dönüştürme kodları oluşturur.
+ * Dolayısıyla, FastAPI'ı kullanarak geliştirme süresinden, hatalardan, kod satırlarından tasarruf edersiniz ve kullanmadığınız durumda (birçok özelliği geliştirmek zorunda kalmakla birlikte) muhtemelen aynı performansı (veya daha iyisini) elde ederdiniz.
+ * Eğer FastAPI'ı karşılaştırıyorsanız, Flask-apispec, NestJS, Molten, vb. gibi veri doğrulama, dönüştürme ve dokümantasyon sağlayan bir web uygulaması frameworkü ile (veya araç setiyle) karşılaştırın.
diff --git a/docs/tr/docs/deployment/cloud.md b/docs/tr/docs/deployment/cloud.md
new file mode 100644
index 000000000..5639567d4
--- /dev/null
+++ b/docs/tr/docs/deployment/cloud.md
@@ -0,0 +1,17 @@
+# FastAPI Uygulamasını Bulut Sağlayıcılar Üzerinde Yayınlama
+
+FastAPI uygulamasını yayınlamak için hemen hemen **herhangi bir bulut sağlayıcıyı** kullanabilirsiniz.
+
+Büyük bulut sağlayıcıların çoğu FastAPI uygulamasını yayınlamak için kılavuzlara sahiptir.
+
+## Bulut Sağlayıcılar - Sponsorlar
+
+Bazı bulut sağlayıcılar ✨ [**FastAPI destekçileridir**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, bu FastAPI ve **ekosisteminin** sürekli ve sağlıklı bir şekilde **gelişmesini** sağlar.
+
+Ayrıca, size **iyi servisler** sağlamakla kalmayıp, **iyi ve sağlıklı bir framework** olan FastAPI'a bağlılıklarını gösterir.
+
+Bu hizmetleri denemek ve kılavuzlarını incelemek isteyebilirsiniz:
+
+*
Platform.sh
+*
Porter
+*
Coherence
diff --git a/docs/tr/docs/deployment/index.md b/docs/tr/docs/deployment/index.md
new file mode 100644
index 000000000..e03bb4ee0
--- /dev/null
+++ b/docs/tr/docs/deployment/index.md
@@ -0,0 +1,21 @@
+# Deployment (Yayınlama)
+
+**FastAPI** uygulamasını deploy etmek oldukça kolaydır.
+
+## Deployment Ne Anlama Gelir?
+
+Bir uygulamayı **deploy** etmek (yayınlamak), uygulamayı **kullanıcılara erişilebilir hale getirmek** için gerekli adımları gerçekleştirmek anlamına gelir.
+
+Bir **Web API** için bu süreç normalde uygulamayı **uzak bir makineye** yerleştirmeyi, iyi performans, kararlılık vb. özellikler sağlayan bir **sunucu programı** ile **kullanıcılarınızın** uygulamaya etkili ve kesintisiz bir şekilde **erişebilmesini** kapsar.
+
+Bu, kodu sürekli olarak değiştirdiğiniz, hata alıp hata giderdiğiniz, geliştirme sunucusunu durdurup yeniden başlattığınız vb. **geliştirme** aşamalarının tam tersidir.
+
+## Deployment Stratejileri
+
+Kullanım durumunuza ve kullandığınız araçlara bağlı olarak bir kaç farklı yol izleyebilirsiniz.
+
+Bir dizi araç kombinasyonunu kullanarak kendiniz **bir sunucu yayınlayabilirsiniz**, yayınlama sürecinin bir kısmını sizin için gerçekleştiren bir **bulut hizmeti** veya diğer olası seçenekleri kullanabilirsiniz.
+
+**FastAPI** uygulamasını yayınlarken aklınızda bulundurmanız gereken ana kavramlardan bazılarını size göstereceğim (ancak bunların çoğu diğer web uygulamaları için de geçerlidir).
+
+Sonraki bölümlerde akılda tutulması gereken diğer ayrıntıları ve yayınlama tekniklerinden bazılarını göreceksiniz. ✨
diff --git a/docs/tr/docs/fastapi-people.md b/docs/tr/docs/fastapi-people.md
deleted file mode 100644
index 3e459036a..000000000
--- a/docs/tr/docs/fastapi-people.md
+++ /dev/null
@@ -1,178 +0,0 @@
-# FastAPI Topluluğu
-
-FastAPI, her kökenden insanı ağırlayan harika bir topluluğa sahip.
-
-## Yazan - Geliştiren
-
-Hey! 👋
-
-İşte bu benim:
-
-{% if people %}
-
-{% for user in people.maintainers %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-Ben **FastAPI** 'nin yazarı ve geliştiricisiyim. Bununla ilgili daha fazla bilgiyi şurada okuyabilirsiniz:
- [FastAPI yardım - yardım al - Yazar ile iletişime geç](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}.
-
-... Burada size harika FastAPI topluluğunu göstermek istiyorum.
-
----
-
-**FastAPI** topluluğundan destek alıyor. Ve katkıda bulunanları vurgulamak istiyorum.
-
-İşte o mükemmel insanlar:
-
-* [GitHubdaki sorunları (issues) çözmelerinde diğerlerine yardım et](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}.
-* [Pull Requests oluşturun](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
-* Pull Requests 'leri gözden geçirin, [özelliklede çevirileri](contributing.md#translations){.internal-link target=_blank}.
-
-Onlara bir alkış. 👏 🙇
-
-## Geçen ayın en aktif kullanıcıları
-
-Bunlar geçen ay boyunca [GitHub' da başkalarına sorunlarında (issues) en çok yardımcı olan ](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} kullanıcılar ☕
-
-{% if people %}
-
-{% for user in people.last_month_active %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## Uzmanlar
-
-İşte **FastAPI Uzmanları**. 🤓
-
-Bunlar *tüm zamanlar boyunca* [GitHub' da başkalarına sorunlarında (issues) en çok yardımcı olan](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} kullanıcılar.
-
-Başkalarına yardım ederek uzman olduklarını kanıtladılar. ✨
-
-{% if people %}
-
-{% for user in people.experts %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## En fazla katkıda bulunanlar
-
-işte **En fazla katkıda bulunanlar**. 👷
-
-Bu kullanıcılar en çok [Pull Requests oluşturan](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} ve onu kaynak koduna *birleştirenler*.
-
-Kaynak koduna, belgelere, çevirilere vb. katkıda bulundular. 📦
-
-{% if people %}
-
-{% for user in people.top_contributors %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-Çok fazla katkıda bulunan var (binden fazla), hepsini şurda görebilirsin:
FastAPI GitHub Katkıda Bulunanlar. 👷
-
-## En fazla inceleme yapanlar
-
-İşte **En fazla inceleme yapanlar**. 🕵️
-
-### Çeviri için İncelemeler
-
-Yalnızca birkaç dil konuşabiliyorum (ve çok da iyi değilim 😅). Bu yüzden döküman çevirilerini [**onaylama yetkisi**](contributing.md#translations){.internal-link target=_blank} siz inceleyenlere aittir. Sizler olmadan diğer birkaç dilde dokümantasyon olmazdı.
-
----
-
-**En fazla inceleme yapanlar** 🕵️ kodun, belgelerin ve özellikle **çevirilerin** kalitesini sağlamak için diğerlerinden daha fazla pull requests incelemiştir.
-
-{% if people %}
-
-{% for user in people.top_reviewers %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## Sponsorlar
-
-işte **Sponsorlarımız**. 😎
-
-**FastAPI** ve diğer projelerde çalışmamı destekliyorlar, özellikle de
GitHub Sponsorları.
-
-### Altın Sponsorlar
-
-{% if sponsors %}
-{% for sponsor in sponsors.gold -%}
-

-{% endfor %}
-{% endif %}
-
-### Gümüş Sponsorlar
-
-{% if sponsors %}
-{% for sponsor in sponsors.silver -%}
-

-{% endfor %}
-{% endif %}
-
-### Bronz Sponsorlar
-
-{% if sponsors %}
-{% for sponsor in sponsors.bronze -%}
-

-{% endfor %}
-{% endif %}
-
-### Bireysel Sponsorlar
-
-{% if people %}
-{% if people.sponsors_50 %}
-
-
-{% for user in people.sponsors_50 %}
-
-
-{% endfor %}
-
-
-
-{% endif %}
-{% endif %}
-
-{% if people %}
-
-{% for user in people.sponsors %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## Veriler hakkında - Teknik detaylar
-
-Bu sayfanın temel amacı, topluluğun başkalarına yardım etme çabasını vurgulamaktır.
-
-Özellikle normalde daha az görünür olan ve çoğu durumda daha zahmetli olan, diğerlerine sorunlar konusunda yardımcı olmak ve pull requests'leri gözden geçirmek gibi çabalar dahil.
-
-Veriler ayda bir hesaplanır, işte kaynak kodu okuyabilirsin :
source code here.
-
-Burada sponsorların katkılarını da tekrardan vurgulamak isterim.
-
-Ayrıca algoritmayı, bölümleri, eşikleri vb. güncelleme hakkımı da saklı tutarım (her ihtimale karşı 🤷).
diff --git a/docs/tr/docs/features.md b/docs/tr/docs/features.md
index f8220fb58..5d40b1086 100644
--- a/docs/tr/docs/features.md
+++ b/docs/tr/docs/features.md
@@ -27,7 +27,7 @@ OpenAPI standartlarına dayalı olan bir framework olarak, geliştiricilerin bir
### Sadece modern Python
-Tamamiyle standartlar **Python 3.6**'nın type hintlerine dayanıyor (Pydantic'in sayesinde). Yeni bir syntax öğrenmene gerek yok. Sadece modern Python.
+Tamamiyle standartlar **Python 3.8**'nın type hintlerine dayanıyor (Pydantic'in sayesinde). Yeni bir syntax öğrenmene gerek yok. Sadece modern Python.
Eğer Python type hintlerini bilmiyorsan veya bir hatırlatmaya ihtiyacın var ise(FastAPI kullanmasan bile) şu iki dakikalık küçük bilgilendirici içeriğe bir göz at: [Python Types](python-types.md){.internal-link target=_blank}.
@@ -67,10 +67,13 @@ second_user_data = {
my_second_user: User = User(**second_user_data)
```
-!!! info
- `**second_user_data` şu anlama geliyor:
+/// info
- Key-Value çiftini direkt olarak `second_user_data` dictionarysine kaydet , yaptığın şey buna eşit olacak: `User(id=4, name="Mary", joined="2018-11-30")`
+`**second_user_data` şu anlama geliyor:
+
+Key-Value çiftini direkt olarak `second_user_data` dictionarysine kaydet , yaptığın şey buna eşit olacak: `User(id=4, name="Mary", joined="2018-11-30")`
+
+///
### Editor desteği
@@ -182,7 +185,7 @@ Bütün entegrasyonlar kullanımı kolay olmak üzere (zorunluluklar ile beraber
## Pydantic özellikleri
-**FastAPI** ile
Pydantic tamamiyle uyumlu ve üzerine kurulu. Yani FastAPI üzerine ekleme yapacağınız herhangi bir Pydantic kodu da çalışacaktır.
+**FastAPI** ile
Pydantic tamamiyle uyumlu ve üzerine kurulu. Yani FastAPI üzerine ekleme yapacağınız herhangi bir Pydantic kodu da çalışacaktır.
Bunlara Pydantic üzerine kurulu
ORM databaseler ve ,
ODM kütüphaneler de dahil olmak üzere.
@@ -197,8 +200,6 @@ Aynı şekilde, databaseden gelen objeyi de **direkt olarak isteğe** de tamamiy
* Eğer Python typelarını nasıl kullanacağını biliyorsan Pydantic kullanmayı da biliyorsundur.
* Kullandığın geliştirme araçları ile iyi çalışır **
IDE/
linter/brain**:
* Pydantic'in veri yapıları aslında sadece senin tanımladığın classlar; Bu yüzden doğrulanmış dataların ile otomatik tamamlama, linting ve mypy'ı kullanarak sorunsuz bir şekilde çalışabilirsin
-* **Hızlı**:
- *
Benchmarklarda, Pydantic'in diğer bütün test edilmiş bütün kütüphanelerden daha hızlı.
* **En kompleks** yapıları bile doğrula:
* Hiyerarşik Pydantic modellerinin kullanımı ile beraber, Python `typing`’s `List` and `Dict`, vs gibi şeyleri doğrula.
* Doğrulayıcılar en kompleks data şemalarının bile temiz ve kolay bir şekilde tanımlanmasına izin veriyor, ve hepsi JSON şeması olarak dokümante ediliyor
diff --git a/docs/tr/docs/history-design-future.md b/docs/tr/docs/history-design-future.md
new file mode 100644
index 000000000..8b2662bc3
--- /dev/null
+++ b/docs/tr/docs/history-design-future.md
@@ -0,0 +1,79 @@
+# Geçmişi, Tasarımı ve Geleceği
+
+Bir süre önce,
bir **FastAPI** kullanıcısı sordu:
+
+> Bu projenin geçmişi nedir? Birkaç hafta içinde hiçbir yerden harika bir şeye dönüşmüş gibi görünüyor [...]
+
+İşte o geçmişin bir kısmı.
+
+## Alternatifler
+
+Bir süredir karmaşık gereksinimlere sahip API'lar oluşturuyor (Makine Öğrenimi, dağıtık sistemler, asenkron işler, NoSQL veritabanları vb.) ve farklı geliştirici ekiplerini yönetiyorum.
+
+Bu süreçte birçok alternatifi araştırmak, test etmek ve kullanmak zorunda kaldım.
+
+**FastAPI**'ın geçmişi, büyük ölçüde önceden geliştirilen araçların geçmişini kapsıyor.
+
+[Alternatifler](alternatives.md){.internal-link target=_blank} bölümünde belirtildiği gibi:
+
+
+
+Başkalarının daha önceki çalışmaları olmasaydı, **FastAPI** var olmazdı.
+
+Geçmişte oluşturulan pek çok araç **FastAPI**'a ilham kaynağı olmuştur.
+
+Yıllardır yeni bir framework oluşturmaktan kaçınıyordum. Başlangıçta **FastAPI**'ın çözdüğü sorunları çözebilmek için pek çok farklı framework, eklenti ve araç kullanmayı denedim.
+
+Ancak bir noktada, geçmişteki diğer araçlardan en iyi fikirleri alarak bütün bu çözümleri kapsayan, ayrıca bütün bunları Python'ın daha önce mevcut olmayan özelliklerini (Python 3.6+ ile gelen tip belirteçleri) kullanarak yapan bir şey üretmekten başka bir seçenek kalmamıştı.
+
+
+
+## Araştırma
+
+Önceki alternatifleri kullanarak hepsinden bir şeyler öğrenip, fikirler alıp, bunları kendim ve çalıştığım geliştirici ekipler için en iyi şekilde birleştirebilme şansım oldu.
+
+Mesela, ideal olarak standart Python tip belirteçlerine dayanması gerektiği açıktı.
+
+Ayrıca, en iyi yaklaşım zaten mevcut olan standartları kullanmaktı.
+
+Sonuç olarak, **FastAPI**'ı kodlamaya başlamadan önce, birkaç ay boyunca OpenAPI, JSON Schema, OAuth2 ve benzerlerinin tanımlamalarını inceledim. İlişkilerini, örtüştükleri noktaları ve farklılıklarını anlamaya çalıştım.
+
+## Tasarım
+
+Sonrasında, (**FastAPI** kullanan bir geliştirici olarak) sahip olmak istediğim "API"ı tasarlamak için biraz zaman harcadım.
+
+Çeşitli fikirleri en popüler Python editörlerinde test ettim: PyCharm, VS Code, Jedi tabanlı editörler.
+
+Bu test, en son
Python Developer Survey'ine göre, kullanıcıların yaklaşık %80'inin kullandığı editörleri kapsıyor.
+
+Bu da demek oluyor ki **FastAPI**, Python geliştiricilerinin %80'inin kullandığı editörlerle test edildi. Ve diğer editörlerin çoğu benzer şekilde çalıştığından, avantajları neredeyse tüm editörlerde çalışacaktır.
+
+Bu şekilde, kod tekrarını mümkün olduğunca azaltmak, her yerde
otomatik tamamlama, tip ve hata kontrollerine sahip olmak için en iyi yolları bulabildim.
+
+Hepsi, tüm geliştiriciler için en iyi geliştirme deneyimini sağlayacak şekilde.
+
+## Gereksinimler
+
+Çeşitli alternatifleri test ettikten sonra, avantajlarından dolayı
**Pydantic**'i kullanmaya karar verdim.
+
+Sonra, JSON Schema ile tamamen uyumlu olmasını sağlamak, kısıtlama bildirimlerini tanımlamanın farklı yollarını desteklemek ve birkaç editördeki testlere dayanarak editör desteğini (tip kontrolleri, otomatik tamamlama) geliştirmek için katkıda bulundum.
+
+Geliştirme sırasında, diğer ana gereksinim olan
**Starlette**'e de katkıda bulundum.
+
+## Geliştirme
+
+**FastAPI**'ı oluşturmaya başladığımda, parçaların çoğu zaten yerindeydi, tasarım tanımlanmıştı, gereksinimler ve araçlar hazırdı, standartlar ve tanımlamalar hakkındaki bilgi net ve tazeydi.
+
+## Gelecek
+
+Şimdiye kadar, **FastAPI**'ın fikirleriyle birçok kişiye faydalı olduğu apaçık ortada.
+
+Birçok kullanım durumuna daha iyi uyduğu için, önceki alternatiflerin yerine seçiliyor.
+
+Ben ve ekibim dahil, birçok geliştirici ve ekip projelerinde **FastAPI**'ya bağlı.
+
+Tabi, geliştirilecek birçok özellik ve iyileştirme mevcut.
+
+**FastAPI**'ın önünde harika bir gelecek var.
+
+[Yardımlarınız](help-fastapi.md){.internal-link target=_blank} çok değerlidir.
diff --git a/docs/tr/docs/how-to/general.md b/docs/tr/docs/how-to/general.md
new file mode 100644
index 000000000..cbfa7beb2
--- /dev/null
+++ b/docs/tr/docs/how-to/general.md
@@ -0,0 +1,39 @@
+# Genel - Nasıl Yapılır - Tarifler
+
+Bu sayfada genel ve sıkça sorulan sorular için dokümantasyonun diğer sayfalarına yönlendirmeler bulunmaktadır.
+
+## Veri Filtreleme - Güvenlik
+
+Döndürmeniz gereken veriden fazlasını döndürmediğinizden emin olmak için, [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank} sayfasını okuyun.
+
+## Dokümantasyon Etiketleri - OpenAPI
+
+*Yol operasyonlarınıza* etiketler ekleyerek dokümantasyon arayüzünde gruplar halinde görünmesini sağlamak için, [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank} sayfasını okuyun.
+
+## Dokümantasyon Özeti ve Açıklaması - OpenAPI
+
+*Yol operasyonlarınıza* özet ve açıklama ekleyip dokümantasyon arayüzünde görünmesini sağlamak için, [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank} sayfasını okuyun.
+
+## Yanıt Açıklaması Dokümantasyonu - OpenAPI
+
+Dokümantasyon arayüzünde yer alan yanıt açıklamasını tanımlamak için, [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank} sayfasını okuyun.
+
+## *Yol Operasyonunu* Kullanımdan Kaldırma - OpenAPI
+
+Bir *yol işlemi*ni kullanımdan kaldırmak ve bunu dokümantasyon arayüzünde göstermek için, [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank} sayfasını okuyun.
+
+## Herhangi Bir Veriyi JSON Uyumlu Hale Getirme
+
+Herhangi bir veriyi JSON uyumlu hale getirmek için, [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} sayfasını okuyun.
+
+## OpenAPI Meta Verileri - Dokümantasyon
+
+OpenAPI şemanıza lisans, sürüm, iletişim vb. meta veriler eklemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank} sayfasını okuyun.
+
+## OpenAPI Bağlantı Özelleştirme
+
+OpenAPI bağlantısını özelleştirmek (veya kaldırmak) için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank} sayfasını okuyun.
+
+## OpenAPI Dokümantasyon Bağlantıları
+
+Dokümantasyonu arayüzünde kullanılan bağlantıları güncellemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank} sayfasını okuyun.
diff --git a/docs/tr/docs/how-to/index.md b/docs/tr/docs/how-to/index.md
new file mode 100644
index 000000000..26dd9026c
--- /dev/null
+++ b/docs/tr/docs/how-to/index.md
@@ -0,0 +1,13 @@
+# Nasıl Yapılır - Tarifler
+
+Burada çeşitli konular hakkında farklı tarifler veya "nasıl yapılır" kılavuzları yer alıyor.
+
+Bu fikirlerin büyük bir kısmı aşağı yukarı **bağımsız** olacaktır, çoğu durumda bunları sadece **projenize** hitap ediyorsa incelemelisiniz.
+
+Projeniz için ilginç ve yararlı görünen bir şey varsa devam edin ve inceleyin, aksi halde bunları atlayabilirsiniz.
+
+/// tip | İpucu
+
+**FastAPI**'ı düzgün (ve önerilen) şekilde öğrenmek istiyorsanız [Öğretici - Kullanıcı Rehberi](../tutorial/index.md){.internal-link target=_blank}'ni bölüm bölüm okuyun.
+
+///
diff --git a/docs/tr/docs/index.md b/docs/tr/docs/index.md
index 6bd30d709..f666e2d06 100644
--- a/docs/tr/docs/index.md
+++ b/docs/tr/docs/index.md
@@ -1,50 +1,54 @@
+# FastAPI
-{!../../../docs/missing-translation.md!}
-
+
- FastAPI framework, yüksek performanslı, öğrenmesi kolay, geliştirmesi hızlı, kullanıma sunulmaya hazır.
+ FastAPI framework, yüksek performanslı, öğrenmesi oldukça kolay, kodlaması hızlı, kullanıma hazır
-
-
+
+
-
-
+
+
+
+
+
---
-**dokümantasyon**:
https://fastapi.tiangolo.com
+**Dokümantasyon**:
https://fastapi.tiangolo.com
-**Kaynak kodu**:
https://github.com/tiangolo/fastapi
+**Kaynak Kod**:
https://github.com/fastapi/fastapi
---
-FastAPI, Python 3.6+'nın standart type hintlerine dayanan modern ve hızlı (yüksek performanslı) API'lar oluşturmak için kullanılabilecek web framework'ü.
-
-Ana özellikleri:
+FastAPI, Python 'nin standart
tip belirteçlerine dayalı, modern ve hızlı (yüksek performanslı) API'lar oluşturmak için kullanılabilecek web framework'tür.
-* **Hızlı**: çok yüksek performanslı, **NodeJS** ve **Go** ile eşdeğer seviyede performans sağlıyor, (Starlette ve Pydantic sayesinde.) [Python'un en hızlı frameworklerinden bir tanesi.](#performans).
-* **Kodlaması hızlı**: Yeni özellikler geliştirmek neredeyse %200 - %300 daha hızlı. *
-* **Daha az bug**: Geliştirici (insan) kaynaklı hatalar neredeyse %40 azaltıldı. *
-* **Sezgileri güçlü**: Editor (otomatik-tamamlama) desteği harika.
Otomatik tamamlama her yerde. Debuglamak ile daha az zaman harcayacaksınız.
-* **Kolay**: Öğrenmesi ve kullanması kolay olacak şekilde. Doküman okumak için harcayacağınız süre azaltıldı.
-* **Kısa**: Kod tekrarını minimuma indirdik. Fonksiyon parametrelerinin tiplerini belirtmede farklı yollar sunarak karşılaşacağınız bug'ları azalttık.
-* **Güçlü**: Otomatik dokümantasyon ile beraber, kullanıma hazır kod yaz.
+Temel özellikleri şunlardır:
-* **Standartlar belirli**: Tamamiyle API'ların açık standartlara bağlı ve (tam uyumlululuk içerisinde);
OpenAPI (eski adıyla Swagger) ve
JSON Schema.
+* **Hızlı**: Çok yüksek performanslı, **NodeJS** ve **Go** ile eşit düzeyde (Starlette ve Pydantic sayesinde). [En hızlı Python framework'lerinden bir tanesidir](#performans).
+* **Kodlaması Hızlı**: Geliştirme hızını yaklaşık %200 ile %300 aralığında arttırır. *
+* **Daha az hata**: İnsan (geliştirici) kaynaklı hataları yaklaşık %40 azaltır. *
+* **Sezgisel**: Muhteşem bir editör desteği. Her yerde
otomatik tamamlama. Hata ayıklama ile daha az zaman harcayacaksınız.
+* **Kolay**: Öğrenmesi ve kullanması kolay olacak şekilde tasarlandı. Doküman okuma ile daha az zaman harcayacaksınız.
+* **Kısa**: Kod tekrarı minimize edildi. Her parametre tanımlamasında birden fazla özellik ve daha az hatayla karşılaşacaksınız.
+* **Güçlü**: Otomatik ve etkileşimli dokümantasyon ile birlikte, kullanıma hazır kod elde edebilirsiniz.
+* **Standard öncelikli**: API'lar için açık standartlara dayalı (ve tamamen uyumlu);
OpenAPI (eski adıyla Swagger) ve
JSON Schema.
-
* Bahsi geçen rakamsal ifadeler tamamiyle, geliştirme takımının kendi sundukları ürünü geliştirirken yaptıkları testlere dayanmakta.
+
* ilgili kanılar, dahili geliştirme ekibinin geliştirdikleri ürünlere yaptıkları testlere dayanmaktadır.
-## Sponsors
+## Sponsorlar
@@ -59,74 +63,70 @@ Ana özellikleri:
-
Other sponsors
+
Diğer Sponsorlar
## Görüşler
+"_[...] Bugünlerde **FastAPI**'ı çok fazla kullanıyorum. [...] Aslında bunu ekibimin **Microsoft'taki Machine Learning servislerinin** tamamında kullanmayı planlıyorum. Bunlardan bazıları **Windows**'un ana ürünlerine ve **Office** ürünlerine entegre ediliyor._"
-"_[...] Bugünlerde **FastAPI**'ı çok fazla kullanıyorum [...] Aslına bakarsanız **Microsoft'taki Machine Learning servislerimizin** hepsinde kullanmayı düşünüyorum. FastAPI ile geliştirdiğimiz servislerin bazıları çoktan **Windows**'un ana ürünlerine ve **Office** ürünlerine entegre edilmeye başlandı bile._"
-
-
Kabir Khan -
Microsoft (ref)
+
Kabir Khan -
Microsoft (ref)
---
-
-"_**FastAPI**'ı **tahminlerimiz**'i sorgulanabilir hale getirmek için **REST** mimarisı ile beraber server üzerinde kullanmaya başladık._"
-
+"_**FastAPI**'ı **tahminlerimiz**'i sorgulanabilir hale getirecek bir **REST** sunucu oluşturmak için benimsedik/kullanmaya başladık._"
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
---
-
-"_**Netflix** **kriz yönetiminde** orkestrasyon yapabilmek için geliştirdiği yeni framework'ü **Dispatch**'in, açık kaynak versiyonunu paylaşmaktan gurur duyuyor. [**FastAPI** ile yapıldı.]_"
+"_**Netflix**, **kriz yönetiminde** orkestrasyon yapabilmek için geliştirdiği yeni framework'ü **Dispatch**'in, açık kaynak sürümünü paylaşmaktan gurur duyuyor. [**FastAPI** ile yapıldı.]_"
Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
---
-
"_**FastAPI** için ayın üzerindeymişcesine heyecanlıyım. Çok eğlenceli!_"
-
---
-"_Dürüst olmak gerekirse, geliştirdiğin şey bir çok açıdan çok sağlam ve parlak gözüküyor. Açıkcası benim **Hug**'ı tasarlarken yapmaya çalıştığım şey buydu - bunu birisinin başardığını görmek gerçekten çok ilham verici._"
+"_Dürüst olmak gerekirse, inşa ettiğiniz şey gerçekten sağlam ve profesyonel görünüyor. Birçok açıdan **Hug**'ın olmasını istediğim şey tam da bu - böyle bir şeyi inşa eden birini görmek gerçekten ilham verici._"
-
Timothy Crosley -
Hug'ın Yaratıcısı (ref)
+
Timothy Crosley -
Hug'ın Yaratıcısı (ref)
---
-"_Eğer REST API geliştirmek için **modern bir framework** öğrenme arayışında isen, **FastAPI**'a bir göz at [...] Hızlı, kullanımı ve öğrenmesi kolay. [...]_"
+"_Eğer REST API geliştirmek için **modern bir framework** öğrenme arayışında isen, **FastAPI**'a bir göz at [...] Hızlı, kullanımı ve öğrenmesi kolay. [...]_"
-"_Biz **API** servislerimizi **FastAPI**'a geçirdik [...] Sizin de beğeneceğinizi düşünüyoruz. [...]_"
+"_**API** servislerimizi **FastAPI**'a taşıdık [...] Sizin de beğeneceğinizi düşünüyoruz. [...]_"
+
+---
-
+"_Python ile kullanıma hazır bir API oluşturmak isteyen herhangi biri için, **FastAPI**'ı şiddetle tavsiye ederim. **Harika tasarlanmış**, **kullanımı kolay** ve **yüksek ölçeklenebilir**, API odaklı geliştirme stratejimizin **ana bileşeni** haline geldi ve Virtual TAC Engineer gibi birçok otomasyon ve servisi yönetiyor._"
+
+
Deon Pillsbury -
Cisco (ref)
---
-## **Typer**, komut satırı uygulamalarının FastAPI'ı
+## Komut Satırı Uygulamalarının FastAPI'ı: **Typer**

-Eğer API yerine
komut satırı uygulaması geliştiriyor isen
**Typer**'a bir göz at.
+Eğer API yerine, terminalde kullanılmak üzere bir
komut satırı uygulaması geliştiriyorsanız
**Typer**'a göz atabilirsiniz.
-**Typer** kısaca FastAPI'ın küçük kız kardeşi. Komut satırı uygulamalarının **FastAPI'ı** olması hedeflendi. ⌨️ 🚀
+**Typer** kısaca FastAPI'ın küçük kardeşi. Ve hedefi komut satırı uygulamalarının **FastAPI'ı** olmak. ⌨️ 🚀
## Gereksinimler
-Python 3.7+
-
FastAPI iki devin omuzları üstünde duruyor:
* Web tarafı için
Starlette.
-* Data tarafı için
Pydantic.
+* Data tarafı için
Pydantic.
-## Yükleme
+## Kurulum
@@ -138,7 +138,7 @@ $ pip install fastapi
-Uygulamanı kullanılabilir hale getirmek için
Uvicorn ya da
Hypercorn gibi bir ASGI serverına ihtiyacın olacak.
+Uygulamamızı kullanılabilir hale getirmek için
Uvicorn ya da
Hypercorn gibi bir ASGI sunucusuna ihtiyacımız olacak.
@@ -152,9 +152,9 @@ $ pip install "uvicorn[standard]"
## Örnek
-### Şimdi dene
+### Kodu Oluşturalım
-* `main.py` adında bir dosya oluştur :
+* `main.py` adında bir dosya oluşturup içine şu kodu yapıştıralım:
```Python
from typing import Union
@@ -177,9 +177,9 @@ def read_item(item_id: int, q: Union[str, None] = None):
Ya da async def
...
-Eğer kodunda `async` / `await` var ise, `async def` kullan:
+Eğer kodunuzda `async` / `await` varsa, `async def` kullanalım:
-```Python hl_lines="9 14"
+```Python hl_lines="9 14"
from typing import Union
from fastapi import FastAPI
@@ -199,13 +199,13 @@ async def read_item(item_id: int, q: Union[str, None] = None):
**Not**:
-Eğer ne olduğunu bilmiyor isen _"Acelen mi var?"_ kısmını oku `async` ve `await`.
+Eğer bu konu hakkında bilginiz yoksa `async` ve `await` dokümantasyonundaki _"Aceleniz mi var?"_ kısmını kontrol edebilirsiniz.
-### Çalıştır
+### Kodu Çalıştıralım
-Serverı aşağıdaki komut ile çalıştır:
+Sunucuyu aşağıdaki komutla çalıştıralım:
@@ -222,56 +222,56 @@ INFO: Application startup complete.
-Çalıştırdığımız uvicorn main:app --reload
hakkında...
+uvicorn main:app --reload
komutuyla ilgili...
-`uvicorn main:app` şunları ifade ediyor:
+`uvicorn main:app` komutunu şu şekilde açıklayabiliriz:
* `main`: dosya olan `main.py` (yani Python "modülü").
-* `app`: ise `main.py` dosyasının içerisinde oluşturduğumuz `app = FastAPI()` 'a denk geliyor.
-* `--reload`: ise kodda herhangi bir değişiklik yaptığımızda serverın yapılan değişiklerileri algılayıp, değişiklikleri siz herhangi bir şey yapmadan uygulamasını sağlıyor.
+* `app`: ise `main.py` dosyasının içerisinde `app = FastAPI()` satırında oluşturduğumuz `FastAPI` nesnesi.
+* `--reload`: kod değişikliklerinin ardından sunucuyu otomatik olarak yeniden başlatır. Bu parameteyi sadece geliştirme aşamasında kullanmalıyız.
-### Dokümantasyonu kontrol et
+### Şimdi de Kontrol Edelim
-Browserını aç ve şu linke git
http://127.0.0.1:8000/items/5?q=somequery.
+Tarayıcımızda şu bağlantıyı açalım
http://127.0.0.1:8000/items/5?q=somequery.
-Bir JSON yanıtı göreceksin:
+Aşağıdaki gibi bir JSON yanıtıyla karşılaşacağız:
```JSON
{"item_id": 5, "q": "somequery"}
```
-Az önce oluşturduğun API:
+Az önce oluşturduğumuz API:
-* `/` ve `/items/{item_id}` adreslerine HTTP talebi alabilir hale geldi.
-* İki _adresde_ `GET`
operasyonlarını (HTTP _metodları_ olarakta bilinen) yapabilir hale geldi.
-* `/items/{item_id}` _adresi_ ayrıca bir `item_id` _adres parametresine_ sahip ve bu bir `int` olmak zorunda.
-* `/items/{item_id}` _adresi_ opsiyonel bir `str` _sorgu paramtersine_ sahip bu da `q`.
+* `/` ve `/items/{item_id}`
_yollarına_ HTTP isteği alabilir.
+* İki _yolda_ `GET`
operasyonlarını (HTTP _metodları_ olarak da bilinen) kabul ediyor.
+* `/items/{item_id}` _yolu_ `item_id` adında bir _yol parametresine_ sahip ve bu parametre `int` değer almak zorundadır.
+* `/items/{item_id}` _yolu_ `q` adında bir _yol parametresine_ sahip ve bu parametre opsiyonel olmakla birlikte, `str` değer almak zorundadır.
-### İnteraktif API dokümantasyonu
+### Etkileşimli API Dokümantasyonu
-Şimdi
http://127.0.0.1:8000/docs adresine git.
+Şimdi
http://127.0.0.1:8000/docs bağlantısını açalım.
-Senin için otomatik oluşturulmuş(
Swagger UI tarafından sağlanan) interaktif bir API dokümanı göreceksin:
+
Swagger UI tarafından sağlanan otomatik etkileşimli bir API dokümantasyonu göreceğiz:

-### Alternatif API dokümantasyonu
+### Alternatif API Dokümantasyonu
-Şimdi
http://127.0.0.1:8000/redoc adresine git.
+Şimdi
http://127.0.0.1:8000/redoc bağlantısını açalım.
-Senin için alternatif olarak (
ReDoc tarafından sağlanan) bir API dokümantasyonu daha göreceksin:
+
ReDoc tarafından sağlanan otomatik dokümantasyonu göreceğiz:

-## Örnek bir değişiklik
+## Örneği Güncelleyelim
-Şimdi `main.py` dosyasını değiştirelim ve body ile `PUT` talebi alabilir hale getirelim.
+Şimdi `main.py` dosyasını, `PUT` isteğiyle birlikte bir gövde alacak şekilde değiştirelim.
-Şimdi Pydantic sayesinde, Python'un standart tiplerini kullanarak bir body tanımlayacağız.
+
Gövdeyi Pydantic sayesinde standart python tiplerini kullanarak tanımlayalım.
-```Python hl_lines="4 9 10 11 12 25 26 27"
+```Python hl_lines="4 9-12 25-27"
from typing import Union
from fastapi import FastAPI
@@ -301,41 +301,41 @@ def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
-Server otomatik olarak yeniden başlamalı (çünkü yukarıda `uvicorn`'u çalıştırırken `--reload` parametresini kullandık.).
+Sunucu otomatik olarak yeniden başlamış olmalı (çünkü yukarıda `uvicorn` komutuyla birlikte `--reload` parametresini kullandık).
-### İnteraktif API dokümantasyonu'nda değiştirme yapmak
+### Etkileşimli API Dokümantasyonundaki Değişimi Görelim
-Şimdi
http://127.0.0.1:8000/docs bağlantısına tekrar git.
+Şimdi
http://127.0.0.1:8000/docs bağlantısına tekrar gidelim.
-* İnteraktif API dokümantasyonu, yeni body ile beraber çoktan yenilenmiş olması lazım:
+* Etkileşimli API dokümantasyonu, yeni gövdede dahil olmak üzere otomatik olarak güncellenmiş olacak:

-* "Try it out"a tıkla, bu senin API parametleri üzerinde deneme yapabilmene izin veriyor:
+* "Try it out" butonuna tıklayalım, bu işlem API parametleri üzerinde değişiklik yapmamıza ve doğrudan API ile etkileşime geçmemize imkan sağlayacak:

-* Şimdi "Execute" butonuna tıkla, kullanıcı arayüzü otomatik olarak API'ın ile bağlantı kurarak ona bu parametreleri gönderecek ve sonucu karşına getirecek.
+* Şimdi "Execute" butonuna tıklayalım, kullanıcı arayüzü API'ımız ile bağlantı kurup parametreleri gönderecek ve sonucu ekranımıza getirecek:

-### Alternatif API dokümantasyonunda değiştirmek
+### Alternatif API Dokümantasyonundaki Değişimi Görelim
-Şimdi ise
http://127.0.0.1:8000/redoc adresine git.
+Şimdi ise
http://127.0.0.1:8000/redoc bağlantısına tekrar gidelim.
-* Alternatif dokümantasyonda koddaki değişimler ile beraber kendini yeni query ve body ile güncelledi.
+* Alternatif dokümantasyonda yaptığımız değişiklikler ile birlikte yeni sorgu parametresi ve gövde bilgisi ile güncelemiş olacak:

### Özet
-Özetleyecek olursak, URL, sorgu veya request body'deki parametrelerini fonksiyon parametresi olarak kullanıyorsun. Bu parametrelerin veri tiplerini bir kere belirtmen yeterli.
+Özetlemek gerekirse, parametrelerin, gövdenin, vb. veri tiplerini fonksiyon parametreleri olarak **bir kere** tanımlıyoruz.
-Type-hinting işlemini Python dilindeki standart veri tipleri ile yapabilirsin
+Bu işlemi standart modern Python tipleriyle yapıyoruz.
-Yeni bir syntax'e alışmana gerek yok, metodlar ve classlar zaten spesifik kütüphanelere ait.
+Yeni bir sözdizimi yapısını, bir kütüphane özel metod veya sınıfları öğrenmeye gerek yoktur.
-Sadece standart **Python 3.6+**.
+Hepsi sadece **Python** standartlarına dayalıdır.
Örnek olarak, `int` tanımlamak için:
@@ -343,64 +343,64 @@ Sadece standart **Python 3.6+**.
item_id: int
```
-ya da daha kompleks `Item` tipi:
+ya da daha kompleks herhangi bir python modelini tanımlayabiliriz, örneğin `Item` modeli için:
```Python
item: Item
```
-...sadece kısa bir parametre tipi belirtmekle beraber, sahip olacakların:
+...ve sadece kısa bir parametre tipi belirterek elde ettiklerimiz:
-* Editör desteği dahil olmak üzere:
+* Editör desteğiyle birlikte:
* Otomatik tamamlama.
- * Tip sorguları.
-* Datanın tipe uyumunun sorgulanması:
- * Eğer data geçersiz ise, otomatik olarak hataları ayıklar.
- * Çok derin JSON objelerinde bile veri tipi sorgusu yapar.
-* Gelen verinin
dönüşümünü aşağıdaki veri tiplerini kullanarak gerçekleştirebiliyor.
+ * Tip kontrolü.
+* Veri Doğrulama:
+ * Veri geçerli değilse, otomatik olarak açıklayıcı hatalar gösterir.
+ * Çok
derin JSON nesnelerinde bile doğrulama yapar.
+* Gelen verinin
dönüşümünü aşağıdaki veri tiplerini kullanarak gerçekleştirir:
* JSON.
- * Path parametreleri.
- * Query parametreleri.
- * Cookies.
+ * Yol parametreleri.
+ * Sorgu parametreleri.
+ * Çerezler.
* Headers.
- * Forms.
- * Files.
-* Giden verinin
dönüşümünü aşağıdaki veri tiplerini kullanarak gerçekleştirebiliyor (JSON olarak):
- * Python tiplerinin (`str`, `int`, `float`, `bool`, `list`, vs) çevirisi.
- * `datetime` objesi.
- * `UUID` objesi.
+ * Formlar.
+ * Dosyalar.
+* Giden verinin
dönüşümünü aşağıdaki veri tiplerini kullanarak gerçekleştirir (JSON olarak):
+ * Python tiplerinin (`str`, `int`, `float`, `bool`, `list`, vb) dönüşümü.
+ * `datetime` nesnesi.
+ * `UUID` nesnesi.
* Veritabanı modelleri.
- * ve daha fazlası...
-* 2 alternatif kullanıcı arayüzü dahil olmak üzere, otomatik interaktif API dokümanu:
+ * ve çok daha fazlası...
+* 2 alternatif kullanıcı arayüzü dahil olmak üzere, otomatik etkileşimli API dokümantasyonu sağlar:
* Swagger UI.
* ReDoc.
---
-Az önceki kod örneğine geri dönelim, **FastAPI**'ın yapacaklarına bir bakış atalım:
+Az önceki örneğe geri dönelim, **FastAPI**'ın yapacaklarına bir bakış atalım:
-* `item_id`'nin `GET` ve `PUT` talepleri içinde olup olmadığının doğruluğunu kontol edecek.
-* `item_id`'nin tipinin `int` olduğunu `GET` ve `PUT` talepleri içinde olup olmadığının doğruluğunu kontol edecek.
- * Eğer `GET` ve `PUT` içinde yok ise ve `int` değil ise, sebebini belirten bir hata mesajı gösterecek
-* Opsiyonel bir `q` parametresinin `GET` talebi için (`http://127.0.0.1:8000/items/foo?q=somequery` içinde) olup olmadığını kontrol edecek
+* `item_id`'nin `GET` ve `PUT` istekleri için, yolda olup olmadığının kontol edecek.
+* `item_id`'nin `GET` ve `PUT` istekleri için, tipinin `int` olduğunu doğrulayacak.
+ * Eğer değilse, sebebini belirten bir hata mesajı gösterecek.
+* Opsiyonel bir `q` parametresinin `GET` isteği içinde (`http://127.0.0.1:8000/items/foo?q=somequery` gibi) olup olmadığını kontrol edecek
* `q` parametresini `= None` ile oluşturduğumuz için, opsiyonel bir parametre olacak.
- * Eğer `None` olmasa zorunlu bir parametre olacak idi (bu yüzden body'de `PUT` parametresi var).
-* `PUT` talebi için `/items/{item_id}`'nin body'sini, JSON olarak okuyor:
- * `name` adında bir parametetre olup olmadığını ve var ise onun `str` olup olmadığını kontol ediyor.
- * `price` adında bir parametetre olup olmadığını ve var ise onun `float` olup olmadığını kontol ediyor.
- * `is_offer` adında bir parametetre olup olmadığını ve var ise onun `bool` olup olmadığını kontol ediyor.
- * Bunların hepsini en derin JSON modellerinde bile yapacaktır.
-* Bütün veri tiplerini otomatik olarak JSON'a çeviriyor veya tam tersi.
-* Her şeyi dokümanlayıp, çeşitli yerlerde:
- * İnteraktif dokümantasyon sistemleri.
- * Otomatik alıcı kodu üretim sistemlerinde ve çeşitli dillerde.
-* İki ayrı web arayüzüyle direkt olarak interaktif bir dokümantasyon sunuyor.
+ * Eğer `None` olmasa zorunlu bir parametre olacaktı (`PUT` metodunun gövdesinde olduğu gibi).
+* `PUT` isteği için `/items/{item_id}`'nin gövdesini, JSON olarak doğrulayıp okuyacak:
+ * `name` adında zorunlu bir parametre olup olmadığını ve varsa tipinin `str` olup olmadığını kontol edecek.
+ * `price` adında zorunlu bir parametre olup olmadığını ve varsa tipinin `float` olup olmadığını kontol edecek.
+ * `is_offer` adında opsiyonel bir parametre olup olmadığını ve varsa tipinin `float` olup olmadığını kontol edecek.
+ * Bunların hepsi en derin JSON nesnelerinde bile çalışacak.
+* Verilerin JSON'a ve JSON'ın python nesnesine dönüşümü otomatik olarak yapılacak.
+* Her şeyi OpenAPI ile uyumlu bir şekilde otomatik olarak dokümanlayacak ve bunlarda aşağıdaki gibi kullanılabilecek:
+ * Etkileşimli dokümantasyon sistemleri.
+ * Bir çok programlama dili için otomatik istemci kodu üretim sistemleri.
+* İki ayrı etkileşimli dokümantasyon arayüzünü doğrudan sağlayacak.
---
-Henüz yüzeysel bir bakış attık, fakat sen çoktan çalışma mantığını anladın.
+Daha yeni başladık ama çalışma mantığını çoktan anlamış oldunuz.
-Şimdi aşağıdaki satırı değiştirmeyi dene:
+Şimdi aşağıdaki satırı değiştirmeyi deneyin:
```Python
return {"item_name": item.name, "item_id": item_id}
@@ -418,22 +418,22 @@ Henüz yüzeysel bir bakış attık, fakat sen çoktan çalışma mantığını
... "item_price": item.price ...
```
-...şimdi editör desteğinin nasıl veri tiplerini bildiğini ve otomatik tamamladığını gör:
+...ve editörünün veri tiplerini bildiğini ve otomatik tamamladığını göreceksiniz:

-Daha fazla örnek ve özellik için
Tutorial - User Guide sayfasını git.
+Daha fazal özellik içeren, daha eksiksiz bir örnek için
Öğretici - Kullanıcı Rehberi sayfasını ziyaret edebilirsin.
-**Spoiler**: Öğretici - Kullanıcı rehberi şunları içeriyor:
+**Spoiler**: Öğretici - Kullanıcı rehberi şunları içerir:
-* **Parameterlerini** nasıl **headers**, **cookies**, **form fields** ve **files** olarak deklare edebileceğini.
-* `maximum_length` ya da `regex` gibi şeylerle nasıl **doğrulama** yapabileceğini.
-* Çok güçlü ve kullanımı kolay **
Zorunluluk Entegrasyonu** oluşturmayı.
-* Güvenlik ve kimlik doğrulama, **JWT tokenleri**'yle beraber **OAuth2** desteği, ve **HTTP Basic** doğrulaması.
-* İleri seviye fakat ona göre oldukça basit olan **derince oluşturulmuş JSON modelleri** (Pydantic sayesinde).
+* **Parameterlerin**, **headers**, **çerezler**, **form alanları** ve **dosyalar** olarak tanımlanması.
+* `maximum_length` ya da `regex` gibi **doğrulama kısıtlamalarının** nasıl yapılabileceği.
+* Çok güçlü ve kullanımı kolay **
Bağımlılık Enjeksiyonu** sistemi oluşturmayı.
+* Güvenlik ve kimlik doğrulama, **JWT tokenleri** ile **OAuth2** desteği, ve **HTTP Basic** doğrulaması.
+* İleri seviye fakat bir o kadarda basit olan **çok derin JSON modelleri** (Pydantic sayesinde).
+* **GraphQL** entegrasyonu:
Strawberry ve diğer kütüphaneleri kullanarak.
* Diğer ekstra özellikler (Starlette sayesinde):
- * **WebSockets**
- * **GraphQL**
+ * **WebSocketler**
* HTTPX ve `pytest` sayesinde aşırı kolay testler.
* **CORS**
* **Cookie Sessions**
@@ -441,34 +441,34 @@ Daha fazla örnek ve özellik için
Python'un en hızlı frameworklerinden birisi , sadece Starlette ve Uvicorn'dan daha yavaş ki FastAPI bunların üzerine kurulu.
+Bağımsız TechEmpower kıyaslamaları gösteriyor ki, Uvicorn ile çalıştırılan **FastAPI** uygulamaları
en hızlı Python framework'lerinden birisi, sadece Starlette ve Uvicorn'dan yavaş, ki FastAPI bunların üzerine kurulu bir kütüphanedir.
-Daha fazla bilgi için, bu bölüme bir göz at
Benchmarks.
+Daha fazla bilgi için, bu bölüme bir göz at
Kıyaslamalar.
-## Opsiyonel gereksinimler
+## Opsiyonel Gereksinimler
Pydantic tarafında kullanılan:
-*
ujson
- daha hızlı JSON
"dönüşümü" için.
-*
email_validator
- email doğrulaması için.
+*
email-validator
- email doğrulaması için.
+*
pydantic-settings
- ayar yönetimi için.
+*
pydantic-extra-types
- Pydantic ile birlikte kullanılabilecek ek tipler için.
Starlette tarafında kullanılan:
-*
httpx
- Eğer `TestClient` kullanmak istiyorsan gerekli.
-*
jinja2
- Eğer kendine ait template konfigürasyonu oluşturmak istiyorsan gerekli
-*
python-multipart
- Form kullanmak istiyorsan gerekli
("dönüşümü").
+*
httpx
- Eğer `TestClient` yapısını kullanacaksanız gereklidir.
+*
jinja2
- Eğer varsayılan template konfigürasyonunu kullanacaksanız gereklidir.
+*
python-multipart
- Eğer `request.form()` ile form
dönüşümü desteğini kullanacaksanız gereklidir.
*
itsdangerous
- `SessionMiddleware` desteği için gerekli.
*
pyyaml
- `SchemaGenerator` desteği için gerekli (Muhtemelen FastAPI kullanırken ihtiyacınız olmaz).
-*
graphene
- `GraphQLApp` desteği için gerekli.
-*
ujson
- `UJSONResponse` kullanmak istiyorsan gerekli.
Hem FastAPI hem de Starlette tarafından kullanılan:
-*
uvicorn
- oluşturduğumuz uygulamayı bir web sunucusuna servis etmek için gerekli
-*
orjson
- `ORJSONResponse` kullanmak istiyor isen gerekli.
+*
uvicorn
- oluşturduğumuz uygulamayı servis edecek web sunucusu görevini üstlenir.
+*
orjson
- `ORJSONResponse` kullanacaksanız gereklidir.
+*
ujson
- `UJSONResponse` kullanacaksanız gerekli.
Bunların hepsini `pip install fastapi[all]` ile yükleyebilirsin.
## Lisans
-Bu proje, MIT lisansı şartlarına göre lisanslanmıştır.
+Bu proje, MIT lisansı şartları altında lisanslanmıştır.
diff --git a/docs/tr/docs/learn/index.md b/docs/tr/docs/learn/index.md
new file mode 100644
index 000000000..52e3aa54d
--- /dev/null
+++ b/docs/tr/docs/learn/index.md
@@ -0,0 +1,5 @@
+# Öğren
+
+**FastAPI** öğrenmek için giriş bölümleri ve öğreticiler burada yer alıyor.
+
+Burayı, bir **kitap**, bir **kurs**, ve FastAPI öğrenmenin **resmi** ve önerilen yolu olarak düşünülebilirsiniz. 😎
diff --git a/docs/tr/docs/project-generation.md b/docs/tr/docs/project-generation.md
new file mode 100644
index 000000000..c9dc24acc
--- /dev/null
+++ b/docs/tr/docs/project-generation.md
@@ -0,0 +1,84 @@
+# Proje oluşturma - Şablonlar
+
+Başlamak için bir proje oluşturucu kullanabilirsiniz, çünkü sizin için önceden yapılmış birçok başlangıç kurulumu, güvenlik, veritabanı ve temel API endpoinlerini içerir.
+
+Bir proje oluşturucu, her zaman kendi ihtiyaçlarınıza göre güncellemeniz ve uyarlamanız gereken esnek bir kuruluma sahip olacaktır, ancak bu, projeniz için iyi bir başlangıç noktası olabilir.
+
+## Full Stack FastAPI PostgreSQL
+
+GitHub:
https://github.com/tiangolo/full-stack-fastapi-postgresql
+
+### Full Stack FastAPI PostgreSQL - Özellikler
+
+* Full **Docker** entegrasyonu (Docker based).
+* Docker Swarm Mode ile deployment.
+* **Docker Compose** entegrasyonu ve lokal geliştirme için optimizasyon.
+* Uvicorn ve Gunicorn ile **Production ready** Python web server'ı.
+* Python
**FastAPI** backend:
+ * **Hızlı**: **NodeJS** ve **Go** ile eşit, çok yüksek performans (Starlette ve Pydantic'e teşekkürler).
+ * **Sezgisel**: Editor desteğı.
Otomatik tamamlama. Daha az debugging.
+ * **Kolay**: Kolay öğrenip kolay kullanmak için tasarlandı. Daha az döküman okuma daha çok iş.
+ * **Kısa**: Minimum kod tekrarı. Her parametre bildiriminde birden çok özellik.
+ * **Güçlü**: Production-ready. Otomatik interaktif dökümantasyon.
+ * **Standartlara dayalı**: API'ler için açık standartlara dayanır (ve tamamen uyumludur):
OpenAPI ve
JSON Şeması.
+ *
**Birçok diger özelliği** dahili otomatik doğrulama, serialization, interaktif dokümantasyon, OAuth2 JWT token ile authentication, vb.
+* **Güvenli şifreleme** .
+* **JWT token** kimlik doğrulama.
+* **SQLAlchemy** models (Flask dan bağımsızdır. Celery worker'ları ile kullanılabilir).
+* Kullanıcılar için temel başlangıç modeli (gerektiği gibi değiştirin ve kaldırın).
+* **Alembic** migration.
+* **CORS** (Cross Origin Resource Sharing).
+* **Celery** worker'ları ile backend içerisinden seçilen işleri çalıştırabilirsiniz.
+* **Pytest**'e dayalı, Docker ile entegre REST backend testleri ile veritabanından bağımsız olarak tam API etkileşimini test edebilirsiniz. Docker'da çalıştığı için her seferinde sıfırdan yeni bir veri deposu oluşturabilir (böylece ElasticSearch, MongoDB, CouchDB veya ne istersen kullanabilirsin ve sadece API'nin çalışıp çalışmadığını test edebilirsin).
+* Atom Hydrogen veya Visual Studio Code Jupyter gibi uzantılarla uzaktan veya Docker içi geliştirme için **Jupyter Çekirdekleri** ile kolay Python entegrasyonu.
+* **Vue** ile frontend:
+ * Vue CLI ile oluşturulmuş.
+ * Dahili **JWT kimlik doğrulama**.
+ * Dahili Login.
+ * Login sonrası, Kontrol paneli.
+ * Kullanıcı oluşturma ve düzenleme kontrol paneli
+ * Kendi kendine kullanıcı sürümü.
+ * **Vuex**.
+ * **Vue-router**.
+ * **Vuetify** güzel material design kompanentleri için.
+ * **TypeScript**.
+ * **Nginx** tabanlı Docker sunucusu (Vue-router için yapılandırılmış).
+ * Docker ile multi-stage yapı, böylece kodu derlemeniz, kaydetmeniz veya işlemeniz gerekmez.
+ * Derleme zamanında Frontend testi (devre dışı bırakılabilir).
+ * Mümkün olduğu kadar modüler yapılmıştır, bu nedenle kutudan çıktığı gibi çalışır, ancak Vue CLI ile yeniden oluşturabilir veya ihtiyaç duyduğunuz şekilde oluşturabilir ve istediğinizi yeniden kullanabilirsiniz.
+* **PGAdmin** PostgreSQL database admin tool'u, PHPMyAdmin ve MySQL ile kolayca değiştirilebilir.
+* **Flower** ile Celery job'larını monitörleme.
+* **Traefik** ile backend ve frontend arasında yük dengeleme, böylece her ikisini de aynı domain altında, path ile ayrılmış, ancak farklı kapsayıcılar tarafından sunulabilirsiniz.
+* Let's Encrypt **HTTPS** sertifikalarının otomatik oluşturulması dahil olmak üzere Traefik entegrasyonu.
+* GitLab **CI** (sürekli entegrasyon), backend ve frontend testi dahil.
+
+## Full Stack FastAPI Couchbase
+
+GitHub:
https://github.com/tiangolo/full-stack-fastapi-couchbase
+
+⚠️ **UYARI** ⚠️
+
+Sıfırdan bir projeye başlıyorsanız alternatiflerine bakın.
+
+Örneğin,
Full Stack FastAPI PostgreSQL daha iyi bir alternatif olabilir, aktif olarak geliştiriliyor ve kullanılıyor. Ve yeni özellik ve ilerlemelere sahip.
+
+İsterseniz Couchbase tabanlı generator'ı kullanmakta özgürsünüz, hala iyi çalışıyor olmalı ve onunla oluşturulmuş bir projeniz varsa bu da sorun değil (ve muhtemelen zaten ihtiyaçlarınıza göre güncellediniz).
+
+Bununla ilgili daha fazla bilgiyi repo belgelerinde okuyabilirsiniz.
+
+## Full Stack FastAPI MongoDB
+
+... müsaitliğime ve diğer faktörlere bağlı olarak daha sonra gelebilir. 😅 🎉
+
+## Machine Learning modelleri, spaCy ve FastAPI
+
+GitHub:
https://github.com/microsoft/cookiecutter-spacy-fastapi
+
+### Machine Learning modelleri, spaCy ve FastAPI - Features
+
+* **spaCy** NER model entegrasyonu.
+* **Azure Cognitive Search** yerleşik istek biçimi.
+* Uvicorn ve Gunicorn ile **Production ready** Python web server'ı.
+* Dahili **Azure DevOps** Kubernetes (AKS) CI/CD deployment.
+* **Multilingual**, Proje kurulumu sırasında spaCy'nin yerleşik dillerinden birini kolayca seçin.
+* **Esnetilebilir** diğer frameworkler (Pytorch, Tensorflow) ile de çalışır sadece spaCy değil.
diff --git a/docs/tr/docs/python-types.md b/docs/tr/docs/python-types.md
index 3b9ab9050..b44aa3b9d 100644
--- a/docs/tr/docs/python-types.md
+++ b/docs/tr/docs/python-types.md
@@ -12,16 +12,18 @@ Bu pythonda tip belirteçleri için **hızlı bir başlangıç / bilgi tazeleme
**FastAPI** kullanmayacak olsanız bile tür belirteçleri hakkında bilgi edinmenizde fayda var.
-!!! not
- Python uzmanıysanız ve tip belirteçleri ilgili her şeyi zaten biliyorsanız, sonraki bölüme geçin.
+/// note | Not
+
+Python uzmanıysanız ve tip belirteçleri ilgili her şeyi zaten biliyorsanız, sonraki bölüme geçin.
+
+///
## Motivasyon
Basit bir örnek ile başlayalım:
-```Python
-{!../../../docs_src/python_types/tutorial001.py!}
-```
+{* ../../docs_src/python_types/tutorial001.py *}
+
Programın çıktısı:
@@ -35,9 +37,8 @@ Fonksiyon sırayla şunları yapar:
* `title()` ile değişkenlerin ilk karakterlerini büyütür.
* Değişkenleri aralarında bir boşlukla beraber
Birleştirir.
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
-```
+{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+
### Düzenle
@@ -79,9 +80,8 @@ Bu kadar.
İşte bunlar "tip belirteçleri":
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
-```
+{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+
Bu, aşağıdaki gibi varsayılan değerleri bildirmekle aynı şey değildir:
@@ -109,9 +109,8 @@ Aradığınızı bulana kadar seçenekleri kaydırabilirsiniz:
Bu fonksiyon, zaten tür belirteçlerine sahip:
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
-```
+{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+
Editör değişkenlerin tiplerini bildiğinden, yalnızca otomatik tamamlama değil, hata kontrolleri de sağlar:
@@ -119,9 +118,8 @@ Editör değişkenlerin tiplerini bildiğinden, yalnızca otomatik tamamlama de
Artık `age` değişkenini `str(age)` olarak kullanmanız gerektiğini biliyorsunuz:
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
-```
+{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+
## Tip bildirme
@@ -140,9 +138,8 @@ Yalnızca `str` değil, tüm standart Python tiplerinin bildirebilirsiniz.
* `bool`
* `bytes`
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
-```
+{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+
### Tip parametreleri ile Generic tipler
@@ -158,9 +155,8 @@ Bu tür tip belirteçlerini desteklemek için özel olarak mevcuttur.
From `typing`, import `List` (büyük harf olan `L` ile):
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial006.py!}
-```
+{* ../../docs_src/python_types/tutorial006.py hl[1] *}
+
Değişkenin tipini yine iki nokta üstüste (`:`) ile belirleyin.
@@ -168,14 +164,16 @@ tip olarak `List` kullanın.
Liste, bazı dahili tipleri içeren bir tür olduğundan, bunları köşeli parantez içine alırsınız:
-```Python hl_lines="4"
-{!../../../docs_src/python_types/tutorial006.py!}
-```
+{* ../../docs_src/python_types/tutorial006.py hl[4] *}
+
-!!! ipucu
- Köşeli parantez içindeki bu dahili tiplere "tip parametreleri" denir.
+/// tip | Ipucu
- Bu durumda `str`, `List`e iletilen tür parametresidir.
+Köşeli parantez içindeki bu dahili tiplere "tip parametreleri" denir.
+
+Bu durumda `str`, `List`e iletilen tür parametresidir.
+
+///
Bunun anlamı şudur: "`items` değişkeni bir `list`tir ve bu listedeki öğelerin her biri bir `str`dir".
@@ -193,9 +191,8 @@ Ve yine, editör bunun bir `str` olduğunu biliyor ve bunun için destek s
`Tuple` ve `set`lerin tiplerini bildirmek için de aynısını yapıyoruz:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial007.py!}
-```
+{* ../../docs_src/python_types/tutorial007.py hl[1,4] *}
+
Bu şu anlama geliyor:
@@ -210,9 +207,8 @@ Bir `dict` tanımlamak için virgülle ayrılmış iki parametre verebilirsiniz.
İkinci parametre ise `dict` değerinin `value` değeri içindir:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial008.py!}
-```
+{* ../../docs_src/python_types/tutorial008.py hl[1,4] *}
+
Bu şu anlama gelir:
@@ -225,7 +221,7 @@ Bu şu anlama gelir:
`Optional` bir değişkenin `str`gibi bir tipi olabileceğini ama isteğe bağlı olarak tipinin `None` olabileceğini belirtir:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009.py!}
```
`str` yerine `Optional[str]` kullanmak editorün bu değerin her zaman `str` tipinde değil bazen `None` tipinde de olabileceğini belirtir ve hataları tespit etmemizde yardımcı olur.
@@ -249,15 +245,13 @@ Bir değişkenin tipini bir sınıf ile bildirebilirsiniz.
Diyelim ki `name` değerine sahip `Person` sınıfınız var:
-```Python hl_lines="1-3"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+
Sonra bir değişkeni 'Person' tipinde tanımlayabilirsiniz:
-```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+
Ve yine bütün editör desteğini alırsınız:
@@ -265,7 +259,7 @@ Ve yine bütün editör desteğini alırsınız:
## Pydantic modelleri
-
Pydantic veri doğrulaması yapmak için bir Python kütüphanesidir.
+
Pydantic veri doğrulaması yapmak için bir Python kütüphanesidir.
Verilerin "biçimini" niteliklere sahip sınıflar olarak düzenlersiniz.
@@ -277,12 +271,14 @@ Ve ortaya çıkan nesne üzerindeki bütün editör desteğini alırsınız.
Resmi Pydantic dokümanlarından alınmıştır:
-```Python
-{!../../../docs_src/python_types/tutorial011.py!}
-```
+{* ../../docs_src/python_types/tutorial011.py *}
+
-!!! info
- Daha fazla şey öğrenmek için
Pydantic'i takip edin.
+/// info
+
+Daha fazla şey öğrenmek için
Pydantic'i takip edin.
+
+///
**FastAPI** tamamen Pydantic'e dayanmaktadır.
@@ -310,5 +306,8 @@ Bütün bunlar kulağa soyut gelebilir. Merak etme. Tüm bunları çalışırken
Önemli olan, standart Python türlerini tek bir yerde kullanarak (daha fazla sınıf, dekoratör vb. eklemek yerine), **FastAPI**'nin bizim için işi yapmasını sağlamak.
-!!! info
- Tüm öğreticiyi zaten okuduysanız ve türler hakkında daha fazla bilgi için geri döndüyseniz, iyi bir kaynak:
the "cheat sheet" from `mypy`.
+/// info
+
+Tüm öğreticiyi zaten okuduysanız ve türler hakkında daha fazla bilgi için geri döndüyseniz, iyi bir kaynak:
the "cheat sheet" from `mypy`.
+
+///
diff --git a/docs/tr/docs/resources/index.md b/docs/tr/docs/resources/index.md
new file mode 100644
index 000000000..fc71a9ca1
--- /dev/null
+++ b/docs/tr/docs/resources/index.md
@@ -0,0 +1,3 @@
+# Kaynaklar
+
+Ek kaynaklar, dış bağlantılar, makaleler ve daha fazlası. ✈️
diff --git a/docs/tr/docs/tutorial/cookie-params.md b/docs/tr/docs/tutorial/cookie-params.md
new file mode 100644
index 000000000..f07508c2f
--- /dev/null
+++ b/docs/tr/docs/tutorial/cookie-params.md
@@ -0,0 +1,35 @@
+# Çerez (Cookie) Parametreleri
+
+`Query` (Sorgu) ve `Path` (Yol) parametrelerini tanımladığınız şekilde çerez parametreleri tanımlayabilirsiniz.
+
+## Import `Cookie`
+
+Öncelikle, `Cookie`'yi projenize dahil edin:
+
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
+
+## `Cookie` Parametrelerini Tanımlayın
+
+Çerez parametrelerini `Path` veya `Query` tanımlaması yapar gibi tanımlayın.
+
+İlk değer varsayılan değerdir; tüm ekstra doğrulama veya belirteç parametrelerini kullanabilirsiniz:
+
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | Teknik Detaylar
+
+`Cookie` sınıfı `Path` ve `Query` sınıflarının kardeşidir. Diğerleri gibi `Param` sınıfını miras alan bir sınıftır.
+
+Ancak `fastapi`'dan projenize dahil ettiğiniz `Query`, `Path`, `Cookie` ve diğerleri aslında özel sınıflar döndüren birer fonksiyondur.
+
+///
+
+/// info | Bilgi
+
+Çerez tanımlamak için `Cookie` sınıfını kullanmanız gerekmektedir, aksi taktirde parametreler sorgu parametreleri olarak yorumlanır.
+
+///
+
+## Özet
+
+Çerez tanımlamalarını `Cookie` sınıfını kullanarak `Query` ve `Path` tanımlar gibi tanımlayın.
diff --git a/docs/tr/docs/tutorial/first-steps.md b/docs/tr/docs/tutorial/first-steps.md
new file mode 100644
index 000000000..2d2949b50
--- /dev/null
+++ b/docs/tr/docs/tutorial/first-steps.md
@@ -0,0 +1,335 @@
+# İlk Adımlar
+
+En sade FastAPI dosyası şu şekilde görünür:
+
+{* ../../docs_src/first_steps/tutorial001.py *}
+
+Yukarıdaki içeriği bir `main.py` dosyasına kopyalayalım.
+
+Uygulamayı çalıştıralım:
+
+
+
+```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.
+```
+
+
+
+/// note | Not
+
+`uvicorn main:app` komutunu şu şekilde açıklayabiliriz:
+
+* `main`: dosya olan `main.py` (yani Python "modülü").
+* `app`: ise `main.py` dosyasının içerisinde `app = FastAPI()` satırında oluşturduğumuz `FastAPI` nesnesi.
+* `--reload`: kod değişikliklerinin ardından sunucuyu otomatik olarak yeniden başlatır. Bu parameteyi sadece geliştirme aşamasında kullanmalıyız.
+
+///
+
+Çıktı olarak şöyle bir satır ile karşılaşacaksınız:
+
+```hl_lines="4"
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+Bu satır, yerel makinenizde uygulamanızın çalıştığı bağlantıyı gösterir.
+
+### Kontrol Edelim
+
+Tarayıcınızı açıp
http://127.0.0.1:8000 bağlantısına gidin.
+
+Şu şekilde bir JSON yanıtı ile karşılaşacağız:
+
+```JSON
+{"message": "Hello World"}
+```
+
+### Etkileşimli API Dokümantasyonu
+
+Şimdi
http://127.0.0.1:8000/docs bağlantısını açalım.
+
+
Swagger UI tarafından sağlanan otomatik etkileşimli bir API dokümantasyonu göreceğiz:
+
+
+
+### Alternatif API Dokümantasyonu
+
+Şimdi
http://127.0.0.1:8000/redoc bağlantısını açalım.
+
+
ReDoc tarafından sağlanan otomatik dokümantasyonu göreceğiz:
+
+
+
+### OpenAPI
+
+**FastAPI**, **OpenAPI** standardını kullanarak tüm API'ınızın tamamını tanımlayan bir "şema" oluşturur.
+
+#### "Şema"
+
+"Şema", bir şeyin tanımı veya açıklamasıdır. Geliştirilen koddan ziyade soyut bir açıklamadır.
+
+#### API "Şeması"
+
+Bu durumda,
OpenAPI, API şemasını nasıl tanımlayacağınızı belirten bir şartnamedir.
+
+Bu şema tanımı, API yollarınızla birlikte yollarınızın aldığı olası parametreler gibi tanımlamaları içerir.
+
+#### Veri "Şeması"
+
+"Şema" terimi, JSON içeriği gibi bazı verilerin şeklini de ifade edebilir.
+
+Bu durumda, JSON özellikleri ve sahip oldukları veri türleri gibi anlamlarına gelir.
+
+#### OpenAPI ve JSON Şema
+
+OpenAPI, API'niz için bir API şeması tanımlar. Ve bu şema, JSON veri şemaları standardı olan **JSON Şema** kullanılarak API'niz tarafından gönderilen ve alınan verilerin tanımlarını (veya "şemalarını") içerir.
+
+#### `openapi.json` Dosyasına Göz At
+
+Ham OpenAPI şemasının nasıl göründüğünü merak ediyorsanız, FastAPI otomatik olarak tüm API'ınızın tanımlamalarını içeren bir JSON (şeması) oluşturur.
+
+Bu şemayı direkt olarak
http://127.0.0.1:8000/openapi.json bağlantısından görüntüleyebilirsiniz.
+
+Aşağıdaki gibi başlayan bir JSON ile karşılaşacaksınız:
+
+```JSON
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+
+
+
+...
+```
+
+#### OpenAPI Ne İşe Yarar?
+
+OpenAPI şeması, FastAPI projesinde bulunan iki etkileşimli dokümantasyon sistemine güç veren şeydir.
+
+OpenAPI'ya dayalı düzinelerce alternatif etkileşimli dokümantasyon aracı mevcuttur. **FastAPI** ile oluşturulmuş uygulamanıza bu alternatiflerden herhangi birini kolayca ekleyebilirsiniz.
+
+Ayrıca, API'ınızla iletişim kuracak önyüz, mobil veya IoT uygulamaları gibi istemciler için otomatik olarak kod oluşturabilirsiniz.
+
+## Adım Adım Özetleyelim
+
+### Adım 1: `FastAPI`yı Projemize Dahil Edelim
+
+{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+
+`FastAPI`, API'niz için tüm işlevselliği sağlayan bir Python sınıfıdır.
+
+/// note | Teknik Detaylar
+
+`FastAPI` doğrudan `Starlette`'i miras alan bir sınıftır.
+
+
Starlette'in tüm işlevselliğini `FastAPI` ile de kullanabilirsiniz.
+
+///
+
+### Adım 2: Bir `FastAPI` "Örneği" Oluşturalım
+
+{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+
+Burada `app` değişkeni `FastAPI` sınıfının bir örneği olacaktır.
+
+Bu, tüm API'yı oluşturmak için ana etkileşim noktası olacaktır.
+
+Bu `app` değişkeni, `uvicorn` komutunda atıfta bulunulan değişkenin ta kendisidir.
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Uygulamanızı aşağıdaki gibi oluşturursanız:
+
+{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
+
+Ve bunu `main.py` dosyasına yerleştirirseniz eğer `uvicorn` komutunu şu şekilde çalıştırabilirsiniz:
+
+
+
+```console
+$ uvicorn main:my_awesome_api --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### Adım 3: Bir *Yol Operasyonu* Oluşturalım
+
+####
Yol
+
+Burada "yol" bağlantıda bulunan ilk `/` ile başlayan ve sonrasında gelen kısmı ifade eder.
+
+Yani, şu şekilde bir bağlantıda:
+
+```
+https://example.com/items/foo
+```
+
+... yol şöyle olur:
+
+```
+/items/foo
+```
+
+/// info | Bilgi
+
+"Yol" genellikle "
endpoint" veya "
route" olarak adlandırılır.
+
+///
+
+Bir API oluştururken, "yol", "kaynaklar" ile "endişeleri" ayırmanın ana yöntemidir.
+
+#### Operasyonlar
+
+Burada "operasyon" HTTP "metodlarından" birini ifade eder.
+
+Bunlardan biri:
+
+* `POST`
+* `GET`
+* `PUT`
+* `DELETE`
+
+...veya daha az kullanılan diğerleri:
+
+* `OPTIONS`
+* `HEAD`
+* `PATCH`
+* `TRACE`
+
+HTTP protokolünde, bu "metodlardan" birini (veya daha fazlasını) kullanarak her bir yol ile iletişim kurabilirsiniz.
+
+---
+
+API oluştururkan, belirli bir amaca hizmet eden belirli HTTP metodlarını kullanırsınız.
+
+Normalde kullanılan:
+
+* `POST`: veri oluşturmak.
+* `GET`: veri okumak.
+* `PUT`: veriyi güncellemek.
+* `DELETE`: veriyi silmek.
+
+Bu nedenle, OpenAPI'da HTTP metodlarından her birine "operasyon" denir.
+
+Biz de onları "**operasyonlar**" olarak adlandıracağız.
+
+#### Bir *Yol Operasyonu Dekoratörü* Tanımlayalım
+
+{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+
+`@app.get("/")` dekoratörü, **FastAPI**'a hemen altındaki fonksiyonun aşağıdaki durumlardan sorumlu olduğunu söyler:
+
+*
get
operasyonu ile
+* `/` yoluna gelen istekler
+
+/// info | `@decorator` Bilgisi
+
+Python'da `@something` sözdizimi "
dekoratör" olarak adlandırılır.
+
+Dekoratörler, dekoratif bir şapka gibi (sanırım terim buradan geliyor) fonksiyonların üzerlerine yerleştirilirler.
+
+Bir "dekoratör" hemen altında bulunan fonksiyonu alır ve o fonksiyon ile bazı işlemler gerçekleştirir.
+
+Bizim durumumuzda, kullandığımız dekoratör, **FastAPI**'a altındaki fonksiyonun `/` yoluna gelen `get` metodlu isteklerden sorumlu olduğunu söyler.
+
+Bu bir **yol operasyonu dekoratörüdür**.
+
+///
+
+Ayrıca diğer operasyonları da kullanabilirsiniz:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+Daha az kullanılanları da kullanabilirsiniz:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+/// tip | İpucu
+
+Her işlemi (HTTP metod) istediğiniz gibi kullanmakta özgürsünüz.
+
+**FastAPI** herhangi bir özel amacı veya anlamı olması konusunda ısrarcı olmaz.
+
+Buradaki bilgiler bir gereklilik değil, bir kılavuz olarak sunulmaktadır.
+
+Mesela GraphQL kullanırkan genelde tüm işlemleri yalnızca `POST` operasyonunu kullanarak gerçekleştirirsiniz.
+
+///
+
+### Adım 4: **Yol Operasyonu Fonksiyonunu** Tanımlayın
+
+Aşağıdaki, bizim **yol operasyonu fonksiyonumuzdur**:
+
+* **yol**: `/`
+* **operasyon**: `get`
+* **fonksiyon**: "dekoratör"ün (`@app.get("/")`'in) altındaki fonksiyondur.
+
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+
+Bu bir Python fonksiyonudur.
+
+Bu fonksiyon bir `GET` işlemi kullanılarak "`/`" bağlantısına bir istek geldiğinde **FastAPI** tarafından çağrılır.
+
+Bu durumda bu fonksiyon bir `async` fonksiyondur.
+
+---
+
+Bu fonksiyonu `async def` yerine normal bir fonksiyon olarak da tanımlayabilirsiniz.
+
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+
+/// note | Not
+
+Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} sayfasını kontrol edebilirsiniz.
+
+///
+
+### Adım 5: İçeriği Geri Döndürün
+
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+
+Bir `dict`, `list` veya `str`, `int` gibi tekil değerler döndürebilirsiniz.
+
+Ayrıca, Pydantic modelleri de döndürebilirsiniz (bu konu ileriki aşamalarda irdelenecektir).
+
+Otomatik olarak JSON'a dönüştürülecek (ORM'ler vb. dahil) başka birçok nesne ve model vardır. En beğendiklerinizi kullanmayı deneyin, yüksek ihtimalle destekleniyordur.
+
+## Özet
+
+* `FastAPI`'yı projemize dahil ettik.
+* Bir `app` örneği oluşturduk.
+* Bir **yol operasyonu dekoratörü** (`@app.get("/")` gibi) yazdık.
+* Bir **yol operasyonu fonksiyonu** (`def root(): ...` gibi) yazdık.
+* Geliştirme sunucumuzu (`uvicorn main:app --reload` gibi) çalıştırdık.
diff --git a/docs/tr/docs/tutorial/path-params.md b/docs/tr/docs/tutorial/path-params.md
new file mode 100644
index 000000000..e1707a5d9
--- /dev/null
+++ b/docs/tr/docs/tutorial/path-params.md
@@ -0,0 +1,258 @@
+# Yol Parametreleri
+
+Yol "parametrelerini" veya "değişkenlerini" Python
string biçimlemede kullanılan sözdizimi ile tanımlayabilirsiniz.
+
+{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+
+Yol parametresi olan `item_id`'nin değeri, fonksiyonunuza `item_id` argümanı olarak aktarılacaktır.
+
+Eğer bu örneği çalıştırıp
http://127.0.0.1:8000/items/foo sayfasına giderseniz, şöyle bir çıktı ile karşılaşırsınız:
+
+```JSON
+{"item_id":"foo"}
+```
+
+## Tip İçeren Yol Parametreleri
+
+Standart Python tip belirteçlerini kullanarak yol parametresinin tipini fonksiyonun içerisinde tanımlayabilirsiniz.
+
+{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+
+Bu durumda, `item_id` bir `int` olarak tanımlanacaktır.
+
+/// check | Ek bilgi
+
+Bu sayede, fonksiyon içerisinde hata denetimi, kod tamamlama gibi konularda editör desteğine kavuşacaksınız.
+
+///
+
+## Veri
Dönüşümü
+
+Eğer bu örneği çalıştırıp tarayıcınızda
http://127.0.0.1:8000/items/3 sayfasını açarsanız, şöyle bir yanıt ile karşılaşırsınız:
+
+```JSON
+{"item_id":3}
+```
+
+/// check | Ek bilgi
+
+Dikkatinizi çekerim ki, fonksiyonunuzun aldığı (ve döndürdüğü) değer olan `3` bir string `"3"` değil aksine bir Python `int`'idir.
+
+Bu tanımlamayla birlikte, **FastAPI** size otomatik istek
"ayrıştırma" özelliği sağlar.
+
+///
+
+## Veri Doğrulama
+
+Eğer tarayıcınızda
http://127.0.0.1:8000/items/foo sayfasını açarsanız, şuna benzer güzel bir HTTP hatası ile karşılaşırsınız:
+
+```JSON
+{
+ "detail": [
+ {
+ "type": "int_parsing",
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "Input should be a valid integer, unable to parse string as an integer",
+ "input": "foo",
+ "url": "https://errors.pydantic.dev/2.1/v/int_parsing"
+ }
+ ]
+}
+```
+
+Çünkü burada `item_id` yol parametresi `int` tipinde bir değer beklerken `"foo"` yani `string` tipinde bir değer almıştı.
+
+Aynı hata
http://127.0.0.1:8000/items/4.2 sayfasında olduğu gibi `int` yerine `float` bir değer verseydik de ortaya çıkardı.
+
+/// check | Ek bilgi
+
+Böylece, aynı Python tip tanımlaması ile birlikte, **FastAPI** veri doğrulama özelliği sağlar.
+
+Dikkatinizi çekerim ki, karşılaştığınız hata, doğrulamanın geçersiz olduğu mutlak noktayı da açık bir şekilde belirtiyor.
+
+Bu özellik, API'ınızla iletişime geçen kodu geliştirirken ve ayıklarken inanılmaz derecede yararlı olacaktır.
+
+///
+
+## Dokümantasyon
+
+Ayrıca, tarayıcınızı
http://127.0.0.1:8000/docs adresinde açarsanız, aşağıdaki gibi otomatik ve interaktif bir API dökümantasyonu ile karşılaşırsınız:
+
+

+
+/// check | Ek bilgi
+
+Üstelik, sadece aynı Python tip tanımlaması ile, **FastAPI** size otomatik ve interaktif (Swagger UI ile entegre) bir dokümantasyon sağlar.
+
+Dikkatinizi çekerim ki, yol parametresi integer olarak tanımlanmıştır.
+
+///
+
+## Standartlara Dayalı Avantajlar, Alternatif Dokümantasyon
+
+Oluşturulan şema
OpenAPI standardına uygun olduğu için birçok uyumlu araç mevcuttur.
+
+Bu sayede, **FastAPI**'ın bizzat kendisi
http://127.0.0.1:8000/redoc sayfasından erişebileceğiniz alternatif (ReDoc kullanan) bir API dokümantasyonu sağlar:
+
+

+
+Aynı şekilde, farklı diller için kod türetme araçları da dahil olmak üzere çok sayıda uyumlu araç bulunur.
+
+## Pydantic
+
+Tüm veri doğrulamaları
Pydantic tarafından arka planda gerçekleştirilir, bu sayede tüm avantajlardan faydalanabilirsiniz. Böylece, emin ellerde olduğunuzu hissedebilirsiniz.
+
+Aynı tip tanımlamalarını `str`, `float`, `bool` ve diğer karmaşık veri tipleri ile kullanma imkanınız vardır.
+
+Bunlardan birkaçı, bu eğitimin ileriki bölümlerinde irdelenmiştir.
+
+## Sıralama Önem Arz Eder
+
+*Yol operasyonları* tasarlarken sabit yol barındıran durumlar ile karşılaşabilirsiniz.
+
+Farz edelim ki `/users/me` yolu geçerli kullanıcı hakkında bilgi almak için kullanılıyor olsun.
+
+Benzer şekilde `/users/{user_id}` gibi tanımlanmış ve belirli bir kullanıcı hakkında veri almak için kullanıcının ID bilgisini kullanan bir yolunuz da mevcut olabilir.
+
+*Yol operasyonları* sıralı bir şekilde gözden geçirildiğinden dolayı `/users/me` yolunun `/users/{user_id}` yolundan önce tanımlanmış olmasından emin olmanız gerekmektedir:
+
+{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+
+Aksi halde, `/users/{user_id}` yolu `"me"` değerinin `user_id` parametresi için gönderildiğini "düşünerek" `/users/me` ile de eşleşir.
+
+Benzer şekilde, bir yol operasyonunu yeniden tanımlamanız mümkün değildir:
+
+{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+
+Yol, ilk kısım ile eşleştiğinden dolayı her koşulda ilk yol operasyonu kullanılacaktır.
+
+## Ön Tanımlı Değerler
+
+Eğer *yol parametresi* alan bir *yol operasyonunuz* varsa ve alabileceği *yol parametresi* değerlerinin ön tanımlı olmasını istiyorsanız, standart Python
`Enum` tipini kullanabilirsiniz.
+
+### Bir `Enum` Sınıfı Oluşturalım
+
+`Enum` sınıfını projemize dahil edip `str` ile `Enum` sınıflarını miras alan bir alt sınıf yaratalım.
+
+`str` sınıfı miras alındığından dolayı, API dokümanı, değerlerin `string` tipinde olması gerektiğini anlayabilecek ve doğru bir şekilde işlenecektir.
+
+Sonrasında, sınıf içerisinde, mevcut ve geçerli değerler olacak olan sabit değerli özelliklerini oluşturalım:
+
+{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
+
+/// info | Bilgi
+
+3.4 sürümünden beri
enumerationlar (ya da enumlar) Python'da mevcuttur.
+
+///
+
+/// tip | İpucu
+
+Merak ediyorsanız söyleyeyim, "AlexNet", "ResNet" ve "LeNet" isimleri Makine Öğrenmesi
modellerini temsil eder.
+
+///
+
+### Bir *Yol Parametresi* Tanımlayalım
+
+Sonrasında, yarattığımız enum sınıfını (`ModelName`) kullanarak tip belirteci aracılığıyla bir *yol parametresi* oluşturalım:
+
+{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+
+### Dokümana Göz Atalım
+
+*Yol parametresi* için mevcut değerler ön tanımlı olduğundan dolayı, interaktif döküman onları güzel bir şekilde gösterebilir:
+
+

+
+### Python *Enumerationları* ile Çalışmak
+
+*Yol parametresinin* değeri bir *enumeration üyesi* olacaktır.
+
+#### *Enumeration Üyelerini* Karşılaştıralım
+
+Parametreyi, yarattığınız enum olan `ModelName` içerisindeki *enumeration üyesi* ile karşılaştırabilirsiniz:
+
+{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+
+#### *Enumeration Değerini* Edinelim
+
+`model_name.value` veya genel olarak `your_enum_member.value` tanımlarını kullanarak (bu durumda bir `str` olan) gerçek değere ulaşabilirsiniz:
+
+{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+
+/// tip | İpucu
+
+`"lenet"` değerine `ModelName.lenet.value` tanımı ile de ulaşabilirsiniz.
+
+///
+
+#### *Enumeration Üyelerini* Döndürelim
+
+JSON gövdesine (örneğin bir `dict`) gömülü olsalar bile *yol operasyonundaki* *enum üyelerini* döndürebilirsiniz.
+
+Bu üyeler istemciye iletilmeden önce kendilerine karşılık gelen değerlerine (bu durumda string) dönüştürüleceklerdir:
+
+{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+
+İstemci tarafında şuna benzer bir JSON yanıtı ile karşılaşırsınız:
+
+```JSON
+{
+ "model_name": "alexnet",
+ "message": "Deep Learning FTW!"
+}
+```
+
+## Yol İçeren Yol Parametreleri
+
+Farz edelim ki elinizde `/files/{file_path}` isminde bir *yol operasyonu* var.
+
+Fakat `file_path` değerinin `home/johndoe/myfile.txt` gibi bir *yol* barındırmasını istiyorsunuz.
+
+Sonuç olarak, oluşturmak istediğin URL `/files/home/johndoe/myfile.txt` gibi bir şey olacaktır.
+
+### OpenAPI Desteği
+
+Test etmesi ve tanımlaması zor senaryolara sebebiyet vereceğinden dolayı OpenAPI, *yol* barındıran *yol parametrelerini* tanımlayacak bir çözüm sunmuyor.
+
+Ancak bunu, Starlette kütüphanesinin dahili araçlarından birini kullanarak **FastAPI**'da gerçekleştirebilirsiniz.
+
+Parametrenin bir yol içermesi gerektiğini belirten herhangi bir doküman eklemememize rağmen dokümanlar yine de çalışacaktır.
+
+### Yol Dönüştürücü
+
+Direkt olarak Starlette kütüphanesinden gelen bir opsiyon sayesinde aşağıdaki gibi *yol* içeren bir *yol parametresi* bağlantısı tanımlayabilirsiniz:
+
+```
+/files/{file_path:path}
+```
+
+Bu durumda, parametrenin adı `file_path` olacaktır ve son kısım olan `:path` kısmı, parametrenin herhangi bir *yol* ile eşleşmesi gerektiğini belirtecektir.
+
+Böylece şunun gibi bir kullanım yapabilirsiniz:
+
+{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+
+/// tip | İpucu
+
+Parametrenin başında `/home/johndoe/myfile.txt` yolunda olduğu gibi (`/`) işareti ile birlikte kullanmanız gerektiği durumlar olabilir.
+
+Bu durumda, URL, `files` ile `home` arasında iki eğik çizgiye (`//`) sahip olup `/files//home/johndoe/myfile.txt` gibi gözükecektir.
+
+///
+
+## Özet
+
+**FastAPI** ile kısa, sezgisel ve standart Python tip tanımlamaları kullanarak şunları elde edersiniz:
+
+* Editör desteği: hata denetimi, otomatik tamamlama, vb.
+* Veri "
dönüştürme"
+* Veri doğrulama
+* API tanımlamaları ve otomatik dokümantasyon
+
+Ve sadece, bunları bir kez tanımlamanız yeterli.
+
+Diğer frameworkler ile karşılaştırıldığında (ham performans dışında), üstte anlatılan durum muhtemelen **FastAPI**'ın göze çarpan başlıca avantajıdır.
diff --git a/docs/tr/docs/tutorial/query-params.md b/docs/tr/docs/tutorial/query-params.md
new file mode 100644
index 000000000..4aa0a82b1
--- /dev/null
+++ b/docs/tr/docs/tutorial/query-params.md
@@ -0,0 +1,189 @@
+# Sorgu Parametreleri
+
+Fonksiyonda yol parametrelerinin parçası olmayan diğer tanımlamalar otomatik olarak "sorgu" parametresi olarak yorumlanır.
+
+{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+
+Sorgu, bağlantıdaki `?` kısmından sonra gelen ve `&` işareti ile ayrılan anahtar-değer çiftlerinin oluşturduğu bir kümedir.
+
+Örneğin, aşağıdaki bağlantıda:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+...sorgu parametreleri şunlardır:
+
+* `skip`: değeri `0`'dır
+* `limit`: değeri `10`'dır
+
+Parametreler bağlantının bir parçası oldukları için doğal olarak string olarak değerlendirilirler.
+
+Fakat, Python tipleri ile tanımlandıkları zaman (yukarıdaki örnekte `int` oldukları gibi), parametreler o tiplere dönüştürülür ve o tipler çerçevesinde doğrulanırlar.
+
+Yol parametreleri için geçerli olan her türlü işlem aynı şekilde sorgu parametreleri için de geçerlidir:
+
+* Editör desteği (şüphesiz)
+* Veri "
ayrıştırma"
+* Veri doğrulama
+* Otomatik dokümantasyon
+
+## Varsayılanlar
+
+Sorgu parametreleri, adres yolunun sabit bir parçası olmadıklarından dolayı isteğe bağlı ve varsayılan değere sahip olabilirler.
+
+Yukarıdaki örnekte `skip=0` ve `limit=10` varsayılan değere sahiplerdir.
+
+Yani, aşağıdaki bağlantıya gitmek:
+
+```
+http://127.0.0.1:8000/items/
+```
+
+şu adrese gitmek ile aynı etkiye sahiptir:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+Ancak, mesela şöyle bir adresi ziyaret ederseniz:
+
+```
+http://127.0.0.1:8000/items/?skip=20
+```
+
+Fonksiyonunuzdaki parametre değerleri aşağıdaki gibi olacaktır:
+
+* `skip=20`: çünkü bağlantıda böyle tanımlandı.
+* `limit=10`: çünkü varsayılan değer buydu.
+
+## İsteğe Bağlı Parametreler
+
+Aynı şekilde, varsayılan değerlerini `None` olarak atayarak isteğe bağlı parametreler tanımlayabilirsiniz:
+
+{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
+
+Bu durumda, `q` fonksiyon parametresi isteğe bağlı olacak ve varsayılan değer olarak `None` alacaktır.
+
+/// check | Ek bilgi
+
+Ayrıca, dikkatinizi çekerim ki; **FastAPI**, `item_id` parametresinin bir yol parametresi olduğunu ve `q` parametresinin yol değil bir sorgu parametresi olduğunu fark edecek kadar beceriklidir.
+
+///
+
+## Sorgu Parametresi Tip Dönüşümü
+
+Aşağıda görüldüğü gibi dönüştürülmek üzere `bool` tipleri de tanımlayabilirsiniz:
+
+{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
+
+Bu durumda, eğer şu adrese giderseniz:
+
+```
+http://127.0.0.1:8000/items/foo?short=1
+```
+
+veya
+
+```
+http://127.0.0.1:8000/items/foo?short=True
+```
+
+veya
+
+```
+http://127.0.0.1:8000/items/foo?short=true
+```
+
+veya
+
+```
+http://127.0.0.1:8000/items/foo?short=on
+```
+
+veya
+
+```
+http://127.0.0.1:8000/items/foo?short=yes
+```
+
+veya adres, herhangi farklı bir harf varyasyonu içermesi durumuna rağmen (büyük harf, sadece baş harfi büyük kelime, vb.) fonksiyonunuz, `bool` tipli `short` parametresini `True` olarak algılayacaktır. Aksi halde `False` olarak algılanacaktır.
+
+
+## Çoklu Yol ve Sorgu Parametreleri
+
+**FastAPI** neyin ne olduğunu ayırt edebileceğinden dolayı aynı anda birden fazla yol ve sorgu parametresi tanımlayabilirsiniz.
+
+Ve parametreleri, herhangi bir sıraya koymanıza da gerek yoktur.
+
+İsimlerine göre belirleneceklerdir:
+
+{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
+
+## Zorunlu Sorgu Parametreleri
+
+Türü yol olmayan bir parametre (şu ana kadar sadece sorgu parametrelerini gördük) için varsayılan değer tanımlarsanız o parametre zorunlu olmayacaktır.
+
+Parametre için belirli bir değer atamak istemeyip parametrenin sadece isteğe bağlı olmasını istiyorsanız değerini `None` olarak atayabilirsiniz.
+
+Fakat, bir sorgu parametresini zorunlu yapmak istiyorsanız varsayılan bir değer atamamanız yeterli olacaktır:
+
+{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+
+Burada `needy` parametresi `str` tipinden oluşan zorunlu bir sorgu parametresidir.
+
+Eğer tarayıcınızda şu bağlantıyı:
+
+```
+http://127.0.0.1:8000/items/foo-item
+```
+
+...`needy` parametresini eklemeden açarsanız şuna benzer bir hata ile karşılaşırsınız:
+
+```JSON
+{
+ "detail": [
+ {
+ "type": "missing",
+ "loc": [
+ "query",
+ "needy"
+ ],
+ "msg": "Field required",
+ "input": null,
+ "url": "https://errors.pydantic.dev/2.1/v/missing"
+ }
+ ]
+}
+```
+
+`needy` zorunlu bir parametre olduğundan dolayı bağlantıda tanımlanması gerekir:
+
+```
+http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
+```
+
+...bu iş görür:
+
+```JSON
+{
+ "item_id": "foo-item",
+ "needy": "sooooneedy"
+}
+```
+
+Ve elbette, bazı parametreleri zorunlu, bazılarını varsayılan değerli ve bazılarını tamamen opsiyonel olarak tanımlayabilirsiniz:
+
+{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
+
+Bu durumda, 3 tane sorgu parametresi var olacaktır:
+
+* `needy`, zorunlu bir `str`.
+* `skip`, varsayılan değeri `0` olan bir `int`.
+* `limit`, isteğe bağlı bir `int`.
+
+/// tip | İpucu
+
+Ayrıca, [Yol Parametrelerinde](path-params.md#on-tanml-degerler){.internal-link target=_blank} de kullanıldığı şekilde `Enum` sınıfından faydalanabilirsiniz.
+
+///
diff --git a/docs/tr/docs/tutorial/request-forms.md b/docs/tr/docs/tutorial/request-forms.md
new file mode 100644
index 000000000..e4e04f5f9
--- /dev/null
+++ b/docs/tr/docs/tutorial/request-forms.md
@@ -0,0 +1,69 @@
+# Form Verisi
+
+İstek gövdesinde JSON verisi yerine form alanlarını karşılamanız gerketiğinde `Form` sınıfını kullanabilirsiniz.
+
+/// info | Bilgi
+
+Formları kullanmak için öncelikle
`python-multipart` paketini indirmeniz gerekmektedir.
+
+Örneğin `pip install python-multipart`.
+
+///
+
+## `Form` Sınıfını Projenize Dahil Edin
+
+`Form` sınıfını `fastapi`'den projenize dahil edin:
+
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
+
+## `Form` Parametrelerini Tanımlayın
+
+Form parametrelerini `Body` veya `Query` için yaptığınız gibi oluşturun:
+
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
+
+Örneğin, OAuth2 spesifikasyonunun kullanılabileceği ("şifre akışı" olarak adlandırılan) yollardan birinde, form alanları olarak
"username" ve
"password" gönderilmesi gerekir.
+
+Bu
spesifikasyon form alanlarını adlandırırken isimlerinin birebir `username` ve `password` olmasını ve JSON verisi yerine form verisi olarak gönderilmesini gerektirir.
+
+`Form` sınıfıyla tanımlama yaparken `Body`, `Query`, `Path` ve `Cookie` sınıflarında kullandığınız aynı validasyon, örnekler, isimlendirme (örneğin `username` yerine `user-name` kullanımı) ve daha fazla konfigurasyonu kullanabilirsiniz.
+
+/// info | Bilgi
+
+`Form` doğrudan `Body` sınıfını miras alan bir sınıftır.
+
+///
+
+/// tip | İpucu
+
+Form gövdelerini tanımlamak için `Form` sınıfını kullanmanız gerekir; çünkü bu olmadan parametreler sorgu parametreleri veya gövde (JSON) parametreleri olarak yorumlanır.
+
+///
+
+## "Form Alanları" Hakkında
+
+HTML formlarının (`
`) verileri sunucuya gönderirken JSON'dan farklı özel bir kodlama kullanır.
+
+**FastAPI** bu verilerin JSON yerine doğru şekilde okunmasını sağlayacaktır.
+
+/// note | Teknik Detaylar
+
+Form verileri normalde `application/x-www-form-urlencoded` medya tipiyle kodlanır.
+
+Ancak form içerisinde dosyalar yer aldığında `multipart/form-data` olarak kodlanır. Bir sonraki bölümde dosyaların işlenmesi hakkında bilgi edineceksiniz.
+
+Form kodlama türleri ve form alanları hakkında daha fazla bilgi edinmek istiyorsanız
MDN web docs for POST
sayfasını ziyaret edebilirsiniz.
+
+///
+
+/// warning | Uyarı
+
+*Yol operasyonları* içerisinde birden fazla `Form` parametresi tanımlayabilirsiniz ancak bunlarla birlikte JSON verisi kabul eden `Body` alanları tanımlayamazsınız çünkü bu durumda istek gövdesi `application/json` yerine `application/x-www-form-urlencoded` ile kodlanmış olur.
+
+Bu **FastAPI**'ın getirdiği bir kısıtlama değildir, HTTP protokolünün bir parçasıdır.
+
+///
+
+## Özet
+
+Form verisi girdi parametreleri tanımlamak için `Form` sınıfını kullanın.
diff --git a/docs/tr/docs/tutorial/static-files.md b/docs/tr/docs/tutorial/static-files.md
new file mode 100644
index 000000000..db30f13bc
--- /dev/null
+++ b/docs/tr/docs/tutorial/static-files.md
@@ -0,0 +1,40 @@
+# Statik Dosyalar
+
+`StaticFiles`'ı kullanarak statik dosyaları bir yol altında sunabilirsiniz.
+
+## `StaticFiles` Kullanımı
+
+* `StaticFiles` sınıfını projenize dahil edin.
+* Bir `StaticFiles()` örneğini belirli bir yola bağlayın.
+
+{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+
+/// note | Teknik Detaylar
+
+Projenize dahil etmek için `from starlette.staticfiles import StaticFiles` kullanabilirsiniz.
+
+**FastAPI**, geliştiricilere kolaylık sağlamak amacıyla `starlette.staticfiles`'ı `fastapi.staticfiles` olarak sağlar. Ancak `StaticFiles` sınıfı aslında doğrudan Starlette'den gelir.
+
+///
+
+### Bağlama (Mounting) Nedir?
+
+"Bağlamak", belirli bir yola tamamen "bağımsız" bir uygulama eklemek anlamına gelir ve ardından tüm alt yollara gelen istekler bu uygulama tarafından işlenir.
+
+Bu, bir `APIRouter` kullanmaktan farklıdır çünkü bağlanmış bir uygulama tamamen bağımsızdır. Ana uygulamanızın OpenAPI ve dokümanlar, bağlanmış uygulamadan hiçbir şey içermez, vb.
+
+[Advanced User Guide](../advanced/index.md){.internal-link target=_blank} bölümünde daha fazla bilgi edinebilirsiniz.
+
+## Detaylar
+
+`"/static"` ifadesi, bu "alt uygulamanın" "bağlanacağı" alt yolu belirtir. Bu nedenle, `"/static"` ile başlayan her yol, bu uygulama tarafından işlenir.
+
+`directory="static"` ifadesi, statik dosyalarınızı içeren dizinin adını belirtir.
+
+`name="static"` ifadesi, alt uygulamanın **FastAPI** tarafından kullanılacak ismini belirtir.
+
+Bu parametrelerin hepsi "`static`"den farklı olabilir, bunları kendi uygulamanızın ihtiyaçlarına göre belirleyebilirsiniz.
+
+## Daha Fazla Bilgi
+
+Daha fazla detay ve seçenek için
Starlette'in Statik Dosyalar hakkındaki dokümantasyonunu incelleyin.
diff --git a/docs/tr/mkdocs.yml b/docs/tr/mkdocs.yml
index e29d25936..de18856f4 100644
--- a/docs/tr/mkdocs.yml
+++ b/docs/tr/mkdocs.yml
@@ -1,148 +1 @@
-site_name: FastAPI
-site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
-site_url: https://fastapi.tiangolo.com/tr/
-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: tr
-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/
- - es: /es/
- - fa: /fa/
- - fr: /fr/
- - he: /he/
- - id: /id/
- - it: /it/
- - ja: /ja/
- - ko: /ko/
- - nl: /nl/
- - pl: /pl/
- - pt: /pt/
- - ru: /ru/
- - sq: /sq/
- - sv: /sv/
- - tr: /tr/
- - uk: /uk/
- - zh: /zh/
-- features.md
-- fastapi-people.md
-- python-types.md
-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: UA-133183413-1
- 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: /es/
- name: es - español
- - link: /fa/
- name: fa
- - link: /fr/
- name: fr - français
- - link: /he/
- name: he
- - link: /id/
- name: id
- - link: /it/
- name: it - italiano
- - link: /ja/
- name: ja - 日本語
- - link: /ko/
- name: ko - 한국어
- - 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: /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
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/tr/overrides/.gitignore b/docs/tr/overrides/.gitignore
deleted file mode 100644
index e69de29bb..000000000
diff --git a/docs/uk/docs/alternatives.md b/docs/uk/docs/alternatives.md
new file mode 100644
index 000000000..1acbe237a
--- /dev/null
+++ b/docs/uk/docs/alternatives.md
@@ -0,0 +1,483 @@
+# Альтернативи, натхнення та порівняння
+
+Що надихнуло на створення **FastAPI**, який він у порінянні з іншими альтернативами та чого він у них навчився.
+
+## Вступ
+
+**FastAPI** не існувало б, якби не попередні роботи інших.
+
+Раніше було створено багато інструментів, які надихнули на його створення.
+
+Я кілька років уникав створення нового фреймворку. Спочатку я спробував вирішити всі функції, охоплені **FastAPI**, використовуючи багато різних фреймворків, плагінів та інструментів.
+
+Але в якийсь момент не було іншого виходу, окрім створення чогось, що надавало б усі ці функції, взявши найкращі ідеї з попередніх інструментів і поєднавши їх найкращим чином, використовуючи мовні функції, які навіть не були доступні раніше (Python 3.6+ підказки типів).
+
+## Попередні інструменти
+
+###
Django
+
+Це найпопулярніший фреймворк Python, який користується широкою довірою. Він використовується для створення таких систем, як Instagram.
+
+Він відносно тісно пов’язаний з реляційними базами даних (наприклад, MySQL або PostgreSQL), тому мати базу даних NoSQL (наприклад, Couchbase, MongoDB, Cassandra тощо) як основний механізм зберігання не дуже просто.
+
+Він був створений для створення HTML у серверній частині, а не для створення API, які використовуються сучасним інтерфейсом (як-от React, Vue.js і Angular) або іншими системами (як-от
IoT пристрої), які спілкуються з ним.
+
+###
Django REST Framework
+
+Фреймворк Django REST був створений як гнучкий інструментарій для створення веб-інтерфейсів API використовуючи Django в основі, щоб покращити його можливості API.
+
+Його використовують багато компаній, включаючи Mozilla, Red Hat і Eventbrite.
+
+Це був один із перших прикладів **автоматичної документації API**, і саме це була одна з перших ідей, яка надихнула на «пошук» **FastAPI**.
+
+/// note | Примітка
+
+Django REST Framework створив Том Крісті. Той самий творець Starlette і Uvicorn, на яких базується **FastAPI**.
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Мати автоматичний веб-інтерфейс документації API.
+
+///
+
+###
Flask
+
+Flask — це «мікрофреймворк», він не включає інтеграцію бази даних, а також багато речей, які за замовчуванням є в Django.
+
+Ця простота та гнучкість дозволяють використовувати бази даних NoSQL як основну систему зберігання даних.
+
+Оскільки він дуже простий, він порівняно легкий та інтуїтивний для освоєння, хоча в деяких моментах документація стає дещо технічною.
+
+Він також зазвичай використовується для інших програм, яким не обов’язково потрібна база даних, керування користувачами або будь-яка з багатьох функцій, які є попередньо вбудованими в Django. Хоча багато з цих функцій можна додати за допомогою плагінів.
+
+Відокремлення частин було ключовою особливістю, яку я хотів зберегти, при цьому залишаючись «мікрофреймворком», який можна розширити, щоб охопити саме те, що потрібно.
+
+Враховуючи простоту Flask, він здавався хорошим підходом для створення API. Наступним, що знайшов, був «Django REST Framework» для Flask.
+
+/// check | Надихнуло **FastAPI** на
+
+Бути мікрофреймоворком. Зробити легким комбінування та поєднання необхідних інструментів та частин.
+
+ Мати просту та легку у використанні систему маршрутизації.
+
+///
+
+###
Requests
+
+**FastAPI** насправді не є альтернативою **Requests**. Сфера їх застосування дуже різна.
+
+Насправді цілком звична річ використовувати Requests *всередині* програми FastAPI.
+
+Але все ж FastAPI черпав натхнення з Requests.
+
+**Requests** — це бібліотека для *взаємодії* з API (як клієнт), а **FastAPI** — це бібліотека для *створення* API (як сервер).
+
+Вони більш-менш знаходяться на протилежних кінцях, доповнюючи одна одну.
+
+Requests мають дуже простий та інтуїтивно зрозумілий дизайн, дуже простий у використанні, з розумними параметрами за замовчуванням. Але в той же час він дуже потужний і налаштовується.
+
+Ось чому, як сказано на офіційному сайті:
+
+> Requests є одним із найбільш завантажуваних пакетів Python усіх часів
+
+Використовувати його дуже просто. Наприклад, щоб виконати запит `GET`, ви повинні написати:
+
+```Python
+response = requests.get("http://example.com/some/url")
+```
+
+Відповідна операція *роуту* API FastAPI може виглядати так:
+
+```Python hl_lines="1"
+@app.get("/some/url")
+def read_url():
+ return {"message": "Hello World"}
+```
+
+Зверніть увагу на схожість у `requests.get(...)` і `@app.get(...)`.
+
+/// check | Надихнуло **FastAPI** на
+
+* Майте простий та інтуїтивно зрозумілий API.
+ * Використовуйте імена (операції) методів HTTP безпосередньо, простим та інтуїтивно зрозумілим способом.
+ * Розумні параметри за замовчуванням, але потужні налаштування.
+
+///
+
+###
Swagger /
OpenAPI
+
+Головною функцією, яку я хотів від Django REST Framework, була автоматична API документація.
+
+Потім я виявив, що існує стандарт для документування API з використанням JSON (або YAML, розширення JSON) під назвою Swagger.
+
+І вже був створений веб-інтерфейс користувача для Swagger API. Отже, можливість генерувати документацію Swagger для API дозволить використовувати цей веб-інтерфейс автоматично.
+
+У якийсь момент Swagger було передано Linux Foundation, щоб перейменувати його на OpenAPI.
+
+Тому, коли говорять про версію 2.0, прийнято говорити «Swagger», а про версію 3+ «OpenAPI».
+
+/// check | Надихнуло **FastAPI** на
+
+Прийняти і використовувати відкритий стандарт для специфікацій API замість спеціальної схеми.
+
+ Інтегрувати інструменти інтерфейсу на основі стандартів:
+
+ *
Інтерфейс Swagger
+ *
ReDoc
+
+ Ці два було обрано через те, що вони досить популярні та стабільні, але, виконавши швидкий пошук, ви можете знайти десятки додаткових альтернативних інтерфейсів для OpenAPI (які можна використовувати з **FastAPI**).
+
+///
+
+### Фреймворки REST для Flask
+
+Існує кілька фреймворків Flask REST, але, витративши час і роботу на їх дослідження, я виявив, що багато з них припинено або залишено, з кількома постійними проблемами, які зробили їх непридатними.
+
+###
Marshmallow
+
+Однією з головних функцій, необхідних для систем API, є "
серіалізація", яка бере дані з коду (Python) і перетворює їх на щось, що можна надіслати через мережу. Наприклад, перетворення об’єкта, що містить дані з бази даних, на об’єкт JSON. Перетворення об’єктів `datetime` на строки тощо.
+
+Іншою важливою функцією, необхідною для API, є перевірка даних, яка забезпечує дійсність даних за певними параметрами. Наприклад, що деяке поле є `int`, а не деяка випадкова строка. Це особливо корисно для вхідних даних.
+
+Без системи перевірки даних вам довелося б виконувати всі перевірки вручну, у коді.
+
+Marshmallow створено для забезпечення цих функцій. Це чудова бібліотека, і я часто нею користувався раніше.
+
+Але він був створений до того, як існували підказки типу Python. Отже, щоб визначити кожну
схему, вам потрібно використовувати спеціальні утиліти та класи, надані Marshmallow.
+
+/// check | Надихнуло **FastAPI** на
+
+Використовувати код для автоматичного визначення "схем", які надають типи даних і перевірку.
+
+///
+
+###
Webargs
+
+Іншою важливою функцією, необхідною для API, є
аналіз даних із вхідних запитів.
+
+Webargs — це інструмент, створений, щоб забезпечити це поверх кількох фреймворків, включаючи Flask.
+
+Він використовує Marshmallow в основі для перевірки даних. І створений тими ж розробниками.
+
+Це чудовий інструмент, і я також часто використовував його, перш ніж створити **FastAPI**.
+
+/// info | Інформація
+
+Webargs був створений тими ж розробниками Marshmallow.
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Мати автоматичну перевірку даних вхідного запиту.
+
+///
+
+###
APISpec
+
+Marshmallow і Webargs забезпечують перевірку, аналіз і серіалізацію як плагіни.
+
+Але документація досі відсутня. Потім було створено APISpec.
+
+Це плагін для багатьох фреймворків (також є плагін для Starlette).
+
+Принцип роботи полягає в тому, що ви пишете визначення схеми, використовуючи формат YAML, у docstring кожної функції, що обробляє маршрут.
+
+І він генерує схеми OpenAPI.
+
+Так це працює у Flask, Starlette, Responder тощо.
+
+Але потім ми знову маємо проблему наявності мікросинтаксису всередині Python строки (великий YAML).
+
+Редактор тут нічим не може допомогти. І якщо ми змінимо параметри чи схеми Marshmallow і забудемо також змінити цю строку документа YAML, згенерована схема буде застарілою.
+
+/// info | Інформація
+
+APISpec був створений тими ж розробниками Marshmallow.
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Підтримувати відкритий стандарт API, OpenAPI.
+
+///
+
+###
Flask-apispec
+
+Це плагін Flask, який об’єднує Webargs, Marshmallow і APISpec.
+
+Він використовує інформацію з Webargs і Marshmallow для автоматичного створення схем OpenAPI за допомогою APISpec.
+
+Це чудовий інструмент, дуже недооцінений. Він має бути набагато популярнішим, ніж багато плагінів Flask. Це може бути пов’язано з тим, що його документація надто стисла й абстрактна.
+
+Це вирішило необхідність писати YAML (інший синтаксис) всередині рядків документів Python.
+
+Ця комбінація Flask, Flask-apispec із Marshmallow і Webargs була моїм улюбленим бекенд-стеком до створення **FastAPI**.
+
+Їі використання призвело до створення кількох генераторів повного стека Flask. Це основний стек, який я (та кілька зовнішніх команд) використовував досі:
+
+*
https://github.com/tiangolo/full-stack
+*
https://github.com/tiangolo/full-stack-flask-couchbase
+*
https://github.com/tiangolo/full-stack-flask-couchdb
+
+І ці самі генератори повного стеку були основою [**FastAPI** генераторів проектів](project-generation.md){.internal-link target=_blank}.
+
+/// info | Інформація
+
+Flask-apispec був створений тими ж розробниками Marshmallow.
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Створення схеми OpenAPI автоматично з того самого коду, який визначає серіалізацію та перевірку.
+
+///
+
+###
NestJS (та
Angular)
+
+Це навіть не Python, NestJS — це фреймворк NodeJS JavaScript (TypeScript), натхненний Angular.
+
+Це досягає чогось подібного до того, що можна зробити з Flask-apispec.
+
+Він має інтегровану систему впровадження залежностей, натхненну Angular two. Він потребує попередньої реєстрації «injectables» (як і всі інші системи впровадження залежностей, які я знаю), тому це збільшує багатослівність та повторення коду.
+
+Оскільки параметри описані за допомогою типів TypeScript (подібно до підказок типу Python), підтримка редактора досить хороша.
+
+Але оскільки дані TypeScript не зберігаються після компіляції в JavaScript, вони не можуть покладатися на типи для визначення перевірки, серіалізації та документації одночасно. Через це та деякі дизайнерські рішення, щоб отримати перевірку, серіалізацію та автоматичну генерацію схеми, потрібно додати декоратори в багатьох місцях. Таким чином код стає досить багатослівним.
+
+Він не дуже добре обробляє вкладені моделі. Отже, якщо тіло JSON у запиті є об’єктом JSON із внутрішніми полями, які, у свою чергу, є вкладеними об’єктами JSON, його неможливо належним чином задокументувати та перевірити.
+
+/// check | Надихнуло **FastAPI** на
+
+Використовувати типи Python, щоб мати чудову підтримку редактора.
+
+ Мати потужну систему впровадження залежностей. Знайдіть спосіб звести до мінімуму повторення коду.
+
+///
+
+###
Sanic
+
+Це був один із перших надзвичайно швидких фреймворків Python на основі `asyncio`. Він був дуже схожий на Flask.
+
+/// note | Технічні деталі
+
+Він використовував
`uvloop` замість стандартного циклу Python `asyncio`. Ось що зробило його таким швидким.
+
+ Це явно надихнуло Uvicorn і Starlette, які зараз швидші за Sanic у відкритих тестах.
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Знайти спосіб отримати божевільну продуктивність.
+
+ Ось чому **FastAPI** базується на Starlette, оскільки це найшвидша доступна структура (перевірена тестами сторонніх розробників).
+
+///
+
+###
Falcon
+
+Falcon — ще один високопродуктивний фреймворк Python, він розроблений як мінімальний і працює як основа інших фреймворків, таких як Hug.
+
+Він розроблений таким чином, щоб мати функції, які отримують два параметри, один «запит» і один «відповідь». Потім ви «читаєте» частини запиту та «записуєте» частини у відповідь. Через такий дизайн неможливо оголосити параметри запиту та тіла за допомогою стандартних підказок типу Python як параметри функції.
+
+Таким чином, перевірка даних, серіалізація та документація повинні виконуватися в коді, а не автоматично. Або вони повинні бути реалізовані як фреймворк поверх Falcon, як Hug. Така сама відмінність спостерігається в інших фреймворках, натхненних дизайном Falcon, що мають один об’єкт запиту та один об’єкт відповіді як параметри.
+
+/// check | Надихнуло **FastAPI** на
+
+Знайти способи отримати чудову продуктивність.
+
+ Разом із Hug (оскільки Hug базується на Falcon) надихнув **FastAPI** оголосити параметр `response` у функціях.
+
+ Хоча у FastAPI це необов’язково, і використовується в основному для встановлення заголовків, файлів cookie та альтернативних кодів стану.
+
+///
+
+###
Molten
+
+Я відкрив для себе Molten на перших етапах створення **FastAPI**. І він має досить схожі ідеї:
+
+* Базується на підказках типу Python.
+* Перевірка та документація цих типів.
+* Система впровадження залежностей.
+
+Він не використовує перевірку даних, серіалізацію та бібліотеку документації сторонніх розробників, як Pydantic, він має свою власну. Таким чином, ці визначення типів даних не можна було б використовувати повторно так легко.
+
+Це вимагає трохи більш докладних конфігурацій. І оскільки він заснований на WSGI (замість ASGI), він не призначений для використання високопродуктивних інструментів, таких як Uvicorn, Starlette і Sanic.
+
+Система впровадження залежностей вимагає попередньої реєстрації залежностей, і залежності вирішуються на основі оголошених типів. Отже, неможливо оголосити більше ніж один «компонент», який надає певний тип.
+
+Маршрути оголошуються в одному місці з використанням функцій, оголошених в інших місцях (замість використання декораторів, які можна розмістити безпосередньо поверх функції, яка обробляє кінцеву точку). Це ближче до того, як це робить Django, ніж до Flask (і Starlette). Він розділяє в коді речі, які відносно тісно пов’язані.
+
+/// check | Надихнуло **FastAPI** на
+
+Визначити додаткові перевірки для типів даних, використовуючи значення "за замовчуванням" атрибутів моделі. Це покращує підтримку редактора, а раніше вона була недоступна в Pydantic.
+
+ Це фактично надихнуло оновити частини Pydantic, щоб підтримувати той самий стиль оголошення перевірки (всі ці функції вже доступні в Pydantic).
+
+///
+
+###
Hug
+
+Hug був одним із перших фреймворків, який реалізував оголошення типів параметрів API за допомогою підказок типу Python. Це була чудова ідея, яка надихнула інші інструменти зробити те саме.
+
+Він використовував спеціальні типи у своїх оголошеннях замість стандартних типів Python, але це все одно був величезний крок вперед.
+
+Це також був один із перших фреймворків, який генерував спеціальну схему, що оголошувала весь API у JSON.
+
+Він не базувався на таких стандартах, як OpenAPI та JSON Schema. Тому було б непросто інтегрувати його з іншими інструментами, як-от Swagger UI. Але знову ж таки, це була дуже інноваційна ідея.
+
+Він має цікаву незвичайну функцію: використовуючи ту саму структуру, можна створювати API, а також CLI.
+
+Оскільки він заснований на попередньому стандарті для синхронних веб-фреймворків Python (WSGI), він не може працювати з Websockets та іншими речами, хоча він також має високу продуктивність.
+
+/// info | Інформація
+
+Hug створив Тімоті Крослі, той самий творець
`isort`, чудовий інструмент для автоматичного сортування імпорту у файлах Python.
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Hug надихнув частину APIStar і був одним із найбільш перспективних інструментів, поряд із APIStar.
+
+ Hug надихнув **FastAPI** на використання підказок типу Python для оголошення параметрів і автоматичного створення схеми, що визначає API.
+
+ Hug надихнув **FastAPI** оголосити параметр `response` у функціях для встановлення заголовків і файлів cookie.
+
+///
+
+###
APIStar (<= 0,5)
+
+Безпосередньо перед тим, як вирішити створити **FastAPI**, я знайшов сервер **APIStar**. Він мав майже все, що я шукав, і мав чудовий дизайн.
+
+Це була одна з перших реалізацій фреймворку, що використовує підказки типу Python для оголошення параметрів і запитів, яку я коли-небудь бачив (до NestJS і Molten). Я знайшов його більш-менш одночасно з Hug. Але APIStar використовував стандарт OpenAPI.
+
+Він мав автоматичну перевірку даних, серіалізацію даних і генерацію схеми OpenAPI на основі підказок того самого типу в кількох місцях.
+
+Визначення схеми тіла не використовували ті самі підказки типу Python, як Pydantic, воно було трохи схоже на Marshmallow, тому підтримка редактора була б не такою хорошою, але все ж APIStar був найкращим доступним варіантом.
+
+Він мав найкращі показники продуктивності на той час (перевершив лише Starlette).
+
+Спочатку він не мав автоматичного веб-інтерфейсу документації API, але я знав, що можу додати до нього інтерфейс користувача Swagger.
+
+Він мав систему введення залежностей. Він вимагав попередньої реєстрації компонентів, як і інші інструменти, розглянуті вище. Але все одно це була чудова функція.
+
+Я ніколи не міг використовувати його в повноцінному проекті, оскільки він не мав інтеграції безпеки, тому я не міг замінити всі функції, які мав, генераторами повного стеку на основі Flask-apispec. У моїх невиконаних проектах я мав створити запит на вилучення, додавши цю функцію.
+
+Але потім фокус проекту змінився.
+
+Це вже не був веб-фреймворк API, оскільки творцю потрібно було зосередитися на Starlette.
+
+Тепер APIStar — це набір інструментів для перевірки специфікацій OpenAPI, а не веб-фреймворк.
+
+/// info | Інформація
+
+APIStar створив Том Крісті. Той самий хлопець, який створив:
+
+ * Django REST Framework
+ * Starlette (на якому базується **FastAPI**)
+ * Uvicorn (використовується Starlette і **FastAPI**)
+
+///
+
+/// check | Надихнуло **FastAPI** на
+
+Існувати.
+
+ Ідею оголошення кількох речей (перевірки даних, серіалізації та документації) за допомогою тих самих типів Python, які в той же час забезпечували чудову підтримку редактора, я вважав геніальною ідеєю.
+
+ І після тривалого пошуку подібної структури та тестування багатьох різних альтернатив, APIStar став найкращим доступним варіантом.
+
+ Потім APIStar перестав існувати як сервер, і було створено Starlette, який став новою кращою основою для такої системи. Це стало останнім джерелом натхнення для створення **FastAPI**. Я вважаю **FastAPI** «духовним спадкоємцем» APIStar, удосконалюючи та розширюючи функції, систему введення тексту та інші частини на основі досвіду, отриманого від усіх цих попередніх інструментів.
+
+///
+
+## Використовується **FastAPI**
+
+###
Pydantic
+
+Pydantic — це бібліотека для визначення перевірки даних, серіалізації та документації (за допомогою схеми JSON) на основі підказок типу Python.
+
+Це робить його надзвичайно інтуїтивним.
+
+Його можна порівняти з Marshmallow. Хоча він швидший за Marshmallow у тестах. Оскільки він базується на тих самих підказках типу Python, підтримка редактора чудова.
+
+/// check | **FastAPI** використовує його для
+
+Виконання перевірки всіх даних, серіалізації даних і автоматичної документацію моделі (на основі схеми JSON).
+
+ Потім **FastAPI** бере ці дані схеми JSON і розміщує їх у OpenAPI, окремо від усіх інших речей, які він робить.
+
+///
+
+###
Starlette
+
+Starlette — це легкий фреймворк/набір інструментів
ASGI, який ідеально підходить для створення високопродуктивних asyncio сервісів.
+
+Він дуже простий та інтуїтивно зрозумілий. Його розроблено таким чином, щоб його можна було легко розширювати та мати модульні компоненти.
+
+Він має:
+
+* Серйозно вражаючу продуктивність.
+* Підтримку WebSocket.
+* Фонові завдання в процесі.
+* Події запуску та завершення роботи.
+* Тестового клієнта, побудований на HTTPX.
+* CORS, GZip, статичні файли, потокові відповіді.
+* Підтримку сеансів і файлів cookie.
+* 100% покриття тестом.
+* 100% анотовану кодову базу.
+* Кілька жорстких залежностей.
+
+Starlette наразі є найшвидшим фреймворком Python із перевірених. Перевершує лише Uvicorn, який є не фреймворком, а сервером.
+
+Starlette надає всі основні функції веб-мікрофреймворку.
+
+Але він не забезпечує автоматичної перевірки даних, серіалізації чи документації.
+
+Це одна з головних речей, які **FastAPI** додає зверху, все на основі підказок типу Python (з використанням Pydantic). Це, а також система впровадження залежностей, утиліти безпеки, створення схеми OpenAPI тощо.
+
+/// note | Технічні деталі
+
+ASGI — це новий «стандарт», який розробляється членами основної команди Django. Це ще не «стандарт Python» (PEP), хоча вони в процесі цього.
+
+ Тим не менш, він уже використовується як «стандарт» кількома інструментами. Це значно покращує сумісність, оскільки ви можете переключити Uvicorn на будь-який інший сервер ASGI (наприклад, Daphne або Hypercorn), або ви можете додати інструменти, сумісні з ASGI, як-от `python-socketio`.
+
+///
+
+/// check | **FastAPI** використовує його для
+
+Керування всіма основними веб-частинами. Додавання функцій зверху.
+
+ Сам клас `FastAPI` безпосередньо успадковує клас `Starlette`.
+
+ Отже, усе, що ви можете робити зі Starlette, ви можете робити це безпосередньо за допомогою **FastAPI**, оскільки це, по суті, Starlette на стероїдах.
+
+///
+
+###
Uvicorn
+
+Uvicorn — це блискавичний сервер ASGI, побудований на uvloop і httptools.
+
+Це не веб-фреймворк, а сервер. Наприклад, він не надає інструментів для маршрутизації. Це те, що фреймворк на кшталт Starlette (або **FastAPI**) забезпечить поверх нього.
+
+Це рекомендований сервер для Starlette і **FastAPI**.
+
+/// check | **FastAPI** рекомендує це як
+
+Основний веб-сервер для запуску програм **FastAPI**.
+
+ Ви можете поєднати його з Gunicorn, щоб мати асинхронний багатопроцесний сервер.
+
+ Додаткову інформацію див. у розділі [Розгортання](deployment/index.md){.internal-link target=_blank}.
+
+///
+
+## Орієнтири та швидкість
+
+Щоб зрозуміти, порівняти та побачити різницю між Uvicorn, Starlette і FastAPI, перегляньте розділ про [Бенчмарки](benchmarks.md){.internal-link target=_blank}.
diff --git a/docs/uk/docs/fastapi-cli.md b/docs/uk/docs/fastapi-cli.md
new file mode 100644
index 000000000..6bbbbc326
--- /dev/null
+++ b/docs/uk/docs/fastapi-cli.md
@@ -0,0 +1,83 @@
+# FastAPI CLI
+
+**FastAPI CLI** це програма командного рядка, яку Ви можете використовувати, щоб обслуговувати Ваш додаток FastAPI, керувати Вашими FastApi проектами, тощо.
+
+Коли Ви встановлюєте FastApi (тобто виконуєте `pip install "fastapi[standard]"`), Ви також встановлюєте пакунок `fastapi-cli`, цей пакунок надає команду `fastapi` в терміналі.
+
+Для запуску Вашого FastAPI проекту для розробки, Ви можете скористатись командою `fastapi dev`:
+
+
+
+```console
+$ fastapi dev main.py
+INFO Using path main.py
+INFO Resolved absolute path /home/user/code/awesomeapp/main.py
+INFO Searching for package file structure from directories with __init__.py files
+INFO Importing from /home/user/code/awesomeapp
+
+ ╭─ Python module file ─╮
+ │ │
+ │ 🐍 main.py │
+ │ │
+ ╰──────────────────────╯
+
+INFO Importing module main
+INFO Found importable FastAPI app
+
+ ╭─ Importable FastAPI app ─╮
+ │ │
+ │ from main import app │
+ │ │
+ ╰──────────────────────────╯
+
+INFO Using import string main:app
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2265862] using WatchFiles
+INFO: Started server process [2265873]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+Програма командного рядка `fastapi` це **FastAPI CLI**.
+
+FastAPI CLI приймає шлях до Вашої Python програми (напр. `main.py`) і автоматично виявляє екземпляр `FastAPI` (зазвичай названий `app`), обирає коректний процес імпорту, а потім обслуговує його.
+
+Натомість, для запуску у продакшн використовуйте `fastapi run`. 🚀
+
+Всередині **FastAPI CLI** використовує
Uvicorn, високопродуктивний, production-ready, ASGI cервер. 😎
+
+## `fastapi dev`
+
+Використання `fastapi dev` ініціює режим розробки.
+
+За замовчуванням, **автоматичне перезавантаження** увімкнене, автоматично перезавантажуючи сервер кожного разу, коли Ви змінюєте Ваш код. Це ресурсо-затратно, та може бути менш стабільним, ніж коли воно вимкнене. Ви повинні використовувати його тільки під час розробки. Воно також слухає IP-адресу `127.0.0.1`, що є IP Вашого девайсу для самостійної комунікації з самим собою (`localhost`).
+
+## `fastapi run`
+
+Виконання `fastapi run` запустить FastAPI у продакшн-режимі за замовчуванням.
+
+За замовчуванням, **автоматичне перезавантаження** вимкнене. Воно також прослуховує IP-адресу `0.0.0.0`, що означає всі доступні IP адреси, тим самим даючи змогу будь-кому комунікувати з девайсом. Так Ви зазвичай будете запускати його у продакшн, наприклад у контейнері.
+
+В більшості випадків Ви можете (і маєте) мати "termination proxy", який обробляє HTTPS для Вас, це залежить від способу розгортання вашого додатку, Ваш провайдер може зробити це для Вас, або Вам потрібно налаштувати його самостійно.
+
+/// tip
+
+Ви можете дізнатись більше про це у [документації про розгортування](deployment/index.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/uk/docs/features.md b/docs/uk/docs/features.md
new file mode 100644
index 000000000..7d679d8ee
--- /dev/null
+++ b/docs/uk/docs/features.md
@@ -0,0 +1,189 @@
+# Функціональні можливості
+
+## Функціональні можливості FastAPI
+
+**FastAPI** надає вам такі можливості:
+
+### Використання відкритих стандартів
+
+*
OpenAPI для створення API, включаючи оголошення
шляхів,
операцій, параметрів, тіл запитів, безпеки тощо.
+* Автоматична документація моделей даних за допомогою
JSON Schema (оскільки OpenAPI базується саме на JSON Schema).
+* Розроблено на основі цих стандартів після ретельного аналізу, а не як додатковий рівень поверх основної архітектури.
+* Це також дає змогу автоматично **генерувати код клієнта** багатьма мовами.
+
+### Автоматична генерація документації
+
+Інтерактивна документація API та вебінтерфейс для його дослідження. Оскільки фреймворк базується на OpenAPI, є кілька варіантів, два з яких включені за замовчуванням.
+
+*
Swagger UI — дозволяє інтерактивно переглядати API, викликати та тестувати його прямо у браузері.
+
+
+
+* Альтернативна документація API за допомогою
ReDoc.
+
+
+
+### Тільки сучасний Python
+
+FastAPI використовує стандартні **типи Python** (завдяки Pydantic). Вам не потрібно вивчати новий синтаксис — лише стандартний сучасний Python.
+
+Якщо вам потрібне коротке нагадування про використання типів у Python (навіть якщо ви не використовуєте FastAPI), перегляньте короткий підручник: [Вступ до типів Python](python-types.md){.internal-link target=_blank}.
+
+Ось приклад стандартного Python-коду з типами:
+
+```Python
+from datetime import date
+from pydantic import BaseModel
+
+# Оголошення змінної як str
+# з підтримкою автодоповнення у редакторі
+def main(user_id: str):
+ return user_id
+
+# Модель Pydantic
+class User(BaseModel):
+ id: int
+ name: str
+ joined: date
+```
+
+Приклад використання цієї моделі:
+
+```Python
+my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
+
+second_user_data = {
+ "id": 4,
+ "name": "Mary",
+ "joined": "2018-11-30",
+}
+
+my_second_user: User = User(**second_user_data)
+```
+
+/// info | Інформація
+
+`**second_user_data` означає:
+
+Передати ключі та значення словника `second_user_data` як аргументи у вигляді "ключ-значення", еквівалентно `User(id=4, name="Mary", joined="2018-11-30")`.
+
+///
+
+### Підтримка редакторів (IDE)
+
+Фреймворк спроєктований так, щоб бути легким і інтуїтивно зрозумілим. Усі рішення тестувалися у різних редакторах ще до початку розробки, щоб забезпечити найкращий досвід програмування.
+
+За результатами опитувань розробників Python
однією з найпопулярніших функцій є "автодоповнення".
+
+**FastAPI** повністю підтримує автодоповнення у всіх місцях, тому вам рідко доведеться повертатися до документації.
+
+Приклад автодоповнення у редакторах:
+
+* у
Visual Studio Code:
+
+
+
+* у
PyCharm:
+
+
+
+### Короткий код
+FastAPI має розумні налаштування **за замовчуванням**, але всі параметри можна налаштовувати відповідно до ваших потреб. Однак за замовчуванням все "просто працює".
+
+### Валідація
+* Підтримка валідації для більшості (або всіх?) **типів даних Python**, зокрема:
+ * JSON-об'єктів (`dict`).
+ * JSON-списків (`list`) з визначенням типів елементів.
+ * Рядків (`str`) із мінімальною та максимальною довжиною.
+ * Чисел (`int`, `float`) з обмеженнями мінімальних та максимальних значень тощо.
+
+* Валідація складніших типів, таких як:
+ * URL.
+ * Email.
+ * UUID.
+ * ...та інші.
+
+Уся валідація виконується через надійний та перевірений **Pydantic**.
+
+### Безпека та автентифікація
+
+**FastAPI** підтримує вбудовану автентифікацію та авторизацію, без прив’язки до конкретних баз даних чи моделей даних.
+
+Підтримуються всі схеми безпеки OpenAPI, включаючи:
+
+* HTTP Basic.
+* **OAuth2** (також із підтримкою **JWT-токенів**). Див. підручник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* Ключі API в:
+ * Заголовках.
+ * Параметрах запиту.
+ * Cookies тощо.
+
+А також усі можливості безпеки від Starlette (зокрема **сесійні cookies**).
+
+Усі вони створені як багаторазові інструменти та компоненти, які легко інтегруються з вашими системами, сховищами даних, реляційними та NoSQL базами даних тощо.
+
+### Впровадження залежностей
+
+**FastAPI** містить надзвичайно просту у використанні, але потужну систему впровадження залежностей.
+
+* Залежності можуть мати власні залежності, утворюючи ієрархію або **"граф залежностей"**.
+* Усі залежності автоматично керуються фреймворком.
+* Усі залежності можуть отримувати дані з запитів і розширювати **обмеження операції за шляхом** та автоматичну документацію.
+* **Автоматична валідація** навіть для параметрів *операцій шляху*, визначених у залежностях.
+* Підтримка складних систем автентифікації користувачів, **з'єднань із базами даних** тощо.
+* **Жодних обмежень** щодо використання баз даних, фронтендів тощо, але водночас проста інтеграція з усіма ними.
+
+### Немає обмежень на "плагіни"
+
+Або іншими словами, вони не потрібні – просто імпортуйте та використовуйте необхідний код.
+
+Будь-яка інтеграція спроєктована настільки просто (з використанням залежностей), що ви можете створити "плагін" для свого застосунку всього у 2 рядках коду, використовуючи ту саму структуру та синтаксис, що й для ваших *операцій шляху*.
+
+### Протестовано
+
+* 100%
покриття тестами.
+* 100%
анотована типами кодова база.
+* Використовується у робочих середовищах.
+
+## Можливості Starlette
+
+**FastAPI** повністю сумісний із (та побудований на основі)
Starlette. Тому будь-який додатковий код Starlette, який ви маєте, також працюватиме.
+
+**FastAPI** фактично є підкласом **Starlette**. Тому, якщо ви вже знайомі зі Starlette або використовуєте його, більшість функціональності працюватиме так само.
+
+З **FastAPI** ви отримуєте всі можливості **Starlette** (адже FastAPI — це, по суті, Starlette на стероїдах):
+
+* Разюча продуктивність. Це
один із найшвидших фреймворків на Python, на рівні з **NodeJS** і **Go**.
+* Підтримка **WebSocket**.
+* Фонові задачі у процесі.
+* Події запуску та завершення роботи.
+* Клієнт для тестування, побудований на HTTPX.
+* Підтримка **CORS**, **GZip**, статичних файлів, потокових відповідей.
+* Підтримка **сесій** і **cookie**.
+* 100% покриття тестами.
+* 100% анотована типами кодова база.
+
+## Можливості Pydantic
+
+**FastAPI** повністю сумісний із (та побудований на основі)
Pydantic. Тому будь-який додатковий код Pydantic, який ви маєте, також працюватиме.
+
+Включаючи зовнішні бібліотеки, побудовані також на Pydantic, такі як
ORM,
ODM для баз даних.
+
+Це також означає, що в багатьох випадках ви можете передати той самий об'єкт, який отримуєте з запиту, **безпосередньо в базу даних**, оскільки все автоматично перевіряється.
+
+Те ж саме відбувається й у зворотному напрямку — у багатьох випадках ви можете просто передати об'єкт, який отримуєте з бази даних, **безпосередньо клієнту**.
+
+З **FastAPI** ви отримуєте всі можливості **Pydantic** (адже FastAPI базується на Pydantic для обробки всіх даних):
+
+* **Ніякої плутанини** :
+ * Не потрібно вчити нову мову для визначення схем.
+ * Якщо ви знаєте типи Python, ви знаєте, як використовувати Pydantic.
+* Легко працює з вашим **
IDE/
лінтером/мозком**:
+ * Оскільки структури даних Pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними.
+* Валідація **складних структур**:
+ * Використання ієрархічних моделей Pydantic. Python `typing`, `List` і `Dict` тощо.
+ * Валідатори дозволяють чітко і просто визначати, перевіряти й документувати складні схеми даних у вигляді JSON-схеми.
+ * Ви можете мати глибоко **вкладені JSON об'єкти** та перевірити та анотувати їх всі.
+* **Розширюваність**:
+ * Pydantic дозволяє визначати користувацькі типи даних або розширювати валідацію методами в моделі декоратором `validator`.
+* 100% покриття тестами.
diff --git a/docs/uk/docs/index.md b/docs/uk/docs/index.md
index cff2c2804..b573ee259 100644
--- a/docs/uk/docs/index.md
+++ b/docs/uk/docs/index.md
@@ -1,50 +1,49 @@
-
-{!../../../docs/missing-translation.md!}
-
-
- FastAPI framework, high performance, easy to learn, fast to code, ready for production
+ Готовий до продакшину, високопродуктивний, простий у вивченні та швидкий для написання коду фреймворк
-
-
+
+
-
-
+
+
+
+
+
---
-**Documentation**:
https://fastapi.tiangolo.com
+**Документація**:
https://fastapi.tiangolo.com
-**Source Code**:
https://github.com/tiangolo/fastapi
+**Програмний код**:
https://github.com/fastapi/fastapi
---
-FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
+FastAPI - це сучасний, швидкий (високопродуктивний), вебфреймворк для створення API за допомогою Python,в основі якого лежить стандартна анотація типів Python.
-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).
+* **Швидкий**: Дуже висока продуктивність, на рівні з **NodeJS** та **Go** (завдяки Starlette та Pydantic). [Один із найшвидших фреймворків](#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.
+* **Швидке написання коду**: Пришвидшує розробку функціоналу приблизно на 200%-300%. *
+* **Менше помилок**: Зменшить кількість помилок спричинених людиною (розробником) на 40%. *
+* **Інтуїтивний**: Чудова підтримка редакторами коду.
Доповнення всюди. Зменште час на налагодження.
+* **Простий**: Спроектований, для легкого використання та навчання. Знадобиться менше часу на читання документації.
+* **Короткий**: Зведе до мінімуму дублювання коду. Кожен оголошений параметр може виконувати кілька функцій.
+* **Надійний**: Ви матимете стабільний код готовий до продакшину з автоматичною інтерактивною документацією.
+* **Стандартизований**: Оснований та повністю сумісний з відкритими стандартами для API:
OpenAPI (попередньо відомий як Swagger) та
JSON Schema.
-
* estimation based on tests on an internal development team, building production applications.
+
* оцінка на основі тестів внутрішньої команди розробників, створення продуктових застосунків.
-## Sponsors
+## Спонсори
@@ -61,11 +60,11 @@ The key features are:
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)
+
Kabir Khan -
Microsoft (ref)
---
@@ -89,7 +88,7 @@ The key features are:
"_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._"
-
+
---
@@ -101,24 +100,22 @@ The key features are:
---
-## **Typer**, the FastAPI of CLIs
+## **Typer**, FastAPI CLI

-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**. ⌨️ 🚀
+Створюючи
CLI застосунок для використання в терміналі, замість веб-API зверніть увагу на
**Typer**.
-## Requirements
+**Typer** є молодшим братом FastAPI. І це **FastAPI для CLI**. ⌨️ 🚀
-Python 3.7+
+## Вимоги
-FastAPI stands on the shoulders of giants:
+FastAPI стоїть на плечах гігантів:
-*
Starlette for the web parts.
-*
Pydantic for the data parts.
+*
Starlette для web частини.
+*
Pydantic для частини даних.
-## Installation
+## Вставновлення
@@ -130,23 +127,23 @@ $ pip install fastapi
-You will also need an ASGI server, for production such as
Uvicorn or
Hypercorn.
+Вам також знадобиться сервер ASGI для продакшину, наприклад
Uvicorn або
Hypercorn.
```console
-$ pip install "uvicorn[standard]"
+$ pip install uvicorn[standard]
---> 100%
```
-## Example
+## Приклад
-### Create it
+### Створіть
-* Create a file `main.py` with:
+* Створіть файл `main.py` з:
```Python
from typing import Union
@@ -167,9 +164,9 @@ def read_item(item_id: int, q: Union[str, None] = None):
```
-Or use async def
...
+Або використайте async def
...
-If your code uses `async` / `await`, use `async def`:
+Якщо ваш код використовує `async` / `await`, скористайтеся `async def`:
```Python hl_lines="9 14"
from typing import Union
@@ -189,15 +186,15 @@ 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.
+Стикнувшись з проблемами, не зайвим буде ознайомитися з розділом _"In a hurry?"_ про `async` та `await` у документації.
-### Run it
+### Запустіть
-Run the server with:
+Запустіть server з:
@@ -214,54 +211,54 @@ INFO: Application startup complete.
-About the command uvicorn main:app --reload
...
+Про команди uvicorn main:app --reload
...
-The command `uvicorn main:app` refers to:
+Команда `uvicorn main:app` посилається на:
-* `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.
+* `main`: файл `main.py` ("Модуль" Python).
+* `app`: об’єкт створений усередині `main.py` рядком `app = FastAPI()`.
+* `--reload`: перезапускає сервер після зміни коду. Використовуйте виключно для розробки.
-### Check it
+### Перевірте
-Open your browser at
http://127.0.0.1:8000/items/5?q=somequery.
+Відкрийте браузер та введіть адресу
http://127.0.0.1:8000/items/5?q=somequery.
-You will see the JSON response as:
+Ви побачите у відповідь подібний JSON:
```JSON
{"item_id": 5, "q": "somequery"}
```
-You already created an API that:
+Ви вже створили API, який:
-* 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`.
+* Отримує HTTP запити за _шляхами_ `/` та `/items/{item_id}`.
+* Обидва _шляхи_ приймають `GET`
операції (також відомі як HTTP _методи_).
+* _Шлях_ `/items/{item_id}` містить _параметр шляху_ `item_id` який має бути типу `int`.
+* _Шлях_ `/items/{item_id}` містить необовʼязковий `str` _параметр запиту_ `q`.
-### Interactive API docs
+### Інтерактивні документації API
-Now go to
http://127.0.0.1:8000/docs.
+Перейдемо сюди
http://127.0.0.1:8000/docs.
-You will see the automatic interactive API documentation (provided by
Swagger UI):
+Ви побачите автоматичну інтерактивну API документацію (створену завдяки
Swagger UI):

-### Alternative API docs
+### Альтернативні документації API
-And now, go to
http://127.0.0.1:8000/redoc.
+Тепер перейдемо сюди
http://127.0.0.1:8000/redoc.
-You will see the alternative automatic documentation (provided by
ReDoc):
+Ви побачите альтернативну автоматичну документацію (створену завдяки
ReDoc):

-## Example upgrade
+## Приклад оновлення
-Now modify the file `main.py` to receive a body from a `PUT` request.
+Тепер модифікуйте файл `main.py`, щоб отримати вміст запиту `PUT`.
-Declare the body using standard Python types, thanks to Pydantic.
+Оголошуйте вміст запиту за допомогою стандартних типів Python завдяки Pydantic.
```Python hl_lines="4 9-12 25-27"
from typing import Union
@@ -293,174 +290,174 @@ 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).
+Сервер повинен автоматично перезавантажуватися (тому що Ви додали `--reload` до `uvicorn` команди вище).
-### Interactive API docs upgrade
+### Оновлення інтерактивної API документації
-Now go to
http://127.0.0.1:8000/docs.
+Тепер перейдемо сюди
http://127.0.0.1:8000/docs.
-* The interactive API documentation will be automatically updated, including the new body:
+* Інтерактивна документація API буде автоматично оновлена, включаючи новий вміст:

-* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
+* Натисніть кнопку "Try it out", це дозволить вам заповнити параметри та безпосередньо взаємодіяти з 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:
+* Потім натисніть кнопку "Execute", інтерфейс користувача зв'яжеться з вашим API, надішле параметри, у відповідь отримає результати та покаже їх на екрані:

-### Alternative API docs upgrade
+### Оновлення альтернативної API документації
-And now, go to
http://127.0.0.1:8000/redoc.
+Зараз перейдемо
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.
+Ви робите це за допомогою стандартних сучасних типів Python.
-You don't have to learn a new syntax, the methods or classes of a specific library, etc.
+Вам не потрібно вивчати новий синтаксис, методи чи класи конкретної бібліотеки тощо.
-Just standard **Python 3.6+**.
+Використовуючи стандартний **Python**.
-For example, for an `int`:
+Наприклад, для `int`:
```Python
item_id: int
```
-or for a more complex `Item` model:
+або для більш складної моделі `Item`:
```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 з високим рівнем вкладеності.
+*
Перетворення вхідних даних: з мережі до даних і типів Python. Читання з:
* 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:
+ * Файлів.
+*
Перетворення вихідних даних: з типів і даних Python до мережевих даних (як JSON):
+ * Конвертація Python типів (`str`, `int`, `float`, `bool`, `list`, тощо).
+ * `datetime` об'єкти.
+ * `UUID` об'єкти.
+ * Моделі бази даних.
+ * ...та багато іншого.
+* Автоматичну інтерактивну документацію API, включаючи 2 альтернативні інтерфейси користувача:
* 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.
+Повертаючись до попереднього прикладу коду, **FastAPI**:
+
+* Підтвердить наявність `item_id` у шляху для запитів `GET` та `PUT`.
+* Підтвердить, що `item_id` має тип `int` для запитів `GET` and `PUT`.
+ * Якщо це не так, клієнт побачить корисну, зрозумілу помилку.
+* Перевірить, чи є необов'язковий параметр запиту з назвою `q` (а саме `http://127.0.0.1:8000/items/foo?q=somequery`) для запитів `GET`.
+ * Оскільки параметр `q` оголошено як `= None`, він необов'язковий.
+ * За відсутності `None` він був би обов'язковим (як і вміст у випадку з `PUT`).
+* Для запитів `PUT` із `/items/{item_id}`, читає вміст як JSON:
+ * Перевірить, чи має обов'язковий атрибут `name` тип `str`.
+ * Перевірить, чи має обов'язковий атрибут `price` тип `float`.
+ * Перевірить, чи існує необов'язковий атрибут `is_offer` та чи має він тип `bool`.
+ * Усе це також працюватиме для глибоко вкладених об'єктів JSON.
+* Автоматично конвертує із та в JSON.
+* Документує все за допомогою OpenAPI, який може бути використано в:
+ * Інтерактивних системах документації.
+ * Системах автоматичної генерації клієнтського коду для багатьох мов.
+* Надає безпосередньо 2 вебінтерфейси інтерактивної документації.
---
-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:
+**Spoiler alert**: туторіал - посібник користувача містить:
-* 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).
-* Many extra features (thanks to Starlette) as:
+* Оголошення **параметрів** з інших місць як: **headers**, **cookies**, **form fields** та **files**.
+* Як встановити **перевірку обмежень** як `maximum_length` або `regex`.
+* Дуже потужна і проста у використанні система **
Ін'єкція Залежностей**.
+* Безпека та автентифікація, включаючи підтримку **OAuth2** з **JWT tokens** та **HTTP Basic** автентифікацію.
+* Досконаліші (але однаково прості) техніки для оголошення **глибоко вкладених моделей JSON** (завдяки Pydantic).
+* Багато додаткових функцій (завдяки Starlette) як-от:
* **WebSockets**
- * **GraphQL**
- * extremely easy tests based on HTTPX and `pytest`
+ * надзвичайно прості тести на основі HTTPX та `pytest`
* **CORS**
* **Cookie Sessions**
- * ...and more.
+ * ...та більше.
+
+## Продуктивність
-## Performance
+Незалежні тести TechEmpower показують що застосунки **FastAPI**, які працюють під керуванням Uvicorn
є одними з найшвидших серед доступних фреймворків в Python, поступаючись лише Starlette та Uvicorn (які внутрішньо використовуються в FastAPI). (*)
-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). (*)
+Щоб дізнатися більше про це, перегляньте розділ
Benchmarks.
-To understand more about it, see the section
Benchmarks.
+## Необов'язкові залежності
-## Optional Dependencies
+Pydantic використовує:
-Used by Pydantic:
+*
email-validator
- для валідації електронної пошти.
+*
pydantic-settings
- для управління налаштуваннями.
+*
pydantic-extra-types
- для додаткових типів, що можуть бути використані з Pydantic.
-*
ujson
- for faster JSON
"parsing".
-*
email_validator
- for email validation.
-Used by Starlette:
+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).
-*
graphene
- Required for `GraphQLApp` support.
-*
ujson
- Required if you want to use `UJSONResponse`.
+*
httpx
- Необхідно, якщо Ви хочете використовувати `TestClient`.
+*
jinja2
- Необхідно, якщо Ви хочете використовувати шаблони як конфігурацію за замовчуванням.
+*
python-multipart
- Необхідно, якщо Ви хочете підтримувати
"розбір" форми за допомогою `request.form()`.
+*
itsdangerous
- Необхідно для підтримки `SessionMiddleware`.
+*
pyyaml
- Необхідно для підтримки Starlette `SchemaGenerator` (ймовірно, вам це не потрібно з FastAPI).
-Used by FastAPI / Starlette:
+FastAPI / Starlette використовують:
-*
uvicorn
- for the server that loads and serves your application.
-*
orjson
- Required if you want to use `ORJSONResponse`.
+*
uvicorn
- для сервера, який завантажує та обслуговує вашу програму.
+*
orjson
- Необхідно, якщо Ви хочете використовувати `ORJSONResponse`.
+*
ujson
- Необхідно, якщо Ви хочете використовувати `UJSONResponse`.
-You can install all of these with `pip install fastapi[all]`.
+Ви можете встановити все це за допомогою `pip install fastapi[all]`.
-## License
+## Ліцензія
-This project is licensed under the terms of the MIT license.
+Цей проєкт ліцензовано згідно з умовами ліцензії MIT.
diff --git a/docs/uk/docs/learn/index.md b/docs/uk/docs/learn/index.md
new file mode 100644
index 000000000..7f9f21e57
--- /dev/null
+++ b/docs/uk/docs/learn/index.md
@@ -0,0 +1,5 @@
+# Навчання
+
+У цьому розділі надані вступні та навчальні матеріали для вивчення FastAPI.
+
+Це можна розглядати як **книгу**, **курс**, або **офіційний** та рекомендований спосіб освоїти FastAPI. 😎
diff --git a/docs/uk/docs/python-types.md b/docs/uk/docs/python-types.md
new file mode 100644
index 000000000..676bafb15
--- /dev/null
+++ b/docs/uk/docs/python-types.md
@@ -0,0 +1,489 @@
+# Вступ до типів Python
+
+Python підтримує додаткові "підказки типу" ("type hints") (також звані "анотаціями типу" ("type annotations")).
+
+Ці **"type hints"** є спеціальним синтаксисом, що дозволяє оголошувати
тип змінної.
+
+За допомогою оголошення типів для ваших змінних, редактори та інструменти можуть надати вам кращу підтримку.
+
+Це просто **швидкий посібник / нагадування** про анотації типів у Python. Він покриває лише мінімум, необхідний щоб використовувати їх з **FastAPI**... що насправді дуже мало.
+
+**FastAPI** повністю базується на цих анотаціях типів, вони дають йому багато переваг.
+
+Але навіть якщо ви ніколи не використаєте **FastAPI**, вам буде корисно дізнатись трохи про них.
+
+/// note
+
+Якщо ви експерт у Python і ви вже знаєте усе про анотації типів - перейдіть до наступного розділу.
+
+///
+
+## Мотивація
+
+Давайте почнемо з простого прикладу:
+
+{* ../../docs_src/python_types/tutorial001.py *}
+
+
+Виклик цієї програми виводить:
+
+```
+John Doe
+```
+
+Функція виконує наступне:
+
+* Бере `first_name` та `last_name`.
+* Конвертує кожну літеру кожного слова у верхній регістр за допомогою `title()`.
+*
Конкатенує їх разом із пробілом по середині.
+
+{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+
+
+### Редагуйте це
+
+Це дуже проста програма.
+
+Але тепер уявіть, що ви писали це з нуля.
+
+У певний момент ви розпочали б визначення функції, у вас були б готові параметри...
+
+Але тоді вам потрібно викликати "той метод, який переводить першу літеру у верхній регістр".
+
+Це буде `upper`? Чи `uppercase`? `first_uppercase`? `capitalize`?
+
+Тоді ви спробуєте давнього друга програміста - автозаповнення редактора коду.
+
+Ви надрукуєте перший параметр функції, `first_name`, тоді крапку (`.`), а тоді натиснете `Ctrl+Space`, щоб запустити автозаповнення.
+
+Але, на жаль, ви не отримаєте нічого корисного:
+
+

+
+### Додайте типи
+
+Давайте змінимо один рядок з попередньої версії.
+
+Ми змінимо саме цей фрагмент, параметри функції, з:
+
+```Python
+ first_name, last_name
+```
+
+на:
+
+```Python
+ first_name: str, last_name: str
+```
+
+Ось і все.
+
+Це "type hints":
+
+{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+
+
+Це не те саме, що оголошення значень за замовчуванням, як це було б з:
+
+```Python
+ first_name="john", last_name="doe"
+```
+
+Це зовсім інше.
+
+Ми використовуємо двокрапку (`:`), не дорівнює (`=`).
+
+І додавання анотації типу зазвичай не змінює того, що сталось би без них.
+
+Але тепер, уявіть що ви посеред процесу створення функції, але з анотаціями типів.
+
+В цей же момент, ви спробуєте викликати автозаповнення з допомогою `Ctrl+Space` і побачите:
+
+

+
+Разом з цим, ви можете прокручувати, переглядати опції, допоки ви не знайдете одну, що звучить схоже:
+
+

+
+## Більше мотивації
+
+Перевірте цю функцію, вона вже має анотацію типу:
+
+{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+
+
+Оскільки редактор знає типи змінних, ви не тільки отримаєте автозаповнення, ви також отримаєте перевірку помилок:
+
+

+
+Тепер ви знаєте, щоб виправити це, вам потрібно перетворити `age` у строку з допомогою `str(age)`:
+
+{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+
+
+## Оголошення типів
+
+Щойно ви побачили основне місце для оголошення анотацій типу. Як параметри функції.
+
+Це також основне місце, де ви б їх використовували у **FastAPI**.
+
+### Прості типи
+
+Ви можете оголошувати усі стандартні типи у Python, не тільки `str`.
+
+Ви можете використовувати, наприклад:
+
+* `int`
+* `float`
+* `bool`
+* `bytes`
+
+{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+
+
+### Generic-типи з параметрами типів
+
+Існують деякі структури даних, які можуть містити інші значення, наприклад `dict`, `list`, `set` та `tuple`. І внутрішні значення також можуть мати свій тип.
+
+Ці типи, які мають внутрішні типи, називаються "**generic**" типами. І оголосити їх можна навіть із внутрішніми типами.
+
+Щоб оголосити ці типи та внутрішні типи, ви можете використовувати стандартний модуль Python `typing`. Він існує спеціально для підтримки анотацій типів.
+
+#### Новіші версії Python
+
+Синтаксис із використанням `typing` **сумісний** з усіма версіями, від Python 3.6 до останніх, включаючи Python 3.9, Python 3.10 тощо.
+
+У міру розвитку Python **новіші версії** мають покращену підтримку анотацій типів і в багатьох випадках вам навіть не потрібно буде імпортувати та використовувати модуль `typing` для оголошення анотацій типу.
+
+Якщо ви можете вибрати новішу версію Python для свого проекту, ви зможете скористатися цією додатковою простотою. Дивіться кілька прикладів нижче.
+
+#### List (список)
+
+Наприклад, давайте визначимо змінну, яка буде `list` із `str`.
+
+//// tab | Python 3.8 і вище
+
+З модуля `typing`, імпортуємо `List` (з великої літери `L`):
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial006.py!}
+```
+
+Оголосимо змінну з тим самим синтаксисом двокрапки (`:`).
+
+Як тип вкажемо `List`, який ви імпортували з `typing`.
+
+Оскільки список є типом, який містить деякі внутрішні типи, ви поміщаєте їх у квадратні дужки:
+
+```Python hl_lines="4"
+{!> ../../docs_src/python_types/tutorial006.py!}
+```
+
+////
+
+//// tab | Python 3.9 і вище
+
+Оголосимо змінну з тим самим синтаксисом двокрапки (`:`).
+
+Як тип вкажемо `list`.
+
+Оскільки список є типом, який містить деякі внутрішні типи, ви поміщаєте їх у квадратні дужки:
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial006_py39.py!}
+```
+
+////
+
+/// info
+
+Ці внутрішні типи в квадратних дужках називаються "параметрами типу".
+
+У цьому випадку, `str` це параметр типу переданий у `List` (або `list` у Python 3.9 і вище).
+
+///
+
+Це означає: "змінна `items` це `list`, і кожен з елементів у цьому списку - `str`".
+
+/// tip
+
+Якщо ви використовуєте Python 3.9 і вище, вам не потрібно імпортувати `List` з `typing`, ви можете використовувати натомість тип `list`.
+
+///
+
+Зробивши це, ваш редактор може надати підтримку навіть під час обробки елементів зі списку:
+
+

+
+Без типів цього майже неможливо досягти.
+
+Зверніть увагу, що змінна `item` є одним із елементів у списку `items`.
+
+І все ж редактор знає, що це `str`, і надає підтримку для цього.
+
+#### Tuple and Set (кортеж та набір)
+
+Ви повинні зробити те ж саме, щоб оголосити `tuple` і `set`:
+
+//// tab | Python 3.8 і вище
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial007.py!}
+```
+
+////
+
+//// tab | Python 3.9 і вище
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial007_py39.py!}
+```
+
+////
+
+Це означає:
+
+* Змінна `items_t` це `tuple` з 3 елементами, `int`, ще `int`, та `str`.
+* Змінна `items_s` це `set`, і кожен його елемент типу `bytes`.
+
+#### Dict (словник)
+
+Щоб оголосити `dict`, вам потрібно передати 2 параметри типу, розділені комами.
+
+Перший параметр типу для ключа у `dict`.
+
+Другий параметр типу для значення у `dict`:
+
+//// tab | Python 3.8 і вище
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial008.py!}
+```
+
+////
+
+//// tab | Python 3.9 і вище
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008_py39.py!}
+```
+
+////
+
+Це означає:
+
+* Змінна `prices` це `dict`:
+ * Ключі цього `dict` типу `str` (наприклад, назва кожного елементу).
+ * Значення цього `dict` типу `float` (наприклад, ціна кожного елементу).
+
+#### Union (об'єднання)
+
+Ви можете оголосити, що змінна може бути будь-яким із **кількох типів**, наприклад, `int` або `str`.
+
+У Python 3.6 і вище (включаючи Python 3.10) ви можете використовувати тип `Union` з `typing` і вставляти в квадратні дужки можливі типи, які можна прийняти.
+
+У Python 3.10 також є **альтернативний синтаксис**, у якому ви можете розділити можливі типи за допомогою
вертикальної смуги (`|`).
+
+//// tab | Python 3.8 і вище
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial008b.py!}
+```
+
+////
+
+//// tab | Python 3.10 і вище
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
+```
+
+////
+
+В обох випадках це означає, що `item` може бути `int` або `str`.
+
+#### Possibly `None` (Optional)
+
+Ви можете оголосити, що значення може мати тип, наприклад `str`, але також може бути `None`.
+
+У Python 3.6 і вище (включаючи Python 3.10) ви можете оголосити його, імпортувавши та використовуючи `Optional` з модуля `typing`.
+
+```Python hl_lines="1 4"
+{!../../docs_src/python_types/tutorial009.py!}
+```
+
+Використання `Optional[str]` замість просто `str` дозволить редактору допомогти вам виявити помилки, коли ви могли б вважати, що значенням завжди є `str`, хоча насправді воно також може бути `None`.
+
+`Optional[Something]` насправді є скороченням для `Union[Something, None]`, вони еквівалентні.
+
+Це також означає, що в Python 3.10 ви можете використовувати `Something | None`:
+
+//// tab | Python 3.8 і вище
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial009.py!}
+```
+
+////
+
+//// tab | Python 3.8 і вище - альтернатива
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial009b.py!}
+```
+
+////
+
+//// tab | Python 3.10 і вище
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial009_py310.py!}
+```
+
+////
+
+#### Generic типи
+
+Ці типи, які приймають параметри типу у квадратних дужках, називаються **Generic types** or **Generics**, наприклад:
+
+//// tab | Python 3.8 і вище
+
+* `List`
+* `Tuple`
+* `Set`
+* `Dict`
+* `Union`
+* `Optional`
+* ...та інші.
+
+////
+
+//// tab | Python 3.9 і вище
+
+Ви можете використовувати ті самі вбудовані типи, як generic (з квадратними дужками та типами всередині):
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+І те саме, що й у Python 3.8, із модуля `typing`:
+
+* `Union`
+* `Optional`
+* ...та інші.
+
+////
+
+//// tab | Python 3.10 і вище
+
+Ви можете використовувати ті самі вбудовані типи, як generic (з квадратними дужками та типами всередині):
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+І те саме, що й у Python 3.8, із модуля `typing`:
+
+* `Union`
+* `Optional` (так само як у Python 3.8)
+* ...та інші.
+
+У Python 3.10, як альтернатива використанню `Union` та `Optional`, ви можете використовувати
вертикальну смугу (`|`) щоб оголосити об'єднання типів.
+
+////
+
+### Класи як типи
+
+Ви також можете оголосити клас як тип змінної.
+
+Скажімо, у вас є клас `Person` з імʼям:
+
+{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+
+
+Потім ви можете оголосити змінну типу `Person`:
+
+{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+
+
+І знову ж таки, ви отримуєте всю підтримку редактора:
+
+

+
+## Pydantic моделі
+
+
Pydantic це бібліотека Python для валідації даних.
+
+Ви оголошуєте «форму» даних як класи з атрибутами.
+
+І кожен атрибут має тип.
+
+Потім ви створюєте екземпляр цього класу з деякими значеннями, і він перевірить ці значення, перетворить їх у відповідний тип (якщо є потреба) і надасть вам об’єкт з усіма даними.
+
+І ви отримуєте всю підтримку редактора з цим отриманим об’єктом.
+
+Приклад з документації Pydantic:
+
+//// tab | Python 3.8 і вище
+
+```Python
+{!> ../../docs_src/python_types/tutorial011.py!}
+```
+
+////
+
+//// tab | Python 3.9 і вище
+
+```Python
+{!> ../../docs_src/python_types/tutorial011_py39.py!}
+```
+
+////
+
+//// tab | Python 3.10 і вище
+
+```Python
+{!> ../../docs_src/python_types/tutorial011_py310.py!}
+```
+
+////
+
+/// info
+
+Щоб дізнатись більше про
Pydantic, перегляньте його документацію.
+
+///
+
+**FastAPI** повністю базується на Pydantic.
+
+Ви побачите набагато більше цього всього на практиці в [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
+
+## Анотації типів у **FastAPI**
+
+**FastAPI** використовує ці підказки для виконання кількох речей.
+
+З **FastAPI** ви оголошуєте параметри з підказками типу, і отримуєте:
+
+* **Підтримку редактора**.
+* **Перевірку типів**.
+
+...і **FastAPI** використовує ті самі оголошення для:
+
+* **Визначення вимог**: з параметрів шляху запиту, параметрів запиту, заголовків, тіл, залежностей тощо.
+* **Перетворення даних**: із запиту в необхідний тип.
+* **Перевірка даних**: що надходять від кожного запиту:
+ * Генерування **автоматичних помилок**, що повертаються клієнту, коли дані недійсні.
+* **Документування** API за допомогою OpenAPI:
+ * який потім використовується для автоматичної інтерактивної документації користувальницьких інтерфейсів.
+
+Все це може здатися абстрактним. Не хвилюйтеся. Ви побачите все це в дії в [Туторіал - Посібник користувача](tutorial/index.md){.internal-link target=_blank}.
+
+Важливо те, що за допомогою стандартних типів Python в одному місці (замість того, щоб додавати більше класів, декораторів тощо), **FastAPI** зробить багато роботи за вас.
+
+/// info
+
+Якщо ви вже пройшли весь навчальний посібник і повернулися, щоб дізнатися більше про типи, ось хороший ресурс
"шпаргалка" від `mypy`.
+
+///
diff --git a/docs/uk/docs/tutorial/background-tasks.md b/docs/uk/docs/tutorial/background-tasks.md
new file mode 100644
index 000000000..912ba8c2a
--- /dev/null
+++ b/docs/uk/docs/tutorial/background-tasks.md
@@ -0,0 +1,85 @@
+# Фонові задачі
+
+Ви можете створювати фонові задачі, які будуть виконуватися *після* повернення відповіді.
+
+Це корисно для операцій, які потрібно виконати після обробки запиту, але клієнту не обов’язково чекати завершення цієї операції перед отриманням відповіді.
+
+Приклади використання:
+
+* Надсилання email-сповіщень після виконання певної дії:
+ * Підключення до поштового сервера та надсилання листа може займати кілька секунд. Ви можете відразу повернути відповідь, а email відправити у фоні.
+* Обробка даних:
+ * Наприклад, якщо отримано файл, який потрібно обробити довготривалим процесом, можна повернути відповідь "Accepted" ("Прийнято", HTTP 202) і виконати обробку файлу у фоні.
+
+## Використання `BackgroundTasks`
+
+Спочатку імпортуйте `BackgroundTasks` і додайте його як параметр у Вашу *функцію операції шляху* (path operation function) до `BackgroundTasks`:
+
+{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+
+**FastAPI** автоматично створить об'єкт `BackgroundTasks` і передасть його у цей параметр.
+
+
+## Створення функції задачі
+
+Створіть функцію, яка буде виконувати фонову задачу.
+
+Це звичайна функція, яка може отримувати параметри.
+
+Вона може бути асинхронною `async def` або звичайною `def` функцією – **FastAPI** обробить її правильно.
+
+У нашому випадку функція записує у файл (імітуючи надсилання email).
+
+І оскільки операція запису не використовує `async` та `await`, ми визначаємо функцію як звичайну `def`:
+
+{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+
+## Додавання фонової задачі
+
+Усередині Вашої *функції обробки шляху*, передайте функцію задачі в об'єкт *background tasks*, використовуючи метод `.add_task()`:
+
+{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+
+`.add_task()` приймає аргументи:
+
+* Функція задача, яка буде виконуватися у фоновому режимі (`write_notification`). Зверніть увагу, що передається обʼєкт без дужок.
+* Будь-яка послідовність аргументів, які потрібно передати у функцію завдання у відповідному порядку (`email`).
+* Будь-які іменовані аргументи, які потрібно передати у функцію задачу (`message="some notification"`).
+
+## Впровадження залежностей
+
+Використання `BackgroundTasks` також працює з системою впровадження залежностей. Ви можете оголосити параметр типу `BackgroundTasks` на різних рівнях: у *функції операції шляху*, у залежності (dependable), у під залежності тощо.
+
+**FastAPI** знає, як діяти в кожному випадку і як повторно використовувати один і той самий об'єкт, щоб усі фонові задачі були об’єднані та виконувалися у фоновому режимі після завершення основного запиту.
+
+{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
+
+У цьому прикладі повідомлення будуть записані у файл `log.txt` *після* того, як відповідь буде надіслана.
+
+Якщо у запиті був переданий query-параметр, він буде записаний у лог у фоновій задачі.
+
+А потім інша фонова задача, яка створюється у *функції операції шляху*, запише повідомлення з використанням path параметра `email`.
+
+## Технічні деталі
+
+Клас `BackgroundTasks` походить безпосередньо з
`starlette.background`.
+
+Він імпортується безпосередньо у FastAPI, щоб Ви могли використовувати його з `fastapi` і випадково не імпортували `BackgroundTask` (без s в кінці) з `starlette.background`.
+
+Якщо використовувати лише `BackgroundTasks` (а не `BackgroundTask`), то його можна передавати як параметр у *функції операції шляху*, і **FastAPI** подбає про все інше, так само як і про використання об'єкта `Request`.
+
+Також можна використовувати `BackgroundTask` окремо в FastAPI, але для цього Вам доведеться створити об'єкт у коді та повернути Starlette `Response`, включаючи його.
+
+Детальніше можна почитати в
офіційній документації Starlette про фонові задачі .
+
+## Застереження
+
+Якщо Вам потрібно виконувати складні фонові обчислення, і при цьому нема потреби запускати їх у тому ж процесі (наприклад, не потрібно спільного доступу до пам’яті чи змінних), можливо, варто скористатися більш потужними інструментами, такими як
Celery.
+
+Такі інструменти зазвичай потребують складнішої конфігурації та менеджера черги повідомлень/завдань, наприклад, RabbitMQ або Redis. Однак вони дозволяють виконувати фонові задачі в кількох процесах і навіть на кількох серверах.
+
+Якщо ж Вам потрібно отримати доступ до змінних і об’єктів із тієї ж **FastAPI** - програми або виконувати невеликі фонові завдання (наприклад, надсилати сповіщення електронною поштою), достатньо просто використовувати `BackgroundTasks`.
+
+## Підсумок
+
+Імпортуйте та використовуйте `BackgroundTasks` як параметр у *функціях операції шляху* та залежностях, щоб додавати фонові задачі.
diff --git a/docs/uk/docs/tutorial/body-fields.md b/docs/uk/docs/tutorial/body-fields.md
new file mode 100644
index 000000000..7ddd9d104
--- /dev/null
+++ b/docs/uk/docs/tutorial/body-fields.md
@@ -0,0 +1,60 @@
+# Тіло - Поля
+
+Так само як ви можете визначати додаткову валідацію та метадані у параметрах *функції обробки шляху* за допомогою `Query`, `Path` та `Body`, ви можете визначати валідацію та метадані всередині моделей Pydantic за допомогою `Field` від Pydantic.
+
+## Імпорт `Field`
+
+Спочатку вам потрібно імпортувати це:
+
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
+
+/// warning
+
+Зверніть увагу, що `Field` імпортується прямо з `pydantic`, а не з `fastapi`, як всі інші (`Query`, `Path`, `Body` тощо).
+
+///
+
+## Оголошення атрибутів моделі
+
+Ви можете використовувати `Field` з атрибутами моделі:
+
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[11:14] *}
+
+`Field` працює так само, як `Query`, `Path` і `Body`, у нього такі самі параметри тощо.
+
+/// note | Технічні деталі
+
+Насправді, `Query`, `Path` та інші, що ви побачите далі, створюють об'єкти підкласів загального класу `Param`, котрий сам є підкласом класу `FieldInfo` з Pydantic.
+
+І `Field` від Pydantic також повертає екземпляр `FieldInfo`.
+
+`Body` також безпосередньо повертає об'єкти підкласу `FieldInfo`. І є інші підкласи, які ви побачите пізніше, що є підкласами класу Body.
+
+Пам'ятайте, що коли ви імпортуєте 'Query', 'Path' та інше з 'fastapi', вони фактично є функціями, які повертають спеціальні класи.
+
+///
+
+/// tip
+
+Зверніть увагу, що кожен атрибут моделі із типом, значенням за замовчуванням та `Field` має ту саму структуру, що й параметр *функції обробки шляху*, з `Field` замість `Path`, `Query` і `Body`.
+
+///
+
+## Додавання додаткової інформації
+
+Ви можете визначити додаткову інформацію у `Field`, `Query`, `Body` тощо. І вона буде включена у згенеровану JSON схему.
+
+Ви дізнаєтеся більше про додавання додаткової інформації пізніше у документації, коли вивчатимете визначення прикладів.
+
+/// warning
+
+Додаткові ключі, передані в `Field`, також будуть присутні у згенерованій схемі OpenAPI для вашого додатка.
+Оскільки ці ключі не обов'язково можуть бути частиною специфікації OpenAPI, деякі інструменти OpenAPI, наприклад, [OpenAPI валідатор](https://validator.swagger.io/), можуть не працювати з вашою згенерованою схемою.
+
+///
+
+## Підсумок
+
+Ви можете використовувати `Field` з Pydantic для визначення додаткових перевірок та метаданих для атрибутів моделі.
+
+Ви також можете використовувати додаткові іменовані аргументи для передачі додаткових метаданих JSON схеми.
diff --git a/docs/uk/docs/tutorial/body-multiple-params.md b/docs/uk/docs/tutorial/body-multiple-params.md
new file mode 100644
index 000000000..e2acf8a70
--- /dev/null
+++ b/docs/uk/docs/tutorial/body-multiple-params.md
@@ -0,0 +1,170 @@
+# Тіло запиту - Декілька параметрів
+
+Тепер, коли ми розглянули використання `Path` та `Query`, розгляньмо більш просунуті способи оголошення тіла запиту в **FastAPI**.
+
+## Змішування `Path`, `Query` та параметрів тіла запиту
+
+По-перше, звісно, Ви можете вільно змішувати оголошення параметрів `Path`, `Query` та тіла запиту, і **FastAPI** правильно їх обробить.
+
+Також Ви можете оголосити параметри тіла як необов’язкові, встановивши для них значення за замовчуванням `None`:
+
+{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
+
+/// note | Примітка
+
+Зверніть увагу, що в цьому випадку параметр `item`, який береться з тіла запиту, є необов'язковим, оскільки має значення за замовчуванням `None`.
+
+///
+
+## Декілька параметрів тіла запиту
+
+У попередньому прикладі *операція шляху* очікувала JSON з атрибутами `Item`, наприклад:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+}
+```
+Але Ви також можете оголосити декілька параметрів тіла, наприклад `item` та `user`:
+
+{* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
+
+У цьому випадку **FastAPI** розпізнає, що є кілька параметрів тіла (два параметри є моделями Pydantic).
+
+Тому він використає назви параметрів як ключі (назви полів) у тілі запиту, очікуючи:
+
+```JSON
+{
+ "item": {
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+ },
+ "user": {
+ "username": "dave",
+ "full_name": "Dave Grohl"
+ }
+}
+```
+
+/// note | Примітка
+
+Зверніть увагу, що хоча `item` оголошено, так само як і раніше, тепер він очікується в тілі під ключем `item`.
+
+///
+
+**FastAPI** автоматично конвертує дані із запиту таким чином, щоб параметр `item` отримав свій вміст, і те ж саме стосується `user`.
+
+Він виконає валідацію складених даних і задокументує їх відповідним чином у схемі OpenAPI та в автоматичній документації.
+
+## Одиничні значення в тілі запиту
+
+Так само як є `Query` і `Path` для визначення додаткових даних для параметрів запиту та шляху, **FastAPI** надає еквівалентний `Body`.
+
+Наприклад, розширюючи попередню модель, Ви можете вирішити додати ще один ключ `importance` в те ж саме тіло запиту разом із `item` і `user`.
+
+Якщо Ви оголосите його як є, то, оскільки це одиничне значення, **FastAPI** припускатиме, що це параметр запиту (query parameter).
+
+Але Ви можете вказати **FastAPI** обробляти його як інший ключ тіла (body key), використовуючи `Body`:
+
+{* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
+
+У цьому випадку **FastAPI** очікуватиме тіло запиту у такому вигляді:
+
+```JSON
+{
+ "item": {
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+ },
+ "user": {
+ "username": "dave",
+ "full_name": "Dave Grohl"
+ },
+ "importance": 5
+}
+```
+Знову ж таки, **FastAPI** конвертуватиме типи даних, перевірятиме їх, створюватиме документацію тощо.
+
+## Декілька body та query параметрів
+
+Звісно, Ви можете оголошувати додаткові query параметри запиту, коли це необхідно, на додаток до будь-яких параметрів тіла запиту.
+
+Оскільки за замовчуванням окремі значення інтерпретуються як параметри запиту, Вам не потрібно явно додавати `Query`, можна просто використати:
+
+```Python
+q: Union[str, None] = None
+```
+
+Або в Python 3.10 та вище:
+
+```Python
+q: str | None = None
+```
+
+Наприклад:
+
+{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
+
+
+/// info | Інформація
+
+`Body` також має ті самі додаткові параметри валідації та метаданих, що й `Query`, `Path` та інші, які Ви побачите пізніше.
+
+///
+
+## Вкладений поодинокий параметр тіла запиту
+
+Припустимо, у вас є лише один параметр тіла запиту `item` з моделі Pydantic `Item`.
+
+За замовчуванням **FastAPI** очікуватиме, що тіло запиту міститиме вміст безпосередньо.
+
+Але якщо Ви хочете, щоб він очікував JSON з ключем `item`, а всередині — вміст моделі (так, як це відбувається при оголошенні додаткових параметрів тіла), Ви можете використати спеціальний параметр `Body` — `embed`:
+
+```Python
+item: Item = Body(embed=True)
+```
+
+як у прикладі:
+
+{* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
+
+У цьому випадку **FastAPI** очікуватиме тіло запиту такого вигляду:
+
+```JSON hl_lines="2"
+{
+ "item": {
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+ }
+}
+```
+
+замість:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2
+}
+```
+
+## Підсумок
+
+Ви можете додавати кілька параметрів тіла до Вашої *функції операції шляху* (*path operation function*), навіть якщо запит може мати лише одне тіло.
+
+Але **FastAPI** обробить це, надасть Вам потрібні дані у функції, перевірить їх та задокументує коректну схему в *операції шляху*.
+
+Також Ви можете оголошувати окремі значення, які будуть отримані як частина тіла запиту.
+
+Крім того, Ви можете вказати **FastAPI** вбудовувати тіло в ключ, навіть якщо оголошено лише один параметр.
diff --git a/docs/uk/docs/tutorial/body-nested-models.md b/docs/uk/docs/tutorial/body-nested-models.md
new file mode 100644
index 000000000..abc33f2eb
--- /dev/null
+++ b/docs/uk/docs/tutorial/body-nested-models.md
@@ -0,0 +1,245 @@
+# Тіло запиту - Вкладені моделі
+
+З **FastAPI** Ви можете визначати, перевіряти, документувати та використовувати моделі, які можуть бути вкладені на будь-яку глибину (завдяки Pydantic).
+
+## Поля списку
+
+Ви можете визначити атрибут як підтип. Наприклад, Python-список (`list`):
+
+{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
+
+Це зробить `tags` списком, хоча не визначається тип елементів списку.
+
+## Поля списку з параметром типу
+
+Але Python має специфічний спосіб оголошення списків з внутрішніми типами або "параметрами типу":
+### Імпортуємо `List` з модуля typing
+
+У Python 3.9 і вище можна використовувати стандартний `list` для оголошення таких типів, як ми побачимо нижче. 💡
+
+Але в Python версії до 3.9 (від 3.6 і вище) спочатку потрібно імпортувати `List` з модуля стандартної бібліотеки Python `typing`:
+
+{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
+
+### Оголошення `list` з параметром типу
+
+Щоб оголосити типи з параметрами типу (внутрішніми типами), такими як `list`, `dict`, `tuple`:
+
+* Якщо Ви використовуєте версію Python до 3.9, імпортуйте їх відповідну версію з модуля `typing`.
+* Передайте внутрішні типи як "параметри типу", використовуючи квадратні дужки: `[` and `]`.
+
+У Python 3.9 це буде виглядати так:
+
+```Python
+my_list: list[str]
+```
+
+У версіях Python до 3.9 це виглядає так:
+
+```Python
+from typing import List
+
+my_list: List[str]
+```
+
+Це стандартний синтаксис Python для оголошення типів.
+
+Використовуйте той самий стандартний синтаксис для атрибутів моделей з внутрішніми типами.
+
+Отже, у нашому прикладі, ми можемо зробити `tags` саме "списком рядків":
+
+{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
+
+## Типи множин
+
+Але потім ми подумали, що теги не повинні повторюватися, вони, ймовірно, повинні бути унікальними рядками.
+
+І Python має спеціальний тип даних для множин унікальних елементів — це `set`.
+
+Тому ми можемо оголосити `tags` як множину рядків:
+
+{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
+
+Навіть якщо Ви отримаєте запит з дубльованими даними, він буде перетворений у множину унікальних елементів.
+
+І коли Ви будете виводити ці дані, навіть якщо джерело містить дублікати, вони будуть виведені як множина унікальних елементів.
+
+І це буде анотовано/документовано відповідно.
+
+## Вкладені моделі
+
+Кожен атрибут моделі Pydantic має тип.
+
+Але цей тип сам може бути іншою моделлю Pydantic.
+
+Отже, Ви можете оголосити глибоко вкладені JSON "об'єкти" з конкретними іменами атрибутів, типами та перевірками.
+
+Усе це, вкладене без обмежень.
+
+### Визначення підмоделі
+
+Наприклад, ми можемо визначити модель `Image`:
+
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
+
+### Використання підмоделі як типу
+
+А потім ми можемо використовувати її як тип атрибута:
+
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
+
+Це означатиме, що **FastAPI** очікуватиме тіло запиту такого вигляду:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2,
+ "tags": ["rock", "metal", "bar"],
+ "image": {
+ "url": "http://example.com/baz.jpg",
+ "name": "The Foo live"
+ }
+}
+```
+
+Завдяки такій декларації у **FastAPI** Ви отримуєте:
+
+* Підтримку в редакторі (автозавершення тощо), навіть для вкладених моделей
+* Конвертацію даних
+* Валідацію даних
+* Автоматичну документацію
+
+## Спеціальні типи та валідація
+
+Окрім звичайних типів, таких як `str`, `int`, `float`, та ін. Ви можете використовувати складніші типи, які наслідують `str`.
+
+Щоб побачити всі доступні варіанти, ознайомтеся з оглядом
типів у Pydantic. Деякі приклади будуть у наступних розділах.
+
+Наприклад, у моделі `Image` є поле `url`, тому ми можемо оголосити його як `HttpUrl` від Pydantic замість `str`:
+
+{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
+
+Рядок буде перевірено як дійсну URL-адресу і задокументовано в JSON Schema / OpenAPI як URL.
+
+## Атрибути зі списками підмоделей
+
+У Pydantic Ви можете використовувати моделі як підтипи для `list`, `set` тощо:
+
+{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
+
+Це означає, що **FastAPI** буде очікувати (конвертувати, валідувати, документувати тощо) JSON тіло запиту у вигляді:
+
+```JSON hl_lines="11"
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2,
+ "tags": [
+ "rock",
+ "metal",
+ "bar"
+ ],
+ "images": [
+ {
+ "url": "http://example.com/baz.jpg",
+ "name": "The Foo live"
+ },
+ {
+ "url": "http://example.com/dave.jpg",
+ "name": "The Baz"
+ }
+ ]
+}
+```
+
+/// info | Інформація
+
+Зверніть увагу, що тепер ключ `images` містить список об'єктів зображень.
+
+///
+
+## Глибоко вкладені моделі
+
+Ви можете визначати вкладені моделі довільної глибини:
+
+{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
+
+/// info | Інформація
+
+Зверніть увагу, що в моделі `Offer` є список `Item`ів, які, своєю чергою, можуть мати необов'язковий список `Image`ів.
+
+///
+
+## Тіла запитів, що складаються зі списків
+
+Якщо верхній рівень JSON тіла, яке Ви очікуєте, є JSON `масивом` (у Python — `list`), Ви можете оголосити тип у параметрі функції, як і в моделях Pydantic:
+
+```Python
+images: List[Image]
+```
+або в Python 3.9 і вище:
+
+```Python
+images: list[Image]
+```
+
+наприклад:
+
+{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
+
+## Підтримка в редакторі всюди
+
+Ви отримаєте підтримку в редакторі всюди.
+
+Навіть для елементів у списках:
+
+

+
+Ви не змогли б отримати таку підтримку в редакторі, якби працювали напряму зі `dict`, а не з моделями Pydantic.
+
+Але Вам не потрібно турбуватися про це: вхідні dict'и автоматично конвертуються, а вихідні дані автоматично перетворюються в JSON.
+
+## Тіла з довільними `dict`
+
+Ви також можете оголосити тіло як `dict` з ключами одного типу та значеннями іншого типу.
+
+Це корисно, якщо Ви не знаєте наперед, які імена полів будуть дійсними (як у випадку з моделями Pydantic).
+
+Це буде корисно, якщо Ви хочете приймати ключі, які заздалегідь невідомі.
+
+---
+
+Це також зручно, якщо Ви хочете мати ключі іншого типу (наприклад, `int`).
+
+Ось що ми розглянемо далі.
+
+У цьому випадку Ви можете приймати будь-який `dict`, якщо його ключі — це `int`, а значення — `float`:
+
+{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
+
+/// tip | Порада
+
+Майте на увазі, що в JSON тілі ключі можуть бути лише рядками (`str`).
+
+Але Pydantic автоматично конвертує дані.
+
+Це означає, що навіть якщо клієнти вашого API надсилатимуть ключі у вигляді рядків, якщо вони містять цілі числа, Pydantic конвертує їх і проведе валідацію.
+
+Тобто `dict`, який Ви отримаєте як `weights`, матиме ключі типу `int` та значення типу `float`.
+
+///
+
+## Підсумок
+
+З **FastAPI** Ви маєте максимальну гнучкість завдяки моделям Pydantic, зберігаючи при цьому код простим, коротким та елегантним.
+
+А також отримуєте всі переваги:
+
+* Підтримка в редакторі (автодоповнення всюди!)
+* Конвертація даних (парсинг/сериалізація)
+* Валідація даних
+* Документація схем
+* Автоматичне створення документації
diff --git a/docs/uk/docs/tutorial/body-updates.md b/docs/uk/docs/tutorial/body-updates.md
new file mode 100644
index 000000000..e78b5a5bf
--- /dev/null
+++ b/docs/uk/docs/tutorial/body-updates.md
@@ -0,0 +1,116 @@
+# Тіло – Оновлення
+
+## Оновлення з використанням `PUT`
+
+Щоб оновити елемент, Ви можете використати
HTTP `PUT` операцію.
+
+Ви можете використати `jsonable_encoder`, щоб перетворити вхідні дані на такі, які можна зберігати як JSON (наприклад, у NoSQL базі даних). Наприклад, перетворюючи `datetime` у `str`.
+
+{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
+
+`PUT` використовується для отримання даних, які мають замінити чинні дані.
+
+### Попередження про заміну
+
+Це означає, що якщо Ви хочете оновити елемент `bar`, використовуючи `PUT` з тілом:
+
+```Python
+{
+ "name": "Barz",
+ "price": 3,
+ "description": None,
+}
+```
+
+оскільки він не містить вже збереженого атрибута `"tax": 20.2`, модель введення прийме значення за замовчуванням `"tax": 10.5`.
+
+І дані будуть збережені з цим "новим" значенням `tax` = `10.5`.
+
+## Часткові оновлення з `PATCH`
+
+Ви також можете використовувати операцію
HTTP `PATCH` для *часткового* оновлення даних.
+
+Це означає, що Ви можете надіслати лише ті дані, які хочете оновити, залишаючи інші без змін.
+
+/// note | Примітка
+
+`PATCH` менш відомий і рідше використовується, ніж `PUT`.
+
+І багато команд використовують лише `PUT`, навіть для часткових оновлень.
+
+Ви **вільні** використовувати їх так, як хочете, **FastAPI** не накладає обмежень.
+
+Але цей посібник показує Вам більш-менш як їх задумано використовувати.
+
+///
+
+### Використання параметра `exclude_unset` у Pydantic
+
+Якщо Ви хочете отримати часткові оновлення, дуже зручно використовувати параметр `exclude_unset` у методі `.model_dump()` моделі Pydantic.
+
+Наприклад: `item.model_dump(exclude_unset=True)`.
+
+/// info | Інформація
+
+У Pydantic v1 цей метод називався `.dict()`, він був застарілий (але все ще підтримується) у Pydantic v2, і був перейменований у `.model_dump()`.
+
+Приклади тут використовують `.dict()` для сумісності з Pydantic v1, але Вам слід використовувати `.model_dump()`, якщо можете використовувати Pydantic v2.
+
+///
+
+Це створить `dict` лише з тими даними, які були явно встановлені під час створення моделі `item`, виключаючи значення за замовчуванням.
+
+Тоді Ви можете використовувати це, щоб створити `dict` лише з даними, які були встановлені (надіслані у запиті), пропускаючи значення за замовчуванням:
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
+
+### Використання параметра `update` у Pydantic
+
+Тепер Ви можете створити копію наявної моделі за допомогою `.model_copy()`, і передати параметр `update` з `dict` , який містить дані для оновлення.
+
+/// info | Інформація
+
+У Pydantic v1 метод називався `.copy()`, він був застарілий (але все ще підтримується) у Pydantic v2, і був перейменований у `.model_copy()`.
+
+Приклади тут використовують `.copy()` для сумісності з Pydantic v1, але якщо Ви можете використовувати Pydantic v2 — Вам слід використовувати `.model_copy()` замість цього.
+
+///
+
+Наприклад: `stored_item_model.model_copy(update=update_data)`:
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
+
+### Підсумок часткових оновлень
+
+У підсумку, щоб застосувати часткові оновлення, Ви:
+
+* (Опціонально) використовуєте `PATCH` замість `PUT`.
+* Отримуєте збережені дані.
+* Поміщаєте ці дані в модель Pydantic.
+* Генеруєте `dict` без значень за замовчуванням з моделі введення (використовуючи `exclude_unset`).
+ * Таким чином Ви оновите лише ті значення, які були явно задані користувачем, замість того, щоб перезаписувати вже збережені значення значеннями за замовчуванням з вашої моделі.
+* Створюєте копію збереженої моделі, оновлюючи її атрибути отриманими частковими оновленнями (використовуючи параметр `update`).
+* Перетворюєте скопійовану модель на щось, що можна зберегти у вашу БД (наприклад, використовуючи `jsonable_encoder`).
+ * Це можна порівняти з повторним використанням методу `.model_dump()` моделі, але це гарантує (і перетворює) значення у типи даних, які можна перетворити на JSON, наприклад, `datetime` на `str`.
+* Зберігаєте дані у вашу БД.
+* Повертаєте оновлену модель.
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
+
+/// tip | Порада
+
+Насправді Ви можете використовувати цю саму техніку і з операцією HTTP `PUT`.
+
+Але приклад тут використовує `PATCH`, тому що він був створений саме для таких випадків.
+
+///
+
+/// note | Примітка
+
+Зверніть увагу, що модель запиту все ще проходить валідацію.
+
+Тож, якщо Ви хочете отримувати часткові оновлення, які можуть не містити жодного атрибута, Вам потрібно мати модель, де всі атрибути позначені як необов’язкові (зі значеннями за замовчуванням або `None`).
+
+Щоб розрізняти моделі з усіма необов’язковими значеннями для **оновлення** і моделі з обов’язковими значеннями для **створення**, Ви можете скористатись ідеями, описаними у [Додаткові моделі](extra-models.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/uk/docs/tutorial/body.md b/docs/uk/docs/tutorial/body.md
new file mode 100644
index 000000000..38fed7bb8
--- /dev/null
+++ b/docs/uk/docs/tutorial/body.md
@@ -0,0 +1,162 @@
+# Тіло запиту
+
+Коли вам потрібно надіслати дані з клієнта (скажімо, браузера) до вашого API, ви надсилаєте їх як **тіло запиту**.
+
+Тіло **запиту** — це дані, надіслані клієнтом до вашого API. Тіло **відповіді** — це дані, які ваш API надсилає клієнту.
+
+Ваш API майже завжди має надсилати тіло **відповіді**. Але клієнтам не обов’язково потрібно постійно надсилати тіла **запитів**.
+
+Щоб оголосити тіло **запиту**, ви використовуєте
Pydantic моделі з усією їх потужністю та перевагами.
+
+/// info
+
+Щоб надіслати дані, ви повинні використовувати один із: `POST` (більш поширений), `PUT`, `DELETE` або `PATCH`.
+
+Надсилання тіла із запитом `GET` має невизначену поведінку в специфікаціях, проте воно підтримується FastAPI лише для дуже складних/екстремальних випадків використання.
+
+Оскільки це не рекомендується, інтерактивна документація з Swagger UI не відображатиме документацію для тіла запиту під час використання `GET`, і проксі-сервери в середині можуть не підтримувати її.
+
+///
+
+## Імпортуйте `BaseModel` від Pydantic
+
+Спочатку вам потрібно імпортувати `BaseModel` з `pydantic`:
+
+{* ../../docs_src/body/tutorial001.py hl[4] *}
+
+## Створіть свою модель даних
+
+Потім ви оголошуєте свою модель даних як клас, який успадковується від `BaseModel`.
+
+Використовуйте стандартні типи Python для всіх атрибутів:
+
+{* ../../docs_src/body/tutorial001.py hl[7:11] *}
+
+Так само, як і при оголошенні параметрів запиту, коли атрибут моделі має значення за замовчуванням, він не є обов’язковим. В іншому випадку це потрібно. Використовуйте `None`, щоб зробити його необов'язковим.
+
+Наприклад, ця модель вище оголошує JSON "`об'єкт`" (або Python `dict`), як:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "An optional description",
+ "price": 45.2,
+ "tax": 3.5
+}
+```
+
+...оскільки `description` і `tax` є необов'язковими (зі значенням за замовчуванням `None`), цей JSON "`об'єкт`" також буде дійсним:
+
+```JSON
+{
+ "name": "Foo",
+ "price": 45.2
+}
+```
+
+## Оголоси її як параметр
+
+Щоб додати модель даних до вашої *операції шляху*, оголосіть її так само, як ви оголосили параметри шляху та запиту:
+
+{* ../../docs_src/body/tutorial001.py hl[18] *}
+
+...і вкажіть її тип як модель, яку ви створили, `Item`.
+
+## Результати
+
+Лише з цим оголошенням типу Python **FastAPI** буде:
+
+* Читати тіло запиту як JSON.
+* Перетворювати відповідні типи (якщо потрібно).
+* Валідувати дані.
+ * Якщо дані недійсні, він поверне гарну та чітку помилку, вказуючи, де саме і які дані були неправильними.
+* Надавати отримані дані у параметрі `item`.
+ * Оскільки ви оголосили його у функції як тип `Item`, ви також матимете всю підтримку редактора (автозаповнення, тощо) для всіх атрибутів та їх типів.
+* Генерувати
JSON Schema визначення для вашої моделі, ви також можете використовувати їх де завгодно, якщо це має сенс для вашого проекту.
+* Ці схеми будуть частиною згенерованої схеми OpenAPI і використовуватимуться автоматичною документацією інтерфейсу користувача.
+
+## Автоматична документація
+
+Схеми JSON ваших моделей будуть частиною вашої схеми, згенерованої OpenAPI, і будуть показані в інтерактивній API документації:
+
+

+
+А також використовуватимуться в API документації всередині кожної *операції шляху*, якій вони потрібні:
+
+

+
+## Підтримка редактора
+
+У вашому редакторі, всередині вашої функції, ви будете отримувати підказки типу та завершення скрізь (це б не сталося, якби ви отримали `dict` замість моделі Pydantic):
+
+

+
+Ви також отримуєте перевірку помилок на наявність операцій з неправильним типом:
+
+

+
+Це не випадково, весь каркас був побудований навколо цього дизайну.
+
+І він був ретельно перевірений на етапі проектування, перед будь-яким впровадженням, щоб переконатися, що він працюватиме з усіма редакторами.
+
+Були навіть деякі зміни в самому Pydantic, щоб підтримати це.
+
+Попередні скріншоти були зроблені у
Visual Studio Code.
+
+Але ви отримаєте ту саму підтримку редактора у
PyCharm та більшість інших редакторів Python:
+
+

+
+/// tip
+
+Якщо ви використовуєте
PyCharm як ваш редактор, ви можете використати
Pydantic PyCharm Plugin.
+
+Він покращує підтримку редакторів для моделей Pydantic за допомогою:
+
+* автозаповнення
+* перевірки типу
+* рефакторингу
+* пошуку
+* інспекції
+
+///
+
+## Використовуйте модель
+
+Усередині функції ви можете отримати прямий доступ до всіх атрибутів об’єкта моделі:
+
+{* ../../docs_src/body/tutorial002.py hl[21] *}
+
+## Тіло запиту + параметри шляху
+
+Ви можете одночасно оголошувати параметри шляху та тіло запиту.
+
+**FastAPI** розпізнає, що параметри функції, які відповідають параметрам шляху, мають бути **взяті з шляху**, а параметри функції, які оголошуються як моделі Pydantic, **взяті з тіла запиту**.
+
+{* ../../docs_src/body/tutorial003.py hl[17:18] *}
+
+## Тіло запиту + шлях + параметри запиту
+
+Ви також можете оголосити параметри **тіло**, **шлях** і **запит** одночасно.
+
+**FastAPI** розпізнає кожен з них і візьме дані з потрібного місця.
+
+{* ../../docs_src/body/tutorial004.py hl[18] *}
+
+Параметри функції будуть розпізнаватися наступним чином:
+
+* Якщо параметр також оголошено в **шляху**, він використовуватиметься як параметр шляху.
+* Якщо параметр має **сингулярний тип** (наприклад, `int`, `float`, `str`, `bool` тощо), він буде інтерпретуватися як параметр **запиту**.
+* Якщо параметр оголошується як тип **Pydantic моделі**, він інтерпретується як **тіло** запиту.
+
+/// note
+
+FastAPI буде знати, що значення "q" не є обов'язковим через значення за замовчуванням "= None".
+
+`Optional` у `Optional[str]` не використовується FastAPI, але дозволить вашому редактору надати вам кращу підтримку та виявляти помилки.
+
+///
+
+## Без Pydantic
+
+Якщо ви не хочете використовувати моделі Pydantic, ви також можете використовувати параметри **Body**. Перегляньте документацію для [Тіло – Кілька параметрів: сингулярні значення в тілі](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
diff --git a/docs/uk/docs/tutorial/cookie-param-models.md b/docs/uk/docs/tutorial/cookie-param-models.md
new file mode 100644
index 000000000..f070b6ac8
--- /dev/null
+++ b/docs/uk/docs/tutorial/cookie-param-models.md
@@ -0,0 +1,76 @@
+# Моделі для Cookie-параметрів
+
+Якщо у Вас є група **cookies** параметрів, які пов'язані між собою, Ви можете створити **Pydantic-модель**, щоб оголосити їх. 🍪
+
+Це дозволить Вам повторно **використовувати модель** у **різних місцях**, а також оголосити валідацію та метадані для всіх параметрів одночасно. 😎
+
+/// note | Нотатки
+
+Це підтримується з версії FastAPI `0.115.0`. 🤓
+
+///
+
+/// tip | Порада
+
+Ця ж техніка застосовується до `Query`, `Cookie`, та `Header`. 😎
+
+///
+
+## Cookie з Pydantic-моделлю
+
+Оголосіть **cookie-параметри**, які Вам потрібні, у **Pydantic-моделі**, а потім оголосіть параметр як `Cookie`:
+
+{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
+
+**FastAPI** буде **витягувати** дані для **кожного поля** з **cookie** параметрів, отриманих у запиті, і передавати Вам Pydantic-модель, яку Ви визначили.
+
+## Перевірка у документації
+
+Ви можете побачити визначені cookie в інтерфейсі документації за адресою `/docs`:
+
+
+

+
+
+/// info | Інформація
+
+Майте на увазі, що оскільки **браузери обробляють cookie** особливим чином і "за лаштунками", вони **не** дозволяють **JavaScript** легко з ними працювати.
+
+Якщо Ви зайдете до **інтерфейсу документації API** за адресою `/docs`, Ви зможете побачити **документацію** для cookie у Ваших **операціях шляху**.
+
+Але навіть якщо Ви заповните дані й натиснете "Execute", оскільки інтерфейс документації працює з **JavaScript**, cookie не будуть відправлені, і Ви побачите **помилку**, ніби Ви не ввели жодних значень.
+
+///
+
+## Заборона додаткових cookie
+
+У деяких спеціальних випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** список cookie, які хочете отримувати.
+
+Ваша API тепер має можливість контролювати власну
згоду на cookie. 🤪🍪
+
+Ви можете використовувати налаштування моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
+
+{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
+
+Якщо клієнт спробує надіслати якісь **додаткові cookie**, він отримає відповідь з **помилкою**.
+
+Бідні банери cookie, які так старанно намагаються отримати Вашу згоду, щоб
API її відхилила. 🍪
+
+Наприклад, якщо клієнт спробує надіслати cookie `santa_tracker` зі значенням `good-list-please`, він отримає відповідь з помилкою, яка повідомить, що
cookie `santa_tracker` не дозволено:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["cookie", "santa_tracker"],
+ "msg": "Extra inputs are not permitted",
+ "input": "good-list-please",
+ }
+ ]
+}
+```
+
+## Підсумок
+
+Ви можете використовувати **Pydantic-моделі** для оголошення
cookie у FastAPI. 😎
diff --git a/docs/uk/docs/tutorial/cookie-params.md b/docs/uk/docs/tutorial/cookie-params.md
new file mode 100644
index 000000000..b320645cb
--- /dev/null
+++ b/docs/uk/docs/tutorial/cookie-params.md
@@ -0,0 +1,34 @@
+# Параметри Cookie
+
+Ви можете визначити параметри Cookie таким же чином, як визначаються параметри `Query` і `Path`.
+
+## Імпорт `Cookie`
+
+Спочатку імпортуйте `Cookie`:
+
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
+
+## Визначення параметрів `Cookie`
+
+Потім визначте параметри cookie, використовуючи таку ж конструкцію як для `Path` і `Query`.
+
+Перше значення це значення за замовчуванням, ви можете також передати всі додаткові параметри валідації чи анотації:
+
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | Технічні Деталі
+
+`Cookie` це "сестра" класів `Path` і `Query`. Вони наслідуються від одного батьківського класу `Param`.
+Але пам'ятайте, що коли ви імпортуєте `Query`, `Path`, `Cookie` та інше з `fastapi`, це фактично функції, що повертають спеціальні класи.
+
+///
+
+/// info
+
+Для визначення cookies ви маєте використовувати `Cookie`, тому що в іншому випадку параметри будуть інтерпритовані, як параметри запиту.
+
+///
+
+## Підсумки
+
+Визначайте cookies за допомогою `Cookie`, використовуючи той же спільний шаблон, що і `Query` та `Path`.
diff --git a/docs/uk/docs/tutorial/cors.md b/docs/uk/docs/tutorial/cors.md
new file mode 100644
index 000000000..95b204d0f
--- /dev/null
+++ b/docs/uk/docs/tutorial/cors.md
@@ -0,0 +1,89 @@
+# CORS (Обмін ресурсами між різними джерелами)
+
+
CORS або "Обмін ресурсами між різними джерелами" є ситуація, коли фронтенд, що працює в браузері, містить JavaScript-код, який взаємодіє з бекендом, розташованим в іншому "джерелі" (origin).
+
+## Джерело (Origin)
+
+Джерело визначається комбінацією протоколу (`http`, `https`), домену (`myapp.com`, `localhost`, `localhost.tiangolo.com`), порту (`80`, `443`, `8080`).
+
+
+Наприклад, такі адреси вважаються різними джерелами:
+
+* `http://localhost`
+* `https://localhost`
+* `http://localhost:8080`
+
+Навіть якщо вони всі містять `localhost`, вони мають різні протоколи або порти, що робить їх окремими "джерелами".
+
+## Кроки
+
+Припустимо, що Ваш фронтенд працює в браузері на `http://localhost:8080`, а його JavaScript намагається відправити запит до бекенду, який працює на `http://localhost` (Оскільки ми не вказуємо порт, браузер за замовчуванням припускає порт `80`).
+
+Потім браузер надішле HTTP-запит `OPTIONS` до бекенду на порту `:80`, і якщо бекенд надішле відповідні заголовки, що дозволяють комунікацію з цього іншого джерела (`http://localhost:8080`), тоді браузер на порту `:8080` дозволить JavaScript у фронтенді надіслати свій запит до бекенду на порту `:80`.
+
+Щоб досягти цього, бекенд на порту `:80` повинен мати список "дозволених джерел".
+
+У цьому випадку список має містити `http://localhost:8080`, щоб фронтенд на порту `:8080` працював коректно.
+
+## Символьне підставляння
+
+Можна також оголосити список як `"*"` ("символьне підставляння"), що означає дозвіл для всіх джерел.
+
+Однак це дозволить лише певні типи комунікації, виключаючи все, що пов'язане з обліковими даними: Cookies, заголовки авторизації, такі як ті, що використовуються з Bearer токенами тощо.
+
+Тому для коректної роботи краще явно вказувати дозволені джерела.
+
+## Використання `CORSMiddleware`
+
+Ви можете налаштувати це у Вашому додатку **FastAPI** за допомогою `CORSMiddleware`.
+
+* Імпортуйте `CORSMiddleware`.
+* Створіть список дозволених джерел (у вигляді рядків).
+* Додайте його як "middleware" у Ваш додаток **FastAPI**.
+
+
+Також можна вказати, чи дозволяє Ваш бекенд:
+
+* Облікові дані (заголовки авторизації, сookies, тощо).
+* Конкретні HTTP-методи (`POST`, `PUT`) або всі за допомогою `"*"`
+* Конкретні HTTP-заголовки або всі за допомогою `"*"`.
+
+
+{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+
+Параметри за замовчуванням у `CORSMiddleware` є досить обмеженими, тому Вам потрібно явно вказати конкретні джерела, методи або заголовки, щоб браузери могли використовувати їх у контексті запитів між різними доменами.
+
+
+Підтримуються такі аргументи:
+
+* `allow_origins` - Список джерел, яким дозволено здійснювати міждоменні запити. Наприклад `['https://example.org', 'https://www.example.org']`. Ви можете використовувати ['*'], щоб дозволити всі джерела.
+* `allow_origin_regex` - Рядок регулярного виразу для відповідності джерелам, яким дозволено здійснювати міждоменні запити. Наприклад, `'https://.*\.example\.org'`.
+* `allow_methods` - Список HTTP-методів, дозволених для міждоменних запитів. За замовчуванням `['GET']`. Ви можете використовувати `['*']`, щоб дозволити всі стандартні методи.
+* `allow_headers` - Список HTTP-заголовків, які підтримуються для міждоменних запитів. За замовчуванням `[]`. Ви можете використовувати `['*']`, щоб дозволити всі заголовки. Заголовки `Accept`, `Accept-Language`, `Content-Language` і `Content-Type` завжди дозволені для
простих CORS-запитів.
+* `allow_credentials` - Визначає, чи підтримуються файли cookie для міждоменних запитів. За замовчуванням `False`. Також, якщо потрібно дозволити обмін обліковими даними (`allow_credentials = True`), параметр `allow_origins` не може бути встановлений як `['*']`, необхідно вказати конкретні джерела.
+* `expose_headers` - Вказує, які заголовки відповіді повинні бути доступні для браузера. За замовчуванням `[]`.
+* `max_age` - Встановлює максимальний час (у секундах) для кешування CORS-відповідей у браузерах. За замовчуванням `600`.
+
+Цей middleware обробляє два типи HTTP-запитів...
+
+### Попередні CORS-запити (preflight requests)
+
+Це будь-які `OPTIONS` - запити, що містять заголовки `Origin` та `Access-Control-Request-Method`.
+
+У такому випадку middleware перехопить вхідний запит і відповість відповідними CORS-заголовками, повертаючи або `200`, або `400` для інформаційних цілей.
+
+### Прості запити
+
+Будь-які запити із заголовком `Origin`. У цьому випадку middleware пропустить запит як звичайний, але додасть відповідні CORS-заголовки у відповідь.
+
+## Додаткова інформація
+
+Більше про
CORS можна дізнатися в
документації Mozilla.
+
+/// note | Технічні деталі
+
+Також можна використовувати `from starlette.middleware.cors import CORSMiddleware`.
+
+**FastAPI** надає кілька middleware у `fastapi.middleware` для зручності розробників. Але більшість доступних middleware походять безпосередньо зі Starlette.
+
+///
diff --git a/docs/uk/docs/tutorial/debugging.md b/docs/uk/docs/tutorial/debugging.md
new file mode 100644
index 000000000..b0e5344f8
--- /dev/null
+++ b/docs/uk/docs/tutorial/debugging.md
@@ -0,0 +1,112 @@
+# Налагодження (Debugging)
+
+Ви можете під'єднати дебагер у Вашому редакторі коду, наприклад, у Visual Studio Code або PyCharm.
+
+## Виклик `uvicorn`
+
+У Вашому FastAPI-додатку імпортуйте та запустіть `uvicorn` безпосередньо:
+
+{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+
+### Про `__name__ == "__main__"`
+
+Головна мета використання `__name__ == "__main__"` — це забезпечення виконання певного коду тільки тоді, коли файл запускається безпосередньо:
+
+
+
+```console
+$ python myapp.py
+```
+
+
+
+але не виконується при його імпорті в інший файл, наприклад:
+
+```Python
+from myapp import app
+```
+
+#### Детальніше
+
+Припустимо, Ваш файл називається `myapp.py`.
+
+Якщо Ви запустите його так:
+
+
+
+```console
+$ python myapp.py
+```
+
+
+
+тоді внутрішня змінна `__name__`, яка створюється автоматично Python, матиме значення `"__main__"`.
+
+Отже, цей блок коду:
+
+```Python
+ uvicorn.run(app, host="0.0.0.0", port=8000)
+```
+
+буде виконаний.
+
+---
+
+Це не станеться, якщо Ви імпортуєте цей модуль (файл).
+
+Якщо у Вас є інший файл, наприклад `importer.py`, з наступним кодом:
+
+```Python
+from myapp import app
+
+# Додатковий код
+```
+
+У цьому випадку автоматично створена змінна у файлі `myapp.py` не матиме значення змінної `__name__` як `"__main__"`.
+
+Отже, рядок:
+
+```Python
+ uvicorn.run(app, host="0.0.0.0", port=8000)
+```
+
+не буде виконано.
+
+/// info | Інформація
+
+Більш детальну інформацію можна знайти в
офіційній документації Python.
+
+///
+
+## Запуск коду з вашим дебагером
+
+Оскільки Ви запускаєте сервер Uvicorn безпосередньо з Вашого коду, Ви можете запустити вашу Python програму (ваш FastAPI додаток) безпосередньо з дебагера.
+
+---
+
+Наприклад, у Visual Studio Code Ви можете:
+
+* Перейдіть на вкладку "Debug".
+* Натисніть "Add configuration...".
+* Виберіть "Python"
+* Запустіть дебагер з опцією "`Python: Current File (Integrated Terminal)`".
+
+Це запустить сервер з Вашим **FastAPI** кодом, зупиниться на точках зупину тощо.
+
+Ось як це може виглядати:
+
+

+
+---
+Якщо Ви використовуєте PyCharm, ви можете:
+
+* Відкрити меню "Run".
+* Вибрати опцію "Debug...".
+* Потім з'явиться контекстне меню.
+* Вибрати файл для налагодження (у цьому випадку, `main.py`).
+
+Це запустить сервер з Вашим **FastAPI** кодом, зупиниться на точках зупину тощо.
+
+Ось як це може виглядати:
+
+

diff --git a/docs/uk/docs/tutorial/encoder.md b/docs/uk/docs/tutorial/encoder.md
new file mode 100644
index 000000000..f202c7989
--- /dev/null
+++ b/docs/uk/docs/tutorial/encoder.md
@@ -0,0 +1,35 @@
+# JSON Compatible Encoder
+
+Існують випадки, коли вам може знадобитися перетворити тип даних (наприклад, модель Pydantic) в щось сумісне з JSON (наприклад, `dict`, `list`, і т. д.).
+
+Наприклад, якщо вам потрібно зберегти це в базі даних.
+
+Для цього, **FastAPI** надає `jsonable_encoder()` функцію.
+
+## Використання `jsonable_encoder`
+
+Давайте уявимо, що у вас є база даних `fake_db`, яка приймає лише дані, сумісні з JSON.
+
+Наприклад, вона не приймає об'єкти типу `datetime`, оскільки вони не сумісні з JSON.
+
+Отже, об'єкт типу `datetime` потрібно перетворити в рядок `str`, який містить дані в
ISO форматі.
+
+Тим самим способом ця база даних не прийматиме об'єкт типу Pydantic model (об'єкт з атрибутами), а лише `dict`.
+
+Ви можете використовувати `jsonable_encoder` для цього.
+
+Вона приймає об'єкт, такий як Pydantic model, і повертає його версію, сумісну з JSON:
+
+{* ../../docs_src/encoder/tutorial001_py310.py hl[4,21] *}
+
+У цьому прикладі вона конвертує Pydantic model у `dict`, а `datetime` у `str`.
+
+Результат виклику цієї функції - це щось, що можна кодувати з використанням стандарту Python
`json.dumps()`.
+
+Вона не повертає велику строку `str`, яка містить дані у форматі JSON (як строка). Вона повертає стандартну структуру даних Python (наприклад `dict`) із значеннями та підзначеннями, які є сумісними з JSON.
+
+/// note | Примітка
+
+`jsonable_encoder` фактично використовується **FastAPI** внутрішньо для перетворення даних. Проте вона корисна в багатьох інших сценаріях.
+
+///
diff --git a/docs/uk/docs/tutorial/extra-data-types.md b/docs/uk/docs/tutorial/extra-data-types.md
new file mode 100644
index 000000000..5da942b6e
--- /dev/null
+++ b/docs/uk/docs/tutorial/extra-data-types.md
@@ -0,0 +1,62 @@
+# Додаткові типи даних
+
+До цього часу, ви використовували загальнопоширені типи даних, такі як:
+
+* `int`
+* `float`
+* `str`
+* `bool`
+
+Але можна також використовувати більш складні типи даних.
+
+І ви все ще матимете ті ж можливості, які були показані до цього:
+
+* Чудова підтримка редактора.
+* Конвертація даних з вхідних запитів.
+* Конвертація даних для відповіді.
+* Валідація даних.
+* Автоматична анотація та документація.
+
+## Інші типи даних
+
+Ось додаткові типи даних для використання:
+
+* `UUID`:
+ * Стандартний "Універсальний Унікальний Ідентифікатор", який часто використовується як ідентифікатор у багатьох базах даних та системах.
+ * У запитах та відповідях буде представлений як `str`.
+* `datetime.datetime`:
+ * Пайтонівський `datetime.datetime`.
+ * У запитах та відповідях буде представлений як `str` в форматі ISO 8601, як: `2008-09-15T15:53:00+05:00`.
+* `datetime.date`:
+ * Пайтонівський `datetime.date`.
+ * У запитах та відповідях буде представлений як `str` в форматі ISO 8601, як: `2008-09-15`.
+* `datetime.time`:
+ * Пайтонівський `datetime.time`.
+ * У запитах та відповідях буде представлений як `str` в форматі ISO 8601, як: `14:23:55.003`.
+* `datetime.timedelta`:
+ * Пайтонівський `datetime.timedelta`.
+ * У запитах та відповідях буде представлений як `float` загальної кількості секунд.
+ * Pydantic також дозволяє представляти це як "ISO 8601 time diff encoding",
більше інформації дивись у документації.
+* `frozenset`:
+ * У запитах і відповідях це буде оброблено так само, як і `set`:
+ * У запитах список буде зчитано, дублікати будуть видалені та він буде перетворений на `set`.
+ * У відповідях, `set` буде перетворений на `list`.
+ * Згенерована схема буде вказувати, що значення `set` є унікальними (з використанням JSON Schema's `uniqueItems`).
+* `bytes`:
+ * Стандартний Пайтонівський `bytes`.
+ * У запитах і відповідях це буде оброблено як `str`.
+ * Згенерована схема буде вказувати, що це `str` з "форматом" `binary`.
+* `Decimal`:
+ * Стандартний Пайтонівський `Decimal`.
+ * У запитах і відповідях це буде оброблено так само, як і `float`.
+* Ви можете перевірити всі дійсні типи даних Pydantic тут:
типи даних Pydantic.
+
+## Приклад
+
+Ось приклад *path operation* з параметрами, використовуючи деякі з вищезазначених типів.
+
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[1,3,12:16] *}
+
+Зверніть увагу, що параметри всередині функції мають свій звичайний тип даних, і ви можете, наприклад, виконувати звичайні маніпуляції з датами, такі як:
+
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[18:19] *}
diff --git a/docs/uk/docs/tutorial/first-steps.md b/docs/uk/docs/tutorial/first-steps.md
new file mode 100644
index 000000000..e910c4ccc
--- /dev/null
+++ b/docs/uk/docs/tutorial/first-steps.md
@@ -0,0 +1,328 @@
+# Перші кроки
+
+Найпростіший файл FastAPI може виглядати так:
+
+{* ../../docs_src/first_steps/tutorial001.py *}
+
+Скопіюйте це до файлу `main.py`.
+
+Запустіть сервер:
+
+
+
+```console
+$ fastapi dev main.py
+INFO Using path main.py
+INFO Resolved absolute path /home/user/code/awesomeapp/main.py
+INFO Searching for package file structure from directories with __init__.py files
+INFO Importing from /home/user/code/awesomeapp
+
+ ╭─ Python module file ─╮
+ │ │
+ │ 🐍 main.py │
+ │ │
+ ╰──────────────────────╯
+
+INFO Importing module main
+INFO Found importable FastAPI app
+
+ ╭─ Importable FastAPI app ─╮
+ │ │
+ │ from main import app │
+ │ │
+ ╰──────────────────────────╯
+
+INFO Using import string main:app
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2265862] using WatchFiles
+INFO: Started server process [2265873]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+У консолі буде рядок приблизно такого змісту:
+
+```hl_lines="4"
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+Цей рядок показує URL, за яким додаток запускається на вашій локальній машині.
+
+### Перевірте
+
+Відкрийте браузер та введіть адресу
http://127.0.0.1:8000.
+
+Ви побачите у відповідь таке повідомлення у форматі JSON:
+
+```JSON
+{"message": "Hello World"}
+```
+
+### Інтерактивна API документація
+
+Перейдемо сюди
http://127.0.0.1:8000/docs.
+
+Ви побачите автоматичну інтерактивну API документацію (створену завдяки
Swagger UI):
+
+
+
+### Альтернативна API документація
+
+Тепер перейдемо сюди
http://127.0.0.1:8000/redoc.
+
+Ви побачите альтернативну автоматичну документацію (створену завдяки
ReDoc):
+
+
+
+### OpenAPI
+
+**FastAPI** генерує "схему" з усім вашим API, використовуючи стандарт **OpenAPI** для визначення API.
+
+#### "Схема"
+
+"Схема" - це визначення або опис чогось. Це не код, який його реалізує, а просто абстрактний опис.
+
+#### API "схема"
+
+У цьому випадку,
OpenAPI є специфікацією, яка визначає, як описати схему вашого API.
+
+Це визначення схеми включає шляхи (paths) вашого API, можливі параметри, які вони приймають тощо.
+
+#### "Схема" даних
+
+Термін "схема" також може відноситися до структури даних, наприклад, JSON.
+
+У цьому випадку це означає - атрибути JSON і типи даних, які вони мають тощо.
+
+#### OpenAPI і JSON Schema
+
+OpenAPI описує схему для вашого API. І ця схема включає визначення (або "схеми") даних, що надсилаються та отримуються вашим API за допомогою **JSON Schema**, стандарту для схем даних JSON.
+
+#### Розглянемо `openapi.json`
+
+Якщо вас цікавить, як виглядає вихідна схема OpenAPI, то FastAPI автоматично генерує JSON-схему з усіма описами API.
+
+Ознайомитися можна за посиланням:
http://127.0.0.1:8000/openapi.json.
+
+Ви побачите приблизно такий JSON:
+
+```JSON
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+
+
+
+...
+```
+
+#### Для чого потрібний OpenAPI
+
+Схема OpenAPI є основою для обох систем інтерактивної документації.
+
+Існують десятки альтернативних інструментів, заснованих на OpenAPI. Ви можете легко додати будь-який з них до **FastAPI** додатку.
+
+Ви також можете використовувати OpenAPI для автоматичної генерації коду для клієнтів, які взаємодіють з API. Наприклад, для фронтенд-, мобільних або IoT-додатків
+
+## А тепер крок за кроком
+
+### Крок 1: імпортуємо `FastAPI`
+
+{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+
+`FastAPI` це клас у Python, який надає всю функціональність для API.
+
+/// note | Технічні деталі
+
+`FastAPI` це клас, який успадковується безпосередньо від `Starlette`.
+
+Ви також можете використовувати всю функціональність
Starlette у `FastAPI`.
+
+///
+
+### Крок 2: створюємо екземпляр `FastAPI`
+
+{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+Змінна `app` є екземпляром класу `FastAPI`.
+
+Це буде головна точка для створення і взаємодії з API.
+
+### Крок 3: визначте операцію шляху (path operation)
+
+#### Шлях (path)
+
+"Шлях" це частина URL, яка йде одразу після символу `/`.
+
+Отже, у такому URL, як:
+
+```
+https://example.com/items/foo
+```
+
+...шлях буде:
+
+```
+/items/foo
+```
+
+/// info | Додаткова інформація
+
+"Шлях" (path) також зазвичай називають "ендпоінтом" (endpoint) або "маршрутом" (route).
+
+///
+
+При створенні API, "шлях" є основним способом розділення "завдань" і "ресурсів".
+#### Operation
+
+"Операція" (operation) тут означає один з "методів" HTTP.
+
+Один з:
+
+* `POST`
+* `GET`
+* `PUT`
+* `DELETE`
+
+...та більш екзотичних:
+
+* `OPTIONS`
+* `HEAD`
+* `PATCH`
+* `TRACE`
+
+У HTTP-протоколі можна спілкуватися з кожним шляхом, використовуючи один (або кілька) з цих "методів".
+
+---
+
+При створенні API зазвичай використовуються конкретні методи HTTP для виконання певних дій.
+
+Як правило, використовують:
+
+* `POST`: для створення даних.
+* `GET`: для читання даних.
+* `PUT`: для оновлення даних.
+* `DELETE`: для видалення даних.
+
+В OpenAPI кожен HTTP метод називається "операція".
+
+Ми також будемо дотримуватися цього терміна.
+
+#### Визначте декоратор операції шляху (path operation decorator)
+
+{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+Декоратор `@app.get("/")` вказує **FastAPI**, що функція нижче, відповідає за обробку запитів, які надходять до неї:
+
+* шлях `/`
+* використовуючи
get
операцію
+
+/// info | `@decorator` Додаткова інформація
+
+Синтаксис `@something` у Python називається "декоратором".
+
+Ви розташовуєте його над функцією. Як гарний декоративний капелюх (мабуть, звідти походить термін).
+
+"Декоратор" приймає функцію нижче і виконує з нею якусь дію.
+
+У нашому випадку, цей декоратор повідомляє **FastAPI**, що функція нижче відповідає **шляху** `/` і **операції** `get`.
+
+Це і є "декоратор операції шляху (path operation decorator)".
+
+///
+
+Можна також використовувати операції:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+І більш екзотичні:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+/// tip | Порада
+
+Ви можете використовувати кожну операцію (HTTP-метод) на свій розсуд.
+
+**FastAPI** не нав'язує жодного певного значення для кожного методу.
+
+Наведена тут інформація є рекомендацією, а не обов'язковою вимогою.
+
+Наприклад, під час використання GraphQL зазвичай усі дії виконуються тільки за допомогою `POST` операцій.
+
+///
+
+### Крок 4: визначте **функцію операції шляху (path operation function)**
+
+Ось "**функція операції шляху**":
+
+* **шлях**: це `/`.
+* **операція**: це `get`.
+* **функція**: це функція, яка знаходиться нижче "декоратора" (нижче `@app.get("/")`).
+
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+
+Це звичайна функція Python.
+
+FastAPI викликатиме її щоразу, коли отримає запит до URL із шляхом "/", використовуючи операцію `GET`.
+
+У даному випадку це асинхронна функція.
+
+---
+
+Ви також можете визначити її як звичайну функцію замість `async def`:
+
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+
+/// note | Примітка
+
+Якщо не знаєте в чому різниця, подивіться [Конкурентність: *"Поспішаєш?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+///
+
+### Крок 5: поверніть результат
+
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+
+Ви можете повернути `dict`, `list`, а також окремі значення `str`, `int`, ітд.
+
+Також можна повернути моделі Pydantic (про це ви дізнаєтесь пізніше).
+
+Існує багато інших об'єктів і моделей, які будуть автоматично конвертовані в JSON (зокрема ORM тощо). Спробуйте використати свої улюблені, велика ймовірність, що вони вже підтримуються.
+
+## Підіб'ємо підсумки
+
+* Імпортуємо `FastAPI`.
+* Створюємо екземпляр `app`.
+* Пишемо **декоратор операції шляху** як `@app.get("/")`.
+* Пишемо **функцію операції шляху**; наприклад, `def root(): ...`.
+* Запускаємо сервер у режимі розробки `fastapi dev`.
diff --git a/docs/uk/docs/tutorial/handling-errors.md b/docs/uk/docs/tutorial/handling-errors.md
new file mode 100644
index 000000000..12a356cd0
--- /dev/null
+++ b/docs/uk/docs/tutorial/handling-errors.md
@@ -0,0 +1,255 @@
+# Обробка Помилок
+
+Є багато ситуацій, коли потрібно повідомити клієнта, який використовує Ваш API, про помилку.
+
+Цим клієнтом може бути браузер із фронтендом, код іншого розробника, IoT-пристрій тощо.
+
+Можливо, Вам потрібно повідомити клієнта, що:
+
+* У нього недостатньо прав для виконання цієї операції.
+* Він не має доступу до цього ресурсу.
+* Елемент, до якого він намагається отримати доступ, не існує.
+* тощо.
+
+У таких випадках зазвичай повертається **HTTP статус-код** в діапазоні **400** (від 400 до 499).
+
+Це схоже на HTTP статус-коди 200 (від 200 до 299). Ці "200" статус-коди означають, що запит пройшов успішно.
+
+Статус-коди в діапазоні 400 означають, що сталася помилка з боку клієнта.
+
+Пам'ятаєте всі ці помилки **404 Not Found** (і жарти про них)?
+
+## Використання `HTTPException`
+
+Щоб повернути HTTP-відповіді з помилками клієнту, використовуйте `HTTPException`.
+
+### Імпорт `HTTPException`
+
+{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+
+### Використання `HTTPException` у коді
+
+`HTTPException` — це звичайна помилка Python із додатковими даними, які стосуються API.
+
+Оскільки це помилка Python, Ви не `повертаєте` його, а `генеруєте` (генеруєте помилку).
+
+Це також означає, що якщо Ви перебуваєте всередині допоміжної функції, яку викликаєте всередині своєї *функції операції шляху*, і там генеруєте `HTTPException`, всередині цієї допоміжної функції, то решта коду в *функції операції шляху* не буде виконана. Запит одразу завершиться, і HTTP-помилка з `HTTPException` буде надіслана клієнту.
+
+Перевага використання `генерації` (raise) помилки замість `повернення` значення (return) стане більш очевидним в розділі про Залежності та Безпеку.
+
+У цьому прикладі, якщо клієнт запитує елемент за ID, якого не існує, буде згенеровано помилку зі статус-кодом `404`:
+
+{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+
+### Отримана відповідь
+
+Якщо клієнт робить запит за шляхом `http://example.com/items/foo` (де `item_id` `"foo"`), він отримає статус-код 200 і JSON відповідь:
+
+```JSON
+{
+ "item": "The Foo Wrestlers"
+}
+```
+
+Але якщо клієнт робить запит на `http://example.com/items/bar` (де `item_id` має не існуюче значення `"bar"`), то отримає статус-код 404 (помилка "не знайдено") та відповідь:
+
+```JSON
+{
+ "detail": "Item not found"
+}
+```
+
+/// tip | Порада
+
+Під час виклику `HTTPException` Ви можете передати будь-яке значення, яке може бути перетворене в JSON, як параметр `detail`, а не лише рядок (`str`).
+
+Ви можете передати `dict`, `list` тощо.
+
+Вони обробляються автоматично за допомогою **FastAPI** та перетворюються в JSON.
+
+///
+
+## Додавання власних заголовків
+
+Іноді потрібно додати власні заголовки до HTTP-помилки, наприклад, для певних типів безпеки.
+
+Ймовірно, Вам не доведеться використовувати це безпосередньо у своєму коді.
+
+Але якщо Вам знадобиться це для складного сценарію, Ви можете додати власні заголовки:
+
+{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+
+## Встановлення власних обробників помилок
+
+Ви можете додати власні обробники помилок за допомогою
тих самих утиліт обробки помилок зі Starlette.
+
+Припустимо, у Вас є власний обʼєкт помилки `UnicornException`, яке Ви (або бібліотека, яку Ви використовуєте) може `згенерувати` (`raise`).
+
+І Ви хочете обробляти це виключення глобально за допомогою FastAPI.
+
+Ви можете додати власний обробник виключень за допомогою `@app.exception_handler()`:
+
+{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
+
+Тут, якщо Ви звернетеся до `/unicorns/yolo`, то згенерується помилка `UnicornException`.
+
+Але вона буде оброблена функцією-обробником `unicorn_exception_handler`.
+
+Отже, Ви отримаєте зрозумілу помилку зі HTTP-статусом `418` і JSON-відповіддю:
+
+```JSON
+{"message": "Oops! yolo did something. There goes a rainbow..."}
+```
+
+/// note | Технічні деталі
+
+Ви також можете використовувати `from starlette.requests import Request` і `from starlette.responses import JSONResponse`.
+
+**FastAPI** надає ті самі `starlette.responses`, що й `fastapi.responses`, просто для зручності розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette. Те ж саме стосується і `Request`.
+
+///
+
+## Перевизначення обробників помилок за замовчуванням
+
+**FastAPI** має кілька обробників помилок за замовчуванням.
+
+Ці обробники відповідають за повернення стандартних JSON-відповідей, коли Ви `генеруєте` (`raise`) `HTTPException`, а також коли запит містить некоректні дані.
+
+Ви можете перевизначити ці обробники, створивши власні.
+
+### Перевизначення помилок валідації запиту
+
+Коли запит містить некоректні дані, **FastAPI** генерує `RequestValidationError`.
+
+І також включає обробник помилок за замовчуванням для нього.
+
+Щоб перевизначити його, імпортуйте `RequestValidationError` і використовуйте його з `@app.exception_handler(RequestValidationError)` для декорування обробника помилок.
+
+Обробник помилок отримує `Request` і саму помилку.
+
+{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
+
+Тепер, якщо Ви перейдете за посиланням `/items/foo`, замість того, щоб отримати стандартну JSON-помилку:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+Ви отримаєте текстову версію:
+
+```
+1 validation error
+path -> item_id
+ value is not a valid integer (type=type_error.integer)
+```
+
+#### `RequestValidationError` проти `ValidationError`
+
+/// warning | Увага
+
+Це технічні деталі, які Ви можете пропустити, якщо вони зараз не важливі для Вас.
+
+///
+
+`RequestValidationError` є підкласом Pydantic
`ValidationError`.
+
+**FastAPI** використовує його для того, якщо Ви використовуєте модель Pydantic у `response_model` і у ваших даних є помилка, Ви побачили помилку у своєму журналі.
+
+Але клієнт/користувач не побачить її. Натомість клієнт отримає "Internal Server Error" зі статусом HTTP `500`.
+
+Так має бути, якщо у Вас виникла `ValidationError` Pydantic у *відповіді* або деінде у вашому коді (не у *запиті* клієнта), це насправді є помилкою у Вашому коді.
+
+І поки Ви її виправляєте, клієнти/користувачі не повинні мати доступу до внутрішньої інформації про помилку, оскільки це може призвести до вразливості безпеки.
+
+### Перевизначення обробника помилок `HTTPException`
+
+Аналогічно, Ви можете перевизначити обробник `HTTPException`.
+
+Наприклад, Ви можете захотіти повернути текстову відповідь замість JSON для цих помилок:
+
+{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
+
+/// note | Технічні деталі
+
+Ви також можете використовувати `from starlette.responses import PlainTextResponse`.
+
+**FastAPI** надає ті самі `starlette.responses`, що й `fastapi.responses`, просто для зручності розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette.
+
+///
+
+### Використання тіла `RequestValidationError`
+
+`RequestValidationError` містить `body`, який він отримав із некоректними даними.
+
+Ви можете використовувати це під час розробки свого додатка, щоб логувати тіло запиту та налагоджувати його, повертати користувачеві тощо.
+
+{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+
+Тепер спробуйте надіслати некоректний елемент, наприклад:
+
+```JSON
+{
+ "title": "towel",
+ "size": "XL"
+}
+```
+Ви отримаєте відповідь, яка повідомить Вам, які саме дані є некоректні у вашому тілі запиту:
+
+
+```JSON hl_lines="12-15"
+{
+ "detail": [
+ {
+ "loc": [
+ "body",
+ "size"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ],
+ "body": {
+ "title": "towel",
+ "size": "XL"
+ }
+}
+```
+
+#### `HTTPException` FastAPI проти `HTTPException` Starlette
+
+**FastAPI** має власний `HTTPException`.
+
+І клас помилки `HTTPException` в **FastAPI** успадковується від класу помилки `HTTPException` в Starlette.
+
+Єдина різниця полягає в тому, що `HTTPException` в **FastAPI** приймає будь-які дані, які можна перетворити на JSON, для поля `detail`, тоді як `HTTPException` у Starlette приймає тільки рядки.
+
+Отже, Ви можете продовжувати використовувати `HTTPException` в **FastAPI** як зазвичай у своєму коді.
+
+Але коли Ви реєструєте обробник виключень, слід реєструвати його для `HTTPException` зі Starlette.
+
+Таким чином, якщо будь-яка частина внутрішнього коду Starlette або розширення чи плагін Starlette згенерує (raise) `HTTPException`, Ваш обробник зможе перехопити та обробити її.
+
+У цьому прикладі, щоб мати можливість використовувати обидва `HTTPException` в одному коді, помилка Starlette перейменовується на `StarletteHTTPException`:
+
+```Python
+from starlette.exceptions import HTTPException as StarletteHTTPException
+```
+
+### Повторне використання обробників помилок **FastAPI**
+
+Якщо Ви хочете використовувати помилки разом із такими ж обробниками помилок за замовчуванням, як у **FastAPI**, Ви можете імпортувати та повторно використовувати їх із `fastapi.exception_handlers`:
+
+{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
+
+У цьому прикладі Ви просто використовуєте `print` для виведення дуже інформативного повідомлення, але Ви зрозуміли основну ідею. Ви можете обробити помилку та повторно використовувати обробники помилок за замовчуванням.
diff --git a/docs/uk/docs/tutorial/header-param-models.md b/docs/uk/docs/tutorial/header-param-models.md
new file mode 100644
index 000000000..6f7b0bdae
--- /dev/null
+++ b/docs/uk/docs/tutorial/header-param-models.md
@@ -0,0 +1,58 @@
+# Моделі Параметрів Заголовків
+
+Якщо у Вас є група пов’язаних параметрів заголовків, Ви можете створити **Pydantic модель** для їх оголошення.
+
+Це дозволить Вам повторно **використовувати модель** в **різних місцях**, а також оголосити валідації та метадані для всіх параметрів одночасно. 😎
+
+/// note | Нотатки
+
+Ця можливість підтримується починаючи з версії FastAPI `0.115.0`. 🤓
+
+///
+
+## Параметри Заголовків з Використанням Pydantic Model
+
+Оголосіть потрібні **параметри заголовків** у **Pydantic моделі**, а потім оголосіть параметр як `Header`:
+
+{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
+
+FastAPI буде витягувати дані для кожного поля з заголовків у запиті та передавати їх у створену Вами Pydantic модель.
+
+**FastAPI** буде **витягувати** дані для **кожного поля** з **заголовків** у запиті та передавати їх у створену Вами Pydantic модель.
+
+## Перевірка в Документації
+
+Ви можете побачити необхідні заголовки в інтерфейсі документації за адресою `/docs`:
+
+
+

+
+
+## Заборона Додаткових Заголовків
+
+У деяких особливих випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** заголовки, які хочете отримати.
+
+Ви можете використати конфігурацію моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
+
+{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
+
+Якщо клієнт спробує надіслати **додаткові заголовки**, він отримає **помилку** у відповіді.
+
+Наприклад, якщо клієнт спробує надіслати заголовок `tool` зі значенням `plumbus`, він отримає **помилку** з повідомленням про те, що параметр заголовка `tool` не дозволений:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["header", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ ]
+}
+```
+
+## Підсумок
+
+Ви можете використовувати **Pydantic моделі** для оголошення **заголовків** у **FastAPI**. 😎
diff --git a/docs/uk/docs/tutorial/header-params.md b/docs/uk/docs/tutorial/header-params.md
new file mode 100644
index 000000000..09c70a4f6
--- /dev/null
+++ b/docs/uk/docs/tutorial/header-params.md
@@ -0,0 +1,91 @@
+# Header-параметри
+
+Ви можете визначати параметри заголовків, так само як визначаєте `Query`, `Path` і `Cookie` параметри.
+
+## Імпорт `Header`
+
+Спочатку імпортуйте `Header`:
+
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
+
+## Оголошення параметрів `Header`
+
+Потім оголосіть параметри заголовків, використовуючи ту ж структуру, що й для `Path`, `Query` та `Cookie`.
+
+Ви можете визначити значення за замовчуванням, а також усі додаткові параметри валідації або анотації:
+
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | Технічні деталі
+
+`Header`є "сестринським" класом для `Path`, `Query` і `Cookie`. Він також успадковується від загального класу `Param`.
+
+Але пам’ятайте, що при імпорті `Query`, `Path`, `Header` та інших із `fastapi`, то насправді вони є функціями, які повертають спеціальні класи.
+
+///
+
+/// info | Інформація
+
+Щоб оголосити заголовки, потрібно використовувати `Header`, інакше параметри будуть інтерпретуватися як параметри запиту.
+
+///
+
+## Автоматичне перетворення
+
+`Header` має додатковий функціонал порівняно з `Path`, `Query` та `Cookie`.
+
+Більшість стандартних заголовків розділяються символом «дефіс», також відомим як «мінус» (`-`).
+
+Але змінна, така як `user-agent`, є недійсною в Python.
+
+Тому, за замовчуванням, `Header` автоматично перетворює символи підкреслення (`_`) на дефіси (`-`) для отримання та документування заголовків.
+
+Оскільки заголовки HTTP не чутливі до регістру, Ви можете використовувати стандартний стиль Python ("snake_case").
+
+Тому Ви можете використовувати `user_agent`, як зазвичай у коді Python, замість того щоб писати з великої літери, як `User_Agent` або щось подібне.
+
+Якщо Вам потрібно вимкнути автоматичне перетворення підкреслень у дефіси, встановіть `convert_underscores` в `Header` значення `False`:
+
+{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
+
+/// warning | Увага
+
+Перед тим як встановити значення `False` для `convert_underscores` пам’ятайте, що деякі HTTP-проксі та сервери не підтримують заголовки з підкресленнями.
+
+///
+
+## Дубльовані заголовки
+
+Можливо отримати дубльовані заголовки, тобто той самий заголовок із кількома значеннями.
+
+Це можна визначити, використовуючи список у типізації параметра.
+
+Ви отримаєте всі значення дубльованого заголовка у вигляді `list` у Python.
+
+Наприклад, щоб оголосити заголовок `X-Token`, який може з’являтися більше ніж один раз:
+
+{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
+
+Якщо Ви взаємодієте з цією операцією шляху, надсилаючи два HTTP-заголовки, наприклад:
+
+```
+X-Token: foo
+X-Token: bar
+```
+
+Відповідь буде така:
+
+```JSON
+{
+ "X-Token values": [
+ "bar",
+ "foo"
+ ]
+}
+```
+
+## Підсумок
+
+Оголошуйте заголовки за допомогою `Header`, використовуючи той самий підхід, що й для `Query`, `Path` та `Cookie`.
+
+Не хвилюйтеся про підкреслення у змінних — **FastAPI** автоматично конвертує їх.
diff --git a/docs/uk/docs/tutorial/index.md b/docs/uk/docs/tutorial/index.md
new file mode 100644
index 000000000..92c3e77a3
--- /dev/null
+++ b/docs/uk/docs/tutorial/index.md
@@ -0,0 +1,83 @@
+# Туторіал - Посібник користувача
+
+У цьому посібнику показано, як користуватися **FastAPI** з більшістю його функцій, крок за кроком.
+
+Кожен розділ поступово надбудовується на попередні, але він структурований на окремі теми, щоб ви могли перейти безпосередньо до будь-якої конкретної, щоб вирішити ваші конкретні потреби API.
+
+Він також створений як довідник для роботи у майбутньому.
+
+Тож ви можете повернутися і побачити саме те, що вам потрібно.
+
+## Запустіть код
+
+Усі блоки коду можна скопіювати та використовувати безпосередньо (це фактично перевірені файли Python).
+
+Щоб запустити будь-який із прикладів, скопіюйте код у файл `main.py` і запустіть `uvicorn` за допомогою:
+
+
+
+```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.
+```
+
+
+
+**ДУЖЕ радимо** написати або скопіювати код, відредагувати його та запустити локально.
+
+Використання його у своєму редакторі – це те, що дійсно показує вам переваги FastAPI, бачите, як мало коду вам потрібно написати, всі перевірки типів, автозаповнення тощо.
+
+---
+
+## Встановлення FastAPI
+
+Першим кроком є встановлення FastAPI.
+
+Для туторіалу ви можете встановити його з усіма необов’язковими залежностями та функціями:
+
+
+
+```console
+$ pip install "fastapi[all]"
+
+---> 100%
+```
+
+
+
+...який також включає `uvicorn`, який ви можете використовувати як сервер, який запускає ваш код.
+
+/// note
+
+Ви також можете встановити його частина за частиною.
+
+Це те, що ви, ймовірно, зробили б, коли захочете розгорнути свою програму у виробничому середовищі:
+
+```
+pip install fastapi
+```
+
+Також встановіть `uvicorn`, щоб він працював як сервер:
+
+```
+pip install "uvicorn[standard]"
+```
+
+І те саме для кожної з опціональних залежностей, які ви хочете використовувати.
+
+///
+
+## Розширений посібник користувача
+
+Існує також **Розширений посібник користувача**, який ви зможете прочитати пізніше після цього **Туторіал - Посібник користувача**.
+
+**Розширений посібник користувача** засновано на цьому, використовує ті самі концепції та навчає вас деяким додатковим функціям.
+
+Але вам слід спочатку прочитати **Туторіал - Посібник користувача** (те, що ви зараз читаєте).
+
+Він розроблений таким чином, що ви можете створити повну програму лише за допомогою **Туторіал - Посібник користувача**, а потім розширити її різними способами, залежно від ваших потреб, використовуючи деякі з додаткових ідей з **Розширеного посібника користувача** .
diff --git a/docs/uk/docs/tutorial/metadata.md b/docs/uk/docs/tutorial/metadata.md
new file mode 100644
index 000000000..64e667ec6
--- /dev/null
+++ b/docs/uk/docs/tutorial/metadata.md
@@ -0,0 +1,120 @@
+# Метадані та URL-адреси документації
+
+Ви можете налаштувати кілька конфігурацій метаданих у Вашому додатку **FastAPI**.
+
+## Метадані для API
+
+Ви можете встановити такі поля, які використовуються в специфікації OpenAPI та в автоматично згенерованих інтерфейсах документації API:
+
+| Параметр | Тип | Опис |
+|------------|------|-------------|
+| `title` | `str` | Назва API. |
+| `summary` | `str` | Короткий опис API.
Доступно з OpenAPI 3.1.0, FastAPI 0.99.0. |
+| `description` | `str` | Більш детальний опис API. Може використовувати Markdown. |
+| `version` | `string` | Версія API. Це версія Вашого додатка, а не OpenAPI. Наприклад, `2.5.0`. |
+| `terms_of_service` | `str` | URL до умов використання API. Якщо вказано, має бути у форматі URL. |
+| `contact` | `dict` | Інформація для контакту з API. Може містити кілька полів.
contact
поля
Параметр | Тип | Опис |
---|
name | str | Ім'я контактної особи або організації. |
url | str | URL з інформацією для контакту. Повинен бути у форматі URL. |
email | str | Email контактної особи або організації. Повинен бути у форматі електронної пошти. |
|
+| `license_info` | `dict` | Інформація про ліцензію для API. Може містити кілька полів.
license_info
поля
Параметр | Тип | Опис |
---|
name | str | ОБОВ'ЯЗКОВО (якщо встановлено license_info ). Назва ліцензії для API. |
identifier | str | Ліцензійний вираз за SPDX для API. Поле identifier взаємовиключне з полем url . Доступно з OpenAPI 3.1.0, FastAPI 0.99.0. |
url | str | URL до ліцензії, яка використовується для API. Повинен бути у форматі URL. |
|
+
+Ви можете налаштувати їх наступним чином:
+
+{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
+
+/// tip | Підказка
+
+У полі `description` можна використовувати Markdown, і він буде відображатися у результаті.
+
+///
+
+З цією конфігурацією автоматична документація API виглядатиме так:
+
+

+
+## Ідентифікатор ліцензії
+
+З початку використання OpenAPI 3.1.0 та FastAPI 0.99.0 Ви також можете налаштувати `license_info` за допомогою `identifier` замість `url`.
+
+Наприклад:
+
+{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
+
+## Метадані для тегів
+
+Ви також можете додати додаткові метадані для різних тегів, які використовуються для групування операцій шляхів, за допомогою параметра `openapi_tags`.
+
+Він приймає список, який містить один словник для кожного тега.
+
+Кожен словник може містити:
+
+* `name` (**обов'язково**): `str` з тією ж назвою тегу, яку Ви використовуєте у параметрі `tags` у Ваших *операціях шляху* та `APIRouter`s.
+* `description`: `str` з коротким описом тегу. Може містити Markdown і буде відображено в інтерфейсі документації.
+* `externalDocs`: `dict` який описує зовнішню документацію з такими полями:
+ * `description`: `str` з коротким описом зовнішньої документації.
+ * `url` (**обов'язково**): `str`з URL-адресою зовнішньої документації.
+
+### Створення метаданих для тегів
+
+Спробуймо це на прикладі з тегами для `users` та `items`.
+
+Створіть метадані для своїх тегів і передайте їх у параметр `openapi_tags`:
+
+{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+
+Зверніть увагу, що в описах можна використовувати Markdown, наприклад, "login" буде показано жирним шрифтом (**login**), а "fancy" буде показано курсивом (_fancy_).
+
+/// tip | Порада
+
+Не обов'язково додавати метадані для всіх тегів, які Ви використовуєте.
+
+///
+
+### Використання тегів
+
+Використовуйте параметр `tags` зі своїми *операціями шляху* (і `APIRouter`) для призначення їх до різних тегів:
+
+{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+
+/// info | Інформація
+
+Детальніше про теги читайте в розділі [Конфігурація шляхів операцій](path-operation-configuration.md#tags){.internal-link target=_blank}.
+
+///
+
+### Перевірка документації
+
+Якщо Ви зараз перевірите документацію, вона покаже всі додаткові метадані:
+
+

+
+### Порядок тегів
+
+Порядок кожного словника метаданих тегу також визначає порядок відображення в інтерфейсі документації.
+
+Наприклад, хоча `users` мав би йти після `items` в алфавітному порядку, він відображається перед ними, оскільки ми додали його метадані як перший словник у списку.
+
+## URL для OpenAPI
+
+За замовчуванням схема OpenAPI надається за адресою `/openapi.json`.
+
+Але Ви можете налаштувати це за допомогою параметра `openapi_url`.
+
+Наприклад, щоб налаштувати його на `/api/v1/openapi.json`:
+
+{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+
+Якщо Ви хочете повністю вимкнути схему OpenAPI, Ви можете встановити `openapi_url=None`, це також вимкне інтерфейси документації, які її використовують.
+
+## URL-адреси документації
+
+Ви можете налаштувати два інтерфейси користувача для документації, які включені:
+
+* **Swagger UI**: доступний за адресою `/docs`.
+ * Ви можете змінити його URL за допомогою параметра `docs_url`.
+ * Ви можете вимкнути його, встановивши `docs_url=None`.
+* **ReDoc**: доступний за адресою `/redoc`.
+ * Ви можете змінити його URL за допомогою параметра `redoc_url`.
+ * Ви можете вимкнути його, встановивши `redoc_url=None`.
+
+Наприклад, щоб налаштувати Swagger UI на `/documentation` і вимкнути ReDoc:
+
+{* ../../docs_src/metadata/tutorial003.py hl[3] *}
diff --git a/docs/uk/docs/tutorial/middleware.md b/docs/uk/docs/tutorial/middleware.md
new file mode 100644
index 000000000..807be484a
--- /dev/null
+++ b/docs/uk/docs/tutorial/middleware.md
@@ -0,0 +1,75 @@
+# Middleware (Проміжний шар)
+
+У **FastAPI** можна додавати middleware (проміжний шар).
+
+"Middleware" — це функція, яка працює з кожним **запитом** перед його обробкою будь-якою конкретною *операцією шляху* (*path operation*), а також з кожною **відповіддю** перед її поверненням.
+
+* Middleware отримує кожен **запит**, що надходить до Вашого застосунку.
+* Може виконати певні дії із цим **запитом** або запустити необхідний код.
+* Далі передає **запит** для обробки основним застосунком (*операцією шляху*).
+* Отримує **відповідь**, сформовану застосунком (*операцією шляху*).
+* Може змінити цю **відповідь** або виконати додатковий код.
+* Повертає **відповідь** клієнту.
+
+/// note | Технічні деталі
+
+Якщо у Вас є залежності з `yield`, код виходу виконається *після* middleware.
+
+Якщо були заплановані фонові задачі (background tasks - розглянуто далі), вони виконаються *після* всіх middleware.
+
+///
+
+## Створення middleware
+
+Щоб створити middleware, Ви використовуєте декоратор `@app.middleware("http")` на функції.
+
+Функція middleware отримує:
+
+* `Запит`.
+* Функцію `call_next`, яка приймає `запит` як параметр.
+ * Ця функція передає `запит` відповідній *операції шляху*.
+ * Потім вона повертає `відповідь`, згенеровану цією *операцією шляху*.
+
+* Ви можете ще змінити `відповідь` перед тим, як повернути її.
+
+
+{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+
+/// tip | Порада
+
+Не забувайте, що власні заголовки можна додавати, використовуючи
префікс 'X-'.
+
+Але якщо у Вас є власні заголовки, які Ви хочете, щоб браузерний клієнт міг побачити, потрібно додати їх до Вашої конфігурації CORS (див. [CORS (Обмін ресурсами між різними джерелами)](cors.md){.internal-link target=_blank} за допомогою параметра `expose_headers`, описаного в
документації Starlette по CORS.
+
+///
+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette.requests import Request`.
+
+**FastAPI** надає це для Вашої зручності як розробника. Але він походить безпосередньо зі Starlette.
+
+///
+
+### До і після `response`(`відповіді`)
+
+Ви можете додати код, який буде виконуватися з `запитом` (`request`), до того, як його обробить будь-яка *операція шляху* (*path operation*).
+
+Також Ви можете додати код, який буде виконуватися після того, як `відповідь` (`response`) буде згенеровано, перед тим як його повернути.
+
+Наприклад, Ви можете додати власний заголовок `X-Process-Time`, який міститиме час у секундах, який витратився на обробку запиту та генерацію відповіді:
+
+{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+
+
+/// tip | Підказка
+
+Тут ми використовуємо
`time.perf_counter()` замість `time.time()` оскільки він може бути більш точним для таких випадків. 🤓
+
+///
+
+## Інші middlewares
+
+Ви можете пізніше прочитати більше про інші middlewares в [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank}.
+
+Ви дізнаєтесь, як обробляти
CORS за допомогою middleware в наступному розділі.
diff --git a/docs/uk/docs/tutorial/path-params-numeric-validations.md b/docs/uk/docs/tutorial/path-params-numeric-validations.md
new file mode 100644
index 000000000..281ee183c
--- /dev/null
+++ b/docs/uk/docs/tutorial/path-params-numeric-validations.md
@@ -0,0 +1,165 @@
+# Path Параметри та валідація числових даних
+
+Так само як Ви можете оголошувати додаткові перевірки та метадані для query параметрів за допомогою `Query`, Ви можете оголошувати той самий тип перевірок і метаданих для параметрів шляху за допомогою `Path`.
+
+## Імпорт Path
+
+Спочатку імпортуйте `Path` з `fastapi` і імпортуйте `Annotated`:
+
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
+
+/// info | Інформація
+
+FastAPI додав підтримку `Annotated` (і почав рекомендувати його використання) у версії 0.95.0.
+
+Якщо у Вас стара версія, при спробі використати `Annotated` можуть виникати помилки.
+
+Переконайтеся, що Ви [оновили версію FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} принаймні до версії 0.95.1 перед використанням `Annotated`.
+
+///
+
+## Оголошення метаданих
+
+Ви можете оголошувати всі ті ж параметри, що і для `Query`.
+
+Наприклад, щоб оголосити значення метаданих `title` для параметра шляху `item_id`, Ви можете написати:
+
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
+
+/// note | Примітка
+
+Параметр шляху завжди є обов’язковим, оскільки він має бути частиною шляху. Навіть якщо Ви оголосите його зі значенням `None` або встановите значення за замовчуванням — він все одно залишатиметься обов’язковим.
+
+///
+
+## Упорядковуйте параметри, як Вам потрібно
+
+/// tip | Підказка
+
+Це, мабуть, не настільки важливо або необхідно, якщо Ви використовуєте `Annotated`.
+
+///
+
+Припустимо, Ви хочете оголосити параметр запиту `q` як обов’язковий `str`.
+
+І Вам не потрібно оголошувати нічого іншого для цього параметра, тому немає потреби використовувати `Query`.
+
+Але Вам все одно потрібно використовувати `Path` для параметра шляху `item_id`. І з певних причин Ви не хочете використовувати `Annotated`.
+
+Python видасть помилку, якщо розмістити значення з "default" перед значенням, яке не має "default".
+
+Але Ви можете змінити порядок і розмістити значення без значення за замовчуванням (параметр запиту `q`) першим.
+
+
+Для **FastAPI** порядок не має значення. Він визначає параметри за їх іменами, типами та значеннями за замовчуванням (`Query`, `Path` тощо) і не звертає уваги на порядок.
+
+Тому Ви можете оголосити Вашу функцію так:
+
+//// tab | Python 3.8 non-Annotated
+
+/// tip | Підказка
+
+За можливості віддавайте перевагу версії з використанням `Annotated`.
+
+///
+
+{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
+
+////
+
+Але майте на увазі, що якщо Ви використовуєте `Annotated`, ця проблема не виникне, оскільки Ви не використовуєте значення за замовчуванням для параметрів `Query()` або `Path()`.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
+
+## Упорядковуйте параметри за потребою, хитрощі
+
+/// tip | Підказка
+
+Це, мабуть, не настільки важливо або необхідно, якщо Ви використовуєте `Annotated`.
+
+///
+
+Ось **невелика хитрість**, яка може стати в пригоді, хоча вона рідко знадобиться.
+
+Якщо Ви хочете:
+
+* оголосити параметр запиту `q` без використання `Query` або значення за замовчуванням
+* оголосити параметр шляху `item_id`, використовуючи `Path`
+* розмістити їх у різному порядку
+* не використовувати `Annotated`
+
+...у Python є спеціальний синтаксис для цього.
+
+Передайте `*` як перший параметр функції.
+
+Python нічого не зробить із цією `*`, але розпізнає, що всі наступні параметри слід викликати як аргументи за ключовим словом (пари ключ-значення), також відомі як
kwargs
. Навіть якщо вони не мають значення за замовчуванням.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+
+### Краще з `Annotated`
+
+Майте на увазі, якщо Ви використовуєте `Annotated`, оскільки Ви не використовуєте значення за замовчуванням для параметрів функції, цієї проблеми не виникне, і, швидше за все, Вам не потрібно буде використовувати `*`.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
+
+## Валідація числових даних: більше або дорівнює
+
+За допомогою `Query` і `Path` (та інших, які Ви побачите пізніше) можна оголошувати числові обмеження.
+
+Тут, завдяки `ge=1`, `item_id` має бути цілим числом, яке "`g`reater than or `e`qual" (більше або дорівнює) `1`.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
+
+## Валідація числових даних: більше ніж і менше або дорівнює
+
+Те саме застосовується до:
+
+* `gt`: `g`reater `t`han (більше ніж)
+* `le`: `l`ess than or `e`qual (менше або дорівнює)
+
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
+
+## Валідація числових даних: float, більше ніж і менше ніж
+
+Валідація чисел також працює для значень типу `float`.
+
+Ось де стає важливо мати можливість оголошувати
gt
, а не тільки
ge
. Це дозволяє, наприклад, вимагати, щоб значення було більше `0`, навіть якщо воно менше `1`.
+
+Таким чином, значення `0.5` буде допустимим. Але `0.0` або `0` — ні.
+
+Те саме стосується
lt
.
+
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
+
+## Підсумок
+
+За допомогою `Query`, `Path` (і інших параметрів, які Ви ще не бачили) можна оголошувати метадані та перевірки рядків, так само як у [Query параметри та валідація рядків](query-params-str-validations.md){.internal-link target=_blank}.
+
+Також можна оголошувати числові перевірки:
+
+* `gt`: `g`reater `t`han (більше ніж)
+* `ge`: `g`reater than or `e`qual (більше або дорівнює)
+* `lt`: `l`ess `t`han (менше ніж)
+* `le`: `l`ess than or `e`qual (менше або дорівнює)
+
+/// info | Інформація
+
+`Query`, `Path` та інші класи, які Ви побачите пізніше, є підкласами спільного класу `Param`.
+
+Всі вони мають однакові параметри для додаткових перевірок і метаданих, які Ви вже бачили.
+
+///
+
+/// note | Технічні деталі
+
+Коли Ви імпортуєте `Query`, `Path` та інші з `fastapi`, насправді це функції.
+
+При виклику вони повертають екземпляри класів з такими ж іменами.
+
+Тобто Ви імпортуєте `Query`, яка є функцією. А коли Ви її викликаєте, вона повертає екземпляр класу, який теж називається `Query`.
+
+Ці функції створені таким чином (замість використання класів напряму), щоб Ваш редактор не відзначав їхні типи як помилки.
+
+Таким чином, Ви можете користуватися своїм звичайним редактором і інструментами для програмування без додаткових налаштувань для ігнорування таких помилок.
+
+///
diff --git a/docs/uk/docs/tutorial/path-params.md b/docs/uk/docs/tutorial/path-params.md
new file mode 100644
index 000000000..e7df1f19a
--- /dev/null
+++ b/docs/uk/docs/tutorial/path-params.md
@@ -0,0 +1,261 @@
+# Path Параметри
+
+Ви можете визначити "параметри" або "змінні" шляху, використовуючи синтаксис форматованих рядків:
+
+{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+
+Значення параметра шляху `item_id` передається у функцію як аргумент `item_id`.
+
+Якщо запустити цей приклад та перейти за посиланням
http://127.0.0.1:8000/items/foo, то отримаємо таку відповідь:
+
+```JSON
+{"item_id":"foo"}
+```
+
+## Path параметри з типами
+
+Ви можете визначити тип параметра шляху у функції, використовуючи стандартні анотації типів Python:
+
+{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+
+У такому випадку `item_id` визначається як `int`.
+
+/// check | Примітка
+
+Це дасть можливість підтримки редактора всередині функції з перевірками помилок, автодоповнення тощо.
+
+///
+
+##
Перетворення даних
+
+Якщо запустити цей приклад і перейти за посиланням
http://127.0.0.1:8000/items/3, то отримаєте таку відповідь:
+
+```JSON
+{"item_id":3}
+```
+
+/// check | Примітка
+
+Зверніть увагу, що значення, яке отримала (і повернула) ваша функція, — це `3`. Це Python `int`, а не рядок `"3"`.
+
+Отже, з таким оголошенням типу **FastAPI** автоматично виконує
"парсинг" запитів.
+
+///
+
+##
Перевірка даних
+
+Якщо ж відкрити у браузері посилання
http://127.0.0.1:8000/items/foo, то побачимо цікаву HTTP-помилку:
+
+```JSON
+{
+ "detail": [
+ {
+ "type": "int_parsing",
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "Input should be a valid integer, unable to parse string as an integer",
+ "input": "foo",
+ "url": "https://errors.pydantic.dev/2.1/v/int_parsing"
+ }
+ ]
+}
+```
+тому що параметр шляху має значення `"foo"`, яке не є типом `int`.
+
+Таку саму помилку отримаємо, якщо передати `float` замість `int`, як бачимо, у цьому прикладі:
http://127.0.0.1:8000/items/4.2
+
+/// check | Примітка
+
+Отже, **FastAPI** надає перевірку типів з таким самим оголошенням типу в Python.
+
+Зверніть увагу, що помилка також чітко вказує саме на те місце, де валідація не пройшла.
+
+Це неймовірно корисно під час розробки та дебагінгу коду, що взаємодіє з вашим API.
+
+///
+
+## Документація
+
+Тепер коли відкриєте свій браузер за посиланням
http://127.0.0.1:8000/docs, то побачите автоматично згенеровану, інтерактивну API-документацію:
+
+

+
+/// check | Примітка
+
+Знову ж таки, лише з цим самим оголошенням типу в Python, FastAPI надає вам автоматичну, інтерактивну документацію (з інтеграцією Swagger UI).
+
+Зверніть увагу, що параметр шляху оголошений як ціле число.
+
+
+///
+
+## Переваги стандартизації, альтернативна документація
+
+І оскільки згенерована схема відповідає стандарту
OpenAPI, існує багато сумісних інструментів.
+
+З цієї причини FastAPI також надає альтернативну документацію API (використовуючи ReDoc), до якої можна отримати доступ за посиланням
http://127.0.0.1:8000/redoc:
+
+

+
+Таким чином, існує багато сумісних інструментів, включаючи інструменти для генерації коду для багатьох мов.
+
+
+## Pydantic
+
+Вся валідація даних виконується за лаштунками за допомогою
Pydantic, тому Ви отримуєте всі переваги від його використання. І можете бути впевнені, що все в надійних руках.
+
+Ви можете використовувати ті самі оголошення типів з `str`, `float`, `bool` та багатьма іншими складними типами даних.
+
+Декілька з них будуть розглянуті в наступних розділах посібника.
+
+## Порядок має значення
+
+При створенні *операцій шляху* можуть виникати ситуації, коли шлях фіксований.
+
+Наприклад, `/users/me`. Припустимо, що це шлях для отримання даних про поточного користувача.
+
+А також у вас може бути шлях `/users/{user_id}`, щоб отримати дані про конкретного користувача за його ID.
+
+Оскільки *операції шляху* оцінюються по черзі, Ви повинні переконатися, що шлях для `/users/me` оголошений перед шляхом для `/users/{user_id}`:
+
+{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+
+Інакше шлях для `/users/{user_id}` також буде відповідати для `/users/me`, "вважаючи", що він отримує параметр `user_id` зі значенням `"me"`.
+
+Аналогічно, Ви не можете оголосити операцію шляху:
+
+{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+
+Перша операція буде завжди використовуватися, оскільки шлях збігається першим.
+## Попередньо визначені значення
+
+Якщо у вас є *операція шляху*, яка приймає *параметр шляху*, але Ви хочете, щоб можливі допустимі значення *параметра шляху* були попередньо визначені, Ви можете використати стандартний Python
Enum.
+
+### Створення класу `Enum`
+
+Імпортуйте `Enum` і створіть підклас, що наслідується від `str` та `Enum`.
+
+Наслідуючи від `str`, документація API зможе визначити, що значення повинні бути типу `string`, і правильно їх відобразить.
+
+Після цього створіть атрибути класу з фіксованими значеннями, які будуть доступними допустимими значеннями:
+
+{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
+
+/// info | Додаткова інформація
+
+
Перелічення (або enums) доступні в Python починаючи з версії 3.4.
+
+///
+
+/// tip | Порада
+
+Якщо вам цікаво, "AlexNet", "ResNet" та "LeNet" — це просто назви ML моделей
Machine Learning.
+
+///
+
+
+### Оголосіть *параметр шляху*
+
+Потім створіть *параметр шляху* з анотацією типу, використовуючи створений вами клас enum (`ModelName`):
+
+{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+
+### Перевірка документації
+
+Оскільки доступні значення для *параметра шляху* визначені заздалегідь, інтерактивна документація зможе красиво їх відобразити:
+
+

+
+### Робота з *перелічуваннями* у Python
+
+Значення *параметра шляху* буде елементом *перелічування*.
+
+#### Порівняння *елементів перелічування*
+
+Ви можете порівнювати його з *елементами перелічування* у створеному вами enum `ModelName`:
+
+{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+
+#### Отримання *значення перелічування*
+
+Ви можете отримати фактичне значення (у цьому випадку це `str`), використовуючи `model_name.value`, або загалом `your_enum_member.value`:
+
+{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+
+/// tip | Порада
+
+Ви також можете отримати доступ до значення `"lenet"`, використовуючи `ModelName.lenet.value`.
+
+///
+
+
+#### Повернення *елементів перелічування*
+
+Ви можете повертати *елементи перелічування* з вашої *операції шляху*, навіть вкладені у JSON-тіло (наприклад, `dict`).
+
+Вони будуть перетворені на відповідні значення (у цьому випадку рядки) перед поверненням клієнту:
+
+{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+
+На стороні клієнта Ви отримаєте відповідь у форматі JSON, наприклад:
+
+```JSON
+{
+ "model_name": "alexnet",
+ "message": "Deep Learning FTW!"
+}
+```
+
+## Path-параметри, що містять шляхи
+
+Припустимо, у вас є *операція шляху* з маршрутом `/files/{file_path}`.
+
+Але вам потрібно, щоб `file_path` містив *шлях*, наприклад `home/johndoe/myfile.txt`.
+
+Отже, URL для цього файлу виглядатиме так: `/files/home/johndoe/myfile.txt`.
+
+
+
+### Підтримка OpenAPI
+
+OpenAPI не підтримує спосіб оголошення *параметра шляху*, що містить *шлях* всередині, оскільки це може призвести до сценаріїв, які складно тестувати та визначати.
+
+Однак (одначе), Ви все одно можете зробити це в **FastAPI**, використовуючи один із внутрішніх інструментів Starlette.
+
+Документація все ще працюватиме, хоча й не додаватиме опису про те, що параметр повинен містити шлях.
+
+### Конвертер шляху
+
+Використовуючи опцію безпосередньо зі Starlette, Ви можете оголосити *параметр шляху*, що містить *шлях*, використовуючи URL на кшталт:
+
+```
+/files/{file_path:path}
+```
+У цьому випадку ім'я параметра — `file_path`, а остання частина `:path` вказує на те, що параметр повинен відповідати будь-якому *шляху*.
+
+Отже, Ви можете використати його так:
+
+{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+
+/// tip | Порада
+
+Вам може знадобитися, щоб параметр містив `/home/johndoe/myfile.txt` із початковою косою рискою (`/`).
+
+У такому випадку URL виглядатиме так: `/files//home/johndoe/myfile.txt`, із подвійною косою рискою (`//`) між `files` і `home`.
+
+///
+
+## Підсумок
+
+З **FastAPI**, використовуючи короткі, інтуїтивно зрозумілі та стандартні оголошення типів Python, Ви отримуєте:
+
+* Підтримку в редакторі: перевірка помилок, автодоповнення тощо.
+* "
Парсинг" даних
+* Валідацію даних
+* Анотацію API та автоматичну документацію
+
+І вам потрібно оголосити їх лише один раз.
+
+Це, ймовірно, основна видима перевага **FastAPI** порівняно з альтернативними фреймворками (окрім високої продуктивності).
diff --git a/docs/uk/docs/tutorial/query-param-models.md b/docs/uk/docs/tutorial/query-param-models.md
new file mode 100644
index 000000000..97eb82fa1
--- /dev/null
+++ b/docs/uk/docs/tutorial/query-param-models.md
@@ -0,0 +1,68 @@
+# Моделі Query параметрів
+
+Якщо у Вас є група **query параметрів**, які пов’язані між собою, Ви можете створити **Pydantic-модель** для їх оголошення.
+
+Це дозволить Вам **повторно використовувати модель** у **різних місцях**, а також оголошувати перевірки та метадані для всіх параметрів одночасно. 😎
+
+/// note | Примітка
+
+Ця можливість підтримується, починаючи з версії FastAPI `0.115.0`. 🤓
+
+///
+
+## Query параметри з Pydantic-моделлю
+
+Оголосіть **query параметри**, які Вам потрібні, у **Pydantic-моделі**, а потім оголосіть цей параметр як `Query`:
+
+{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
+
+**FastAPI** буде **витягувати** дані для **кожного поля** з **query параметрів** у запиті та передавати їх у визначену вами Pydantic-модель.
+
+## Перевірте документацію
+
+Ви можете побачити параметри запиту в UI документації за `/docs`:
+
+
+

+
+
+## Заборона зайвих Query параметрів
+
+У деяких особливих випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** query параметри, які дозволено отримувати.
+
+Ви можете використати конфігурацію моделі Pydantic, щоб заборонити (`forbid`) будь-які зайві (`extra`) поля:
+
+{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
+
+Якщо клієнт спробує надіслати **зайві** дані у **query параметрах**, він отримає **помилку**.
+
+Наприклад, якщо клієнт спробує надіслати query параметр `tool` зі значенням `plumbus`, як у цьому запиті:
+
+```http
+https://example.com/items/?limit=10&tool=plumbus
+```
+
+Він отримає відповідь з **помилкою**, яка повідомить, що query параметр `tool ` не дозволено:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["query", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus"
+ }
+ ]
+}
+```
+
+## Підсумок
+
+Ви можете використовувати **Pydantic-моделі** для оголошення **query параметрів** у **FastAPI**. 😎
+
+/// tip | Підказка
+
+Спойлер: Ви також можете використовувати Pydantic-моделі для оголошення cookie та заголовків, але про це Ви дізнаєтеся пізніше в цьому посібнику. 🤫
+
+///
diff --git a/docs/uk/docs/tutorial/query-params-str-validations.md b/docs/uk/docs/tutorial/query-params-str-validations.md
new file mode 100644
index 000000000..cd3f4ad93
--- /dev/null
+++ b/docs/uk/docs/tutorial/query-params-str-validations.md
@@ -0,0 +1,491 @@
+# Query параметри та валідація рядків
+
+**FastAPI** дозволяє оголошувати додаткову інформацію та виконувати валідацію для Ваших параметрів.
+
+Розглянемо цей додаток як приклад:
+
+{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
+
+Query параметр `q` має тип `str | None`, що означає, що він може бути як `str`, так і `None`. За замовчуванням він має значення `None`, тому FastAPI розуміє, що цей параметр не є обов'язковим.
+
+/// note | Примітка
+
+FastAPI знає, що `q` не є обов’язковим, завдяки значенню за замовчуванням `= None`.
+
+Використання `str | None` дозволить Вашому редактору коду надавати кращу підтримку та виявляти помилки.
+
+///
+
+## Додаткова валідація
+
+Ми хочемо, щоб навіть якщо `q` є необов’язковим, **його довжина не перевищувала 50 символів**, якщо він все ж буде переданий.
+
+### Імпорт `Query` та `Annotated`
+
+Щоб це зробити, спочатку імпортуємо:
+
+* `Query` з `fastapi`
+* `Annotated` з `typing`
+
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
+
+/// info | Інформація
+
+FastAPI додав підтримку `Annotated` (і почав рекомендувати його) у версії 0.95.0.
+
+Якщо у Вас старіша версія, під час використання `Annotated` можуть виникати помилки.
+
+Переконайтеся, що Ви [оновили версію FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} до принаймні 0.95.1, перш ніж використовувати `Annotated`.
+
+///
+
+## Використання `Annotated` у типі параметра `q`
+
+Пам’ятаєте, як я раніше розповідав, що `Annotated` можна використовувати для додавання метаданих до параметрів у [Вступі до типів Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}?
+
+Зараз саме час використати його разом із FastAPI. 🚀
+
+Раніше ми мали таку анотацію типу:
+
+//// tab | Python 3.10+
+
+```Python
+q: str | None = None
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+q: Union[str, None] = None
+```
+
+////
+
+Тепер ми загорнемо її у `Annotated`, і отримаємо:
+
+//// tab | Python 3.10+
+
+```Python
+q: Annotated[str | None] = None
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+q: Annotated[Union[str, None]] = None
+```
+
+////
+
+Обидві ці версії означають одне й те саме: `q` — це параметр, який може бути `str` або `None`, і за замовчуванням має значення `None`.
+
+А тепер переходимо до цікавого! 🎉
+
+## Додавання `Query` до `Annotated` у параметр `q`
+
+Тепер, коли у нас є `Annotated`, де ми можемо додавати додаткову інформацію (зокрема валідацію), додамо `Query` всередину `Annotated` і встановимо параметр `max_length` у `50`:
+
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
+
+Зверніть увагу, що значення за замовчуванням усе ще `None`, тому параметр залишається необов'язковим.
+
+Але тепер, додавши `Query(max_length=50)` всередину `Annotated`, ми повідомляємо FastAPI, що хочемо **додаткову валідацію** для цього значення — воно має містити максимум 50 символів. 😎
+
+/// tip | Підказка
+
+Ми використовуємо `Query()`, оскільки це **query параметр**. Далі ми розглянемо інші варіанти, як-от `Path()`, `Body()`, `Header()` та `Cookie()`, які приймають ті самі аргументи, що й `Query()`.
+
+///
+
+Тепер FastAPI:
+
+* **Перевірить** дані, щоб переконатися, що їхня довжина не перевищує 50 символів
+* Покажe **чітку помилку** клієнту, якщо дані недійсні
+* **Задокументує** параметр в OpenAPI-схемі *операції шляху* (що відобразиться в **автоматично згенерованій документації**)
+
+## Альтернативний (застарілий) метод: Query як значення за замовчуванням
+
+У попередніх версіях FastAPI (до
0.95.0) `Query` використовувався як значення за замовчуванням для параметра, а не всередині `Annotated`. Ви, ймовірно, побачите код, який використовує цей підхід, тому варто розглянути його.
+
+/// tip | Підказка
+
+Для нового коду та коли це можливо, використовуйте `Annotated`, як показано вище. Це має багато переваг (пояснених нижче) і не має недоліків. 🍰
+
+///
+
+Раніше ми писали `Query()` як значення за замовчуванням для параметра функції, встановлюючи `max_length` у 50:
+
+{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
+
+Оскільки в цьому випадку (без `Annotated`) нам потрібно замінити `None` у функції на `Query()`, тепер ми повинні явно встановити значення за замовчуванням через параметр `Query(default=None)`. Це виконує ту саму роль визначення значення за замовчуванням (принаймні для FastAPI).
+
+Таким чином:
+
+```Python
+q: str | None = Query(default=None)
+```
+
+...робить параметр необов’язковим зі значенням за замовчуванням `None`, що еквівалентно:
+
+
+```Python
+q: str | None = None
+```
+Але у версії з `Query` ми явно вказуємо, що це query параметр.
+
+Далі ми можемо передавати `Query` додаткові параметри, зокрема `max_length`, який застосовується до рядків:
+
+```Python
+q: str | None = Query(default=None, max_length=50)
+```
+
+Це забезпечить валідацію даних, виведе зрозумілу помилку у разі недійсних даних і задокументує параметр у схемі OpenAPI *операції шляху*.
+
+### `Query` як значення за замовчуванням або всередині `Annotated`
+
+Важливо пам’ятати, якщо використовувати `Query` всередині `Annotated`, не можна задавати параметр `default` у `Query`.
+
+Замість цього використовуйте значення за замовчуванням у самій функції. Інакше це буде нелогічно.
+
+Наприклад, цей варіант є некоректним:
+
+```Python
+q: Annotated[str, Query(default="rick")] = "morty"
+```
+
+...тому, що не зрозуміло, яке значення має бути значенням за замовчуванням: `"rick"` чи `"morty"`.
+
+Коректні варіанти:
+
+```Python
+q: Annotated[str, Query()] = "rick"
+```
+
+...або у старих кодових базах Ви знайдете:
+
+```Python
+q: str = Query(default="rick")
+```
+
+### Переваги використання `Annotated`
+
+**Використання `Annotated` є рекомендованим** замість задання значення за замовчуванням у параметрах функції, оскільки воно **краще** з кількох причин. 🤓
+
+Значення **за замовчуванням** параметра **функції** є його **фактичним значенням за замовчуванням**, що є більш інтуїтивним у Python загалом. 😌
+
+Ви можете **викликати** ту саму функцію **в інших місцях** без FastAPI, і вона **працюватиме очікувано**. Якщо параметр є **обов’язковим** (без значення за замовчуванням), Ваш **редактор** повідомить про помилку, а **Python** також видасть помилку, якщо Ви виконаєте функцію без передавання цього параметра.
+
+Якщо Ви не використовуєте `Annotated`, а використовуєте **(старий) стиль значень за замовчуванням**, то при виклику цієї функції без FastAPI **в інших місцях**, потрібно **не забути** передати їй аргументи, інакше значення будуть відрізнятися від очікуваних (наприклад, Ви отримаєте `QueryInfo` або подібне замість `str`). Ваш редактор не повідомить про помилку, і Python також не видасть помилку при запуску функції, поки не виникне помилка під час виконання операцій усередині.
+
+Оскільки `Annotated` може містити кілька анотацій метаданих, Ви навіть можете використовувати ту саму функцію з іншими інструментами, такими як
Typer. 🚀
+
+## Додавання додаткових валідацій
+
+Ви також можете додати параметр `min_length`:
+
+{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
+
+## Додавання регулярних виразів
+
+Ви можете визначити
регулярний вираз pattern, якому має відповідати параметр:
+
+{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
+
+Цей конкретний шаблон регулярного виразу перевіряє, що отримане значення параметра:
+
+* `^`: починається з наступних символів, перед якими немає інших символів.
+* `fixedquery`: точно відповідає значенню `fixedquery`.
+* `$`: закінчується тут, після `fixedquery` немає жодних символів.
+
+Якщо Ви почуваєтеся розгублено щодо **"регулярних виразів"**, не хвилюйтеся. Вони є складною темою для багатьох людей. Ви все одно можете зробити багато речей без їх використання.
+
+Але тепер Ви знаєте, що коли вони знадобляться, їх можна застосовувати у **FastAPI**.
+
+### Pydantic v1 `regex` замість `pattern`
+
+До версії Pydantic 2 і FastAPI 0.100.0 параметр називався `regex` замість `pattern`, але тепер він застарів.
+
+Ви все ще можете зустріти код, який використовує його:
+
+//// tab | Pydantic v1
+
+{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
+
+////
+
+Але майте на увазі, що він є застарілим і його слід оновити до нового параметра `pattern`. 🤓
+
+## Значення за замовчуванням
+
+Ви можете використовувати значення за замовчуванням, відмінні від `None`.
+
+Наприклад, якщо Ви хочете оголосити параметр запиту `q` з `min_length` `3` і значенням за замовчуванням `"fixedquery"`:
+
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
+
+/// note | Технічні деталі
+
+Наявність значення за замовчуванням будь-якого типу, включаючи `None`, робить параметр необов’язковим (not required).
+
+///
+
+## Обов’язкові параметри
+
+Якщо нам не потрібно вказувати додаткові перевірки або метадані, ми можемо зробити параметр `q` обов’язковим, просто не оголошуючи значення за замовчуванням, наприклад:
+
+```Python
+q: str
+```
+
+замість:
+
+```Python
+q: str | None = None
+```
+
+Але тепер ми оголошуємо його з `Query`, наприклад:
+
+//// tab | Annotated
+
+```Python
+q: Annotated[str | None, Query(min_length=3)] = None
+```
+
+////
+
+Тому, якщо Вам потрібно зробити значення обов’язковим, використовуючи `Query`, просто не вказуйте значення за замовчуванням:
+
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
+
+### Обов’язкове значення, яке може бути `None`
+
+Ви можете вказати, що параметр може приймати `None`, але при цьому залишається обов’язковим. Це змусить клієнтів надіслати значення, навіть якщо воно дорівнює `None`.
+
+Щоб зробити це, оголосіть, що `None` є допустимим типом, але не вказуйте значення за замовчуванням:
+
+{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
+
+## Список параметрів запиту / кілька значень
+
+Якщо Ви визначаєте параметр запиту за допомогою `Query`, Ви також можете дозволити отримання списку значень, тобто дозволити отримання кількох значень.
+
+Наприклад, щоб дозволити параметру запиту `q` з'являтися кілька разів в URL, можна написати:
+
+{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
+
+Тоді, у випадку запиту за URL:
+
+```
+http://localhost:8000/items/?q=foo&q=bar
+```
+
+Ви отримаєте кілька значень *query параметра* `q` (`foo` і `bar`) у вигляді списку `list` в Python у Вашій *функції обробки шляху*, у *параметрі функції* `q`.
+
+Отже, відповідь на цей URL буде:
+
+```JSON
+{
+ "q": [
+ "foo",
+ "bar"
+ ]
+}
+```
+
+/// tip | Підказка
+
+Щоб оголосити параметр запиту з типом `list`, як у наведеному вище прикладі, потрібно явно використовувати `Query`, інакше він буде інтерпретований як тіло запиту.
+
+///
+
+Інтерактивна API-документація оновиться відповідно, дозволяючи передавати кілька значень:
+
+

+
+### Список параметрів запиту / кілька значень за замовчуванням
+
+Ви також можете визначити значення за замовчуванням для `list`, якщо жодне значення не було передане:
+
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
+
+Якщо Ви перейдете за посиланням:
+
+```
+http://localhost:8000/items/
+```
+
+то значення `q` за замовчуванням буде: `["foo", "bar"]`, і Ваша відповідь виглядатиме так:
+
+```JSON
+{
+ "q": [
+ "foo",
+ "bar"
+ ]
+}
+```
+
+#### Використання тільки `list`
+
+Ви також можете використовувати `list` без уточнення типу, замість `list[str]`:
+
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
+
+/// note | Технічні деталі
+
+Майте на увазі, що в цьому випадку FastAPI не перевірятиме вміст списку.
+
+Наприклад, `list[int]` перевірятиме (і документуватиме), що всі елементи списку є цілими числами. Але `list` без уточнення цього не робитиме.
+
+///
+
+## Додавання додаткових метаданих
+
+Ви можете додати більше інформації про параметр.
+
+Ця інформація буде включена у згенерований OpenAPI та використана в інтерфейсах документації та зовнішніх інструментах.
+
+/// note | Технічні деталі
+
+Майте на увазі, що різні інструменти можуть мати різний рівень підтримки OpenAPI.
+
+Деякі з них можуть ще не відображати всю додаткову інформацію, хоча в більшості випадків ця функція вже запланована для розробки.
+
+///
+
+Ви можете додати `title` :
+
+{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
+
+А також `description`:
+
+{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
+
+## Аліаси параметрів
+
+Уявіть, що Ви хочете, щоб параметр називався `item-query`.
+
+Наприклад:
+
+```
+http://127.0.0.1:8000/items/?item-query=foobaritems
+```
+
+Але `item-query` — це некоректна назва змінної в Python.
+
+Найближчий допустимий варіант — `item_query`.
+
+Проте Вам потрібно, щоб параметр залишався саме `item-query`...
+
+У такому випадку можна оголосити `alias`, і саме він буде використовуватися для отримання значення параметра:
+
+{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
+
+## Виведення параметрів як застарілих
+
+Припустимо, що Ви більше не хочете використовувати цей параметр.
+
+Вам потрібно залишити його на деякий час, оскільки ним користуються клієнти, але Ви хочете, щоб документація чітко показувала, що він є
застарілим.
+
+Тоді Ви можете передати параметр `deprecated=True` до `Query`:
+
+{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
+
+Документація буде показувати це таким чином:
+
+

+
+## Виняток параметрів з OpenAPI
+
+Щоб виключити параметр запиту зі згенерованої схеми OpenAPI (і, таким чином, з автоматичних систем документації), встановіть параметр `include_in_schema` для `Query` в `False`:
+
+{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
+
+## Кастомна валідація
+
+Можуть бути випадки, коли Вам потрібно провести **кастомну валідацію**, яку не можна реалізувати за допомогою параметрів, показаних вище.
+
+У таких випадках ви можете використати **кастомну функцію валідації**, яка буде застосована після звичайної валідації (наприклад, після перевірки, що значення є типом `str`).
+
+Це можна досягти за допомогою
Pydantic's `AfterValidator` в середині `Annotated`.
+
+/// tip | Підказка
+
+Pydantic також має
`BeforeValidator` та інші. 🤓
+
+///
+
+Наприклад, цей кастомний валідатор перевіряє, чи починається ID елемента з `isbn-` для номера книги
ISBN або з `imdb-` для ID URL фільму на
IMDB:
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
+
+/// info | Інформація
+
+Це доступно з версії Pydantic 2 або вище. 😎
+
+///
+
+/// tip | Підказка
+
+Якщо Вам потрібно виконати будь-яку валідацію, яка вимагає взаємодії з будь-яким **зовнішнім компонентом**, таким як база даних чи інший API, ви повинні замість цього використовувати **FastAPI Dependencies**. Ви дізнаєтесь про них пізніше.
+
+Ці кастомні валідатори використовуються для речей, які можна перевірити лише з **тими даними**, що надані в запиті.
+
+///
+
+### Зрозумійте цей код
+
+Головний момент – це використання **`AfterValidator` з функцією всередині `Annotated`**. Можете пропустити цю частину, якщо хочете. 🤸
+
+---
+
+Але якщо Вам цікаво розібратися в цьому конкретному прикладі коду і Вам ще не набридло, ось кілька додаткових деталей.
+
+#### Рядок із `value.startswith()`
+
+Звернули увагу? Рядок із `value.startswith()` може приймати кортеж, і тоді він перевірятиме кожне значення в кортежі:
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
+
+#### Випадковий елемент
+
+За допомогою `data.items()` ми отримуємо
ітерабельний об'єкт із кортежами, що містять ключ і значення для кожного елемента словника.
+
+Ми перетворюємо цей ітерабельний об'єкт у звичайний `list` за допомогою `list(data.items())`.
+
+Потім, використовуючи `random.choice()`, ми можемо отримати випадкове значення зі списку, тобто отримуємо кортеж із `(id, name)`. Це може бути щось на зразок `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
+
+Далі ми **присвоюємо ці два значення** кортежу змінним `id` і `name`.
+
+Тож, якщо користувач не вказав ID елемента, він все одно отримає випадкову рекомендацію.
+
+...і все це реалізовано в **одному рядку коду**. 🤯 Хіба не прекрасний Python? 🐍
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
+
+## Підсумок
+
+Ви можете оголошувати додаткові валідації та метаінформацію для своїх параметрів.
+
+Загальні валідації та метаінформація:
+
+* `alias`
+* `title`
+* `description`
+* `deprecated`
+
+Валідації, специфічні для рядків:
+
+* `min_length`
+* `max_length`
+* `pattern`
+
+Кастомні валідації за допомогою `AfterValidator`.
+
+У цих прикладах Ви побачили, як оголошувати валідації для значень `str`.
+
+Дивіться наступні розділи, щоб дізнатися, як оголошувати валідації для інших типів, наприклад чисел.
diff --git a/docs/uk/docs/tutorial/query-params.md b/docs/uk/docs/tutorial/query-params.md
new file mode 100644
index 000000000..16bb42af3
--- /dev/null
+++ b/docs/uk/docs/tutorial/query-params.md
@@ -0,0 +1,192 @@
+# Query Параметри
+
+Коли Ви оголошуєте інші параметри функції, які не є частиною параметрів шляху, вони автоматично інтерпретуються як "query" параметри.
+
+{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+
+Query параметри — це набір пар ключ-значення, що йдуть після символу `?` в URL, розділені символами `&`.
+
+Наприклад, в URL:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+...query параметрами є:
+
+* `skip`: зі значенням `0`
+* `limit`: зі значенням `10`
+
+Оскільки вони є частиною URL, вони "за замовчуванням" є рядками.
+
+Але коли Ви оголошуєте їх із типами Python (у наведеному прикладі як `int`), вони перетворюються на цей тип і проходять перевірку відповідності.
+
+Увесь той самий процес, який застосовується до параметрів шляху, також застосовується до query параметрів:
+
+* Підтримка в редакторі (автодоповнення, перевірка помилок)
+*
"Парсинг" даних
+* Валідація даних
+* Автоматична документація
+
+
+## Значення за замовчуванням
+
+Оскільки query параметри не є фіксованою частиною шляху, вони можуть бути необов’язковими та мати значення за замовчуванням.
+
+У наведеному вище прикладі вони мають значення за замовчуванням: `skip=0` і `limit=10`.
+
+Отже, результат переходу за URL:
+
+```
+http://127.0.0.1:8000/items/
+```
+буде таким самим, як і перехід за посиланням:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+Але якщо Ви перейдете, наприклад, за посиланням:
+
+```
+http://127.0.0.1:8000/items/?skip=20
+```
+
+Значення параметрів у вашій функції будуть такими:
+
+* `skip=20`: оскільки Ви вказали його в URL
+* `limit=10`: оскільки це значення за замовчуванням
+
+## Необов'язкові параметри
+
+Аналогічно, Ви можете оголосити необов’язкові query параметри, встановивши для них значення за замовчуванням `None`:
+
+{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
+
+У цьому випадку параметр функції `q` буде необов’язковим і за замовчуванням матиме значення `None`.
+
+/// check | Примітка
+
+Також зверніть увагу, що **FastAPI** достатньо розумний, щоб визначити, що параметр шляху `item_id` є параметром шляху, а `q` — ні, отже, це query параметр.
+
+///
+
+## Перетворення типу Query параметра
+
+Ви також можете оголошувати параметри типу `bool`, і вони будуть автоматично конвертовані:
+
+{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
+
+У цьому випадку, якщо Ви звернетесь до:
+
+
+```
+http://127.0.0.1:8000/items/foo?short=1
+```
+
+або
+
+```
+http://127.0.0.1:8000/items/foo?short=True
+```
+
+або
+
+```
+http://127.0.0.1:8000/items/foo?short=true
+```
+
+або
+
+```
+http://127.0.0.1:8000/items/foo?short=on
+```
+
+або
+
+```
+http://127.0.0.1:8000/items/foo?short=yes
+```
+
+або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр `short` зі значенням `True` з типом даних `bool`. В іншому випадку – `False`.
+
+## Кілька path і query параметрів
+
+Ви можете одночасно оголошувати кілька path і query параметрів, і **FastAPI** автоматично визначить, який з них до чого належить.
+
+
+Не потрібно дотримуватись певного порядку їх оголошення.
+
+Вони визначаються за назвою:
+
+{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
+
+## Обов’язкові Query параметри
+
+Якщо Ви оголошуєте значення за замовчуванням для параметрів, які не є path-параметрами (у цьому розділі ми бачили поки що лише path параметри), тоді вони стають необов’язковими.
+
+Якщо Ви не хочете вказувати конкретні значення, але хочете зробити параметр опціональним, задайте `None` як значення за замовчуванням.
+
+Але якщо Ви хочете зробити query параметр обов’язковим, просто не вказуйте для нього значення за замовчуванням:
+
+{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+
+Тут `needy` – обов’язковий query параметр типу `str`.
+
+Якщо Ви відкриєте у браузері URL-адресу:
+
+```
+http://127.0.0.1:8000/items/foo-item
+```
+
+...без додавання обов’язкового параметра `needy`, Ви побачите помилку:
+
+```JSON
+{
+ "detail": [
+ {
+ "type": "missing",
+ "loc": [
+ "query",
+ "needy"
+ ],
+ "msg": "Field required",
+ "input": null,
+ "url": "https://errors.pydantic.dev/2.1/v/missing"
+ }
+ ]
+}
+```
+
+Оскільки `needy` є обов’язковим параметром, вам потрібно вказати його в URL:
+
+```
+http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
+```
+
+...цей запит поверне:
+
+```JSON
+{
+ "item_id": "foo-item",
+ "needy": "sooooneedy"
+}
+```
+
+
+Звичайно, Ви можете визначити деякі параметри як обов’язкові, інші зі значенням за замовчуванням, а ще деякі — повністю опціональні:
+
+{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
+
+У цьому випадку є 3 query параметри:
+
+* `needy`, обов’язковий `str`.
+* `skip`, `int` зі значенням за замовчуванням `0`.
+* `limit`, опціональний `int`.
+
+
+/// tip | Підказка
+
+Ви також можете використовувати `Enum`-и, так само як і з [Path Parameters](path-params.md#predefined-values){.internal-link target=_blank}.
+
+///
diff --git a/docs/uk/docs/tutorial/request-files.md b/docs/uk/docs/tutorial/request-files.md
new file mode 100644
index 000000000..18b7cc01c
--- /dev/null
+++ b/docs/uk/docs/tutorial/request-files.md
@@ -0,0 +1,175 @@
+# Запит файлів
+
+Ви можете визначити файли, які будуть завантажуватися клієнтом, використовуючи `File`.
+
+/// info | Інформація
+
+Щоб отримувати завантажені файли, спочатку встановіть
python-multipart.
+
+Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його та встановили пакет, наприклад:
+
+```console
+$ pip install python-multipart
+```
+
+Це необхідно, оскільки завантажені файли передаються у вигляді "форматованих даних форми".
+
+///
+
+## Імпорт `File`
+
+Імпортуйте `File` та `UploadFile` з `fastapi`:
+
+{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
+
+## Визначення параметрів `File`
+
+Створіть параметри файлів так само як Ви б створювали `Body` або `Form`:
+
+{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
+
+/// info | Інформація
+
+`File` — це клас, який безпосередньо успадковує `Form`.
+
+Але пам’ятайте, що коли Ви імпортуєте `Query`, `Path`, `File` та інші з `fastapi`, це насправді функції, які повертають спеціальні класи.
+
+///
+
+/// tip | Підказка
+
+Щоб оголосити тіла файлів, Вам потрібно використовувати `File`, тому що інакше параметри будуть інтерпретовані як параметри запиту або параметри тіла (JSON).
+
+///
+
+Файли будуть завантажені у вигляді "форматованих даних форми".
+
+Якщо Ви оголосите тип параметра функції обробника маршруту як `bytes`, **FastAPI** прочитає файл за Вас, і Ви отримаєте його вміст у вигляді `bytes`.
+
+Однак майте на увазі, що весь вміст буде збережено в пам'яті. Це працюватиме добре для малих файлів.
+
+Але в деяких випадках Вам може знадобитися `UploadFile`.
+
+## Параметри файлу з `UploadFile`
+
+Визначте параметр файлу з типом `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
+
+Використання `UploadFile` має кілька переваг перед `bytes`:
+
+* Вам не потрібно використовувати `File()` у значенні за замовчуванням параметра.
+* Використовується "буферизований" файл:
+ * Файл зберігається в пам'яті до досягнення певного обмеження, після чого він записується на диск.
+* Це означає, що він добре працює для великих файлів, таких як зображення, відео, великі двійкові файли тощо, не споживаючи всю пам'ять.
+Ви можете отримати метадані про завантажений файл.
+* Він має
file-like `асинхронний файловий інтерфейс` interface.
+* Він надає фактичний об'єкт Python
`SpooledTemporaryFile`, який можна передавати безпосередньо іншим бібліотекам.
+
+### `UploadFile`
+
+`UploadFile` має такі атрибути:
+
+* `filename`: Рядок `str` з оригінальною назвою файлу, який був завантажений (наприклад, `myimage.jpg`).
+* `content_type`: Рядок `str` з MIME-типом (наприклад, `image/jpeg`).
+* `file`: Об'єкт
SpooledTemporaryFile (
файлоподібний об'єкт). Це фактичний файловий об'єкт Python, який можна безпосередньо передавати іншим функціям або бібліотекам, що очікують "файлоподібний" об'єкт.
+
+`UploadFile` має такі асинхронні `async` методи. Вони викликають відповідні методи файлу під капотом (використовуючи внутрішній `SpooledTemporaryFile`).
+
+* `write(data)`: Записує `data` (`str` або `bytes`) у файл.
+* `read(size)`: Читає `size` (`int`) байтів/символів з файлу.
+* `seek(offset)`: Переміщується до позиції `offset` (`int`) у файлі.
+ * Наприклад, `await myfile.seek(0)` поверне курсор на початок файлу.
+ * This is especially useful if you run `await myfile.read()` once and then need to read the contents again. Це особливо корисно, якщо Ви виконуєте await `await myfile.read()` один раз, а потім потрібно знову прочитати вміст.
+* `close()`: Закриває файл.
+
+Оскільки всі ці методи є асинхронними `async`, Вам потрібно використовувати "await":
+
+Наприклад, всередині `async` *функції обробки шляху* Ви можете отримати вміст за допомогою:
+
+```Python
+contents = await myfile.read()
+```
+Якщо Ви знаходитесь у звичайній `def` *функції обробки шляху*, Ви можете отримати доступ до `UploadFile.file` безпосередньо, наприклад:
+
+```Python
+contents = myfile.file.read()
+```
+
+/// note | Технічні деталі `async`
+
+Коли Ви використовуєте `async` методи, **FastAPI** виконує файлові операції у пулі потоків та очікує їх завершення.
+
+///
+
+/// note | Технічні деталі Starlette
+
+`UploadFile` у **FastAPI** успадковується безпосередньо від `UploadFile` у **Starlette**, але додає деякі необхідні частини, щоб зробити його сумісним із **Pydantic** та іншими компонентами FastAPI.
+
+///
+
+## Що таке "Form Data"
+
+Спосіб, у який HTML-форми (`
`) надсилають дані на сервер, зазвичай використовує "спеціальне" кодування, відмінне від JSON.
+
+**FastAPI** забезпечує правильне зчитування цих даних з відповідної частини запиту, а не з JSON.
+
+/// note | Технічні деталі
+
+Дані з форм зазвичай кодуються за допомогою "media type" `application/x-www-form-urlencoded`, якщо вони не містять файлів.
+
+Але якщо форма містить файли, вона кодується у форматі `multipart/form-data`. Якщо Ви використовуєте `File`, **FastAPI** визначить, що потрібно отримати файли з відповідної частини тіла запиту.
+
+Щоб дізнатися більше про ці типи кодування та формові поля, ознайомтеся з
документацією MDN щодо POST
.
+
+///
+
+/// warning | Увага
+
+Ви можете оголосити кілька параметрів `File` і `Form` в *операції шляху*, але Ви не можете одночасно оголошувати поля `Body`, які мають надходити у форматі JSON, оскільки тіло запиту буде закодоване у форматі `multipart/form-data`, а не `application/json`.
+
+Це не обмеження **FastAPI**, а особливість протоколу HTTP.
+
+///
+
+## Опціональне Завантаження Файлів
+
+Файл можна зробити необов’язковим, використовуючи стандартні анотації типів і встановлюючи значення за замовчуванням `None`:
+
+{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
+
+## `UploadFile` із Додатковими Мета Даними
+
+Ви також можете використовувати `File()` разом із `UploadFile`, наприклад, для встановлення додаткових метаданих:
+
+{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
+
+## Завантаження Кількох Файлів
+
+Можна завантажувати кілька файлів одночасно.
+
+Вони будуть пов’язані з одним і тим самим "form field", який передається у вигляді "form data".
+
+Щоб це реалізувати, потрібно оголосити список `bytes` або `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
+
+Ви отримаєте, як і було оголошено, `list` із `bytes` або `UploadFile`.
+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette.responses import HTMLResponse`.
+
+**FastAPI** надає ті ж самі `starlette.responses`, що й `fastapi.responses`, для зручності розробників. Однак більшість доступних відповідей надходять безпосередньо від Starlette.
+
+///
+
+### Завантаження декількох файлів із додатковими метаданими
+
+Так само як і раніше, Ви можете використовувати `File()`, щоб встановити додаткові параметри навіть для `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
+
+## Підсумок
+
+Використовуйте `File`, `bytes`та `UploadFile`, щоб оголошувати файли для завантаження у запитах, які надсилаються у вигляді form data.
diff --git a/docs/uk/docs/tutorial/request-form-models.md b/docs/uk/docs/tutorial/request-form-models.md
new file mode 100644
index 000000000..7f5759e79
--- /dev/null
+++ b/docs/uk/docs/tutorial/request-form-models.md
@@ -0,0 +1,78 @@
+# Моделі форм (Form Models)
+
+У FastAPI Ви можете використовувати **Pydantic-моделі** для оголошення **полів форми**.
+
+/// info | Інформація
+
+Щоб використовувати форми, спочатку встановіть
python-multipart.
+
+Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили бібліотеку, наприклад:
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+/// note | Підказка
+
+Ця функція підтримується, починаючи з FastAPI версії `0.113.0`. 🤓
+
+///
+
+## Використання Pydantic-моделей для форм
+
+Вам просто потрібно оголосити **Pydantic-модель** з полями, які Ви хочете отримати як **поля форми**, а потім оголосити параметр як `Form`:
+
+{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
+
+**FastAPI** **витягне** дані для **кожного поля** з **формових даних** у запиті та надасть вам Pydantic-модель, яку Ви визначили.
+
+## Перевірка документації
+
+Ви можете перевірити це в UI документації за `/docs`:
+
+
+

+
+
+## Заборона додаткових полів форми
+
+У деяких особливих випадках (ймовірно, рідко) Ви можете **обмежити** форму лише тими полями, які були оголошені в Pydantic-моделі, і **заборонити** будь-які **додаткові** поля.
+
+/// note | Підказка
+
+Ця функція підтримується, починаючи з FastAPI версії `0.114.0`. 🤓
+
+///
+
+Ви можете використати конфігурацію Pydantic-моделі, щоб заборонити `forbid` будь-які додаткові `extra` поля:
+
+{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
+
+Якщо клієнт спробує надіслати додаткові дані, він отримає **відповідь з помилкою**.
+
+Наприклад, якщо клієнт спробує надіслати наступні поля форми:
+
+* `username`: `Rick`
+* `password`: `Portal Gun`
+* `extra`: `Mr. Poopybutthole`
+
+Він отримає відповідь із помилкою, яка повідомляє, що поле `extra` не дозволено:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "Mr. Poopybutthole"
+ }
+ ]
+}
+```
+
+## Підсумок
+
+Ви можете використовувати Pydantic-моделі для оголошення полів форми у FastAPI. 😎
diff --git a/docs/uk/docs/tutorial/request-forms-and-files.md b/docs/uk/docs/tutorial/request-forms-and-files.md
new file mode 100644
index 000000000..a089ef945
--- /dev/null
+++ b/docs/uk/docs/tutorial/request-forms-and-files.md
@@ -0,0 +1,41 @@
+# Запити з формами та файлами
+
+У FastAPI Ви можете одночасно отримувати файли та поля форми, використовуючи `File` і `Form`.
+
+/// info | Інформація
+
+Щоб отримувати завантажені файли та/або дані форми, спочатку встановіть
python-multipart.
+
+Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили бібліотеку, наприклад:
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+## Імпорт `File` та `Form`
+
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
+
+## Оголошення параметрів `File` та `Form`
+
+Створіть параметри файлів та форми так само як і для `Body` або `Query`:
+
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
+
+Файли та поля форми будуть завантажені як формові дані, і Ви отримаєте як файли, так і введені користувачем поля.
+
+Ви також можете оголосити деякі файли як `bytes`, а деякі як `UploadFile`.
+
+/// warning | Увага
+
+Ви можете оголосити кілька параметрів `File` і `Form` в операції *шляху*, але не можете одночасно оголошувати `Body`-поля, які очікуєте отримати у форматі JSON, оскільки запит матиме тіло, закодоване за допомогою `multipart/form-data`, а не `application/json`.
+
+Це не обмеження **FastAPI**, а частина протоколу HTTP.
+
+///
+
+## Підсумок
+
+Використовуйте `File` та `Form` разом, коли вам потрібно отримувати дані форми та файли в одному запиті.
diff --git a/docs/uk/docs/tutorial/request-forms.md b/docs/uk/docs/tutorial/request-forms.md
new file mode 100644
index 000000000..10c58a73e
--- /dev/null
+++ b/docs/uk/docs/tutorial/request-forms.md
@@ -0,0 +1,73 @@
+# Дані форми
+
+Якщо Вам потрібно отримувати поля форми замість JSON, Ви можете використовувати `Form`.
+
+/// info | Інформація
+
+Щоб використовувати форми, спочатку встановіть
`python-multipart`.
+
+Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, і потім встановили бібліотеку, наприклад:
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+## Імпорт `Form`
+
+Імпортуйте `Form` з `fastapi`:
+
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
+
+## Оголошення параметрів `Form`
+
+Створюйте параметри форми так само як Ви б створювали `Body` або `Query`:
+
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
+
+Наприклад, один зі способів використання специфікації OAuth2 (так званий "password flow") вимагає надсилати `username` та `password` як поля форми.
+
+
spec вимагає, щоб ці поля мали точні назви `username` і `password` та надсилалися у вигляді полів форми, а не JSON.
+
+З `Form` Ви можете оголошувати ті ж конфігурації, що і з `Body` (та `Query`, `Path`, `Cookie`), включаючи валідацію, приклади, псевдоніми (наприклад, `user-name` замість `username`) тощо.
+
+/// info | Інформація
+
+`Form` — це клас, який безпосередньо наслідується від `Body`.
+
+///
+
+/// tip | Порада
+
+Щоб оголосити тіло форми, потрібно явно використовувати `Form`, оскільки без нього параметри будуть інтерпретуватися як параметри запиту або тіла (JSON).
+
+///
+
+## Про "поля форми"
+
+HTML-форми (`
`) надсилають дані на сервер у "спеціальному" кодуванні, яке відрізняється від JSON.
+
+**FastAPI** подбає про те, щоб зчитати ці дані з правильного місця, а не з JSON.
+
+/// note | Технічні деталі
+
+Дані з форм зазвичай кодуються за допомогою "типу медіа" `application/x-www-form-urlencoded`.
+
+Але якщо форма містить файли, вона кодується як `multipart/form-data`. Ви дізнаєтеся про обробку файлів у наступному розділі.
+
+Якщо Ви хочете дізнатися більше про ці кодування та поля форм, зверніться до
MDN вебдокументації для POST
.
+
+///
+
+/// warning | Попередження
+
+Ви можете оголосити кілька параметрів `Form` в *операції шляху*, але не можете одночасно оголосити поля `Body`, які Ви очікуєте отримати у форматі JSON, оскільки тіло запиту буде закодовано у форматі `application/x-www-form-urlencoded`, а не `application/json`.
+
+Це не обмеження **FastAPI**, а частина HTTP-протоколу.
+
+///
+
+## Підсумок
+
+Використовуйте `Form` для оголошення вхідних параметрів у вигляді даних форми.
diff --git a/docs/uk/docs/tutorial/response-model.md b/docs/uk/docs/tutorial/response-model.md
new file mode 100644
index 000000000..def1f8a2d
--- /dev/null
+++ b/docs/uk/docs/tutorial/response-model.md
@@ -0,0 +1,358 @@
+# Модель відповіді — Тип, що повертається
+
+Ви можете оголосити тип, який використовуватиметься у відповіді, за допомогою *анотації типу, що повертається* *функцією операцією шляху* (path operation)
+
+**Анотацію типу** можна вказати так само як і для вхідних **параметрів** функції: це можуть бути моделі Pydantic, списки (lists), словники (dictionaries), скалярні значення, як-от цілі числа (integers), булеві значення (booleans) тощо.
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+FastAPI використовуватиме цей тип, щоб:
+
+* **Перевірити правильність** повернених даних.
+ * Якщо дані не валідні (наприклад, відсутнє поле), це означає, що Ваш код додатку працює некоректно і не повертає те, що повинен. У такому випадку FastAPI поверне помилку сервера, замість того щоб віддати недопустимі дані. Так Ви та Ваші клієнти будете впевнені, що отримуєте очікувані дані у правильному форматі.
+
+* Додати **JSON Schema** відповіді до специфікації OpenAPI в *операціях шляху*.
+ * Це буде використано в **автоматичній документації**.
+ * А також інструментами, які автоматично генерують клієнтський код.
+
+Але найголовніше:
+
+* FastAPI **обмежить та відфільтрує** вихідні дані відповідно до типу, вказаного у відповіді.
+ * Це особливо важливо для **безпеки**. Деталі нижче.
+
+## Параметр `response_model`
+
+Іноді Вам потрібно або зручно повертати інші типи даних, ніж ті, що зазначені як тип відповіді.
+
+Наприклад, Ви можете **повертати словник** або об’єкт бази даних, але **оголосити модель Pydantic** як модель відповіді. Тоді модель Pydantic автоматично оброблятиме валідацію, документацію тощо.
+
+Якщо Ви додасте анотацію типу для повернення, редактор коду або mypy можуть поскаржитися, що функція повертає інший тип (наприклад, dict замість Item).
+
+У таких випадках можна скористатися параметром `response_model` в декораторі маршруту (наприклад, @app.get()).
+
+Параметр `response_model` працює з будь-яким *оператором шляху*:
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* тощо.
+
+{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
+
+/// note | Примітка
+
+Зверніть увагу, що `response_model` є параметром методу-декоратора (`get`, `post`, тощо), а не *функцією операцією шляху* (path operation function), як це робиться з параметрами або тілом запиту.
+
+///
+
+`response_model` приймає такий самий тип, який Ви б вказали для поля моделі Pydantic. Тобто це може бути як Pydantic-модель, так і, наприклад, `list` із моделей Pydantic — `List[Item]`.
+
+FastAPI використовуватиме `response_model` для створення документації, валідації даних та — найважливіше — **перетворення та фільтрації вихідних даних** згідно з оголошеним типом.
+
+/// tip | Порада
+
+Якщо у Вас увімкнено сувору перевірку типів у редакторі, mypy тощо, Ви можете оголосити тип повернення функції як `Any`.
+
+Таким чином, Ви повідомляєте редактору, що свідомо повертаєте будь-що. Але FastAPI усе одно виконуватиме створення документації, валідацію, фільтрацію тощо за допомогою параметра `response_model`.
+
+///
+
+### Пріоритет `response_model`
+
+Якщо Ви вказуєте і тип повернення, і `response_model`, то FastAPI використовуватиме `response_model` з пріоритетом.
+
+Таким чином, Ви можете додати правильні анотації типів до ваших функцій, навіть якщо вони повертають тип, відмінний від `response_model`. Це буде корисно для редакторів коду та інструментів, таких як mypy. І при цьому FastAPI продовжить виконувати валідацію даних, генерувати документацію тощо на основі `response_model`.
+
+Ви також можете використати `response_model=None`, щоб вимкнути створення моделі відповіді для цієї *операції шляху*. Це може знадобитися, якщо Ви додаєте анотації типів до об'єктів, які не є допустимими полями Pydantic — приклад цього Ви побачите в одному з наступних розділів.
+
+## Повернути ті самі вхідні дані
+
+Тут ми оголошуємо модель `UserIn`, яка містить звичайний текстовий пароль:
+
+{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
+
+/// info | Інформація
+
+Щоб використовувати `EmailStr`, спочатку встановіть
`email-validator`.
+
+Переконайтесь, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили пакет, наприклад:
+
+```console
+$ pip install email-validator
+```
+
+or with:
+
+```console
+$ pip install "pydantic[email]"
+```
+
+///
+
+І ми використовуємо цю модель, щоб оголосити і вхідні, і вихідні дані:
+
+{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}
+
+Тепер, коли браузер створює користувача з паролем, API поверне той самий пароль у відповіді.
+
+У цьому випадку це може не бути проблемою, адже саме користувач надіслав пароль.
+
+Але якщо ми використаємо цю ж модель для іншої операції шляху, ми можемо випадково надіслати паролі наших користувачів кожному клієнту.
+
+/// danger | Обережно
+
+Ніколи не зберігайте пароль користувача у відкритому вигляді та не надсилайте його у відповіді, якщо тільки Ви не знаєте всі ризики і точно розумієте, що робите.
+
+///
+
+## Додайте окрему вихідну модель
+
+Замість цього ми можемо створити вхідну модель з відкритим паролем і вихідну модель без нього:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
+
+Тут, навіть якщо *функція операції шляху* повертає об'єкт користувача, який містить пароль:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
+
+...ми оголосили `response_model` як нашу модель `UserOut`, яка не містить пароля:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
+
+Таким чином, **FastAPI** автоматично відфільтрує всі дані, які не вказані у вихідній моделі (за допомогою Pydantic).
+
+### `response_model` або тип повернення
+
+У цьому випадку, оскільки дві моделі різні, якщо ми анотуємо тип повернення функції як `UserOut`, редактор і такі інструменти, як mypy, видадуть помилку, бо фактично ми повертаємо інший тип.
+
+Тому в цьому прикладі ми використовуємо параметр `response_model`, а не анотацію типу повернення.
+
+...але читайте далі, щоб дізнатися, як обійти це обмеження.
+
+## Тип повернення і фільтрація даних
+
+Продовжимо з попереднього прикладу. Ми хотіли **анотувати функцію одним типом**, але при цьому повертати з неї більше даних.
+
+Ми хочемо, щоб FastAPI продовжував **фільтрувати** ці дані за допомогою response_model. Тобто навіть якщо функція повертає більше інформації, у відповіді будуть лише ті поля, які вказані у response_model.
+
+У попередньому прикладі, оскільки класи були різні, нам довелося використовувати параметр `response_model`. Але це означає, що ми не отримуємо підтримки з боку редактора коду та інструментів перевірки типів щодо типу, який повертає функція.
+
+Проте в більшості випадків, коли нам потрібно зробити щось подібне, ми просто хочемо, щоб модель **відфільтрувала або прибрала** частину даних, як у цьому прикладі.
+
+У таких випадках ми можемо використати класи та спадкування, щоб скористатися **анотаціями типів** функцій — це дає кращу підтримку з боку редактора та інструментів типу mypy, і при цьому FastAPI продовжує виконувати **фільтрацію даних** у відповіді.
+
+{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
+
+Завдяки цьому ми отримуємо підтримку інструментів — від редакторів і mypy, оскільки цей код є коректним з точки зору типів, — але ми також отримуємо фільтрацію даних від FastAPI.
+
+Як це працює? Давайте розберемося. 🤓
+
+### Типи та підтримка інструментів
+
+Спершу подивимось, як це бачать редактори, mypy та інші інструменти.
+
+`BaseUser` має базові поля. Потім `UserIn` успадковує `BaseUser` і додає поле `password`, отже, він матиме всі поля з обох моделей.
+
+Ми зазначаємо тип повернення функції як `BaseUser`, але фактично повертаємо екземпляр `UserIn`.
+
+Редактор, mypy та інші інструменти не скаржитимуться на це, тому що з точки зору типізації `UserIn` є підкласом `BaseUser`, а це означає, що він є `валідним` типом, коли очікується будь-що, що є `BaseUser`.
+
+### Фільтрація даних у FastAPI
+
+Тепер для FastAPI він бачить тип повернення і переконується, що те, що Ви повертаєте, містить **тільки** поля, які оголошені у цьому типі.
+
+FastAPI виконує кілька внутрішніх операцій з Pydantic, щоб гарантувати, що правила наслідування класів не застосовуються для фільтрації повернених даних, інакше Ви могли б повернути значно більше даних, ніж очікували.
+
+Таким чином, Ви отримуєте найкраще з двох світів: анотації типів **з підтримкою інструментів** і **фільтрацію даних**.
+
+## Подивитись у документації
+
+Коли Ви дивитесь автоматичну документацію, Ви можете побачити, що вхідна модель і вихідна модель мають власну JSON-схему:
+
+

+
+І обидві моделі використовуються для інтерактивної API-документації:
+
+

+
+## Інші анотації типів повернення
+
+Існують випадки, коли Ви повертаєте щось, що не є допустимим полем Pydantic, але анотуєте це у функції лише для того, щоб отримати підтримку від інструментів (редактора, mypy тощо).
+
+### Повернення Response напряму
+
+Найпоширенішим випадком буде [повернення Response напряму, як пояснюється пізніше у розширеній документації](../advanced/response-directly.md){.internal-link target=_blank}.
+
+{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
+
+Цей простий випадок автоматично обробляється FastAPI, тому що анотація типу повернення — це клас (або підклас) `Response`.
+
+І інструменти також будуть задоволені, бо і `RedirectResponse`, і `JSONResponse` є підкласами `Response`, отже анотація типу коректна.
+
+### Анотація підкласу Response
+
+Також можна використовувати підклас `Response` у анотації типу:
+
+{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
+
+Це теж працюватиме, бо `RedirectResponse` — підклас `Response`, і FastAPI автоматично обробить цей простий випадок.
+
+### Некоректні анотації типу повернення
+
+Але коли Ви повертаєте якийсь інший довільний об’єкт, що не є валідним типом Pydantic (наприклад, об’єкт бази даних), і анотуєте його так у функції, FastAPI спробує створити Pydantic модель відповіді на основі цієї анотації типу, і це завершиться помилкою.
+
+Те саме станеться, якщо Ви використовуєте
union між різними типами, де один або більше не є валідними типами Pydantic, наприклад, це спричинить помилку 💥:
+
+{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
+
+...це не працює, тому що тип анотації не є типом Pydantic і не є просто класом `Response` або його підкласом, а є об’єднанням (union) — або `Response`, або `dict`.
+
+### Відключення Моделі Відповіді
+
+Продовжуючи приклад вище, можливо, Ви не хочете використовувати стандартну валідацію даних, автоматичну документацію, фільтрацію тощо, які FastAPI виконує за замовчуванням.
+
+Але ви все одно можете залишити анотацію типу у функції, щоб зберегти підтримку з боку інструментів, таких як редактори коду або статичні перевірки типів (наприклад, mypy).
+
+У такому випадку ви можете вимкнути генерацію моделі відповіді, встановивши `response_model=None`:
+
+{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
+
+Це змусить FastAPI пропустити генерацію моделі відповіді, і таким чином Ви зможете використовувати будь-які анотації типів повернення без впливу на вашу FastAPI аплікацію. 🤓
+
+## Параметри кодування моделі відповіді
+
+Ваша модель відповіді може мати значення за замовчуванням, наприклад:
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}
+
+* `description: Union[str, None] = None` (або `str | None = None` у Python 3.10) має значення за замовчуванням `None`.
+* `tax: float = 10.5` має значення за замовчуванням `10.5`.
+* `tags: List[str] = []` має значення за замовчуванням порожній список: `[]`.
+
+Але Ви можете захотіти не включати їх у результат, якщо вони фактично не були збережені.
+
+Наприклад, якщо у Вас є моделі з багатьма необов’язковими атрибутами у NoSQL базі даних, але Ви не хочете відправляти дуже довгі JSON-відповіді, повні значень за замовчуванням.
+
+### Використовуйте параметр `response_model_exclude_unset`
+
+Ви можете встановити параметр декоратора шляху `response_model_exclude_unset=True`:
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}
+
+і ці значення за замовчуванням не будуть включені у відповідь, тільки фактично встановлені значення.
+
+Отже, якщо Ви надішлете запит до цього оператора шляху для елемента з item_id `foo`, відповідь (без включення значень за замовчуванням) буде:
+
+```JSON
+{
+ "name": "Foo",
+ "price": 50.2
+}
+```
+
+/// info | Інформація
+
+У Pydantic версії 1 метод називався `.dict()`, він був застарілий (але ще підтримується) у Pydantic версії 2 і перейменований у `.model_dump()`.
+
+Приклади тут використовують `.dict()` для сумісності з Pydantic v1, але Вам слід використовувати `.model_dump()`, якщо Ви можете використовувати Pydantic v2.
+
+///
+
+/// info | Інформація
+
+FastAPI використовує `.dict()` моделі Pydantic з
параметром `exclude_unset`, щоб досягти цього.
+
+///
+
+/// info | Інформація
+
+Ви також можете використовувати:
+
+* `response_model_exclude_defaults=True`
+* `response_model_exclude_none=True`
+
+як описано в
документації Pydantic for `exclude_defaults` та `exclude_none`.
+
+///
+
+#### Дані зі значеннями для полів із типовими значеннями
+
+Але якщо Ваші дані мають значення для полів моделі з типовими значеннями, як у елемента з item_id `bar`:
+
+```Python hl_lines="3 5"
+{
+ "name": "Bar",
+ "description": "The bartenders",
+ "price": 62,
+ "tax": 20.2
+}
+```
+вони будуть включені у відповідь.
+
+#### Дані з тими самими значеннями, що й типові
+
+Якщо дані мають ті самі значення, що й типові, як у елемента з item_id `baz`:
+
+```Python hl_lines="3 5-6"
+{
+ "name": "Baz",
+ "description": None,
+ "price": 50.2,
+ "tax": 10.5,
+ "tags": []
+}
+```
+
+FastAPI достатньо розумний (насправді, Pydantic достатньо розумний), щоб зрозуміти, що, хоча `description`, `tax` і `tags` мають ті самі значення, що й типові, вони були встановлені явно (а не взяті як значення за замовчуванням).
+
+Отже, вони будуть включені у JSON-відповідь.
+
+/// tip | Порада
+
+Зверніть увагу, що типові значення можуть бути будь-якими, не лише `None`.
+
+Це може бути list (`[]`), `float` 10.5 тощо.
+
+///
+
+### `response_model_include` та `response_model_exclude`
+
+Ви також можете використовувати параметри *декоратора операції шляху* `response_model_include` та `response_model_exclude`.
+
+Вони приймають `set` (множину) рядків (`str`) з іменами атрибутів, які потрібно включити (пропускаючи інші) або виключити (включаючи інші).
+
+Це можна використовувати як швидкий спосіб, якщо у Вас є лише одна модель Pydantic і Ви хочете видалити деякі дані з виводу.
+
+/// tip | Порада
+
+Але все ж рекомендується використовувати описані вище підходи, із застосуванням кількох класів, замість цих параметрів.
+
+
+Це тому, що JSON Schema, який генерується у вашому OpenAPI додатку (і в документації), все одно буде відповідати повній моделі, навіть якщо Ви використовуєте `response_model_include` або `response_model_exclude` для виключення деяких атрибутів.
+
+Це також стосується `response_model_by_alias`, який працює подібним чином.
+
+///
+
+{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}
+
+/// tip | Порада
+
+Синтаксис `{"name", "description"}` створює `set` з цими двома значеннями.
+
+Він еквівалентний `set(["name", "description"])`.
+
+///
+
+#### Використання `list` замість `set`
+
+Якщо Ви забудете використати `set` і натомість застосуєте `list` або `tuple`, FastAPI все одно перетворить це на `set`, і все працюватиме правильно:
+
+{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
+
+## Підсумок
+
+Використовуйте параметр `response_model` *декоратора операції шляху*, щоб визначати моделі відповіді, особливо щоб гарантувати фільтрацію приватних даних.
+
+Використовуйте `response_model_exclude_unset`, щоб повертати лише явно встановлені значення.
diff --git a/docs/uk/docs/tutorial/response-status-code.md b/docs/uk/docs/tutorial/response-status-code.md
new file mode 100644
index 000000000..1ed69d6f2
--- /dev/null
+++ b/docs/uk/docs/tutorial/response-status-code.md
@@ -0,0 +1,100 @@
+# Статус коди Відповідей
+
+Так само як Ви можете вказати модель відповіді, Ви також можете оголосити HTTP код статусу для відповіді за допомогою параметра `status_code` в будь-якій з *операцій шляху*:
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* тощо.
+
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+
+/// note | Нотатка
+
+Зверніть увагу, що `status_code` є параметром методу "декоратора" (`get`, `post` і т.д.), а не Вашої *функції операції шляху*, як усі інші параметри та тіло запиту.
+
+///
+
+Параметр `status_code` приймає число, яке відповідає HTTP коду статусу.
+
+/// info | Інформація
+`status_code` також може отримувати значення з `IntEnum`, наприклад, з Python
`http.HTTPStatus`.
+
+///
+
+Він буде:
+
+* Повертати вказаний код статусу у відповіді.
+* Документувати його як такий у схемі OpenAPI (і, таким чином, в інтерфейсі користувача):
+
+

+
+/// note | Нотатка
+
+Деякі коди відповіді (див. наступний розділ) вказують, що відповідь не має тіла.
+
+FastAPI знає про це і створить OpenAPI документацію, яка вказує, що тіла відповіді немає.
+
+///
+
+## Про HTTP статус коди
+
+/// note | Нотатка
+
+Якщо Ви вже знаєте, що таке HTTP коди статусу, переходьте до наступного розділу.
+
+///
+
+В HTTP Ви надсилаєте числовий код статусу з 3 цифр як частину відповіді.
+
+Ці коди статусу мають пов’язану назву для їх розпізнавання, але найважливішою частиною є саме число.
+
+Коротко:
+
+* **`100 - 199`** "Інформаційні" відповіді. Ви рідко використовуєте їх напряму. Відповіді з такими кодами не можуть мати тіла.
+* **`200 - 299`** "Успішні" відповіді. Це ті, які Ви використовуватимете найчастіше.
+ * `200` - код за замовчуванням, який означає, що все пройшло "OK".
+ * Інший приклад – `201`, "Created" (створено). Його зазвичай використовують після створення нового запису в базі даних.
+ * Особливий випадок – `204`, "No Content" (немає вмісту). Ця відповідь використовується, коли немає даних для повернення клієнту, тому відповідь не повинна мати тіла.
+* **`300 - 399`** "Перенаправлення". Відповіді з цими кодами можуть мати або не мати тіла, за винятком `304`, "Not Modified" (не змінено), яка не повинна мати тіла.
+* **`400 - 499`** "Помилка клієнта". Це другий тип, який Ви, ймовірно, будете використовувати найчастіше.
+ * Приклад `404`, "Not Found" (не знайдено).
+ * Для загальних помилок клієнта можна використовувати `400`.
+* `500 - 599` "Помилки сервера". Ви майже ніколи не використовуєте їх напряму. Якщо в коді Вашого застосунку або на сервері щось пішло не так, автоматично буде повернено один із цих кодів статусу.
+
+/// tip | Порада
+
+Щоб дізнатися більше про кожен код статусу і призначення кожного з них, перегляньте документацію
MDN про HTTP коди статусу.
+
+///
+
+## Легкий спосіб запам'ятати назви
+
+Розглянемо ще раз попередній приклад:
+
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+
+`201` - це код статусу для "Created" (створено).
+
+Але Вам не потрібно запам'ятовувати, що означає кожен із цих кодів.
+
+Ви можете використовувати зручні змінні з `fastapi.status`
+
+{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+
+Ці змінні просто для зручності. Вони містять ті ж самі числа, але Ви можете скористатися автозаповненням в редакторі:
+
+

+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette import status`.
+
+**FastAPI** надає ті ж самі змінні `starlette.status` як `fastapi.status`, просто для зручності розробника. Однак вони походять безпосередньо зі Starlette.
+
+///
+
+## Зміна значення за замовчуванням
+
+Далі, у Посібнику для досвідчених користувачів{.internal-link target=_blank}, Ви дізнаєтесь, як повернути інший код статусу, ніж той, який Ви оголосили тут.
diff --git a/docs/uk/docs/tutorial/schema-extra-example.md b/docs/uk/docs/tutorial/schema-extra-example.md
new file mode 100644
index 000000000..853fd5e65
--- /dev/null
+++ b/docs/uk/docs/tutorial/schema-extra-example.md
@@ -0,0 +1,222 @@
+# Декларування прикладів вхідних даних
+
+Ви можете задати приклади даних, які Ваш застосунок може отримувати.
+
+Ось кілька способів, як це зробити.
+
+## Додаткові дані JSON-схеми в моделях Pydantic
+
+Ви можете задати `examples` для моделі Pydantic, які буде додано до згенерованої JSON-схеми.
+
+//// tab | Pydantic v2
+
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
+
+////
+
+//// tab | Pydantic v1
+
+{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
+
+////
+
+Ця додаткова інформація буде додана як є до **JSON-схеми**, і вона буде використовуватися в документації до API.
+
+//// tab | Pydantic v2
+
+У версії Pydantic 2 використовується атрибут `model_config`, який приймає `dict`, як описано в
документації Pydantic: Конфігурація.
+
+Ви можете встановити `"json_schema_extra"` як `dict`, що містить будь-які додаткові дані, які Ви хочете відобразити у згенерованій JSON-схемі, включаючи `examples`.
+
+////
+
+//// tab | Pydantic v1
+
+У версії Pydantic 1 використовується внутрішній клас `Config` і параметр `schema_extra`, як описано в
документації Pydantic: Налаштування схеми.
+
+Ви можете задати `schema_extra` як `dict`, що містить будь-які додаткові дані, які Ви хочете бачити у згенерованій JSON-схемі, включаючи `examples`.
+
+////
+
+/// tip | Підказка
+
+Ви можете використати ту ж техніку, щоб розширити JSON-схему і додати власну додаткову інформацію.
+
+Наприклад, Ви можете використати її для додавання метаданих для інтерфейсу користувача на фронтенді тощо.
+
+///
+
+/// info | Інформація
+
+OpenAPI 3.1.0 (який використовується починаючи з FastAPI 0.99.0) додав підтримку `examples`, що є частиною стандарту **JSON-схеми**.
+
+До цього підтримувався лише ключ `example` з одним прикладом. Він все ще підтримується в OpenAPI 3.1.0, але є застарілим і не входить до стандарту JSON Schema. Тому рекомендується перейти з `example` на `examples`. 🤓
+
+Більше про це можна прочитати в кінці цієї сторінки.
+
+///
+
+## Додаткові аргументи `Field`
+
+Коли ви використовуєте `Field()` у моделях Pydantic, Ви також можете вказати додаткові `examples`:
+
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
+
+## `examples` у JSON-схемі — OpenAPI
+
+При використанні будь-кого з наступного:
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+Ви також можете задати набір `examples` з додатковою інформацією, яка буде додана до їхніх **JSON-схем** у **OpenAPI**.
+
+### `Body` з `examples`
+
+Тут ми передаємо `examples`, які містять один приклад очікуваних даних у `Body()`:
+
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *}
+
+### Приклад у UI документації
+
+За допомогою будь-якого з наведених вище методів це виглядатиме так у документації за `/docs`:
+
+

+
+### `Body` з кількома `examples`
+
+Звичайно, Ви також можете передати кілька `examples`:
+
+{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}
+
+Коли Ви це робите, приклади будуть частиною внутрішньої **JSON-схеми** для цих даних.
+
+Втім, на момент написання цього (
26 серпня 2023), Swagger UI — інструмент, який відповідає за відображення UI документації — не підтримує показ кількох прикладів у **JSON-схеми**. Але нижче можна прочитати про обхідний шлях.
+
+### Специфічні для OpenAPI `examples`
+
+Ще до того, як **JSON-схема** почала підтримувати `examples`, OpenAPI вже мала підтримку поля з такою ж назвою — `examples`.
+
+Це **специфічне для OpenAPI** поле `examples` розміщується в іншій частині специфікації OpenAPI — у **деталях кожної *операції шляху***, а не всередині самої JSON-схеми.
+
+Swagger UI вже давно підтримує це поле `examples`. Тому Ви можете використовувати його, щоб **відображати** кілька **прикладів у документації**.
+
+Це поле `examples` у специфікації OpenAPI — це `dict` (словник) з **кількома прикладами** (а не список `list`), кожен із яких може містити додаткову інформацію, що буде додана до **OpenAPI**.
+
+Воно не включається до JSON Schema кожного параметра, а розміщується зовні, безпосередньо в *операції шляху*.
+
+### Використання параметра `openapi_examples`
+
+Ви можете оголосити специфічні для OpenAPI `examples` у FastAPI за допомогою параметра `openapi_examples` для:
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+Ключі словника (`dict`) ідентифікують кожен приклад, а кожне значення `dict` — кожен специфічний словник `dict` в `examples` може містити:
+
+* `summary`: короткий опис прикладу.
+* `description`: розгорнутий опис (може містити Markdown).
+* `value`: сам приклад, наприклад, словник (`dict`).
+* `externalValue`: альтернатива `value`, URL-адреса, що вказує на приклад. Проте ця опція може не підтримуватися більшістю інструментів, на відміну від `value`.
+
+Використання виглядає так:
+
+{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
+
+### Приклади OpenAPI у UI документації
+
+З параметром `openapi_examples`, доданим до `Body()`, документація `/docs` виглядатиме так:
+
+

+
+## Технічні деталі
+
+/// tip | Підказка
+
+Якщо Ви вже використовуєте **FastAPI** версії **0.99.0 або вище**, Ви можете **пропустити** цей розділ.
+
+Він більш актуальний для старих версій, до появи OpenAPI 3.1.0.
+
+Можна вважати це коротким **історичним екскурсом** у OpenAPI та JSON Schema. 🤓
+
+///
+
+/// warning | Попередження
+
+Це дуже технічна інформація про стандарти **JSON Schema** і **OpenAPI**.
+
+Якщо вищезгадані ідеї вже працюють у Вас — можете не заглиблюватися в ці деталі.
+
+///
+
+До OpenAPI 3.1.0 специфікація використовувала стару та модифіковану версію **JSON Schema**.
+
+Оскільки JSON Schema раніше не підтримувала `examples`, OpenAPI додала власне поле `examples`.
+
+OpenAPI також додала `example` і `examples` до інших частин специфікації:
+
+*
`Parameter Object` (в специфікації) використовується FastAPI для:
+ * `Path()`
+ * `Query()`
+ * `Header()`
+ * `Cookie()`
+*
`Request Body Object`, в полі `content`, в `Media Type Object` (в специфікації) використовується FastAPI для:
+ * `Body()`
+ * `File()`
+ * `Form()`
+
+/// info | Інформація
+
+Цей старий параметр `examples`, специфічний для OpenAPI, тепер називається `openapi_examples`, починаючи з FastAPI версії `0.103.0`.
+
+///
+
+### Поле `examples` у JSON Schema
+
+Пізніше JSON Schema додала поле
`examples` у нову версію специфікації.
+
+І вже OpenAPI 3.1.0 базується на цій новій версії (JSON Schema 2020-12), яка включає поле `examples`.
+
+Тепер це поле `examples` є пріоритетним і замінює старе (і кастомне) поле `example`, яке стало застарілим.
+
+Нове поле `examples` у JSON Schema — це **просто список (`list`)** прикладів, без додаткових метаданих (на відміну від OpenAPI).
+
+/// info | Інформація
+
+Навіть після того, як з'явився OpenAPI 3.1.0, який підтримував examples у JSON Schema, інструмент Swagger UI ще деякий час не підтримував цю версію (підтримка з’явилась з версії 5.0.0 🎉).
+
+Через це версії FastAPI до 0.99.0 все ще використовували версії OpenAPI нижчі за 3.1.0.
+
+///
+
+### `Examples` в Pydantic і FastAPI
+
+Коли Ви додаєте `examples` у модель Pydantic через `schema_extra` або `Field(examples=["something"])`, ці приклади додаються до **JSON Schema** цієї моделі.
+
+І ця **JSON Schema** Pydantic-моделі включається до **OpenAPI** Вашого API, а потім використовується в UI документації (docs UI).
+
+У версіях FastAPI до 0.99.0 (починаючи з 0.99.0 використовується новіший OpenAPI 3.1.0), коли Ви використовували `example` або `examples` з іншими утилітами (`Query()`, `Body()` тощо), ці приклади не додавалися до JSON Schema, який описує ці дані (навіть не до власної версії JSON Schema у OpenAPI). Натомість вони додавалися безпосередньо до опису *обробника шляху* *(path operation)* в OpenAPI (тобто поза межами частин, які використовують JSON Schema).
+
+Але тепер, коли FastAPI 0.99.0 і вище використовують OpenAPI 3.1.0, а той — JSON Schema 2020-12, разом із Swagger UI 5.0.0 і вище — все стало більш узгодженим, і examples тепер включаються до JSON Schema.
+
+### Swagger UI та специфічні для OpenAPI `examples`
+
+Раніше (станом на 26 серпня 2023 року) Swagger UI не підтримував кілька прикладів у JSON Schema, тому користувачі не мали можливості показати декілька прикладів у документації.
+
+Щоб вирішити це, FastAPI починаючи з версії 0.103.0 **додав підтримку** старого **OpenAPI-специфічного** поля `examples` через новий параметр `openapi_examples`. 🤓
+
+### Підсумок
+
+Раніше я казав, що не люблю історію... а тепер ось я — розповідаю "технічні історичні" лекції. 😅
+
+Коротко: **оновіться до FastAPI 0.99.0 або вище** — і все стане значно **простішим, узгодженим та інтуїтивно зрозумілим**, і Вам не доведеться знати всі ці історичні деталі. 😎
diff --git a/docs/uk/docs/tutorial/security/index.md b/docs/uk/docs/tutorial/security/index.md
new file mode 100644
index 000000000..c3d94be8d
--- /dev/null
+++ b/docs/uk/docs/tutorial/security/index.md
@@ -0,0 +1,104 @@
+# Безпека
+
+Існує багато способів реалізувати безпеку, автентифікацію та авторизацію.
+
+Це зазвичай складна і "непроста" тема.
+
+У багатьох фреймворках і системах забезпечення безпеки та автентифікації займає величезну частину зусиль і коду (іноді — понад 50% всього написаного коду).
+
+**FastAPI** надає кілька інструментів, які допоможуть Вам впоратися з **безпекою** легко, швидко, стандартним способом, без необхідності вивчати всі специфікації безпеки.
+
+Але спочатку — кілька коротких понять.
+
+## Поспішаєте?
+
+Якщо Вам не цікаві всі ці терміни й просто потрібно *швидко* додати автентифікацію за логіном і паролем — переходьте до наступних розділів.
+
+## OAuth2
+
+OAuth2 — це специфікація, що описує кілька способів обробки автентифікації та авторизації.
+
+Це досить об'ємна специфікація, яка охоплює складні випадки використання.
+
+Вона включає способи автентифікації через "третю сторону".
+
+Саме це лежить в основі "входу через Google, Facebook, X (Twitter), GitHub" тощо.
+
+### OAuth 1
+
+Раніше існував OAuth 1, який значно відрізняється від OAuth2 і є складнішим, оскільки містив специфікації для шифрування комунікацій.
+
+Зараз майже не використовується.
+
+OAuth2 не вказує, як саме шифрувати з'єднання — воно очікує, що ваш застосунок працює через HTTPS.
+
+/// tip | Порада
+
+У розділі про **деплой** Ви побачите, як налаштувати HTTPS безкоштовно з Traefik та Let's Encrypt.
+
+///
+
+## OpenID Connect
+
+OpenID Connect — ще одна специфікація, побудована на основі **OAuth2**.
+
+Вона розширює OAuth2, уточнюючи деякі неоднозначності для досягнення кращої сумісності.
+
+Наприклад, вхід через Google використовує OpenID Connect (який базується на OAuth2).
+
+Але вхід через Facebook — ні. Він має власну реалізацію на базі OAuth2.
+
+### OpenID (не "OpenID Connect")
+
+Існувала також специфікація "OpenID", яка намагалася розвʼязати ті самі задачі, що й **OpenID Connect**, але не базувалась на OAuth2.
+
+Це була зовсім інша система, і сьогодні вона майже не використовується.
+
+## OpenAPI
+
+OpenAPI (раніше Swagger) — це специфікація для побудови API (тепер під егідою Linux Foundation).
+
+**FastAPI** базується на **OpenAPI**.
+
+Завдяки цьому Ви отримуєте автоматичну інтерактивну документацію, генерацію коду та багато іншого.
+
+OpenAPI дозволяє описувати різні "схеми" безпеки.
+
+Використовуючи їх, Ви можете скористатися всіма цими інструментами, що базуються на стандартах, зокрема інтерактивними системами документації.
+
+OpenAPI визначає такі схеми безпеки:
+
+* `apiKey`: специфічний для застосунку ключ, який може передаватися через:
+ * Параметр запиту.
+ * Заголовок.
+ * Cookie.
+* `http`: стандартні методи HTTP-автентифікації, включаючи:
+ * `bearer`: заголовок `Authorization` зі значенням `Bearer` та токеном. Це успадковано з OAuth2.
+ * HTTP Basic автентифікація
+ * HTTP Digest, тощо.
+* `oauth2`: усі способи обробки безпеки за допомогою OAuth2 (так звані «потоки»).
+ * Деякі з цих потоків підходять для створення власного провайдера автентифікації OAuth 2.0 (наприклад, Google, Facebook, X (Twitter), GitHub тощо):
+ * `implicit`— неявний
+ * `clientCredentials`— облікові дані клієнта
+ * `authorizationCode` — код авторизації
+ * Але є один окремий «потік», який ідеально підходить для реалізації автентифікації всередині одного додатку:
+ * `password`: у наступних розділах буде приклад використання цього потоку.
+* `openIdConnect`: дозволяє автоматично виявляти параметри автентифікації OAuth2.
+ * Це автоматичне виявлення визначається у специфікації OpenID Connect.
+
+
+/// tip | Порада
+
+Інтеграція інших провайдерів автентифікації/авторизації, таких як Google, Facebook, X (Twitter), GitHub тощо — також можлива і відносно проста.
+
+Найскладніше — це створити власного провайдера автентифікації/авторизації, як Google чи Facebook. Але **FastAPI** надає Вам інструменти, щоб зробити це легко, беручи на себе важку частину роботи.
+
+///
+
+## Інструменти **FastAPI**
+
+FastAPI надає кілька інструментів для кожної з описаних схем безпеки в модулі `fastapi.security`, які спрощують використання цих механізмів захисту.
+
+У наступних розділах Ви побачите, як додати безпеку до свого API за допомогою цих інструментів **FastAPI**.
+
+А також побачите, як вона автоматично інтегрується в інтерактивну документацію вашого API.
diff --git a/docs/uk/docs/tutorial/static-files.md b/docs/uk/docs/tutorial/static-files.md
new file mode 100644
index 000000000..a84782d8f
--- /dev/null
+++ b/docs/uk/docs/tutorial/static-files.md
@@ -0,0 +1,40 @@
+# Статичні файли
+
+Ви можете автоматично надавати статичні файли з каталогу, використовуючи `StaticFiles`.
+
+## Використання `StaticFiles`
+
+* Імпортуйте `StaticFiles`.
+* "Під'єднати" екземпляр `StaticFiles()` з вказанням необхідного шляху.
+
+{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+
+/// note | Технічні деталі
+
+Ви також можете використовувати `from starlette.staticfiles import StaticFiles`.
+
+**FastAPI** надає той самий `starlette.staticfiles`, що й `fastapi.staticfiles` для зручності розробників. Але фактично він безпосередньо походить із Starlette.
+
+///
+
+### Що таке "Під'єднання"
+
+"Під'єднання" означає додавання повноцінного "незалежного" застосунку за певним шляхом, який потім обробляє всі під шляхи.
+
+Це відрізняється від використання `APIRouter`, оскільки під'єднаний застосунок є повністю незалежним. OpenAPI та документація вашого основного застосунку не будуть знати нічого про ваш під'єднаний застосунок.
+
+Ви можете дізнатися більше про це в [Посібнику для просунутих користувачів](../advanced/index.md){.internal-link target=_blank}.
+
+## Деталі
+
+Перше `"/static"` вказує на під шлях, за яким буде "під'єднано" цей новий "застосунок". Тому будь-який шлях, який починається з `"/static"`, буде оброблятися ним.
+
+`directory="static"` визначає каталог, що містить ваші статичні файли.
+
+`name="static"` це ім'я, яке можна використовувати всередині **FastAPI**.
+
+Усі ці параметри можуть бути змінені відповідно до потреб і особливостей вашого застосунку.
+
+## Додаткова інформація
+
+Детальніше про налаштування та можливості можна дізнатися в
документації Starlette про статичні файли.
diff --git a/docs/uk/docs/tutorial/testing.md b/docs/uk/docs/tutorial/testing.md
new file mode 100644
index 000000000..25fc370d6
--- /dev/null
+++ b/docs/uk/docs/tutorial/testing.md
@@ -0,0 +1,240 @@
+# Тестування
+
+Тестування **FastAPI** додатків є простим та ефективним завдяки бібліотеці
Starlette, яка базується на
HTTPX.
+Оскільки HTTPX розроблений на основі Requests, його API є інтуїтивно зрозумілим для тих, хто вже знайомий з Requests.
+
+З його допомогою Ви можете використовувати
pytest безпосередньо з **FastAPI**.
+
+## Використання `TestClient`
+
+/// info | Інформація
+
+Щоб використовувати `TestClient`, спочатку встановіть
`httpx`.
+
+Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили саму бібліотеку, наприклад:
+
+```console
+$ pip install httpx
+```
+
+///
+
+Імпортуйте `TestClient`.
+
+Створіть `TestClient`, передавши йому Ваш застосунок **FastAPI**.
+
+Створюйте функції з іменами, що починаються з `test_` (це стандартна угода для `pytest`).
+
+Використовуйте об'єкт `TestClient` так само як і `httpx`.
+
+Записуйте прості `assert`-вирази зі стандартними виразами Python, які потрібно перевірити (це також стандарт для `pytest`).
+
+{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+
+
+/// tip | Порада
+
+Зверніть увагу, що тестові функції — це звичайні `def`, а не `async def`.
+
+Виклики клієнта також звичайні, без використання `await`.
+
+Це дозволяє використовувати `pytest` без зайвих ускладнень.
+
+///
+
+/// note | Технічні деталі
+
+Ви також можете використовувати `from starlette.testclient import TestClient`.
+
+**FastAPI** надає той самий `starlette.testclient` під назвою `fastapi.testclient` для зручності розробників, але він безпосередньо походить із Starlette.
+
+///
+
+/// tip | Порада
+
+Якщо Вам потрібно викликати `async`-функції у ваших тестах, окрім відправлення запитів до 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** :
+
+{* ../../docs_src/app_testing/main.py *}
+
+### Файл тестування
+
+Ви можете створити файл `test_main.py` з Вашими тестами. Він може знаходитися в тому ж пакеті Python (у тій самій директорії з файлом `__init__.py`):
+
+
+``` hl_lines="5"
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Оскільки цей файл знаходиться в тому ж пакеті, Ви можете використовувати відносний імпорт, щоб імпортувати об'єкт `app` із модуля `main` (`main.py`):
+
+{* ../../docs_src/app_testing/test_main.py hl[3] *}
+
+
+...і написати код для тестів так само як і раніше.
+
+## Тестування: розширений приклад
+
+Тепер розширимо цей приклад і додамо більше деталей, щоб побачити, як тестувати різні частини.
+
+### Розширений файл застосунку **FastAPI**
+
+Залишимо ту саму структуру файлів:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Припустимо, що тепер файл `main.py` із Вашим **FastAPI**-застосунком містить додаткові операції шляху (**path operations**).
+
+Він має `GET`-операцію, яка може повертати помилку.
+
+Він має `POST`-операцію, яка може повертати кілька помилок.
+
+Обидві операції шляху вимагають заголовок `X-Token`.
+
+//// tab | Python 3.10+
+
+```Python
+{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python
+{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+{!> ../../docs_src/app_testing/app_b_an/main.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Порада
+
+Бажано використовувати версію з `Annotated`, якщо це можливо
+
+///
+
+```Python
+{!> ../../docs_src/app_testing/app_b_py310/main.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Порада
+
+Бажано використовувати версію з `Annotated`, якщо це можливо
+
+///
+
+```Python
+{!> ../../docs_src/app_testing/app_b/main.py!}
+```
+
+////
+
+### Розширений тестовий файл
+
+Потім Ви можете оновити `test_main.py`, додавши розширені тести:
+
+{* ../../docs_src/app_testing/app_b/test_main.py *}
+
+Коли Вам потрібно передати клієнту інформацію в запиті, але Ви не знаєте, як це зробити, Ви можете пошукати (наприклад, у Google) спосіб реалізації в `httpx`, або навіть у `requests`, оскільки HTTPX розроблений на основі дизайну Requests.
+
+Далі Ви просто повторюєте ці ж дії у ваших тестах.
+
+Наприклад:
+
+* Щоб передати *path* або *query* параметр, додайте його безпосередньо до URL.
+* Щоб передати тіло JSON, передайте Python-об'єкт (наприклад, `dict`) у параметр `json`.
+* Якщо потрібно надіслати *Form Data* замість JSON, використовуйте параметр `data`.
+* Щоб передати заголовки *headers*, використовуйте `dict` у параметрі `headers`.
+* Для *cookies* використовуйте `dict` у параметрі `cookies`.
+
+Докладніше про передачу даних у бекенд (за допомогою `httpx` або `TestClient`) можна знайти в
документації HTTPX.
+
+/// info | Інформація
+
+Зверніть увагу, що `TestClient` отримує дані, які можна конвертувати в JSON, а не Pydantic-моделі.
+Якщо у Вас є Pydantic-модель у тесті, і Ви хочете передати її дані в додаток під час тестування, Ви можете використати `jsonable_encoder`, описаний у розділі [JSON Compatible Encoder](encoder.md){.internal-link target=_blank}.
+
+///
+
+## Запуск тестів
+
+Після цього вам потрібно встановити `pytest`.
+
+Переконайтеся, що Ви створили [віртуальне середовище]{.internal-link target=_blank}, активували його і встановили необхідні пакети, наприклад:
+
+
+
+```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/uk/mkdocs.yml b/docs/uk/mkdocs.yml
index 711328771..de18856f4 100644
--- a/docs/uk/mkdocs.yml
+++ b/docs/uk/mkdocs.yml
@@ -1,145 +1 @@
-site_name: FastAPI
-site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
-site_url: https://fastapi.tiangolo.com/uk/
-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: uk
-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/
- - es: /es/
- - fa: /fa/
- - fr: /fr/
- - he: /he/
- - id: /id/
- - it: /it/
- - ja: /ja/
- - ko: /ko/
- - nl: /nl/
- - pl: /pl/
- - pt: /pt/
- - ru: /ru/
- - sq: /sq/
- - sv: /sv/
- - 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: UA-133183413-1
- 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: /es/
- name: es - español
- - link: /fa/
- name: fa
- - link: /fr/
- name: fr - français
- - link: /he/
- name: he
- - link: /id/
- name: id
- - link: /it/
- name: it - italiano
- - link: /ja/
- name: ja - 日本語
- - link: /ko/
- name: ko - 한국어
- - 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: /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
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/uk/overrides/.gitignore b/docs/uk/overrides/.gitignore
deleted file mode 100644
index e69de29bb..000000000
diff --git a/docs/ur/docs/benchmarks.md b/docs/ur/docs/benchmarks.md
new file mode 100644
index 000000000..8d583de2f
--- /dev/null
+++ b/docs/ur/docs/benchmarks.md
@@ -0,0 +1,51 @@
+# بینچ مارکس
+انڈیپنڈنٹ ٹیک امپور بینچ مارک **FASTAPI** Uvicorn کے تحت چلنے والی ایپلی کیشنز کو
ایک تیز رفتار Python فریم ورک میں سے ایک ، صرف Starlette اور Uvicorn کے نیچے ( FASTAPI کے ذریعہ اندرونی طور پر استعمال کیا جاتا ہے ) (*)
+
+لیکن جب بینچ مارک اور موازنہ کی جانچ پڑتال کرتے ہو تو آپ کو مندرجہ ذیل بات ذہن میں رکھنی چاہئے.
+
+## بینچ مارک اور رفتار
+
+جب آپ بینچ مارک کی جانچ کرتے ہیں تو ، مساوی کے مقابلے میں مختلف اقسام کے متعدد اوزار دیکھنا عام ہے.
+
+خاص طور پر ، Uvicorn, Starlette اور FastAPI کو دیکھنے کے لئے ( بہت سے دوسرے ٹولز ) کے ساتھ موازنہ کیا گیا.
+
+ٹول کے ذریعہ حل ہونے والا آسان مسئلہ ، اس کی بہتر کارکردگی ہوگی. اور زیادہ تر بینچ مارک ٹول کے ذریعہ فراہم کردہ اضافی خصوصیات کی جانچ نہیں کرتے ہیں.
+
+درجہ بندی کی طرح ہے:
+
+
+ - سرور ASGI :Uvicorn
+
+ - Starlette: (Uvicorn استعمال کرتا ہے) ایک ویب مائیکرو فریم ورک
+
+ - FastAPI: (Starlette کا استعمال کرتا ہے) ایک API مائکرو فریم ورک جس میں APIs بنانے کے لیے کئی اضافی خصوصیات ہیں، ڈیٹا کی توثیق وغیرہ کے ساتھ۔
+
+
+
+
+
+ - Uvicorn:
+
+ - بہترین کارکردگی ہوگی، کیونکہ اس میں سرور کے علاوہ زیادہ اضافی کوڈ نہیں ہے۔
+ - آپ براہ راست Uvicorn میں درخواست نہیں لکھیں گے۔ اس کا مطلب یہ ہوگا کہ آپ کے کوڈ میں کم و بیش، کم از کم، Starlette (یا FastAPI) کی طرف سے فراہم کردہ تمام کوڈ شامل کرنا ہوں گے۔ اور اگر آپ نے ایسا کیا تو، آپ کی حتمی ایپلیکیشن کا وہی اوور ہیڈ ہوگا جیسا کہ ایک فریم ورک استعمال کرنے اور آپ کے ایپ کوڈ اور کیڑے کو کم سے کم کرنا۔
+ - اگر آپ Uvicorn کا موازنہ کر رہے ہیں تو اس کا موازنہ Daphne، Hypercorn، uWSGI وغیرہ ایپلیکیشن سرورز سے کریں۔
+
+
+
+ - Starlette:
+
+ - Uvicorn کے بعد اگلی بہترین کارکردگی ہوگی۔ درحقیقت، Starlette چلانے کے لیے Uvicorn کا استعمال کرتی ہے۔ لہذا، یہ شاید زیادہ کوڈ پر عمل درآمد کرکے Uvicorn سے "سست" ہوسکتا ہے۔
+ - لیکن یہ آپ کو آسان ویب ایپلیکیشنز بنانے کے لیے ٹولز فراہم کرتا ہے، راستوں پر مبنی روٹنگ کے ساتھ، وغیرہ۔>
+ - اگر آپ سٹارلیٹ کا موازنہ کر رہے ہیں تو اس کا موازنہ Sanic، Flask، Django وغیرہ سے کریں۔ ویب فریم ورکس (یا مائیکرو فریم ورکس)
+
+
+
+ - FastAPI:
+
+ - جس طرح سے Uvicorn Starlette کا استعمال کرتا ہے اور اس سے تیز نہیں ہو سکتا، Starlette FastAPI کا استعمال کرتا ہے، اس لیے یہ اس سے تیز نہیں ہو سکتا۔
+ - Starlette FastAPI کے اوپری حصے میں مزید خصوصیات فراہم کرتا ہے۔ وہ خصوصیات جن کی آپ کو APIs بناتے وقت تقریباً ہمیشہ ضرورت ہوتی ہے، جیسے ڈیٹا کی توثیق اور سیریلائزیشن۔ اور اسے استعمال کرنے سے، آپ کو خودکار دستاویزات مفت میں مل جاتی ہیں (خودکار دستاویزات چلنے والی ایپلی کیشنز میں اوور ہیڈ کو بھی شامل نہیں کرتی ہیں، یہ اسٹارٹ اپ پر تیار ہوتی ہیں)۔
+ - اگر آپ نے FastAPI کا استعمال نہیں کیا ہے اور Starlette کو براہ راست استعمال کیا ہے (یا کوئی دوسرا ٹول، جیسے Sanic، Flask، Responder، وغیرہ) آپ کو تمام ڈیٹا کی توثیق اور سیریلائزیشن کو خود نافذ کرنا ہوگا۔ لہذا، آپ کی حتمی ایپلیکیشن اب بھی وہی اوور ہیڈ ہوگی جیسا کہ اسے FastAPI کا استعمال کرتے ہوئے بنایا گیا تھا۔ اور بہت سے معاملات میں، یہ ڈیٹا کی توثیق اور سیریلائزیشن ایپلی کیشنز میں لکھے گئے کوڈ کی سب سے بڑی مقدار ہے۔
+ - لہذا، FastAPI کا استعمال کرکے آپ ترقیاتی وقت، Bugs، کوڈ کی لائنوں کی بچت کر رہے ہیں، اور شاید آپ کو وہی کارکردگی (یا بہتر) ملے گی اگر آپ اسے استعمال نہیں کرتے (جیسا کہ آپ کو یہ سب اپنے کوڈ میں لاگو کرنا ہوگا۔ )>
+ - اگر آپ FastAPI کا موازنہ کر رہے ہیں، تو اس کا موازنہ ویب ایپلیکیشن فریم ورک (یا ٹولز کے سیٹ) سے کریں جو ڈیٹا کی توثیق، سیریلائزیشن اور دستاویزات فراہم کرتا ہے، جیسے Flask-apispec، NestJS، Molten، وغیرہ۔ مربوط خودکار ڈیٹا کی توثیق، سیریلائزیشن اور دستاویزات کے ساتھ فریم ورک۔
+
+
diff --git a/docs/ur/mkdocs.yml b/docs/ur/mkdocs.yml
new file mode 100644
index 000000000..de18856f4
--- /dev/null
+++ b/docs/ur/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/vi/docs/deployment/cloud.md b/docs/vi/docs/deployment/cloud.md
new file mode 100644
index 000000000..9ab72769d
--- /dev/null
+++ b/docs/vi/docs/deployment/cloud.md
@@ -0,0 +1,17 @@
+# Triển khai FastAPI trên các Dịch vụ Cloud
+
+Bạn có thể sử dụng **bất kỳ nhà cung cấp dịch vụ cloud** nào để triển khai ứng dụng FastAPI của mình.
+
+Trong hầu hết các trường hợp, các nhà cung cấp dịch vụ cloud lớn đều có hướng dẫn triển khai FastAPI với họ.
+
+## Nhà cung cấp dịch vụ Cloud - Nhà tài trợ
+Một vài nhà cung cấp dịch vụ cloud ✨ [**tài trợ cho FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, điều này giúp đảm bảo sự phát triển liên tục và khỏe mạnh của FastAPI và hệ sinh thái của nó.
+
+Thêm nữa, điều này cũng thể hiện cam kết thực sự của họ đối với FastAPI và **cộng đồng người dùng** (bạn), vì họ không chỉ muốn cung cấp cho bạn một **dịch vụ tốt** mà còn muốn đảm bảo rằng bạn có một **framework tốt và bền vững**, đó chính là FastAPI. 🙇
+
+Bạn có thể thử các dịch vụ của họ và làm theo hướng dẫn của họ:
+
+*
Platform.sh
+*
Porter
+*
Coherence
+*
Render
diff --git a/docs/vi/docs/deployment/index.md b/docs/vi/docs/deployment/index.md
new file mode 100644
index 000000000..24ffdc71b
--- /dev/null
+++ b/docs/vi/docs/deployment/index.md
@@ -0,0 +1,21 @@
+# Triển khai
+
+Triển khai một ứng dụng **FastAPI** khá dễ dàng.
+
+## Triển khai là gì
+
+Triển khai một ứng dụng có nghĩa là thực hiện các bước cần thiết để làm cho nó **sẵn sàng phục vụ người dùng**.
+
+Đối với một **API web**, điều này có nghĩa là đặt nó trong một **máy chủ từ xa**, với một **chương trình máy chủ** cung cấp hiệu suất tốt, ổn định, v.v., để người dùng của bạn có thể truy cập ứng dụng của bạn một cách hiệu quả và không bị gián đoạn hoặc gặp vấn đề.
+
+Điều này trái ngược với các **giai đoạn phát triển**, trong đó bạn liên tục thay đổi mã, phá vỡ nó và sửa nó, ngừng và khởi động lại máy chủ phát triển, v.v.
+
+## Các Chiến lược Triển khai
+
+Có nhiều cách để triển khai ứng dụng của bạn tùy thuộc vào trường hợp sử dụng của bạn và các công cụ mà bạn sử dụng.
+
+Bạn có thể **triển khai một máy chủ** của riêng bạn bằng cách sử dụng một sự kết hợp các công cụ, hoặc bạn có thể sử dụng một **dịch vụ cloud** để làm một số công việc cho bạn, hoặc các tùy chọn khác.
+
+Tôi sẽ chỉ ra một số khái niệm chính cần thiết khi triển khai một ứng dụng **FastAPI** (mặc dù hầu hết nó áp dụng cho bất kỳ loại ứng dụng web nào).
+
+Bạn sẽ thấy nhiều chi tiết cần thiết và một số kỹ thuật để triển khai trong các phần tiếp theo. ✨
diff --git a/docs/vi/docs/deployment/versions.md b/docs/vi/docs/deployment/versions.md
new file mode 100644
index 000000000..04de393e7
--- /dev/null
+++ b/docs/vi/docs/deployment/versions.md
@@ -0,0 +1,93 @@
+# Về các phiên bản của FastAPI
+
+**FastAPI** đã được sử dụng ở quy mô thực tế (production) trong nhiều ứng dụng và hệ thống. Và phạm vi kiểm thử được giữ ở mức 100%. Nhưng việc phát triển của nó vẫn đang diễn ra nhanh chóng.
+
+Các tính năng mới được bổ sung thường xuyên, lỗi được sửa định kỳ, và mã nguồn vẫn đang được cải thiện liên tục
+
+Đó là lí do các phiên bản hiện tại vẫn còn là 0.x.x, điều này phản ánh rằng mỗi phiên bản có thể có các thay đổi gây mất tương thích. Điều này tuân theo các quy ước về
Semantic Versioning.
+
+Bạn có thể tạo ra sản phẩm thực tế với **FastAPI** ngay bây giờ (và bạn có thể đã làm điều này trong một thời gian dài), bạn chỉ cần đảm bảo rằng bạn sử dụng một phiên bản hoạt động đúng với các đoạn mã còn lại của bạn.
+
+## Cố định phiên bản của `fastapi`
+
+Điều đầu tiên bạn nên làm là "cố định" phiên bản của **FastAPI** bạn đang sử dụng để phiên bản mới nhất mà bạn biết hoạt động đúng với ứng dụng của bạn.
+
+Ví dụ, giả sử bạn đang sử dụng phiên bản `0.112.0` trong ứng dụng của bạn.
+
+Nếu bạn sử dụng một tệp `requirements.txt` bạn có thể chỉ định phiên bản với:
+
+```txt
+fastapi[standard]==0.112.0
+```
+
+Như vậy, bạn sẽ sử dụng chính xác phiên bản `0.112.0`.
+
+Hoặc bạn cũng có thể cố định nó với:
+
+```txt
+fastapi[standard]>=0.112.0,<0.113.0
+```
+
+Như vậy, bạn sẽ sử dụng các phiên bản `0.112.0` trở lên, nhưng nhỏ hơn `0.113.0`, ví dụ, một phiên bản `0.112.2` vẫn được chấp nhận.
+
+Nếu bạn sử dụng bất kỳ công cụ nào để quản lý cài đặt của bạn, như `uv`, Poetry, Pipenv, hoặc bất kỳ công cụ nào khác, chúng đều có một cách để bạn có thể định nghĩa các phiên bản cụ thể cho các gói của bạn.
+
+## Các phiên bản có sẵn
+
+Bạn có thể xem các phiên bản có sẵn (ví dụ để kiểm tra phiên bản mới nhất) trong [Release Notes](../release-notes.md){.internal-link target=_blank}.
+
+## Về các phiên bản
+
+Theo quy ước về Semantic Versioning, bất kỳ phiên bản nào bên dưới `1.0.0` có thể thêm các thay đổi gây mất tương thích.
+
+**FastAPI** cũng theo quy ước rằng bất kỳ thay đổi phiên bản "PATCH" nào là cho các lỗi và các thay đổi không gây mất tương thích.
+
+/// tip
+
+"PATCH" là số cuối cùng, ví dụ, trong `0.2.3`, phiên bản PATCH là `3`.
+
+///
+
+Vì vậy, bạn có thể cố định đến một phiên bản như:
+
+```txt
+fastapi>=0.45.0,<0.46.0
+```
+
+Các thay đổi gây mất tương thích và các tính năng mới được thêm vào trong các phiên bản "MINOR".
+
+/// tip
+
+"MINOR" là số ở giữa, ví dụ, trong `0.2.3`, phiên bản MINOR là `2`.
+
+///
+
+## Nâng cấp các phiên bản của FastAPI
+
+Bạn nên thêm các bài kiểm tra (tests) cho ứng dụng của bạn.
+
+Với **FastAPI** điều này rất dễ dàng (nhờ vào Starlette), kiểm tra tài liệu: [Testing](../tutorial/testing.md){.internal-link target=_blank}
+
+Sau khi bạn có các bài kiểm tra, bạn có thể nâng cấp phiên bản **FastAPI** lên một phiên bản mới hơn, và đảm bảo rằng tất cả mã của bạn hoạt động đúng bằng cách chạy các bài kiểm tra của bạn.
+
+Nếu mọi thứ đang hoạt động, hoặc sau khi bạn thực hiện các thay đổi cần thiết, và tất cả các bài kiểm tra của bạn đều đi qua, thì bạn có thể cố định phiên bản của `fastapi` đến phiên bản mới hơn.
+
+## Về Starlette
+
+Bạn không nên cố định phiên bản của `starlette`.
+
+Các phiên bản khác nhau của **FastAPI** sẽ sử dụng một phiên bản Starlette mới hơn.
+
+Vì vậy, bạn có thể để **FastAPI** sử dụng phiên bản Starlette phù hợp.
+
+## Về Pydantic
+
+Pydantic bao gồm các bài kiểm tra của riêng nó cho **FastAPI**, vì vậy các phiên bản mới hơn của Pydantic (trên `1.0.0`) luôn tương thích với **FastAPI**.
+
+Bạn có thể cố định Pydantic đến bất kỳ phiên bản nào trên `1.0.0` mà bạn muốn.
+
+Ví dụ:
+
+```txt
+pydantic>=2.7.0,<3.0.0
+```
diff --git a/docs/vi/docs/environment-variables.md b/docs/vi/docs/environment-variables.md
new file mode 100644
index 000000000..dd06f8959
--- /dev/null
+++ b/docs/vi/docs/environment-variables.md
@@ -0,0 +1,300 @@
+# Biến môi trường (Environment Variables)
+
+/// tip
+
+Nếu bạn đã biết về "biến môi trường" và cách sử dụng chúng, bạn có thể bỏ qua phần này.
+
+///
+
+Một biến môi trường (còn được gọi là "**env var**") là một biến mà tồn tại **bên ngoài** đoạn mã Python, ở trong **hệ điều hành**, và có thể được đọc bởi đoạn mã Python của bạn (hoặc bởi các chương trình khác).
+
+Các biến môi trường có thể được sử dụng để xử lí **các thiết lập** của ứng dụng, như một phần của **các quá trình cài đặt** Python, v.v.
+
+## Tạo và Sử dụng các Biến Môi Trường
+
+Bạn có thể **tạo** và sử dụng các biến môi trường trong **shell (terminal)**, mà không cần sử dụng Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// Bạn có thể tạo một biến môi trường MY_NAME với
+$ export MY_NAME="Wade Wilson"
+
+// Sau đó bạn có thể sử dụng nó với các chương trình khác, như
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Tạo một biến môi trường MY_NAME
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Sử dụng nó với các chương trình khác, như là
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## Đọc các Biến Môi Trường trong Python
+
+Bạn cũng có thể tạo các biến môi trường **bên ngoài** đoạn mã Python, trong terminal (hoặc bằng bất kỳ phương pháp nào khác), và sau đó **đọc chúng trong Python**.
+
+Ví dụ, bạn có một file `main.py` với:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+Tham số thứ hai cho
`os.getenv()` là giá trị mặc định để trả về.
+
+Nếu không được cung cấp, nó mặc định là `None`, ở đây chúng ta cung cấp `"World"` là giá trị mặc định để sử dụng.
+
+///
+
+Sau đó bạn có thể gọi chương trình Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// Ở đây chúng ta chưa cài đặt biến môi trường
+$ python main.py
+
+// Vì chúng ta chưa cài đặt biến môi trường, chúng ta nhận được giá trị mặc định
+
+Hello World from Python
+
+// Nhưng nếu chúng ta tạo một biến môi trường trước đó
+$ export MY_NAME="Wade Wilson"
+
+// Và sau đó gọi chương trình lại
+$ python main.py
+
+// Bây giờ nó có thể đọc biến môi trường
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Ở đây chúng ta chưa cài đặt biến môi trường
+$ python main.py
+
+// Vì chúng ta chưa cài đặt biến môi trường, chúng ta nhận được giá trị mặc định
+
+Hello World from Python
+
+// Nhưng nếu chúng ta tạo một biến môi trường trước đó
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Và sau đó gọi chương trình lại
+$ python main.py
+
+// Bây giờ nó có thể đọc biến môi trường
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+Vì các biến môi trường có thể được tạo bên ngoài đoạn mã Python, nhưng có thể được đọc bởi đoạn mã Python, và không cần được lưu trữ (commit vào `git`) cùng với các file khác, nên chúng thường được sử dụng để lưu các thiết lập hoặc **cấu hình**.
+
+Bạn cũng có thể tạo ra một biến môi trường dành riêng cho một **lần gọi chương trình**, chỉ có thể được sử dụng bởi chương trình đó, và chỉ trong thời gian chạy của chương trình.
+
+Để làm điều này, tạo nó ngay trước chương trình đó, trên cùng một dòng:
+
+
+
+```console
+// Tạo một biến môi trường MY_NAME cho lần gọi chương trình này
+$ MY_NAME="Wade Wilson" python main.py
+
+// Bây giờ nó có thể đọc biến môi trường
+
+Hello Wade Wilson from Python
+
+// Biến môi trường không còn tồn tại sau đó
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip
+
+Bạn có thể đọc thêm về điều này tại
The Twelve-Factor App: Config.
+
+///
+
+## Các Kiểu (Types) và Kiểm tra (Validation)
+
+Các biến môi trường có thể chỉ xử lí **chuỗi ký tự**, vì chúng nằm bên ngoài đoạn mã Python và phải tương thích với các chương trình khác và phần còn lại của hệ thống (và thậm chí với các hệ điều hành khác, như Linux, Windows, macOS).
+
+Điều này có nghĩa là **bất kỳ giá trị nào** được đọc trong Python từ một biến môi trường **sẽ là một `str`**, và bất kỳ hành động chuyển đổi sang kiểu dữ liệu khác hoặc hành động kiểm tra nào cũng phải được thực hiện trong đoạn mã.
+
+Bạn sẽ học thêm về việc sử dụng biến môi trường để xử lí **các thiết lập ứng dụng** trong [Hướng dẫn nâng cao - Các thiết lập và biến môi trường](./advanced/settings.md){.internal-link target=_blank}.
+
+## Biến môi trường `PATH`
+
+Có một biến môi trường **đặc biệt** được gọi là **`PATH`** được sử dụng bởi các hệ điều hành (Linux, macOS, Windows) nhằm tìm các chương trình để thực thi.
+
+Giá trị của biến môi trường `PATH` là một chuỗi dài được tạo bởi các thư mục được phân tách bởi dấu hai chấm `:` trên Linux và macOS, và bởi dấu chấm phẩy `;` trên Windows.
+
+Ví dụ, biến môi trường `PATH` có thể có dạng như sau:
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Điều này có nghĩa là hệ thống sẽ tìm kiếm các chương trình trong các thư mục:
+
+* `/usr/local/bin`
+* `/usr/bin`
+* `/bin`
+* `/usr/sbin`
+* `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
+```
+
+Điều này có nghĩa là hệ thống sẽ tìm kiếm các chương trình trong các thư mục:
+
+* `C:\Program Files\Python312\Scripts`
+* `C:\Program Files\Python312`
+* `C:\Windows\System32`
+
+////
+
+Khi bạn gõ một **lệnh** trong terminal, hệ điều hành **tìm kiếm** chương trình trong **mỗi thư mục** được liệt kê trong biến môi trường `PATH`.
+
+Ví dụ, khi bạn gõ `python` trong terminal, hệ điều hành tìm kiếm một chương trình được gọi `python` trong **thư mục đầu tiên** trong danh sách đó.
+
+Nếu tìm thấy, nó sẽ **sử dụng** nó. Nếu không tìm thấy, nó sẽ tiếp tục tìm kiếm trong **các thư mục khác**.
+
+### Cài đặt Python và cập nhật biến môi trường `PATH`
+
+Khi bạn cài đặt Python, bạn có thể được hỏi nếu bạn muốn cập nhật biến môi trường `PATH`.
+
+//// tab | Linux, macOS
+
+Giả sử bạn cài đặt Python vào thư mục `/opt/custompython/bin`.
+
+Nếu bạn chọn cập nhật biến môi trường `PATH`, thì cài đặt sẽ thêm `/opt/custompython/bin` vào biến môi trường `PATH`.
+
+Nó có thể có dạng như sau:
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
+```
+
+Như vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong `/opt/custompython/bin` (thư mục cuối) và sử dụng nó.
+
+////
+
+//// tab | Windows
+
+Giả sử bạn cài đặt Python vào thư mục `C:\opt\custompython\bin`.
+
+Nếu bạn chọn cập nhật biến môi trường `PATH`, thì cài đặt sẽ thêm `C:\opt\custompython\bin` vào biến môi trường `PATH`.
+
+Nó có thể có dạng như sau:
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
+```
+
+Như vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong `C:\opt\custompython\bin` (thư mục cuối) và sử dụng nó.
+
+////
+
+Vậy, nếu bạn gõ:
+
+
+
+```console
+$ python
+```
+
+
+
+//// tab | Linux, macOS
+
+Hệ thống sẽ **tìm kiếm** chương trình `python` trong `/opt/custompython/bin` và thực thi nó.
+
+Nó tương đương với việc bạn gõ:
+
+
+
+```console
+$ /opt/custompython/bin/python
+```
+
+
+
+////
+
+//// tab | Windows
+
+Hệ thống sẽ **tìm kiếm** chương trình `python` trong `C:\opt\custompython\bin\python` và thực thi nó.
+
+Nó tương đương với việc bạn gõ:
+
+
+
+```console
+$ C:\opt\custompython\bin\python
+```
+
+
+
+////
+
+Thông tin này sẽ hữu ích khi bạn học về [Môi trường ảo](virtual-environments.md){.internal-link target=_blank}.
+
+## Kết luận
+
+Với những thông tin này, bạn có thể hiểu được **các biến môi trường là gì** và **cách sử dụng chúng trong Python**.
+
+Bạn có thể đọc thêm về chúng tại
Wikipedia cho Biến môi trường.
+
+Trong nhiều trường hợp, cách các biến môi trường trở nên hữu ích và có thể áp dụng không thực sự rõ ràng ngay từ đầu, nhưng chúng sẽ liên tục xuất hiện trong rất nhiều tình huống khi bạn phát triển ứng dụng, vì vậy việc hiểu biết về chúng là hữu ích.
+
+Chẳng hạn, bạn sẽ cần những thông tin này khi bạn học về [Môi trường ảo](virtual-environments.md).
diff --git a/docs/vi/docs/fastapi-cli.md b/docs/vi/docs/fastapi-cli.md
new file mode 100644
index 000000000..d9e315ae4
--- /dev/null
+++ b/docs/vi/docs/fastapi-cli.md
@@ -0,0 +1,75 @@
+# FastAPI CLI
+
+**FastAPI CLI** là một chương trình dòng lệnh có thể được sử dụng để phục vụ ứng dụng FastAPI của bạn, quản lý dự án FastAPI của bạn và nhiều hoạt động khác.
+
+Khi bạn cài đặt FastAPI (vd với `pip install "fastapi[standard]"`), nó sẽ bao gồm một gói được gọi là `fastapi-cli`, gói này cung cấp lệnh `fastapi` trong terminal.
+
+Để chạy ứng dụng FastAPI của bạn cho quá trình phát triển (development), bạn có thể sử dụng lệnh `fastapi dev`:
+
+
+
+```console
+$ fastapi dev main.py
+
+ FastAPI Starting development server 🚀
+
+ Searching for package file structure from directories with
+ __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with the
+ following code:
+
+ from main import app
+
+ app Using import string: main:app
+
+ server Server started at http://127.0.0.1:8000
+ server Documentation at http://127.0.0.1:8000/docs
+
+ tip Running in development mode, for production use:
+ fastapi run
+
+ Logs:
+
+ INFO Will watch for changes in these directories:
+ ['/home/user/code/awesomeapp']
+ INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to
+ quit)
+ INFO Started reloader process [383138] using WatchFiles
+ INFO Started server process [383153]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+```
+
+
+
+Chương trình dòng lệnh `fastapi` là **FastAPI CLI**.
+
+FastAPI CLI nhận đường dẫn đến chương trình Python của bạn (vd `main.py`) và tự động phát hiện đối tượng `FastAPI` (thường được gọi là `app`), xác định quá trình nhập đúng, và sau đó chạy nó (serve).
+
+Đối với vận hành thực tế (production), bạn sẽ sử dụng `fastapi run` thay thế. 🚀
+
+Ở bên trong, **FastAPI CLI** sử dụng
Uvicorn, một server ASGI có hiệu suất cao, sẵn sàng cho vận hành thực tế (production). 😎
+
+## `fastapi dev`
+
+Chạy `fastapi dev` sẽ khởi động quá trình phát triển.
+
+Mặc định, **auto-reload** được bật, tự động tải lại server khi bạn thay đổi code của bạn. Điều này tốn nhiều tài nguyên và có thể kém ổn định hơn khi nó bị tắt. Bạn nên sử dụng nó cho quá trình phát triển. Nó cũng lắng nghe địa chỉ IP `127.0.0.1`, đó là địa chỉ IP của máy tính để tự giao tiếp với chính nó (`localhost`).
+
+## `fastapi run`
+
+Chạy `fastapi run` mặc định sẽ khởi động FastAPI cho quá trình vận hành thực tế.
+
+Mặc định, **auto-reload** bị tắt. Nó cũng lắng nghe địa chỉ IP `0.0.0.0`, đó là tất cả các địa chỉ IP có sẵn, như vậy nó sẽ được truy cập công khai bởi bất kỳ ai có thể giao tiếp với máy tính. Đây là cách bạn thường chạy nó trong sản phẩm hoàn thiện, ví dụ trong một container.
+
+Trong hầu hết các trường hợp, bạn sẽ (và nên) có một "proxy điểm cuối (termination proxy)" xử lý HTTPS cho bạn, điều này sẽ phụ thuộc vào cách bạn triển khai ứng dụng của bạn, nhà cung cấp có thể làm điều này cho bạn, hoặc bạn có thể cần thiết lập nó.
+
+/// tip
+
+Bạn có thể tìm hiểu thêm về FastAPI CLI trong [tài liệu triển khai](deployment/index.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/vi/docs/features.md b/docs/vi/docs/features.md
new file mode 100644
index 000000000..2220d9fa5
--- /dev/null
+++ b/docs/vi/docs/features.md
@@ -0,0 +1,200 @@
+# Tính năng
+
+## Tính năng của FastAPI
+
+**FastAPI** cho bạn những tính năng sau:
+
+### Dựa trên những tiêu chuẩn mở
+
+*
OpenAPI cho việc tạo API, bao gồm những khai báo về
đường dẫn các toán tử, tham số, body requests, cơ chế bảo mật, etc.
+* Tự động tài liệu hóa data model theo
JSON Schema (OpenAPI bản thân nó được dựa trên JSON Schema).
+* Được thiết kế xung quanh các tiêu chuẩn này sau khi nghiên cứu tỉ mỉ thay vì chỉ suy nghĩ đơn giản và sơ xài.
+* Điều này cho phép tự động hóa **trình sinh code client** cho nhiều ngôn ngữ lập trình khác nhau.
+
+### Tự động hóa tài liệu
+
+
+Tài liệu tương tác API và web giao diện người dùng. Là một framework được dựa trên OpenAPI do đó có nhiều tùy chọn giao diện cho tài liệu API, 2 giao diện bên dưới là mặc định.
+
+*
Swagger UI, với giao diện khám phá, gọi và kiểm thử API trực tiếp từ trình duyệt.
+
+
+
+* Thay thế với tài liệu API với
ReDoc.
+
+
+
+### Chỉ cần phiên bản Python hiện đại
+
+Tất cả được dựa trên khai báo kiểu dữ liệu chuẩn của **Python 3.8** (cảm ơn Pydantic). Bạn không cần học cú pháp mới, chỉ cần biết chuẩn Python hiện đại.
+
+Nếu bạn cần 2 phút để làm mới lại cách sử dụng các kiểu dữ liệu mới của Python (thậm chí nếu bạn không sử dụng FastAPI), xem hướng dẫn ngắn: [Kiểu dữ liệu Python](python-types.md){.internal-link target=_blank}.
+
+Bạn viết chuẩn Python với kiểu dữ liệu như sau:
+
+```Python
+from datetime import date
+
+from pydantic import BaseModel
+
+# Declare a variable as a str
+# and get editor support inside the function
+def main(user_id: str):
+ return user_id
+
+
+# A Pydantic model
+class User(BaseModel):
+ id: int
+ name: str
+ joined: date
+```
+
+Sau đó có thể được sử dụng:
+
+```Python
+my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
+
+second_user_data = {
+ "id": 4,
+ "name": "Mary",
+ "joined": "2018-11-30",
+}
+
+my_second_user: User = User(**second_user_data)
+```
+
+/// info
+
+`**second_user_data` nghĩa là:
+
+Truyền các khóa và giá trị của dict `second_user_data` trực tiếp như các tham số kiểu key-value, tương đương với: `User(id=4, name="Mary", joined="2018-11-30")`
+
+///
+
+### Được hỗ trợ từ các trình soạn thảo
+
+
+Toàn bộ framework được thiết kế để sử dụng dễ dàng và trực quan, toàn bộ quyết định đã được kiểm thử trên nhiều trình soạn thảo thậm chí trước khi bắt đầu quá trình phát triển, để chắc chắn trải nghiệm phát triển là tốt nhất.
+
+Trong lần khảo sát cuối cùng dành cho các lập trình viên Python, đã rõ ràng
rằng đa số các lập trình viên sử dụng tính năng "autocompletion".
+
+Toàn bộ framework "FastAPI" phải đảm bảo rằng: autocompletion hoạt động ở mọi nơi. Bạn sẽ hiếm khi cần quay lại để đọc tài liệu.
+
+Đây là các trình soạn thảo có thể giúp bạn:
+
+* trong
Visual Studio Code:
+
+
+
+* trong
PyCharm:
+
+
+
+Bạn sẽ có được auto-completion trong code, thậm chí trước đó là không thể. Như trong ví dụ, khóa `price` bên trong một JSON (đó có thể được lồng nhau) đến từ một request.
+
+Không còn nhập sai tên khóa, quay đi quay lại giữa các tài liệu hoặc cuộn lên cuộn xuống để tìm xem cuối cùng bạn đã sử dụng `username` hay `user_name`.
+
+### Ngắn gọn
+
+FastAPI có các giá trị mặc định hợp lý cho mọi thứ, với các cấu hình tùy chọn ở mọi nơi. Tất cả các tham số có thể được tinh chỉnh để thực hiện những gì bạn cần và để định nghĩa API bạn cần.
+
+Nhưng mặc định, tất cả **đều hoạt động**.
+
+### Validation
+
+* Validation cho đa số (hoặc tất cả?) **các kiểu dữ liệu** Python, bao gồm:
+ * JSON objects (`dict`).
+ * Mảng JSON (`list`) định nghĩa kiểu dữ liệu từng phần tử.
+ * Xâu (`str`), định nghĩa độ dài lớn nhất, nhỏ nhất.
+ * Số (`int`, `float`) với các giá trị lớn nhất, nhỏ nhất, etc.
+
+* Validation cho nhiều kiểu dữ liệu bên ngoài như:
+ * URL.
+ * Email.
+ * UUID.
+ * ...và nhiều cái khác.
+
+Tất cả validation được xử lí bằng những thiết lập tốt và mạnh mẽ của **Pydantic**.
+
+### Bảo mật và xác thực
+
+Bảo mật và xác thực đã tích hợp mà không làm tổn hại tới cơ sở dữ liệu hoặc data models.
+
+Tất cả cơ chế bảo mật định nghĩa trong OpenAPI, bao gồm:
+
+* HTTP Basic.
+* **OAuth2** (với **JWT tokens**). Xem hướng dẫn [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* API keys in:
+ * Headers.
+ * Các tham số trong query string.
+ * Cookies, etc.
+
+Cộng với tất cả các tính năng bảo mật từ Starlette (bao gồm **session cookies**).
+
+Tất cả được xây dựng dưới dạng các công cụ và thành phần có thể tái sử dụng, dễ dàng tích hợp với hệ thống, kho lưu trữ dữ liệu, cơ sở dữ liệu quan hệ và NoSQL của bạn,...
+
+### Dependency Injection
+
+FastAPI bao gồm một hệ thống
Dependency Injection vô cùng dễ sử dụng nhưng vô cùng mạnh mẽ.
+
+* Thậm chí, các dependency có thể có các dependency khác, tạo thành một phân cấp hoặc **"một đồ thị" của các dependency**.
+* Tất cả **được xử lí tự động** bởi framework.
+* Tất cả các dependency có thể yêu cầu dữ liệu từ request và **tăng cường các ràng buộc từ đường dẫn** và tự động tài liệu hóa.
+* **Tự động hóa validation**, thậm chí với các tham số *đường dẫn* định nghĩa trong các dependency.
+* Hỗ trợ hệ thống xác thực người dùng phức tạp, **các kết nối cơ sở dữ liệu**,...
+* **Không làm tổn hại** cơ sở dữ liệu, frontends,... Nhưng dễ dàng tích hợp với tất cả chúng.
+
+### Không giới hạn "plug-ins"
+
+Hoặc theo một cách nào khác, không cần chúng, import và sử dụng code bạn cần.
+
+Bất kì tích hợp nào được thiết kế để sử dụng đơn giản (với các dependency), đến nỗi bạn có thể tạo một "plug-in" cho ứng dụng của mình trong 2 dòng code bằng cách sử dụng cùng một cấu trúc và cú pháp được sử dụng cho *path operations* của bạn.
+
+### Đã được kiểm thử
+
+* 100%
test coverage.
+* 100%
type annotated code base.
+* Được sử dụng cho các ứng dụng sản phẩm.
+
+## Tính năng của Starlette
+
+`FastAPI` is thực sự là một sub-class của `Starlette`. Do đó, nếu bạn đã biết hoặc đã sử dụng Starlette, đa số các chức năng sẽ làm việc giống như vậy.
+
+Với **FastAPI**, bạn có được tất cả những tính năng của **Starlette**:
+
+* Hiệu năng thực sự ấn tượng. Nó là
một trong nhưng framework Python nhanh nhất, khi so sánh với **NodeJS** và **Go**.
+* Hỗ trợ **WebSocket**.
+* In-process background tasks.
+* Startup and shutdown events.
+* Client cho kiểm thử xây dựng trên HTTPX.
+* **CORS**, GZip, Static Files, Streaming responses.
+* Hỗ trợ **Session and Cookie**.
+* 100% test coverage.
+* 100% type annotated codebase.
+
+## Tính năng của Pydantic
+
+**FastAPI** tương thích đầy đủ với (và dựa trên)
Pydantic. Do đó, bất kì code Pydantic nào bạn thêm vào cũng sẽ hoạt động.
+
+Bao gồm các thư viện bên ngoài cũng dựa trên Pydantic, như
ORMs,
ODMs cho cơ sở dữ liệu.
+
+Nó cũng có nghĩa là trong nhiều trường hợp, bạn có thể truyền cùng object bạn có từ một request **trực tiếp cho cơ sở dữ liệu**, vì mọi thứ được validate tự động.
+
+Điều tương tự áp dụng cho các cách khác nhau, trong nhiều trường hợp, bạn có thể chỉ truyền object từ cơ sở dữ liêu **trực tiếp tới client**.
+
+Với **FastAPI**, bạn có tất cả những tính năng của **Pydantic** (FastAPI dựa trên Pydantic cho tất cả những xử lí về dữ liệu):
+
+* **Không gây rối não**:
+ * Không cần học ngôn ngữ mô tả cấu trúc mới.
+ * Nếu bạn biết kiểu dữ liệu Python, bạn biết cách sử dụng Pydantic.
+* Sử dụng tốt với **
IDE/
linter/não của bạn**:
+
+ * Bởi vì các cấu trúc dữ liệu của Pydantic chỉ là các instances của class bạn định nghĩa; auto-completion, linting, mypy và trực giác của bạn nên làm việc riêng biệt với những dữ liệu mà bạn đã validate.
+* Validate **các cấu trúc phức tạp**:
+ * Sử dụng các models Pydantic phân tầng, `List` và `Dict` của Python `typing`,...
+ * Và các validators cho phép các cấu trúc dữ liệu phức tạp trở nên rõ ràng và dễ dàng để định nghĩa, kiểm tra và tài liệu hóa thành JSON Schema.
+ * Bạn có thể có các object **JSON lồng nhau** và tất cả chúng đã validate và annotated.
+* **Có khả năng mở rộng**:
+ * Pydantic cho phép bạn tùy chỉnh kiểu dữ liệu bằng việc định nghĩa hoặc bạn có thể mở rộng validation với các decorator trong model.
+* 100% test coverage.
diff --git a/docs/vi/docs/index.md b/docs/vi/docs/index.md
new file mode 100644
index 000000000..5c6b7e8a4
--- /dev/null
+++ b/docs/vi/docs/index.md
@@ -0,0 +1,475 @@
+# FastAPI
+
+
+
+
+
+
+
+ FastAPI framework, hiệu năng cao, dễ học, dễ code, sẵn sàng để tạo ra sản phẩm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+**Tài liệu**:
https://fastapi.tiangolo.com
+
+**Mã nguồn**:
https://github.com/fastapi/fastapi
+
+---
+
+FastAPI là một web framework hiện đại, hiệu năng cao để xây dựng web APIs với Python dựa trên tiêu chuẩn Python type hints.
+
+Những tính năng như:
+
+* **Nhanh**: Hiệu năng rất cao khi so sánh với **NodeJS** và **Go** (cảm ơn Starlette và Pydantic). [Một trong những Python framework nhanh nhất](#hieu-nang).
+* **Code nhanh**: Tăng tốc độ phát triển tính năng từ 200% tới 300%. *
+* **Ít lỗi hơn**: Giảm khoảng 40% những lỗi phát sinh bởi con người (nhà phát triển). *
+* **Trực giác tốt hơn**: Được các trình soạn thảo hỗ tuyệt vời.
Completion mọi nơi. Ít thời gian gỡ lỗi.
+* **Dễ dàng**: Được thiết kế để dễ dàng học và sử dụng. Ít thời gian đọc tài liệu.
+* **Ngắn**: Tối thiểu code bị trùng lặp. Nhiều tính năng được tích hợp khi định nghĩa tham số. Ít lỗi hơn.
+* **Tăng tốc**: Có được sản phẩm cùng với tài liệu (được tự động tạo) có thể tương tác.
+* **Được dựa trên các tiêu chuẩn**: Dựa trên (và hoàn toàn tương thích với) các tiêu chuẩn mở cho APIs :
OpenAPI (trước đó được biết đến là Swagger) và
JSON Schema.
+
+
* ước tính được dựa trên những kiểm chứng trong nhóm phát triển nội bộ, xây dựng các ứng dụng sản phẩm.
+
+## Nhà tài trợ
+
+
+
+{% if sponsors %}
+{% for sponsor in sponsors.gold -%}
+

+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+

+{% endfor %}
+{% endif %}
+
+
+
+
Những nhà tài trợ khác
+
+## Ý kiến đánh giá
+
+"_[...] Tôi đang sử dụng **FastAPI** vô cùng nhiều vào những ngày này. [...] Tôi thực sự đang lên kế hoạch sử dụng nó cho tất cả các nhóm **dịch vụ ML tại Microsoft**. Một vài trong số đó đang tích hợp vào sản phẩm lõi của **Window** và một vài sản phẩm cho **Office**._"
+
+
Kabir Khan -
Microsoft (ref)
+
+---
+
+"_Chúng tôi tích hợp thư viện **FastAPI** để sinh ra một **REST** server, nó có thể được truy vấn để thu được những **dự đoán**._ [bởi Ludwid] "
+
+
Piero Molino, Yaroslav Dudin, và Sai Sumanth Miryala -
Uber (ref)
+
+---
+
+"_**Netflix** vui mừng thông báo việc phát hành framework mã nguồn mở của chúng tôi cho *quản lí khủng hoảng* tập trung: **Dispatch**! [xây dựng với **FastAPI**]_"
+
+
Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
+
+---
+
+"_Tôi vô cùng hào hứng về **FastAPI**. Nó rất thú vị_"
+
+
+
+---
+
+"_Thành thật, những gì bạn đã xây dựng nhìn siêu chắc chắn và bóng bẩy. Theo nhiều cách, nó là những gì tôi đã muốn Hug trở thành - thật sự truyền cảm hứng để thấy ai đó xây dựng nó._"
+
+
Timothy Crosley - người tạo ra
Hug (ref)
+
+---
+
+"_Nếu bạn đang tìm kiếm một **framework hiện đại** để xây dựng một REST APIs, thử xem xét **FastAPI** [...] Nó nhanh, dễ dùng và dễ học [...]_"
+
+"_Chúng tôi đã chuyển qua **FastAPI cho **APIs** của chúng tôi [...] Tôi nghĩ bạn sẽ thích nó [...]_"
+
+
+
+
+---
+
+"_Nếu ai đó đang tìm cách xây dựng sản phẩm API bằng Python, tôi sẽ đề xuất **FastAPI**. Nó **được thiết kế đẹp đẽ**, **sử dụng đơn giản** và **có khả năng mở rộng cao**, nó đã trở thành một **thành phần quan trọng** trong chiến lược phát triển API của chúng tôi và đang thúc đẩy nhiều dịch vụ và mảng tự động hóa như Kỹ sư TAC ảo của chúng tôi._"
+
+
Deon Pillsbury -
Cisco (ref)
+
+---
+
+## **Typer**, giao diện dòng lệnh của FastAPI
+
+

+
+Nếu bạn đang xây dựng một
CLI - ứng dụng được sử dụng trong giao diện dòng lệnh, xem về
**Typer**.
+
+**Typer** là một người anh em của FastAPI. Và nó được dự định trở thành **giao diện dòng lệnh cho FastAPI**. ⌨️ 🚀
+
+## Yêu cầu
+
+FastAPI đứng trên vai những người khổng lồ:
+
+*
Starlette cho phần web.
+*
Pydantic cho phần data.
+
+## Cài đặt
+
+
+
+```console
+$ pip install fastapi
+
+---> 100%
+```
+
+
+
+Bạn cũng sẽ cần một ASGI server cho production như
Uvicorn hoặc
Hypercorn.
+
+
+
+```console
+$ pip install "uvicorn[standard]"
+
+---> 100%
+```
+
+
+
+## Ví dụ
+
+### Khởi tạo
+
+* Tạo một tệp tin `main.py` như sau:
+
+```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}
+```
+
+
+Hoặc sử dụng async def
...
+
+Nếu code của bạn sử dụng `async` / `await`, hãy sử dụng `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}
+```
+
+**Lưu ý**:
+
+Nếu bạn không biết, xem phần _"In a hurry?"_ về `async` và `await` trong tài liệu này.
+
+
+
+### Chạy ứng dụng
+
+Chạy server như sau:
+
+
+
+```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.
+```
+
+
+
+
+Về lệnh uvicorn main:app --reload
...
+
+Lệnh `uvicorn main:app` tham chiếu tới những thành phần sau:
+
+* `main`: tệp tin `main.py` (một Python "module").
+* `app`: object được tạo trong tệp tin `main.py` tại dòng `app = FastAPI()`.
+* `--reload`: chạy lại server sau khi code thay đổi. Chỉ sử dụng trong quá trình phát triển.
+
+
+
+### Kiểm tra
+
+Mở trình duyệt của bạn tại
http://127.0.0.1:8000/items/5?q=somequery.
+
+Bạn sẽ thấy một JSON response:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+Bạn đã sẵn sàng để tạo một API như sau:
+
+* Nhận HTTP request với _đường dẫn_ `/` và `/items/{item_id}`.
+* Cả hai _đường dẫn_ sử dụng
toán tử `GET` (cũng đươc biết đến là _phương thức_ HTTP).
+* _Đường dẫn_ `/items/{item_id}` có một _tham số đường dẫn_ `item_id`, nó là một tham số kiểu `int`.
+* _Đường dẫn_ `/items/{item_id}` có một _tham số query string_ `q`, nó là một tham số tùy chọn kiểu `str`.
+
+### Tài liệu tương tác API
+
+Truy cập
http://127.0.0.1:8000/docs.
+
+Bạn sẽ thấy tài liệu tương tác API được tạo tự động (cung cấp bởi
Swagger UI):
+
+
+
+### Tài liệu API thay thế
+
+Và bây giờ, hãy truy cập tới
http://127.0.0.1:8000/redoc.
+
+Bạn sẽ thấy tài liệu được thay thế (cung cấp bởi
ReDoc):
+
+
+
+## Nâng cấp ví dụ
+
+Bây giờ sửa tệp tin `main.py` để nhận body từ một request `PUT`.
+
+Định nghĩa của body sử dụng kiểu dữ liệu chuẩn của Python, cảm ơn 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}
+```
+
+Server nên tự động chạy lại (bởi vì bạn đã thêm `--reload` trong lệnh `uvicorn` ở trên).
+
+### Nâng cấp tài liệu API
+
+Bây giờ truy cập tới
http://127.0.0.1:8000/docs.
+
+* Tài liệu API sẽ được tự động cập nhật, bao gồm body mới:
+
+
+
+* Click vào nút "Try it out", nó cho phép bạn điền những tham số và tương tác trực tiếp với API:
+
+
+
+* Sau khi click vào nút "Execute", giao diện người dùng sẽ giao tiếp với API của bạn bao gồm: gửi các tham số, lấy kết quả và hiển thị chúng trên màn hình:
+
+
+
+### Nâng cấp tài liệu API thay thế
+
+Và bây giờ truy cập tới
http://127.0.0.1:8000/redoc.
+
+* Tài liệu thay thế cũng sẽ phản ánh tham số và body mới:
+
+
+
+### Tóm lại
+
+Bạn khai báo **một lần** kiểu dữ liệu của các tham số, body, etc là các tham số của hàm số.
+
+Bạn định nghĩa bằng cách sử dụng các kiểu dữ liệu chuẩn của Python.
+
+Bạn không phải học một cú pháp mới, các phương thức và class của một thư viện cụ thể nào.
+
+Chỉ cần sử dụng các chuẩn của **Python**.
+
+Ví dụ, với một tham số kiểu `int`:
+
+```Python
+item_id: int
+```
+
+hoặc với một model `Item` phức tạp hơn:
+
+```Python
+item: Item
+```
+
+...và với định nghĩa đơn giản đó, bạn có được:
+
+* Sự hỗ trợ từ các trình soạn thảo, bao gồm:
+ * Completion.
+ * Kiểm tra kiểu dữ liệu.
+* Kiểm tra kiểu dữ liệu:
+ * Tự động sinh lỗi rõ ràng khi dữ liệu không hợp lệ .
+ * Kiểm tra JSON lồng nhau .
+*
Chuyển đổi dữ liệu đầu vào: tới từ network sang dữ liệu kiểu Python. Đọc từ:
+ * JSON.
+ * Các tham số trong đường dẫn.
+ * Các tham số trong query string.
+ * Cookies.
+ * Headers.
+ * Forms.
+ * Files.
+*
Chuyển đổi dữ liệu đầu ra: chuyển đổi từ kiểu dữ liệu Python sang dữ liệu network (như JSON):
+ * Chuyển đổi kiểu dữ liệu Python (`str`, `int`, `float`, `bool`, `list`,...).
+ * `datetime` objects.
+ * `UUID` objects.
+ * Database models.
+ * ...và nhiều hơn thế.
+* Tự động tạo tài liệu tương tác API, bao gồm 2 giao diện người dùng:
+ * Swagger UI.
+ * ReDoc.
+
+---
+
+Quay trở lại ví dụ trước, **FastAPI** sẽ thực hiện:
+
+* Kiểm tra xem có một `item_id` trong đường dẫn với các request `GET` và `PUT` không?
+* Kiểm tra xem `item_id` có phải là kiểu `int` trong các request `GET` và `PUT` không?
+ * Nếu không, client sẽ thấy một lỗi rõ ràng và hữu ích.
+* Kiểm tra xem nếu có một tham số `q` trong query string (ví dụ như `http://127.0.0.1:8000/items/foo?q=somequery`) cho request `GET`.
+ * Tham số `q` được định nghĩa `= None`, nó là tùy chọn.
+ * Nếu không phải `None`, nó là bắt buộc (như body trong trường hợp của `PUT`).
+* Với request `PUT` tới `/items/{item_id}`, đọc body như JSON:
+ * Kiểm tra xem nó có một thuộc tính bắt buộc kiểu `str` là `name` không?
+ * Kiểm tra xem nó có một thuộc tính bắt buộc kiểu `float` là `price` không?
+ * Kiểm tra xem nó có một thuộc tính tùy chọn là `is_offer` không? Nếu có, nó phải có kiểu `bool`.
+ * Tất cả những kiểm tra này cũng được áp dụng với các JSON lồng nhau.
+* Chuyển đổi tự động các JSON object đến và JSON object đi.
+* Tài liệu hóa mọi thứ với OpenAPI, tài liệu đó có thể được sử dụng bởi:
+
+ * Các hệ thống tài liệu có thể tương tác.
+ * Hệ thống sinh code tự động, cho nhiều ngôn ngữ lập trình.
+* Cung cấp trực tiếp 2 giao diện web cho tài liệu tương tác
+
+---
+
+Chúng tôi chỉ trình bày những thứ cơ bản bên ngoài, nhưng bạn đã hiểu cách thức hoạt động của nó.
+
+Thử thay đổi dòng này:
+
+```Python
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+...từ:
+
+```Python
+ ... "item_name": item.name ...
+```
+
+...sang:
+
+```Python
+ ... "item_price": item.price ...
+```
+
+...và thấy trình soạn thảo của bạn nhận biết kiểu dữ liệu và gợi ý hoàn thiện các thuộc tính.
+
+
+
+Ví dụ hoàn chỉnh bao gồm nhiều tính năng hơn, xem
Tutorial - User Guide.
+
+
+**Cảnh báo tiết lỗ**: Tutorial - User Guide:
+
+* Định nghĩa **tham số** từ các nguồn khác nhau như: **headers**, **cookies**, **form fields** và **files**.
+* Cách thiết lập **các ràng buộc cho validation** như `maximum_length` hoặc `regex`.
+* Một hệ thống **
Dependency Injection vô cùng mạnh mẽ và dễ dàng sử dụng.
+* Bảo mật và xác thực, hỗ trợ **OAuth2**(với **JWT tokens**) và **HTTP Basic**.
+* Những kĩ thuật nâng cao hơn (nhưng tương đối dễ) để định nghĩa **JSON models lồng nhau** (cảm ơn Pydantic).
+* Tích hợp **GraphQL** với
Strawberry và các thư viện khác.
+* Nhiều tính năng mở rộng (cảm ơn Starlette) như:
+ * **WebSockets**
+ * kiểm thử vô cùng dễ dàng dựa trên HTTPX và `pytest`
+ * **CORS**
+ * **Cookie Sessions**
+ * ...và nhiều hơn thế.
+
+## Hiệu năng
+
+Independent TechEmpower benchmarks cho thấy các ứng dụng **FastAPI** chạy dưới Uvicorn là
một trong những Python framework nhanh nhất, chỉ đứng sau Starlette và Uvicorn (được sử dụng bên trong FastAPI). (*)
+
+Để hiểu rõ hơn, xem phần
Benchmarks.
+
+## Các dependency tùy chọn
+
+Sử dụng bởi Pydantic:
+
+*
email-validator
- cho email validation.
+
+Sử dụng Starlette:
+
+*
httpx
- Bắt buộc nếu bạn muốn sử dụng `TestClient`.
+*
jinja2
- Bắt buộc nếu bạn muốn sử dụng cấu hình template engine mặc định.
+*
python-multipart
- Bắt buộc nếu bạn muốn hỗ trợ
"parsing", form với `request.form()`.
+*
itsdangerous
- Bắt buộc để hỗ trợ `SessionMiddleware`.
+*
pyyaml
- Bắt buộc để hỗ trợ `SchemaGenerator` cho Starlette (bạn có thể không cần nó trong FastAPI).
+
+Sử dụng bởi FastAPI / Starlette:
+
+*
uvicorn
- Server để chạy ứng dụng của bạn.
+*
orjson
- Bắt buộc nếu bạn muốn sử dụng `ORJSONResponse`.
+*
ujson
- Bắt buộc nếu bạn muốn sử dụng `UJSONResponse`.
+
+Bạn có thể cài đặt tất cả những dependency trên với `pip install "fastapi[all]"`.
+
+## Giấy phép
+
+Dự án này được cấp phép dưới những điều lệ của giấy phép MIT.
diff --git a/docs/vi/docs/python-types.md b/docs/vi/docs/python-types.md
new file mode 100644
index 000000000..403e89930
--- /dev/null
+++ b/docs/vi/docs/python-types.md
@@ -0,0 +1,593 @@
+# Giới thiệu kiểu dữ liệu Python
+
+Python hỗ trợ tùy chọn "type hints" (còn được gọi là "type annotations").
+
+Những **"type hints"** hay chú thích là một cú pháp đặc biệt cho phép khai báo
kiểu dữ liệu của một biến.
+
+Bằng việc khai báo kiểu dữ liệu cho các biến của bạn, các trình soạn thảo và các công cụ có thể hỗ trợ bạn tốt hơn.
+
+Đây chỉ là một **hướng dẫn nhanh** về gợi ý kiểu dữ liệu trong Python. Nó chỉ bao gồm những điều cần thiết tối thiểu để sử dụng chúng với **FastAPI**... đó thực sự là rất ít.
+
+**FastAPI** hoàn toàn được dựa trên những gợi ý kiểu dữ liệu, chúng mang đến nhiều ưu điểm và lợi ích.
+
+Nhưng thậm chí nếu bạn không bao giờ sử dụng **FastAPI**, bạn sẽ được lợi từ việc học một ít về chúng.
+
+/// note
+
+Nếu bạn là một chuyên gia về Python, và bạn đã biết mọi thứ về gợi ý kiểu dữ liệu, bỏ qua và đi tới chương tiếp theo.
+
+///
+
+## Động lực
+
+Hãy bắt đầu với một ví dụ đơn giản:
+
+{* ../../docs_src/python_types/tutorial001.py *}
+
+
+Kết quả khi gọi chương trình này:
+
+```
+John Doe
+```
+
+Hàm thực hiện như sau:
+
+* Lấy một `first_name` và `last_name`.
+* Chuyển đổi kí tự đầu tiên của mỗi biến sang kiểu chữ hoa với `title()`.
+*
Nối chúng lại với nhau bằng một kí tự trắng ở giữa.
+
+{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+
+
+### Sửa đổi
+
+Nó là một chương trình rất đơn giản.
+
+Nhưng bây giờ hình dung rằng bạn đang viết nó từ đầu.
+
+Tại một vài thời điểm, bạn sẽ bắt đầu định nghĩa hàm, bạn có các tham số...
+
+Nhưng sau đó bạn phải gọi "phương thức chuyển đổi kí tự đầu tiên sang kiểu chữ hoa".
+
+Có phải là `upper`? Có phải là `uppercase`? `first_uppercase`? `capitalize`?
+
+Sau đó, bạn thử hỏi người bạn cũ của mình, autocompletion của trình soạn thảo.
+
+Bạn gõ tham số đầu tiên của hàm, `first_name`, sau đó một dấu chấm (`.`) và sau đó ấn `Ctrl+Space` để kích hoạt bộ hoàn thành.
+
+Nhưng đáng buồn, bạn không nhận được điều gì hữu ích cả:
+
+

+
+### Thêm kiểu dữ liệu
+
+Hãy sửa một dòng từ phiên bản trước.
+
+Chúng ta sẽ thay đổi chính xác đoạn này, tham số của hàm, từ:
+
+```Python
+ first_name, last_name
+```
+
+sang:
+
+```Python
+ first_name: str, last_name: str
+```
+
+Chính là nó.
+
+Những thứ đó là "type hints":
+
+{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+
+
+Đó không giống như khai báo những giá trị mặc định giống như:
+
+```Python
+ first_name="john", last_name="doe"
+```
+
+Nó là một thứ khác.
+
+Chúng ta sử dụng dấu hai chấm (`:`), không phải dấu bằng (`=`).
+
+Và việc thêm gợi ý kiểu dữ liệu không làm thay đổi những gì xảy ra so với khi chưa thêm chúng.
+
+But now, imagine you are again in the middle of creating that function, but with type hints.
+
+Tại cùng một điểm, bạn thử kích hoạt autocomplete với `Ctrl+Space` và bạn thấy:
+
+

+
+Với cái đó, bạn có thể cuộn, nhìn thấy các lựa chọn, cho đến khi bạn tìm thấy một "tiếng chuông":
+
+

+
+## Động lực nhiều hơn
+
+Kiểm tra hàm này, nó đã có gợi ý kiểu dữ liệu:
+
+{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+
+
+Bởi vì trình soạn thảo biết kiểu dữ liệu của các biến, bạn không chỉ có được completion, bạn cũng được kiểm tra lỗi:
+
+

+
+Bây giờ bạn biết rằng bạn phải sửa nó, chuyển `age` sang một xâu với `str(age)`:
+
+{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+
+
+## Khai báo các kiểu dữ liệu
+
+Bạn mới chỉ nhìn thấy những nơi chủ yếu để đặt khai báo kiểu dữ liệu. Như là các tham số của hàm.
+
+Đây cũng là nơi chủ yếu để bạn sử dụng chúng với **FastAPI**.
+
+### Kiểu dữ liệu đơn giản
+
+Bạn có thể khai báo tất cả các kiểu dữ liệu chuẩn của Python, không chỉ là `str`.
+
+Bạn có thể sử dụng, ví dụ:
+
+* `int`
+* `float`
+* `bool`
+* `bytes`
+
+{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+
+
+### Các kiểu dữ liệu tổng quát với tham số kiểu dữ liệu
+
+Có một vài cấu trúc dữ liệu có thể chứa các giá trị khác nhau như `dict`, `list`, `set` và `tuple`. Và những giá trị nội tại cũng có thể có kiểu dữ liệu của chúng.
+
+Những kiểu dữ liệu nội bộ này được gọi là những kiểu dữ liệu "**tổng quát**". Và có khả năng khai báo chúng, thậm chí với các kiểu dữ liệu nội bộ của chúng.
+
+Để khai báo những kiểu dữ liệu và những kiểu dữ liệu nội bộ đó, bạn có thể sử dụng mô đun chuẩn của Python là `typing`. Nó có hỗ trợ những gợi ý kiểu dữ liệu này.
+
+#### Những phiên bản mới hơn của Python
+
+Cú pháp sử dụng `typing` **tương thích** với tất cả các phiên bản, từ Python 3.6 tới những phiên bản cuối cùng, bao gồm Python 3.9, Python 3.10,...
+
+As Python advances, **những phiên bản mới** mang tới sự hỗ trợ được cải tiến cho những chú thích kiểu dữ liệu và trong nhiều trường hợp bạn thậm chí sẽ không cần import và sử dụng mô đun `typing` để khai báo chú thích kiểu dữ liệu.
+
+Nếu bạn có thể chọn một phiên bản Python gần đây hơn cho dự án của bạn, ban sẽ có được những ưu điểm của những cải tiến đơn giản đó.
+
+Trong tất cả các tài liệu tồn tại những ví dụ tương thích với mỗi phiên bản Python (khi có một sự khác nhau).
+
+Cho ví dụ "**Python 3.6+**" có nghĩa là nó tương thích với Python 3.7 hoặc lớn hơn (bao gồm 3.7, 3.8, 3.9, 3.10,...). và "**Python 3.9+**" nghĩa là nó tương thích với Python 3.9 trở lên (bao gồm 3.10,...).
+
+Nếu bạn có thể sử dụng **phiên bản cuối cùng của Python**, sử dụng những ví dụ cho phiên bản cuối, những cái đó sẽ có **cú pháp đơn giản và tốt nhât**, ví dụ, "**Python 3.10+**".
+
+#### List
+
+Ví dụ, hãy định nghĩa một biến là `list` các `str`.
+
+//// tab | Python 3.9+
+
+Khai báo biến với cùng dấu hai chấm (`:`).
+
+Tương tự kiểu dữ liệu `list`.
+
+Như danh sách là một kiểu dữ liệu chứa một vài kiểu dữ liệu có sẵn, bạn đặt chúng trong các dấu ngoặc vuông:
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial006_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+Từ `typing`, import `List` (với chữ cái `L` viết hoa):
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial006.py!}
+```
+
+Khai báo biến với cùng dấu hai chấm (`:`).
+
+Tương tự như kiểu dữ liệu, `List` bạn import từ `typing`.
+
+Như danh sách là một kiểu dữ liệu chứa các kiểu dữ liệu có sẵn, bạn đặt chúng bên trong dấu ngoặc vuông:
+
+```Python hl_lines="4"
+{!> ../../docs_src/python_types/tutorial006.py!}
+```
+
+////
+
+/// info
+
+Các kiểu dữ liệu có sẵn bên trong dấu ngoặc vuông được gọi là "tham số kiểu dữ liệu".
+
+Trong trường hợp này, `str` là tham số kiểu dữ liệu được truyền tới `List` (hoặc `list` trong Python 3.9 trở lên).
+
+///
+
+Có nghĩa là: "biến `items` là một `list`, và mỗi phần tử trong danh sách này là một `str`".
+
+/// tip
+
+Nếu bạn sử dụng Python 3.9 hoặc lớn hơn, bạn không phải import `List` từ `typing`, bạn có thể sử dụng `list` để thay thế.
+
+///
+
+Bằng cách này, trình soạn thảo của bạn có thể hỗ trợ trong khi xử lí các phần tử trong danh sách:
+
+

+
+Đa phần đều không thể đạt được nếu không có các kiểu dữ liệu.
+
+Chú ý rằng, biến `item` là một trong các phần tử trong danh sách `items`.
+
+Và do vậy, trình soạn thảo biết nó là một `str`, và cung cấp sự hỗ trợ cho nó.
+
+#### Tuple and Set
+
+Bạn sẽ làm điều tương tự để khai báo các `tuple` và các `set`:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial007_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial007.py!}
+```
+
+////
+
+Điều này có nghĩa là:
+
+* Biến `items_t` là một `tuple` với 3 phần tử, một `int`, một `int` nữa, và một `str`.
+* Biến `items_s` là một `set`, và mỗi phần tử của nó có kiểu `bytes`.
+
+#### Dict
+
+Để định nghĩa một `dict`, bạn truyền 2 tham số kiểu dữ liệu, phân cách bởi dấu phẩy.
+
+Tham số kiểu dữ liệu đầu tiên dành cho khóa của `dict`.
+
+Tham số kiểu dữ liệu thứ hai dành cho giá trị của `dict`.
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial008.py!}
+```
+
+////
+
+Điều này có nghĩa là:
+
+* Biến `prices` là một `dict`:
+ * Khóa của `dict` này là kiểu `str` (đó là tên của mỗi vật phẩm).
+ * Giá trị của `dict` này là kiểu `float` (đó là giá của mỗi vật phẩm).
+
+#### Union
+
+Bạn có thể khai báo rằng một biến có thể là **một vài kiểu dữ liệu" bất kì, ví dụ, một `int` hoặc một `str`.
+
+Trong Python 3.6 hoặc lớn hơn (bao gồm Python 3.10) bạn có thể sử dụng kiểu `Union` từ `typing` và đặt trong dấu ngoặc vuông những giá trị được chấp nhận.
+
+In Python 3.10 there's also a **new syntax** where you can put the possible types separated by a
vertical bar (`|`).
+
+Trong Python 3.10 cũng có một **cú pháp mới** mà bạn có thể đặt những kiểu giá trị khả thi phân cách bởi một dấu
sổ dọc (`|`).
+
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial008b.py!}
+```
+
+////
+
+Trong cả hai trường hợp có nghĩa là `item` có thể là một `int` hoặc `str`.
+
+#### Khả năng `None`
+
+Bạn có thể khai báo một giá trị có thể có một kiểu dữ liệu, giống như `str`, nhưng nó cũng có thể là `None`.
+
+Trong Python 3.6 hoặc lớn hơn (bao gồm Python 3.10) bạn có thể khai báo nó bằng các import và sử dụng `Optional` từ mô đun `typing`.
+
+```Python hl_lines="1 4"
+{!../../docs_src/python_types/tutorial009.py!}
+```
+
+Sử dụng `Optional[str]` thay cho `str` sẽ cho phép trình soạn thảo giúp bạn phát hiện các lỗi mà bạn có thể gặp như một giá trị luôn là một `str`, trong khi thực tế nó rất có thể là `None`.
+
+`Optional[Something]` là một cách viết ngắn gọn của `Union[Something, None]`, chúng là tương đương nhau.
+
+Điều này cũng có nghĩa là trong Python 3.10, bạn có thể sử dụng `Something | None`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial009_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial009.py!}
+```
+
+////
+
+//// tab | Python 3.8+ alternative
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial009b.py!}
+```
+
+////
+
+#### Sử dụng `Union` hay `Optional`
+
+If you are using a Python version below 3.10, here's a tip from my very **subjective** point of view:
+
+Nếu bạn đang sử dụng phiên bản Python dưới 3.10, đây là một mẹo từ ý kiến rất "chủ quan" của tôi:
+
+* 🚨 Tránh sử dụng `Optional[SomeType]`
+* Thay vào đó ✨ **sử dụng `Union[SomeType, None]`** ✨.
+
+Cả hai là tương đương và bên dưới chúng giống nhau, nhưng tôi sẽ đễ xuất `Union` thay cho `Optional` vì từ "**tùy chọn**" có vẻ ngầm định giá trị là tùy chọn, và nó thực sự có nghĩa rằng "nó có thể là `None`", do đó nó không phải là tùy chọn và nó vẫn được yêu cầu.
+
+Tôi nghĩ `Union[SomeType, None]` là rõ ràng hơn về ý nghĩa của nó.
+
+Nó chỉ là về các từ và tên. Nhưng những từ đó có thể ảnh hưởng cách bạn và những đồng đội của bạn suy nghĩ về code.
+
+Cho một ví dụ, hãy để ý hàm này:
+
+{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+
+
+Tham số `name` được định nghĩa là `Optional[str]`, nhưng nó **không phải là tùy chọn**, bạn không thể gọi hàm mà không có tham số:
+
+```Python
+say_hi() # Oh, no, this throws an error! 😱
+```
+
+Tham số `name` **vẫn được yêu cầu** (không phải là *tùy chọn*) vì nó không có giá trị mặc định. Trong khi đó, `name` chấp nhận `None` như là giá trị:
+
+```Python
+say_hi(name=None) # This works, None is valid 🎉
+```
+
+Tin tốt là, khi bạn sử dụng Python 3.10, bạn sẽ không phải lo lắng về điều đó, bạn sẽ có thể sử dụng `|` để định nghĩa hợp của các kiểu dữ liệu một cách đơn giản:
+
+{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
+
+
+Và sau đó, bạn sẽ không phải lo rằng những cái tên như `Optional` và `Union`. 😎
+
+
+#### Những kiểu dữ liệu tổng quát
+
+Những kiểu dữ liệu này lấy tham số kiểu dữ liệu trong dấu ngoặc vuông được gọi là **Kiểu dữ liệu tổng quát**, cho ví dụ:
+
+//// tab | Python 3.10+
+
+Bạn có thể sử dụng các kiểu dữ liệu có sẵn như là kiểu dữ liệu tổng quát (với ngoặc vuông và kiểu dữ liệu bên trong):
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+Và tương tự với Python 3.6, từ mô đun `typing`:
+
+* `Union`
+* `Optional` (tương tự như Python 3.6)
+* ...và các kiểu dữ liệu khác.
+
+Trong Python 3.10, thay vì sử dụng `Union` và `Optional`, bạn có thể sử dụng
sổ dọc ('|') để khai báo hợp của các kiểu dữ liệu, điều đó tốt hơn và đơn giản hơn nhiều.
+
+////
+
+//// tab | Python 3.9+
+
+Bạn có thể sử dụng các kiểu dữ liệu có sẵn tương tự như (với ngoặc vuông và kiểu dữ liệu bên trong):
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+Và tương tự với Python 3.6, từ mô đun `typing`:
+
+* `Union`
+* `Optional`
+* ...and others.
+
+////
+
+//// tab | Python 3.8+
+
+* `List`
+* `Tuple`
+* `Set`
+* `Dict`
+* `Union`
+* `Optional`
+* ...và các kiểu khác.
+
+////
+
+### Lớp như kiểu dữ liệu
+
+Bạn cũng có thể khai báo một lớp như là kiểu dữ liệu của một biến.
+
+Hãy nói rằng bạn muốn có một lớp `Person` với một tên:
+
+{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+
+
+Sau đó bạn có thể khai báo một biến có kiểu là `Person`:
+
+{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+
+
+Và lại một lần nữa, bạn có được tất cả sự hỗ trợ từ trình soạn thảo:
+
+

+
+Lưu ý rằng, điều này có nghĩa rằng "`one_person`" là một **thực thể** của lớp `Person`.
+
+Nó không có nghĩa "`one_person`" là một **lớp** gọi là `Person`.
+
+## Pydantic models
+
+
Pydantic là một thư viện Python để validate dữ liệu hiệu năng cao.
+
+Bạn có thể khai báo "hình dạng" của dữa liệu như là các lớp với các thuộc tính.
+
+Và mỗi thuộc tính có một kiểu dữ liệu.
+
+Sau đó bạn tạo một thực thể của lớp đó với một vài giá trị và nó sẽ validate các giá trị, chuyển đổi chúng sang kiểu dữ liệu phù hợp (nếu đó là trường hợp) và cho bạn một object với toàn bộ dữ liệu.
+
+Và bạn nhận được tất cả sự hỗ trợ của trình soạn thảo với object kết quả đó.
+
+Một ví dụ từ tài liệu chính thức của Pydantic:
+
+//// tab | Python 3.10+
+
+```Python
+{!> ../../docs_src/python_types/tutorial011_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python
+{!> ../../docs_src/python_types/tutorial011_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+{!> ../../docs_src/python_types/tutorial011.py!}
+```
+
+////
+
+/// info
+
+Để học nhiều hơn về
Pydantic, tham khảo tài liệu của nó.
+
+///
+
+**FastAPI** được dựa hoàn toàn trên Pydantic.
+
+Bạn sẽ thấy nhiều ví dụ thực tế hơn trong [Hướng dẫn sử dụng](tutorial/index.md){.internal-link target=_blank}.
+
+/// tip
+
+Pydantic có một hành vi đặc biệt khi bạn sử dụng `Optional` hoặc `Union[Something, None]` mà không có giá trị mặc dịnh, bạn có thể đọc nhiều hơn về nó trong tài liệu của Pydantic về
Required Optional fields.
+
+///
+
+## Type Hints với Metadata Annotations
+
+Python cũng có một tính năng cho phép đặt **metadata bổ sung** trong những gợi ý kiểu dữ liệu này bằng cách sử dụng `Annotated`.
+
+//// tab | Python 3.9+
+
+Trong Python 3.9, `Annotated` là một phần của thư viện chuẩn, do đó bạn có thể import nó từ `typing`.
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial013_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+Ở phiên bản dưới Python 3.9, bạn import `Annotated` từ `typing_extensions`.
+
+Nó đã được cài đặt sẵng cùng với **FastAPI**.
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial013.py!}
+```
+
+////
+
+Python bản thân nó không làm bất kì điều gì với `Annotated`. Với các trình soạn thảo và các công cụ khác, kiểu dữ liệu vẫn là `str`.
+
+Nhưng bạn có thể sử dụng `Annotated` để cung cấp cho **FastAPI** metadata bổ sung về cách mà bạn muốn ứng dụng của bạn xử lí.
+
+Điều quan trọng cần nhớ là ***tham số kiểu dữ liệu* đầu tiên** bạn truyền tới `Annotated` là **kiểu giá trị thực sự**. Phần còn lại chỉ là metadata cho các công cụ khác.
+
+Bây giờ, bạn chỉ cần biết rằng `Annotated` tồn tại, và nó là tiêu chuẩn của Python. 😎
+
+
+Sau đó, bạn sẽ thấy sự **mạnh mẽ** mà nó có thể làm.
+
+/// tip
+
+Thực tế, cái này là **tiêu chuẩn của Python**, nghĩa là bạn vẫn sẽ có được **trải nghiệm phát triển tốt nhất có thể** với trình soạn thảo của bạn, với các công cụ bạn sử dụng để phân tích và tái cấu trúc code của bạn, etc. ✨
+
+Và code của bạn sẽ tương thích với nhiều công cụ và thư viện khác của Python. 🚀
+
+///
+
+## Các gợi ý kiểu dữ liệu trong **FastAPI**
+
+**FastAPI** lấy các ưu điểm của các gợi ý kiểu dữ liệu để thực hiện một số thứ.
+
+Với **FastAPI**, bạn khai báo các tham số với gợi ý kiểu và bạn có được:
+
+* **Sự hỗ trợ từ các trình soạn thảo**.
+* **Kiểm tra kiểu dữ liệu (type checking)**.
+
+...và **FastAPI** sử dụng các khia báo để:
+
+* **Định nghĩa các yêu cầu**: từ tham số đường dẫn của request, tham số query, headers, bodies, các phụ thuộc (dependencies),...
+* **Chuyển dổi dữ liệu*: từ request sang kiểu dữ liệu được yêu cầu.
+* **Kiểm tra tính đúng đắn của dữ liệu**: tới từ mỗi request:
+ * Sinh **lỗi tự động** để trả về máy khác khi dữ liệu không hợp lệ.
+* **Tài liệu hóa** API sử dụng OpenAPI:
+ * cái mà sau được được sử dụng bởi tài liệu tương tác người dùng.
+
+Điều này có thể nghe trừu tượng. Đừng lo lắng. Bạn sẽ thấy tất cả chúng trong [Hướng dẫn sử dụng](tutorial/index.md){.internal-link target=_blank}.
+
+Điều quan trọng là bằng việc sử dụng các kiểu dữ liệu chuẩn của Python (thay vì thêm các lớp, decorators,...), **FastAPI** sẽ thực hiện nhiều công việc cho bạn.
+
+/// info
+
+Nếu bạn đã đi qua toàn bộ các hướng dẫn và quay trở lại để tìm hiểu nhiều hơn về các kiểu dữ liệu, một tài nguyên tốt như
"cheat sheet" từ `mypy`.
+
+///
diff --git a/docs/vi/docs/tutorial/first-steps.md b/docs/vi/docs/tutorial/first-steps.md
new file mode 100644
index 000000000..901c8fd59
--- /dev/null
+++ b/docs/vi/docs/tutorial/first-steps.md
@@ -0,0 +1,335 @@
+# Những bước đầu tiên
+
+Tệp tin FastAPI đơn giản nhất có thể trông như này:
+
+{* ../../docs_src/first_steps/tutorial001.py *}
+
+Sao chép sang một tệp tin `main.py`.
+
+Chạy live server:
+
+
+
+```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.
+```
+
+
+
+/// note
+
+Câu lệnh `uvicorn main:app` được giải thích như sau:
+
+* `main`: tệp tin `main.py` (một Python "mô đun").
+* `app`: một object được tạo ra bên trong `main.py` với dòng `app = FastAPI()`.
+* `--reload`: làm server khởi động lại sau mỗi lần thay đổi. Chỉ sử dụng trong môi trường phát triển.
+
+///
+
+Trong output, có một dòng giống như:
+
+```hl_lines="4"
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+Dòng đó cho thấy URL, nơi mà app của bạn đang được chạy, trong máy local của bạn.
+
+### Kiểm tra
+
+Mở trình duyệt của bạn tại
http://127.0.0.1:8000.
+
+Bạn sẽ thấy một JSON response như:
+
+```JSON
+{"message": "Hello World"}
+```
+
+### Tài liệu tương tác API
+
+Bây giờ tới
http://127.0.0.1:8000/docs.
+
+Bạn sẽ thấy một tài liệu tương tác API (cung cấp bởi
Swagger UI):
+
+
+
+### Phiên bản thay thế của tài liệu API
+
+Và bây giờ tới
http://127.0.0.1:8000/redoc.
+
+Bạn sẽ thấy một bản thay thế của tài liệu (cung cấp bởi
ReDoc):
+
+
+
+### OpenAPI
+
+**FastAPI** sinh một "schema" với tất cả API của bạn sử dụng tiêu chuẩn **OpenAPI** cho định nghĩa các API.
+
+#### "Schema"
+
+Một "schema" là một định nghĩa hoặc mô tả thứ gì đó. Không phải code triển khai của nó, nhưng chỉ là một bản mô tả trừu tượng.
+
+#### API "schema"
+
+Trong trường hợp này,
OpenAPI là một bản mô tả bắt buộc cơ chế định nghĩa API của bạn.
+
+Định nghĩa cấu trúc này bao gồm những đường dẫn API của bạn, các tham số có thể có,...
+
+#### "Cấu trúc" dữ liệu
+
+Thuật ngữ "cấu trúc" (schema) cũng có thể được coi như là hình dạng của dữ liệu, tương tự như một JSON content.
+
+Trong trường hợp đó, nó có nghĩa là các thuộc tính JSON và các kiểu dữ liệu họ có,...
+
+#### OpenAPI và JSON Schema
+
+OpenAPI định nghĩa một cấu trúc API cho API của bạn. Và cấu trúc đó bao gồm các dịnh nghĩa (or "schema") về dữ liệu được gửi đi và nhận về bởi API của bạn, sử dụng **JSON Schema**, một tiêu chuẩn cho cấu trúc dữ liệu JSON.
+
+#### Kiểm tra `openapi.json`
+
+Nếu bạn tò mò về việc cấu trúc OpenAPI nhìn như thế nào thì FastAPI tự động sinh một JSON (schema) với các mô tả cho tất cả API của bạn.
+
+Bạn có thể thấy nó trực tiếp tại:
http://127.0.0.1:8000/openapi.json.
+
+Nó sẽ cho thấy một JSON bắt đầu giống như:
+
+```JSON
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+
+
+
+...
+```
+
+#### OpenAPI dùng để làm gì?
+
+Cấu trúc OpenAPI là sức mạnh của tài liệu tương tác.
+
+Và có hàng tá các bản thay thế, tất cả đều dựa trên OpenAPI. Bạn có thể dễ dàng thêm bất kì bản thay thế bào cho ứng dụng của bạn được xây dựng với **FastAPI**.
+
+Bạn cũng có thể sử dụng nó để sinh code tự động, với các client giao viết qua API của bạn. Ví dụ, frontend, mobile hoặc các ứng dụng IoT.
+
+## Tóm lại, từng bước một
+
+### Bước 1: import `FastAPI`
+
+{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+
+`FastAPI` là một Python class cung cấp tất cả chức năng cho API của bạn.
+
+/// note | Chi tiết kĩ thuật
+
+`FastAPI` là một class kế thừa trực tiếp `Starlette`.
+
+Bạn cũng có thể sử dụng tất cả
Starlette chức năng với `FastAPI`.
+
+///
+
+### Bước 2: Tạo một `FastAPI` "instance"
+
+{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+
+Biến `app` này là một "instance" của class `FastAPI`.
+
+Đây sẽ là điểm cốt lõi để tạo ra tất cả API của bạn.
+
+`app` này chính là điều được nhắc tới bởi `uvicorn` trong câu lệnh:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Nếu bạn tạo ứng dụng của bạn giống như:
+
+{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
+
+Và đặt nó trong một tệp tin `main.py`, sau đó bạn sẽ gọi `uvicorn` giống như:
+
+
+
+```console
+$ uvicorn main:my_awesome_api --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### Bước 3: tạo một *đường dẫn toán tử*
+
+#### Đường dẫn
+
+"Đường dẫn" ở đây được nhắc tới là phần cuối cùng của URL bắt đầu từ `/`.
+
+Do đó, trong một URL nhìn giống như:
+
+```
+https://example.com/items/foo
+```
+
+...đường dẫn sẽ là:
+
+```
+/items/foo
+```
+
+/// info
+
+Một đường dẫn cũng là một cách gọi chung cho một "endpoint" hoặc một "route".
+
+///
+
+Trong khi xây dựng một API, "đường dẫn" là các chính để phân tách "mối quan hệ" và "tài nguyên".
+
+#### Toán tử (Operation)
+
+"Toán tử" ở đây được nhắc tới là một trong các "phương thức" HTTP.
+
+Một trong những:
+
+* `POST`
+* `GET`
+* `PUT`
+* `DELETE`
+
+...và một trong những cái còn lại:
+
+* `OPTIONS`
+* `HEAD`
+* `PATCH`
+* `TRACE`
+
+Trong giao thức HTTP, bạn có thể giao tiếp trong mỗi đường dẫn sử dụng một (hoặc nhiều) trong các "phương thức này".
+
+---
+
+Khi xây dựng các API, bạn thường sử dụng cụ thể các phương thức HTTP này để thực hiện một hành động cụ thể.
+
+Thông thường, bạn sử dụng
+
+* `POST`: để tạo dữ liệu.
+* `GET`: để đọc dữ liệu.
+* `PUT`: để cập nhật dữ liệu.
+* `DELETE`: để xóa dữ liệu.
+
+Do đó, trong OpenAPI, mỗi phương thức HTTP được gọi là một "toán tử (operation)".
+
+Chúng ta cũng sẽ gọi chúng là "**các toán tử**".
+
+#### Định nghĩa moojt *decorator cho đường dẫn toán tử*
+
+{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+
+`@app.get("/")` nói **FastAPI** rằng hàm bên dưới có trách nhiệm xử lí request tới:
+
+* đường dẫn `/`
+* sử dụng một
toán tửget
+
+/// info | Thông tin về "`@decorator`"
+
+Cú pháp `@something` trong Python được gọi là một "decorator".
+
+Bạn đặt nó trên một hàm. Giống như một chiếc mũ xinh xắn (Tôi ddonas đó là lí do mà thuật ngữ này ra đời).
+
+Một "decorator" lấy một hàm bên dưới và thực hiện một vài thứ với nó.
+
+Trong trường hợp của chúng ta, decorator này nói **FastAPI** rằng hàm bên dưới ứng với **đường dẫn** `/` và một **toán tử** `get`.
+
+Nó là một "**decorator đường dẫn toán tử**".
+
+///
+
+Bạn cũng có thể sử dụng với các toán tử khác:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+Và nhiều hơn với các toán tử còn lại:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+/// tip
+
+Bạn thoải mái sử dụng mỗi toán tử (phương thức HTTP) như bạn mơ ước.
+
+**FastAPI** không bắt buộc bất kì ý nghĩa cụ thể nào.
+
+Thông tin ở đây được biểu thị như là một chỉ dẫn, không phải là một yêu cầu bắt buộc.
+
+Ví dụ, khi sử dụng GraphQL bạn thông thường thực hiện tất cả các hành động chỉ bằng việc sử dụng các toán tử `POST`.
+
+///
+
+### Step 4: Định nghĩa **hàm cho đường dẫn toán tử**
+
+Đây là "**hàm cho đường dẫn toán tử**":
+
+* **đường dẫn**: là `/`.
+* **toán tử**: là `get`.
+* **hàm**: là hàm bên dưới "decorator" (bên dưới `@app.get("/")`).
+
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+
+Đây là một hàm Python.
+
+Nó sẽ được gọi bởi **FastAPI** bất cứ khi nào nó nhận một request tới URL "`/`" sử dụng một toán tử `GET`.
+
+Trong trường hợp này, nó là một hàm `async`.
+
+---
+
+Bạn cũng có thể định nghĩa nó như là một hàm thông thường thay cho `async def`:
+
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+
+/// note
+
+Nếu bạn không biết sự khác nhau, kiểm tra [Async: *"Trong khi vội vàng?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+///
+
+### Bước 5: Nội dung trả về
+
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+
+Bạn có thể trả về một `dict`, `list`, một trong những giá trị đơn như `str`, `int`,...
+
+Bạn cũng có thể trả về Pydantic model (bạn sẽ thấy nhiều hơn về nó sau).
+
+Có nhiều object và model khác nhau sẽ được tự động chuyển đổi sang JSON (bao gồm cả ORM,...). Thử sử dụng loại ưa thích của bạn, nó có khả năng cao đã được hỗ trợ.
+
+## Tóm lại
+
+* Import `FastAPI`.
+* Tạo một `app` instance.
+* Viết một **decorator cho đường dẫn toán tử** (giống như `@app.get("/")`).
+* Viết một **hàm cho đường dẫn toán tử** (giống như `def root(): ...` ở trên).
+* Chạy server trong môi trường phát triển (giống như `uvicorn main:app --reload`).
diff --git a/docs/vi/docs/tutorial/index.md b/docs/vi/docs/tutorial/index.md
new file mode 100644
index 000000000..dfeeed8c5
--- /dev/null
+++ b/docs/vi/docs/tutorial/index.md
@@ -0,0 +1,83 @@
+# Hướng dẫn sử dụng
+
+Hướng dẫn này cho bạn thấy từng bước cách sử dụng **FastAPI** đa số các tính năng của nó.
+
+Mỗi phần được xây dựng từ những phần trước đó, nhưng nó được cấu trúc thành các chủ đề riêng biệt, do đó bạn có thể xem trực tiếp từng phần cụ thể bất kì để giải quyết những API cụ thể mà bạn cần.
+
+Nó cũng được xây dựng để làm việc như một tham chiếu trong tương lai.
+
+Do đó bạn có thể quay lại và tìm chính xác những gì bạn cần.
+
+## Chạy mã
+
+Tất cả các code block có thể được sao chép và sử dụng trực tiếp (chúng thực chất là các tệp tin Python đã được kiểm thử).
+
+Để chạy bất kì ví dụ nào, sao chép code tới tệp tin `main.py`, và bắt đầu `uvicorn` với:
+
+
+
+```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.
+```
+
+
+
+**Khuyến khích** bạn viết hoặc sao chép code, sửa và chạy nó ở local.
+
+Sử dụng nó trong trình soạn thảo của bạn thực sự cho bạn thấy những lợi ích của FastAPI, thấy được cách bạn viết code ít hơn, tất cả đều được type check, autocompletion,...
+
+---
+
+## Cài đặt FastAPI
+
+Bước đầu tiên là cài đặt FastAPI.
+
+Với hướng dẫn này, bạn có thể muốn cài đặt nó với tất cả các phụ thuộc và tính năng tùy chọn:
+
+
+
+```console
+$ pip install "fastapi[all]"
+
+---> 100%
+```
+
+
+
+...dó cũng bao gồm `uvicorn`, bạn có thể sử dụng như một server để chạy code của bạn.
+
+/// note
+
+Bạn cũng có thể cài đặt nó từng phần.
+
+Đây là những gì bạn có thể sẽ làm một lần duy nhất bạn muốn triển khai ứng dụng của bạn lên production:
+
+```
+pip install fastapi
+```
+
+Cũng cài đặt `uvicorn` để làm việc như một server:
+
+```
+pip install "uvicorn[standard]"
+```
+
+Và tương tự với từng phụ thuộc tùy chọn mà bạn muốn sử dụng.
+
+///
+
+## Hướng dẫn nâng cao
+
+Cũng có một **Hướng dẫn nâng cao** mà bạn có thể đọc nó sau **Hướng dẫn sử dụng**.
+
+**Hướng dẫn sử dụng nâng cao**, xây dựng dựa trên cái này, sử dụng các khái niệm tương tự, và dạy bạn những tính năng mở rộng.
+
+Nhưng bạn nên đọc **Hướng dẫn sử dụng** đầu tiên (những gì bạn đang đọc).
+
+Nó được thiết kế do đó bạn có thể xây dựng một ứng dụng hoàn chỉnh chỉ với **Hướng dẫn sử dụng**, và sau đó mở rộng nó theo các cách khác nhau, phụ thuộc vào những gì bạn cần, sử dụng một vài ý tưởng bổ sung từ **Hướng dẫn sử dụng nâng cao**.
diff --git a/docs/vi/docs/tutorial/static-files.md b/docs/vi/docs/tutorial/static-files.md
new file mode 100644
index 000000000..ecf8c2485
--- /dev/null
+++ b/docs/vi/docs/tutorial/static-files.md
@@ -0,0 +1,40 @@
+# Tệp tĩnh (Static Files)
+
+Bạn có thể triển khai tệp tĩnh tự động từ một thư mục bằng cách sử dụng StaticFiles.
+
+## Sử dụng `Tệp tĩnh`
+
+- Nhập `StaticFiles`.
+- "Mount" a `StaticFiles()` instance in a specific path.
+
+{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+
+/// note | Chi tiết kỹ thuật
+
+Bạn cũng có thể sử dụng `from starlette.staticfiles import StaticFiles`.
+
+**FastAPI** cung cấp cùng `starlette.staticfiles` như `fastapi.staticfiles` giúp đơn giản hóa việc sử dụng, nhưng nó thực sự đến từ Starlette.
+
+///
+
+### "Mounting" là gì
+
+"Mounting" có nghĩa là thêm một ứng dụng "độc lập" hoàn chỉnh vào một đường dẫn cụ thể, sau đó ứng dụng đó sẽ chịu trách nhiệm xử lý tất cả các đường dẫn con.
+
+Điều này khác với việc sử dụng `APIRouter` vì một ứng dụng được gắn kết là hoàn toàn độc lập. OpenAPI và tài liệu từ ứng dụng chính của bạn sẽ không bao gồm bất kỳ thứ gì từ ứng dụng được gắn kết, v.v.
+
+Bạn có thể đọc thêm về điều này trong [Hướng dẫn Người dùng Nâng cao](../advanced/index.md){.internal-link target=\_blank}.
+
+## Chi tiết
+
+Đường dẫn đầu tiên `"/static"` là đường dẫn con mà "ứng dụng con" này sẽ được "gắn" vào. Vì vậy, bất kỳ đường dẫn nào bắt đầu bằng `"/static"` sẽ được xử lý bởi nó.
+
+Đường dẫn `directory="static"` là tên của thư mục chứa tệp tĩnh của bạn.
+
+Tham số `name="static"` đặt tên cho nó để có thể được sử dụng bên trong **FastAPI**.
+
+Tất cả các tham số này có thể khác với `static`, điều chỉnh chúng với phù hợp với ứng dụng của bạn.
+
+## Thông tin thêm
+
+Để biết thêm chi tiết và tùy chọn, hãy xem
Starlette's docs about Static Files.
diff --git a/docs/vi/docs/virtual-environments.md b/docs/vi/docs/virtual-environments.md
new file mode 100644
index 000000000..22d8e153e
--- /dev/null
+++ b/docs/vi/docs/virtual-environments.md
@@ -0,0 +1,842 @@
+# Môi trường ảo (Virtual Environments)
+
+Khi bạn làm việc trong các dự án Python, bạn có thể sử dụng một **môi trường ảo** (hoặc một cơ chế tương tự) để cách ly các gói bạn cài đặt cho mỗi dự án.
+
+/// info
+Nếu bạn đã biết về các môi trường ảo, cách tạo chúng và sử dụng chúng, bạn có thể bỏ qua phần này. 🤓
+
+///
+
+/// tip
+
+Một **môi trường ảo** khác với một **biến môi trường (environment variable)**.
+
+Một **biến môi trường** là một biến trong hệ thống có thể được sử dụng bởi các chương trình.
+
+Một **môi trường ảo** là một thư mục với một số tệp trong đó.
+
+///
+
+/// info
+
+Trang này sẽ hướng dẫn bạn cách sử dụng các **môi trường ảo** và cách chúng hoạt động.
+
+Nếu bạn đã sẵn sàng sử dụng một **công cụ có thể quản lý tất cả mọi thứ** cho bạn (bao gồm cả việc cài đặt Python), hãy thử
uv.
+
+///
+
+## Tạo một Dự án
+
+Đầu tiên, tạo một thư mục cho dự án của bạn.
+
+Cách tôi thường làm là tạo một thư mục có tên `code` trong thư mục `home/user`.
+
+Và trong thư mục đó, tôi tạo một thư mục cho mỗi dự án.
+
+
+
+```console
+// Đi đến thư mục home
+$ cd
+// Tạo một thư mục cho tất cả các dự án của bạn
+$ mkdir code
+// Vào thư mục code
+$ cd code
+// Tạo một thư mục cho dự án này
+$ mkdir awesome-project
+// Vào thư mục dự án
+$ cd awesome-project
+```
+
+
+
+## Tạo một Môi trường ảo
+
+Khi bạn bắt đầu làm việc với một dự án Python **trong lần đầu**, hãy tạo một môi trường ảo **
trong thư mục dự án của bạn**.
+
+/// tip
+
+Bạn cần làm điều này **một lần cho mỗi dự án**, không phải mỗi khi bạn làm việc.
+///
+
+//// tab | `venv`
+
+Để tạo một môi trường ảo, bạn có thể sử dụng module `venv` có sẵn của Python.
+
+
+
+```console
+$ python -m venv .venv
+```
+
+
+
+/// details | Cách các lệnh hoạt động
+
+* `python`: sử dụng chương trình `python`
+* `-m`: gọi một module như một script, chúng ta sẽ nói về module đó sau
+* `venv`: sử dụng module `venv` được cài đặt sẵn của Python
+* `.venv`: tạo môi trường ảo trong thư mục mới `.venv`
+
+///
+
+////
+
+//// tab | `uv`
+
+Nếu bạn có
`uv` được cài đặt, bạn có thể sử dụng nó để tạo một môi trường ảo.
+
+
+
+```console
+$ uv venv
+```
+
+
+
+/// tip
+
+Mặc định, `uv` sẽ tạo một môi trường ảo trong một thư mục có tên `.venv`.
+
+Nhưng bạn có thể tùy chỉnh nó bằng cách thêm một đối số với tên thư mục.
+
+///
+
+////
+
+Lệnh này tạo một môi trường ảo mới trong một thư mục có tên `.venv`.
+
+/// details | `.venv` hoặc tên khác
+
+Bạn có thể tạo môi trường ảo trong một thư mục khác, nhưng thường người ta quy ước đặt nó là `.venv`.
+
+///
+
+## Kích hoạt Môi trường ảo
+
+Kích hoạt môi trường ảo mới để bất kỳ lệnh Python nào bạn chạy hoặc gói nào bạn cài đặt sẽ sử dụng nó.
+
+/// tip
+
+Làm điều này **mỗi khi** bạn bắt đầu một **phiên terminal mới** để làm việc trên dự án.
+
+///
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+Nếu bạn sử dụng Bash cho Windows (ví dụ:
Git Bash):
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+/// tip
+
+Mỗi khi bạn cài đặt thêm một **package mới** trong môi trường đó, hãy **kích hoạt** môi trường đó lại.
+
+Điều này đảm bảo rằng khi bạn sử dụng một **chương trình dòng lệnh (
CLI)** được cài đặt từ gói đó, bạn sẽ dùng bản cài đặt từ môi trường ảo của mình thay vì bản được cài đặt toàn cục khác có thể có phiên bản khác với phiên bản bạn cần.
+
+///
+
+## Kiểm tra xem Môi trường ảo đã được Kích hoạt chưa
+
+Kiểm tra xem môi trường ảo đã được kích hoạt chưa (lệnh trước đó đã hoạt động).
+
+/// tip
+
+Điều này là **không bắt buộc**, nhưng nó là một cách tốt để **kiểm tra** rằng mọi thứ đang hoạt động như mong đợi và bạn đang sử dụng đúng môi trường ảo mà bạn đã định.
+
+///
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+Nếu nó hiển thị `python` binary tại `.venv/bin/python`, trong dự án của bạn (trong trường hợp `awesome-project`), thì tức là nó hoạt động. 🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+Nếu nó hiển thị `python` binary tại `.venv\Scripts\python`, trong dự án của bạn (trong trường hợp `awesome-project`), thì tức là nó hoạt động. 🎉
+
+////
+
+## Nâng cấp `pip`
+
+/// tip
+
+Nếu bạn sử dụng
`uv` bạn sử dụng nó để cài đặt thay vì `pip`, thì bạn không cần cập nhật `pip`. 😎
+
+///
+
+Nếu bạn sử dụng `pip` để cài đặt gói (nó được cài đặt mặc định với Python), bạn nên **nâng cấp** nó lên phiên bản mới nhất.
+
+Nhiều lỗi khác nhau trong khi cài đặt gói được giải quyết chỉ bằng cách nâng cấp `pip` trước.
+
+/// tip
+
+Bạn thường làm điều này **một lần**, ngay sau khi bạn tạo môi trường ảo.
+
+///
+
+Đảm bảo rằng môi trường ảo đã được kích hoạt (với lệnh trên) và sau đó chạy:
+
+
+
+```console
+$ python -m pip install --upgrade pip
+
+---> 100%
+```
+
+
+
+## Thêm `.gitignore`
+
+Nếu bạn sử dụng **Git** (nên làm), hãy thêm một file `.gitignore` để Git bỏ qua mọi thứ trong `.venv`.
+
+/// tip
+
+Nếu bạn sử dụng
`uv` để tạo môi trường ảo, nó đã tự động làm điều này cho bạn, bạn có thể bỏ qua bước này. 😎
+
+///
+
+/// tip
+
+Làm điều này **một lần**, ngay sau khi bạn tạo môi trường ảo.
+
+///
+
+
+
+```console
+$ echo "*" > .venv/.gitignore
+```
+
+
+
+/// details | Cách lệnh hoạt động
+
+* `echo "*"`: sẽ "in" văn bản `*` trong terminal (phần tiếp theo sẽ thay đổi điều đó một chút)
+* `>`: bất kỳ văn bản nào được in ra terminal bởi lệnh trước `>` không được in ra mà thay vào đó được viết vào file ở phía bên phải của `>`
+* `.gitignore`: tên của file mà văn bản sẽ được viết vào
+
+Và `*` với Git có nghĩa là "mọi thứ". Vì vậy, nó sẽ bỏ qua mọi thứ trong thư mục `.venv`.
+
+Lệnh này sẽ tạo một file `.gitignore` với nội dung:
+
+```gitignore
+*
+```
+
+///
+
+## Cài đặt gói (packages)
+
+Sau khi kích hoạt môi trường, bạn có thể cài đặt các gói trong đó.
+
+/// tip
+
+Thực hiện điều này **một lần** khi cài đặt hoặc cập nhật gói cần thiết cho dự án của bạn.
+
+Nếu bạn cần cập nhật phiên bản hoặc thêm một gói mới, bạn sẽ **thực hiện điều này lại**.
+
+///
+
+### Cài đặt gói trực tiếp
+
+Nếu bạn cần cập nhật phiên bản hoặc thêm một gói mới, bạn sẽ **thực hiện điều này lại**.
+
+/// tip
+Để quản lý dự án tốt hơn, hãy liệt kê tất cả các gói và phiên bản cần thiết trong một file (ví dụ `requirements.txt` hoặc `pyproject.toml`).
+
+///
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install "fastapi[standard]"
+
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+Nếu bạn có
`uv`:
+
+
+
+```console
+$ uv pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+////
+
+### Cài đặt từ `requirements.txt`
+
+Nếu bạn có một tệp `requirements.txt`, bạn có thể sử dụng nó để cài đặt các gói.
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+Nếu bạn có
`uv`:
+
+
+
+```console
+$ uv pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+/// details | `requirements.txt`
+
+Một tệp `requirements.txt` với một số gói sẽ trông như thế này:
+
+```requirements.txt
+fastapi[standard]==0.113.0
+pydantic==2.8.0
+```
+
+///
+
+## Chạy Chương trình của bạn
+
+Sau khi kích hoạt môi trường ảo, bạn có thể chạy chương trình của mình, nó sẽ sử dụng Python trong môi trường ảo của bạn với các gói bạn đã cài đặt.
+
+
+
+```console
+$ python main.py
+
+Hello World
+```
+
+
+
+## Cấu hình Trình soạn thảo của bạn
+
+Nếu bạn sử dụng một trình soạn thảo, hãy đảm bảo bạn cấu hình nó để sử dụng cùng môi trường ảo mà bạn đã tạo (trình soạn thảo sẽ tự động phát hiện môi trường ảo) để bạn có thể nhận được tính năng tự động hoàn thành câu lệnh (autocomplete) và in lỗi trực tiếp trong trình soạn thảo (inline errors).
+
+Ví dụ:
+
+*
VS Code
+*
PyCharm
+
+/// tip
+
+Bạn thường chỉ cần làm điều này **một lần**, khi bạn tạo môi trường ảo.
+
+///
+
+## Huỷ kích hoạt Môi trường ảo
+
+Khi bạn hoàn tất việc làm trên dự án của bạn, bạn có thể **huỷ kích hoạt** môi trường ảo.
+
+
+
+```console
+$ deactivate
+```
+
+
+
+Như vậy, khi bạn chạy `python`, nó sẽ không chạy từ môi trường ảo đó với các gói đã cài đặt.
+
+## Sẵn sàng để Làm việc
+
+Bây giờ bạn đã sẵn sàng để làm việc trên dự án của mình rồi đấy.
+
+/// tip
+
+Bạn muốn hiểu tất cả những gì ở trên?
+
+Tiếp tục đọc. 👇🤓
+
+///
+
+## Tại sao cần Môi trường ảo
+
+Để làm việc với FastAPI, bạn cần cài đặt
Python.
+
+Sau đó, bạn sẽ cần **cài đặt** FastAPI và bất kỳ **gói** nào mà bạn muốn sử dụng.
+
+Để cài đặt gói, bạn thường sử dụng lệnh `pip` có sẵn với Python (hoặc các phiên bản tương tự).
+
+Tuy nhiên, nếu bạn sử dụng `pip` trực tiếp, các gói sẽ được cài đặt trong **môi trường Python toàn cục** của bạn (phần cài đặt toàn cục của Python).
+
+### Vấn đề
+
+Vậy, vấn đề gì khi cài đặt gói trong môi trường Python toàn cục?
+
+Trong một vài thời điểm, bạn sẽ phải viết nhiều chương trình khác nhau phụ thuộc vào **các gói khác nhau**. Và một số dự án bạn thực hiện lại phụ thuộc vào **các phiên bản khác nhau** của cùng một gói. 😱
+
+Ví dụ, bạn có thể tạo một dự án được gọi là `philosophers-stone`, chương trình này phụ thuộc vào một gói khác được gọi là **`harry`, sử dụng phiên bản `1`**. Vì vậy, bạn cần cài đặt `harry`.
+
+```mermaid
+flowchart LR
+ stone(philosophers-stone) -->|phụ thuộc| harry-1[harry v1]
+```
+
+Sau đó, vào một vài thời điểm sau, bạn tạo một dự án khác được gọi là `prisoner-of-azkaban`, và dự án này cũng phụ thuộc vào `harry`, nhưng dự án này cần **`harry` phiên bản `3`**.
+
+```mermaid
+flowchart LR
+ azkaban(prisoner-of-azkaban) --> |phụ thuộc| harry-3[harry v3]
+```
+
+Bây giờ, vấn đề là, nếu bạn cài đặt các gói toàn cục (trong môi trường toàn cục) thay vì trong một **môi trường ảo cục bộ**, bạn sẽ phải chọn phiên bản `harry` nào để cài đặt.
+
+Nếu bạn muốn chạy `philosophers-stone` bạn sẽ cần phải cài đặt `harry` phiên bản `1`, ví dụ với:
+
+
+
+```console
+$ pip install "harry==1"
+```
+
+
+
+Và sau đó bạn sẽ có `harry` phiên bản `1` được cài đặt trong môi trường Python toàn cục của bạn.
+
+```mermaid
+flowchart LR
+ subgraph global[môi trường toàn cục]
+ harry-1[harry v1]
+ end
+ subgraph stone-project[dự án philosophers-stone ]
+ stone(philosophers-stone) -->|phụ thuộc| harry-1
+ end
+```
+
+Nhưng sau đó, nếu bạn muốn chạy `prisoner-of-azkaban`, bạn sẽ cần phải gỡ bỏ `harry` phiên bản `1` và cài đặt `harry` phiên bản `3` (hoặc chỉ cần cài đặt phiên bản `3` sẽ tự động gỡ bỏ phiên bản `1`).
+
+
+
+```console
+$ pip install "harry==3"
+```
+
+
+
+Và sau đó bạn sẽ có `harry` phiên bản `3` được cài đặt trong môi trường Python toàn cục của bạn.
+
+Và nếu bạn cố gắng chạy `philosophers-stone` lại, có khả năng nó sẽ **không hoạt động** vì nó cần `harry` phiên bản `1`.
+
+```mermaid
+flowchart LR
+ subgraph global[môi trường toàn cục]
+ harry-1[
harry v1]
+ style harry-1 fill:#ccc,stroke-dasharray: 5 5
+ harry-3[harry v3]
+ end
+ subgraph stone-project[dự án philosophers-stone ]
+ stone(philosophers-stone) -.-x|⛔️| harry-1
+ end
+ subgraph azkaban-project[dự án prisoner-of-azkaban ]
+ azkaban(prisoner-of-azkaban) --> |phụ thuộc| harry-3
+ end
+```
+
+/// tip
+
+Mặc dù các gói Python thường cố gắng **tránh các thay đổi làm hỏng code** trong **phiên bản mới**, nhưng để đảm bảo an toàn, bạn nên chủ động cài đặt phiên bản mới và chạy kiểm thử để xác nhận mọi thứ vẫn hoạt động đúng.
+
+///
+
+Bây giờ, hãy hình dung về **nhiều** gói khác nhau mà tất cả các dự án của bạn phụ thuộc vào. Rõ ràng rất khó để quản lý. Điều này dẫn tới việc là bạn sẽ có nhiều dự án với **các phiên bản không tương thích** của các gói, và bạn có thể không biết tại sao một số thứ không hoạt động.
+
+Hơn nữa, tuỳ vào hệ điều hành của bạn (vd Linux, Windows, macOS), có thể đã có Python được cài đặt sẵn. Trong trường hợp ấy, một vài gói nhiều khả năng đã được cài đặt trước với các phiên bản **cần thiết cho hệ thống của bạn**. Nếu bạn cài đặt các gói trong môi trường Python toàn cục, bạn có thể sẽ **phá vỡ** một số chương trình đã được cài đặt sẵn cùng hệ thống.
+
+## Nơi các Gói được Cài đặt
+
+Khi bạn cài đặt Python, nó sẽ tạo ra một vài thư mục và tệp trong máy tính của bạn.
+
+Một vài thư mục này là những thư mục chịu trách nhiệm có tất cả các gói bạn cài đặt.
+
+Khi bạn chạy:
+
+
+
+```console
+// Đừng chạy lệnh này ngay, đây chỉ là một ví dụ 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+Lệnh này sẽ tải xuống một tệp nén với mã nguồn FastAPI, thường là từ
PyPI.
+
+Nó cũng sẽ **tải xuống** các tệp cho các gói khác mà FastAPI phụ thuộc vào.
+
+Sau đó, nó sẽ **giải nén** tất cả các tệp đó và đưa chúng vào một thư mục trong máy tính của bạn.
+
+Mặc định, nó sẽ đưa các tệp đã tải xuống và giải nén vào thư mục được cài đặt cùng Python của bạn, đó là **môi trường toàn cục**.
+
+## Những Môi trường ảo là gì?
+
+Cách giải quyết cho vấn đề có tất cả các gói trong môi trường toàn cục là sử dụng một **môi trường ảo cho mỗi dự án** bạn làm việc.
+
+Một môi trường ảo là một **thư mục**, rất giống với môi trường toàn cục, trong đó bạn có thể cài đặt các gói cho một dự án.
+
+Vì vậy, mỗi dự án sẽ có một môi trường ảo riêng của nó (thư mục `.venv`) với các gói riêng của nó.
+
+```mermaid
+flowchart TB
+ subgraph stone-project[dự án philosophers-stone ]
+ stone(philosophers-stone) --->|phụ thuộc| harry-1
+ subgraph venv1[.venv]
+ harry-1[harry v1]
+ end
+ end
+ subgraph azkaban-project[dự án prisoner-of-azkaban ]
+ azkaban(prisoner-of-azkaban) --->|phụ thuộc| harry-3
+ subgraph venv2[.venv]
+ harry-3[harry v3]
+ end
+ end
+ stone-project ~~~ azkaban-project
+```
+
+## Kích hoạt Môi trường ảo nghĩa là gì
+
+Khi bạn kích hoạt một môi trường ảo, ví dụ với:
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+Nếu bạn sử dụng Bash cho Windows (ví dụ
Git Bash):
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+Lệnh này sẽ tạo hoặc sửa đổi một số [biến môi trường](environment-variables.md){.internal-link target=_blank} mà sẽ được sử dụng cho các lệnh tiếp theo.
+
+Một trong số đó là biến `PATH`.
+
+/// tip
+
+Bạn có thể tìm hiểu thêm về biến `PATH` trong [Biến môi trường](environment-variables.md#path-environment-variable){.internal-link target=_blank} section.
+
+///
+
+Kích hoạt môi trường ảo thêm đường dẫn `.venv/bin` (trên Linux và macOS) hoặc `.venv\Scripts` (trên Windows) vào biến `PATH`.
+
+Giả sử rằng trước khi kích hoạt môi trường, biến `PATH` như sau:
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Nghĩa là hệ thống sẽ tìm kiếm chương trình trong:
+
+* `/usr/bin`
+* `/bin`
+* `/usr/sbin`
+* `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Windows\System32
+```
+
+Nghĩa là hệ thống sẽ tìm kiếm chương trình trong:
+
+* `C:\Windows\System32`
+
+////
+
+Sau khi kích hoạt môi trường ảo, biến `PATH` sẽ như sau:
+
+//// tab | Linux, macOS
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Nghĩa là hệ thống sẽ bắt đầu tìm kiếm chương trình trong:
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin
+```
+
+trước khi tìm kiếm trong các thư mục khác.
+
+Vì vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong:
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+và sử dụng chương trình đó.
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
+```
+
+Nghĩa là hệ thống sẽ bắt đầu tìm kiếm chương trình trong:
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts
+```
+
+trước khi tìm kiếm trong các thư mục khác.
+
+Vì vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong:
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+và sử dụng chương trình đó.
+
+////
+
+Một chi tiết quan trọng là nó sẽ đưa địa chỉ của môi trường ảo vào **đầu** của biến `PATH`. Hệ thống sẽ tìm kiếm nó **trước** khi tìm kiếm bất kỳ Python nào khác có sẵn. Vì vậy, khi bạn chạy `python`, nó sẽ sử dụng Python **từ môi trường ảo** thay vì bất kỳ Python nào khác (ví dụ, Python từ môi trường toàn cục).
+
+Kích hoạt một môi trường ảo cũng thay đổi một vài thứ khác, nhưng đây là một trong những điều quan trọng nhất mà nó thực hiện.
+
+## Kiểm tra một Môi trường ảo
+
+Khi bạn kiểm tra một môi trường ảo đã được kích hoạt chưa, ví dụ với:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+
+Điều đó có nghĩa là chương trình `python` sẽ được sử dụng là chương trình **trong môi trường ảo**.
+
+Bạn sử dụng `which` trên Linux và macOS và `Get-Command` trên Windows PowerShell.
+
+Cách hoạt động của lệnh này là nó sẽ đi và kiểm tra biến `PATH`, đi qua **mỗi đường dẫn theo thứ tự**, tìm kiếm chương trình được gọi là `python`. Khi nó tìm thấy nó, nó sẽ **hiển thị cho bạn đường dẫn** đến chương trình đó.
+
+Điều quan trọng nhất là khi bạn gọi `python`, đó chính là chương trình `python` được thực thi.
+
+Vì vậy, bạn có thể xác nhận nếu bạn đang ở trong môi trường ảo đúng.
+
+/// tip
+
+Dễ dàng kích hoạt một môi trường ảo, cài đặt Python, và sau đó **chuyển đến một dự án khác**.
+
+Và dự án thứ hai **sẽ không hoạt động** vì bạn đang sử dụng **Python không đúng**, từ một môi trường ảo cho một dự án khác.
+
+Thật tiện lợi khi có thể kiểm tra `python` nào đang được sử dụng 🤓
+
+///
+
+## Tại sao lại Huỷ kích hoạt một Môi trường ảo
+
+Ví dụ, bạn có thể làm việc trên một dự án `philosophers-stone`, **kích hoạt môi trường ảo**, cài đặt các gói và làm việc với môi trường ảo đó.
+
+Sau đó, bạn muốn làm việc trên **dự án khác** `prisoner-of-azkaban`.
+
+Bạn đi đến dự án đó:
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+```
+
+
+
+Nếu bạn không tắt môi trường ảo cho `philosophers-stone`, khi bạn chạy `python` trong terminal, nó sẽ cố gắng sử dụng Python từ `philosophers-stone`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+$ python main.py
+
+// Lỗi khi import sirius, nó không được cài đặt 😱
+Traceback (most recent call last):
+ File "main.py", line 1, in
+ import sirius
+```
+
+
+
+Nếu bạn huỷ kích hoạt môi trường ảo hiện tại và kích hoạt môi trường ảo mới cho `prisoner-of-azkaban`, khi bạn chạy `python`, nó sẽ sử dụng Python từ môi trường ảo trong `prisoner-of-azkaban`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// Bạn không cần phải ở trong thư mục trước để huỷ kích hoạt, bạn có thể làm điều đó ở bất kỳ đâu, ngay cả sau khi đi đến dự án khác 😎
+$ deactivate
+
+// Kích hoạt môi trường ảo trong prisoner-of-azkaban/.venv 🚀
+$ source .venv/bin/activate
+
+// Bây giờ khi bạn chạy python, nó sẽ tìm thấy gói sirius được cài đặt trong môi trường ảo này ✨
+$ python main.py
+
+I solemnly swear 🐺
+
+(Tôi long trọng thề 🐺 - câu này được lấy từ Harry Potter, chú thích của người dịch)
+```
+
+
+
+## Các cách làm tương tự
+
+Đây là một hướng dẫn đơn giản để bạn có thể bắt đầu và hiểu cách mọi thứ hoạt động **bên trong**.
+
+Có nhiều **cách khác nhau** để quản lí các môi trường ảo, các gói phụ thuộc (requirements), và các dự án.
+
+Một khi bạn đã sẵn sàng và muốn sử dụng một công cụ để **quản lí cả dự án**, các gói phụ thuộc, các môi trường ảo, v.v. Tôi sẽ khuyên bạn nên thử
uv.
+
+`uv` có thể làm nhiều thứ, chẳng hạn:
+
+* **Cài đặt Python** cho bạn, bao gồm nhiều phiên bản khác nhau
+* Quản lí **các môi trường ảo** cho các dự án của bạn
+* Cài đặt **các gói (packages)**
+* Quản lí **các thành phần phụ thuộc và phiên bản** của các gói cho dự án của bạn
+* Đảm bảo rằng bạn có một **tập hợp chính xác** các gói và phiên bản để cài đặt, bao gồm các thành phần phụ thuộc của chúng, để bạn có thể đảm bảo rằng bạn có thể chạy dự án của bạn trong sản xuất chính xác như trong máy tính của bạn trong khi phát triển, điều này được gọi là **locking**
+* Và còn nhiều thứ khác nữa
+
+## Kết luận
+
+Nếu bạn đã đọc và hiểu hết những điều này, khá chắc là bây giờ bạn đã **biết nhiều hơn** về môi trường ảo so với kha khá lập trình viên khác đấy. 🤓
+
+Những hiểu biết chi tiết này có thể sẽ hữu ích với bạn trong tương lai khi mà bạn cần gỡ lỗi một vài thứ phức tạp, và bạn đã có những hiểu biết về **ngọn ngành gốc rễ cách nó hoạt động**. 😎
diff --git a/docs/vi/mkdocs.yml b/docs/vi/mkdocs.yml
new file mode 100644
index 000000000..de18856f4
--- /dev/null
+++ b/docs/vi/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/yo/docs/index.md b/docs/yo/docs/index.md
new file mode 100644
index 000000000..d6aa78b3d
--- /dev/null
+++ b/docs/yo/docs/index.md
@@ -0,0 +1,474 @@
+# FastAPI
+
+
+
+
+
+
+
+ Ìlànà wẹ́ẹ́bù FastAPI, iṣẹ́ gíga, ó rọrùn láti kọ̀, o yára láti kóòdù, ó sì ṣetán fún iṣelọpọ ní lílo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+**Àkọsílẹ̀**:
https://fastapi.tiangolo.com
+
+**Orisun Kóòdù**:
https://github.com/fastapi/fastapi
+
+---
+
+FastAPI jẹ́ ìgbàlódé, tí ó yára (iṣẹ-giga), ìlànà wẹ́ẹ́bù fún kikọ àwọn API pẹ̀lú Python èyí tí ó da lori àwọn ìtọ́kasí àmì irúfẹ́ Python.
+
+Àwọn ẹya pàtàkì ni:
+
+* **Ó yára**: Iṣẹ tí ó ga púpọ̀, tí ó wa ni ibamu pẹ̀lú **NodeJS** àti **Go** (ọpẹ si Starlette àti Pydantic). [Ọkan nínú àwọn ìlànà Python ti o yára jùlọ ti o wa](#isesi).
+* **Ó yára láti kóòdù**: O mu iyara pọ si láti kọ àwọn ẹya tuntun kóòdù nipasẹ "Igba ìdá ọgọ́rùn-ún" (i.e. 200%) si "ọ̀ọ́dúrún ìdá ọgọ́rùn-ún" (i.e. 300%).
+* **Àìtọ́ kékeré**: O n din aṣiṣe ku bi ọgbon ìdá ọgọ́rùn-ún (i.e. 40%) ti eda eniyan (oṣiṣẹ kóòdù) fa. *
+* **Ọgbọ́n àti ìmọ̀**: Atilẹyin olootu nla.
Ìparí nibi gbogbo. Àkókò díẹ̀ nipa wíwá ibi tí ìṣòro kóòdù wà.
+* **Irọrun**: A kọ kí ó le rọrun láti lo àti láti kọ ẹkọ nínú rè. Ó máa fún ọ ní àkókò díẹ̀ látı ka àkọsílẹ.
+* **Ó kúkurú ní kikọ**: Ó dín àtúnkọ àti àtúntò kóòdù kù. Ìkéde àṣàyàn kọ̀ọ̀kan nínú rẹ̀ ní ọ̀pọ̀lọpọ̀ àwọn ìlò. O ṣe iranlọwọ láti má ṣe ní ọ̀pọ̀lọpọ̀ àṣìṣe.
+* **Ó lágbára**: Ó ń ṣe àgbéjáde kóòdù tí ó ṣetán fún ìṣelọ́pọ̀. Pẹ̀lú àkọsílẹ̀ tí ó máa ṣàlàyé ara rẹ̀ fún ẹ ní ìbáṣepọ̀ aládàáṣiṣẹ́ pẹ̀lú rè.
+* **Ajohunše/Ìtọ́kasí**: Ó da lori (àti ibamu ni kikun pẹ̀lú) àwọn ìmọ ajohunše/ìtọ́kasí fún àwọn API:
OpenAPI (èyí tí a mọ tẹlẹ si Swagger) àti
JSON Schema.
+
+
* iṣiro yi da lori àwọn idanwo tí ẹgbẹ ìdàgbàsókè FastAPI ṣe, nígbàtí wọn kọ àwọn ohun elo iṣelọpọ kóòdù pẹ̀lú rẹ.
+
+## Àwọn onígbọ̀wọ́
+
+
+
+{% if sponsors %}
+{% for sponsor in sponsors.gold -%}
+

+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+

+{% endfor %}
+{% endif %}
+
+
+
+
Àwọn onígbọ̀wọ́ míràn
+
+## Àwọn ero àti èsì
+
+"_[...] Mò ń lo **FastAPI** púpọ̀ ní lẹ́nu àìpẹ́ yìí. [...] Mo n gbero láti lo o pẹ̀lú àwọn ẹgbẹ mi fún gbogbo iṣẹ **ML wa ni Microsoft**. Diẹ nínú wọn ni afikun ti ifilelẹ àwọn ẹya ara ti ọja **Windows** wa pẹ̀lú àwọn ti **Office**._"
+
+
Kabir Khan -
Microsoft (ref)
+
+---
+
+"_A gba àwọn ohun èlò ìwé afọwọkọ **FastAPI** tí kò yí padà láti ṣẹ̀dá olùpín **REST** tí a lè béèrè lọ́wọ́ rẹ̀ láti gba **àsọtẹ́lẹ̀**. [fún Ludwig]_"
+
+
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
+
+---
+
+"_**Netflix** ni inudidun láti kede itusilẹ orisun kóòdù ti ìlànà iṣọkan **iṣakoso Ìṣòro** wa: **Ìfiránṣẹ́**! [a kọ pẹ̀lú **FastAPI**]_"
+
+
Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
+
+---
+
+"_Inú mi dùn púpọ̀ nípa **FastAPI**. Ó mú inú ẹnì dùn púpọ̀!_"
+
+
+
+---
+
+"_Ní tòótọ́, ohun tí o kọ dára ó sì tún dán. Ní ọ̀pọ̀lọpọ̀ ọ̀nà, ohun tí mo fẹ́ kí **Hug** jẹ́ nìyẹn - ó wúni lórí gan-an láti rí ẹnìkan tí ó kọ́ nǹkan bí èyí._"
+
+
+
+---
+
+"_Ti o ba n wa láti kọ ọkan **ìlànà igbalode** fún kikọ àwọn REST API, ṣayẹwo **FastAPI** [...] Ó yára, ó rọrùn láti lò, ó sì rọrùn láti kọ́[...]_"
+
+"_A ti yipada si **FastAPI** fún **APIs** wa [...] Mo lérò pé wà á fẹ́ràn rẹ̀ [...]_"
+
+
+
+---
+
+"_Ti ẹnikẹni ba n wa láti kọ iṣelọpọ API pẹ̀lú Python, èmi yóò ṣe'dúró fún **FastAPI**. Ó jẹ́ ohun tí **àgbékalẹ̀ rẹ̀ lẹ́wà**, **ó rọrùn láti lò** àti wipe ó ni **ìwọ̀n gíga**, o tí dí **bọtini paati** nínú alakọkọ API ìdàgbàsókè kikọ fún wa, àti pe o ni ipa lori adaṣiṣẹ àti àwọn iṣẹ gẹ́gẹ́ bíi Onímọ̀-ẹ̀rọ TAC tí órí Íńtánẹ́ẹ̀tì_"
+
+
Deon Pillsbury -
Cisco (ref)
+
+---
+
+## **Typer**, FastAPI ti CLIs
+
+

+
+Ti o ba n kọ ohun èlò
CLI láti ṣeé lọ nínú ohun èlò lori ebute kọmputa dipo API, ṣayẹwo
**Typer**.
+
+**Typer** jẹ́ àbúrò ìyá FastAPI kékeré. Àti pé wọ́n kọ́ láti jẹ́ **FastAPI ti CLIs**. ⌨️ 🚀
+
+## Èròjà
+
+FastAPI dúró lórí àwọn èjìká tí àwọn òmíràn:
+
+*
Starlette fún àwọn ẹ̀yà ayélujára.
+*
Pydantic fún àwọn ẹ̀yà àkójọf'áyẹ̀wò.
+
+## Fifi sórí ẹrọ
+
+
+
+```console
+$ pip install fastapi
+
+---> 100%
+```
+
+
+Iwọ yóò tún nílò olupin ASGI, fún iṣelọpọ bii
Uvicorn tabi
Hypercorn.
+
+
+
+```console
+$ pip install "uvicorn[standard]"
+
+---> 100%
+```
+
+
+
+## Àpẹẹrẹ
+
+### Ṣẹ̀dá rẹ̀
+
+* Ṣẹ̀dá fáìlì `main.py (èyí tíí ṣe, akọkọ.py)` pẹ̀lú:
+
+```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}
+```
+
+
+Tàbí lò async def
...
+
+Tí kóòdù rẹ̀ bá ń lò `async` / `await`, lò `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}
+```
+
+**Akiyesi**:
+
+Tí o kò bá mọ̀, ṣàyẹ̀wò ibi tí a ti ní _"In a hurry?"_ (i.e. _"Ní kíákíá?"_) nípa `async` and `await` nínú àkọsílẹ̀.
+
+
+
+### Mu ṣiṣẹ
+
+Mú olupin ṣiṣẹ pẹ̀lú:
+
+
+
+```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.
+```
+
+
+
+
+Nipa aṣẹ kóòdù náà uvicorn main:app --reload
...
+
+Àṣẹ `uvicorn main:app` ń tọ́ka sí:
+
+* `main`: fáìlì náà 'main.py' (Python "module").
+* `app` jẹ object( i.e. nǹkan) tí a ṣẹ̀dá nínú `main.py` pẹ̀lú ilà `app = FastAPI()`.
+* `--reload`: èyí yóò jẹ́ ki olupin tún bẹ̀rẹ̀ lẹ́hìn àwọn àyípadà kóòdù. Jọ̀wọ́, ṣe èyí fún ìdàgbàsókè kóòdù nìkan, má ṣe é ṣe lori àgbéjáde kóòdù tabi fún iṣelọpọ kóòdù.
+
+
+
+
+### Ṣayẹwo rẹ
+
+Ṣii aṣàwákiri kọ̀ǹpútà rẹ ni
http://127.0.0.1:8000/items/5?q=somequery.
+
+Ìwọ yóò sì rí ìdáhùn JSON bíi:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+O tí ṣẹ̀dá API èyí tí yóò:
+
+* Gbà àwọn ìbéèrè HTTP ni àwọn _ipa ọ̀nà_ `/` àti `/items/{item_id}`.
+* Èyí tí àwọn _ipa ọ̀nà_ (i.e. _paths_) méjèèjì gbà àwọn
iṣẹ `GET` (a tun mọ si _àwọn ọna_ HTTP).
+* Èyí tí _ipa ọ̀nà_ (i.e. _paths_) `/items/{item_id}` ní _àwọn ohun-ini ipa ọ̀nà_ tí ó yẹ kí ó jẹ́ `int` i.e. `ÒǸKÀ`.
+* Èyí tí _ipa ọ̀nà_ (i.e. _paths_) `/items/{item_id}` ní àṣàyàn `str` _àwọn ohun-ini_ (i.e. _query parameter_) `q`.
+
+### Ìbáṣepọ̀ àkọsílẹ̀ API
+
+Ní báyìí, lọ sí
http://127.0.0.1:8000/docs.
+
+Lẹ́yìn náà, iwọ yóò rí ìdáhùn àkọsílẹ̀ API tí ó jẹ́ ìbáṣepọ̀ alaifọwọyi/aládàáṣiṣẹ́ (tí a pèṣè nípaṣẹ̀
Swagger UI):
+
+
+
+### Ìdàkejì àkọsílẹ̀ API
+
+Ní báyìí, lọ sí
http://127.0.0.1:8000/redoc.
+
+Wà á rí àwọn àkọsílẹ̀ aládàáṣiṣẹ́ mìíràn (tí a pese nipasẹ
ReDoc):
+
+
+
+## Àpẹẹrẹ ìgbésókè mìíràn
+
+Ní báyìí ṣe àtúnṣe fáìlì `main.py` láti gba kókó èsì láti inú ìbéèrè `PUT`.
+
+Ní báyìí, ṣe ìkéde kókó èsì API nínú kóòdù rẹ nipa lílo àwọn ìtọ́kasí àmì irúfẹ́ Python, ọpẹ́ pàtàkìsi sí 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}
+```
+
+Olupin yóò tún ṣe àtúnṣe laifọwọyi/aládàáṣiṣẹ́ (nítorí wípé ó se àfikún `-reload` si àṣẹ kóòdù `uvicorn` lókè).
+
+### Ìbáṣepọ̀ ìgbésókè àkọsílẹ̀ API
+
+Ní báyìí, lọ sí
http://127.0.0.1:8000/docs.
+
+* Ìbáṣepọ̀ àkọsílẹ̀ API yóò ṣe imudojuiwọn àkọsílẹ̀ API laifọwọyi, pẹ̀lú kókó èsì ìdáhùn API tuntun:
+
+
+
+* Tẹ bọtini "Gbiyanju rẹ" i.e. "Try it out", yóò gbà ọ́ láàyè láti jẹ́ kí ó tẹ́ àlàyé tí ó nílò kí ó le sọ̀rọ̀ tààrà pẹ̀lú API:
+
+
+
+* Lẹhinna tẹ bọtini "Ṣiṣe" i.e. "Execute", olùmúlò (i.e. user interface) yóò sọrọ pẹ̀lú API rẹ, yóò ṣe afiranṣẹ àwọn èròjà, pàápàá jùlọ yóò gba àwọn àbájáde yóò si ṣafihan wọn loju ìbòjú:
+
+
+
+### Ìdàkejì ìgbésókè àkọsílẹ̀ API
+
+Ní báyìí, lọ sí
http://127.0.0.1:8000/redoc.
+
+* Ìdàkejì àkọsílẹ̀ API yóò ṣ'afihan ìbéèrè èròjà/pàrámítà tuntun àti kókó èsì ti API:
+
+
+
+### Àtúnyẹ̀wò
+
+Ni akopọ, ìwọ yóò kéde ni **kete** àwọn iru èròjà/pàrámítà, kókó èsì API, abbl (i.e. àti bẹbẹ lọ), bi àwọn èròjà iṣẹ.
+
+O ṣe ìyẹn pẹ̀lú irúfẹ́ àmì ìtọ́kasí ìgbàlódé Python.
+
+O ò nílò láti kọ́ síńtáàsì tuntun, ìlànà tàbí ọ̀wọ́ kíláàsì kan pàtó, abbl (i.e. àti bẹbẹ lọ).
+
+Ìtọ́kasí **Python**
+
+Fún àpẹẹrẹ, fún `int`:
+
+```Python
+item_id: int
+```
+
+tàbí fún àwòṣe `Item` tí ó nira díẹ̀ síi:
+
+```Python
+item: Item
+```
+
+... àti pẹ̀lú ìkéde kan ṣoṣo yẹn ìwọ yóò gbà:
+
+* Atilẹyin olootu, pẹ̀lú:
+ * Pipari.
+ * Àyẹ̀wò irúfẹ́ àmì ìtọ́kasí.
+* Ìfọwọ́sí àkójọf'áyẹ̀wò (i.e. data):
+ * Aṣiṣe alaifọwọyi/aládàáṣiṣẹ́ àti aṣiṣe ti ó hàn kedere nígbàtí àwọn àkójọf'áyẹ̀wò (i.e. data) kò wulo tabi tí kò fẹsẹ̀ múlẹ̀.
+ * Ìfọwọ́sí fún ohun elo JSON tí ó jìn gan-an.
+*
Ìyípadà tí input àkójọf'áyẹ̀wò: tí ó wà láti nẹtiwọọki si àkójọf'áyẹ̀wò àti irúfẹ́ àmì ìtọ́kasí Python. Ó ń ka láti:
+ * JSON.
+ * èròjà ọ̀nà tí ò gbé gbà.
+ * èròjà ìbéèrè.
+ * Àwọn Kúkì
+ * Àwọn Àkọlé
+ * Àwọn Fọọmu
+ * Àwọn Fáìlì
+*
Ìyípadà èsì àkójọf'áyẹ̀wò: yíyípadà láti àkójọf'áyẹ̀wò àti irúfẹ́ àmì ìtọ́kasí Python si nẹtiwọọki (gẹ́gẹ́ bí JSON):
+ * Yí irúfẹ́ àmì ìtọ́kasí padà (`str`, `int`, `float`, `bool`, `list`, abbl i.e. àti bèbè ló).
+ * Àwọn ohun èlò `datetime`.
+ * Àwọn ohun èlò `UUID`.
+ * Àwọn awoṣẹ́ ibi ìpamọ́ àkójọf'áyẹ̀wò.
+ * ...àti ọ̀pọ̀lọpọ̀ díẹ̀ síi.
+* Ìbáṣepọ̀ àkọsílẹ̀ API aládàáṣiṣẹ́, pẹ̀lú ìdàkejì àgbékalẹ̀-àwọn-olùmúlò (i.e user interfaces) méjì:
+ * Àgbékalẹ̀-olùmúlò Swagger.
+ * ReDoc.
+
+---
+
+Nisinsin yi, tí ó padà sí àpẹẹrẹ ti tẹ́lẹ̀, **FastAPI** yóò:
+
+* Fọwọ́ sí i pé `item_id` wà nínú ọ̀nà ìbéèrè HTTP fún `GET` àti `PUT`.
+* Fọwọ́ sí i pé `item_id` jẹ́ irúfẹ́ àmì ìtọ́kasí `int` fún ìbéèrè HTTP `GET` àti `PUT`.
+ * Tí kìí bá ṣe bẹ, oníbàárà yóò ríi àṣìṣe tí ó wúlò, kedere.
+* Ṣàyẹ̀wò bóyá ìbéèrè àṣàyàn pàrámítà kan wà tí orúkọ rẹ̀ ń jẹ́ `q` (gẹ́gẹ́ bíi `http://127.0.0.1:8000/items/foo?q=somequery`) fún ìbéèrè HTTP `GET`.
+ * Bí wọ́n ṣe kéde pàrámítà `q` pẹ̀lú `= None`, ó jẹ́ àṣàyàn (i.e optional).
+ * Láìsí `None` yóò nílò (gẹ́gẹ́ bí kókó èsì ìbéèrè HTTP ṣe wà pẹ̀lú `PUT`).
+* Fún àwọn ìbéèrè HTTP `PUT` sí `/items/{item_id}`, kà kókó èsì ìbéèrè HTTP gẹ́gẹ́ bí JSON:
+ * Ṣàyẹ̀wò pé ó ní àbùdá tí ó nílò èyí tíí ṣe `name` i.e. `orúkọ` tí ó yẹ kí ó jẹ́ `str`.
+ * Ṣàyẹ̀wò pé ó ní àbùdá tí ó nílò èyí tíí ṣe `price` i.e. `iye` tí ó gbọ́dọ̀ jẹ́ `float`.
+ * Ṣàyẹ̀wò pé ó ní àbùdá àṣàyàn `is_offer`, tí ó yẹ kí ó jẹ́ `bool`, tí ó bá wà níbẹ̀.
+ * Gbogbo èyí yóò tún ṣiṣẹ́ fún àwọn ohun èlò JSON tí ó jìn gidi gan-an.
+* Yìí padà láti àti sí JSON lai fi ọwọ́ yi.
+* Ṣe àkọsílẹ̀ ohun gbogbo pẹ̀lú OpenAPI, èyí tí yóò wà ní lílo nípaṣẹ̀:
+ * Àwọn ètò àkọsílẹ̀ ìbáṣepọ̀.
+ * Aládàáṣiṣẹ́ oníbárà èlètò tíí ṣẹ̀dá kóòdù, fún ọ̀pọ̀lọpọ̀ àwọn èdè.
+* Pese àkọsílẹ̀ òní ìbáṣepọ̀ ti àwọn àgbékalẹ̀ ayélujára méjì tààrà.
+
+---
+
+A ń ṣẹ̀ṣẹ̀ ń mú ẹyẹ bọ́ làpò ní, ṣùgbọ́n ó ti ni òye bí gbogbo rẹ̀ ṣe ń ṣiṣẹ́.
+
+Gbiyanju láti yí ìlà padà pẹ̀lú:
+
+```Python
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+...láti:
+
+```Python
+ ... "item_name": item.name ...
+```
+
+...ṣí:
+
+```Python
+ ... "item_price": item.price ...
+```
+
+.. kí o sì wo bí olóòtú rẹ yóò ṣe parí àwọn àbùdá náà fúnra rẹ̀, yóò sì mọ irúfẹ́ wọn:
+
+
+
+Fún àpẹẹrẹ pípé síi pẹ̀lú àwọn àbùdá mìíràn, wo
Ìdánilẹ́kọ̀ọ́ - Ìtọ́sọ́nà Olùmúlò.
+
+**Itaniji gẹ́gẹ́ bí isọ'ye**: ìdánilẹ́kọ̀ọ́ - itọsọna olùmúlò pẹ̀lú:
+
+* Ìkéde àṣàyàn **pàrámítà** láti àwọn oriṣiriṣi ibòmíràn gẹ́gẹ́ bíi: àwọn **àkọlé èsì API**, **kúkì**, **ààyè fọọmu**, àti **fáìlì**.
+* Bíi ó ṣe lé ṣètò **àwọn ìdíwọ́ ìfọwọ́sí** bí `maximum_length` tàbí `regex`.
+* Ó lágbára púpọ̀ ó sì rọrùn láti lo ètò **
Àfikún Ìgbẹ́kẹ̀lé Kóòdù**.
+* Ààbò àti ìfọwọ́sowọ́pọ̀, pẹ̀lú àtìlẹ́yìn fún **OAuth2** pẹ̀lú **àmì JWT** àti **HTTP Ipilẹ ìfọwọ́sowọ́pọ̀**.
+* Àwọn ìlànà ìlọsíwájú (ṣùgbọ́n tí ó rọrùn bákan náà) fún ìkéde **àwọn àwòṣe JSON tó jinlẹ̀** (ọpẹ́ pàtàkìsi sí Pydantic).
+* Iṣọpọ **GraphQL** pẹ̀lú
Strawberry àti àwọn ohun èlò ìwé kóòdù afọwọkọ mìíràn tí kò yí padà.
+* Ọpọlọpọ àwọn àfikún àwọn ẹ̀yà (ọpẹ́ pàtàkìsi sí Starlette) bí:
+ * **WebSockets**
+ * àwọn ìdánwò tí ó rọrùn púpọ̀ lórí HTTPX àti `pytest`
+ * **CORS**
+ * **Cookie Sessions**
+ * ...àti síwájú síi.
+
+## Ìṣesí
+
+Àwọn àlá TechEmpower fi hàn pé **FastAPI** ń ṣiṣẹ́ lábẹ́ Uvicorn gẹ́gẹ́ bí
ọ̀kan lára àwọn ìlànà Python tí ó yára jùlọ tí ó wà, ní ìsàlẹ̀ Starlette àti Uvicorn fúnra wọn (tí FastAPI ń lò fúnra rẹ̀). (*)
+
+Láti ní òye síi nípa rẹ̀, wo abala àwọn
Àlá.
+
+## Àṣàyàn Àwọn Àfikún Ìgbẹ́kẹ̀lé Kóòdù
+
+Èyí tí Pydantic ń lò:
+
+*
email-validator
- fún ifọwọsi ímeèlì.
+*
pydantic-settings
- fún ètò ìsàkóso.
+*
pydantic-extra-types
- fún àfikún oríṣi láti lọ pẹ̀lú Pydantic.
+
+Èyí tí Starlette ń lò:
+
+*
httpx
- Nílò tí ó bá fẹ́ láti lọ `TestClient`.
+*
jinja2
- Nílò tí ó bá fẹ́ láti lọ iṣeto awoṣe aiyipada.
+*
python-multipart
- Nílò tí ó bá fẹ́ láti ṣe àtìlẹ́yìn fún
"àyẹ̀wò" fọọmu, pẹ̀lú `request.form()`.
+*
itsdangerous
- Nílò fún àtìlẹ́yìn `SessionMiddleware`.
+*
pyyaml
- Nílò fún àtìlẹ́yìn Starlette's `SchemaGenerator` (ó ṣe ṣe kí ó má nílò rẹ̀ fún FastAPI).
+
+Èyí tí FastAPI / Starlette ń lò:
+
+*
uvicorn
- Fún olupin tí yóò sẹ́ àmúyẹ àti tí yóò ṣe ìpèsè fún iṣẹ́ rẹ tàbí ohun èlò rẹ.
+*
orjson
- Nílò tí ó bá fẹ́ láti lọ `ORJSONResponse`.
+*
ujson
- Nílò tí ó bá fẹ́ láti lọ `UJSONResponse`.
+
+Ó lè fi gbogbo àwọn wọ̀nyí sórí ẹrọ pẹ̀lú `pip install "fastapi[all]"`.
+
+## Iwe-aṣẹ
+
+Iṣẹ́ yìí ni iwe-aṣẹ lábẹ́ àwọn òfin tí iwe-aṣẹ MIT.
diff --git a/docs/yo/mkdocs.yml b/docs/yo/mkdocs.yml
new file mode 100644
index 000000000..de18856f4
--- /dev/null
+++ b/docs/yo/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/zh-hant/docs/about/index.md b/docs/zh-hant/docs/about/index.md
new file mode 100644
index 000000000..5dcee68f2
--- /dev/null
+++ b/docs/zh-hant/docs/about/index.md
@@ -0,0 +1,3 @@
+# 關於 FastAPI
+
+關於 FastAPI、其設計、靈感來源等更多資訊。 🤓
diff --git a/docs/zh-hant/docs/async.md b/docs/zh-hant/docs/async.md
new file mode 100644
index 000000000..6ab75d2ab
--- /dev/null
+++ b/docs/zh-hant/docs/async.md
@@ -0,0 +1,442 @@
+# 並行與 async / await
+
+有關*路徑操作函式*的 `async def` 語法的細節與非同步 (asynchronous) 程式碼、並行 (concurrency) 與平行 (parallelism) 的一些背景知識。
+
+## 趕時間嗎?
+
+
TL;DR:
+
+如果你正在使用要求你以 `await` 語法呼叫的第三方函式庫,例如:
+
+```Python
+results = await some_library()
+```
+
+然後,使用 `async def` 宣告你的*路徑操作函式*:
+
+
+```Python hl_lines="2"
+@app.get('/')
+async def read_results():
+ results = await some_library()
+ return results
+```
+
+/// note | 注意
+
+你只能在 `async def` 建立的函式內使用 `await`。
+
+///
+
+---
+
+如果你使用的是第三方函式庫並且它需要與某些外部資源(例如資料庫、API、檔案系統等)進行通訊,但不支援 `await`(目前大多數資料庫函式庫都是這樣),在這種情況下,你可以像平常一樣使用 `def` 宣告*路徑操作函式*,如下所示:
+
+```Python hl_lines="2"
+@app.get('/')
+def results():
+ results = some_library()
+ return results
+```
+
+---
+
+如果你的應用程式不需要與外部資源進行任何通訊並等待其回應,請使用 `async def`。
+
+---
+
+如果你不確定該用哪個,直接用 `def` 就好。
+
+---
+
+**注意**:你可以在*路徑操作函式*中混合使用 `def` 和 `async def` ,並使用最適合你需求的方式來定義每個函式。FastAPI 會幫你做正確的處理。
+
+無論如何,在上述哪種情況下,FastAPI 仍將以非同步方式運行,並且速度非常快。
+
+但透過遵循上述步驟,它將能進行一些效能最佳化。
+
+## 技術細節
+
+現代版本的 Python 支援使用 **「協程」** 的 **`async` 和 `await`** 語法來寫 **「非同步程式碼」**。
+
+接下來我們逐一介紹:
+
+* **非同步程式碼**
+* **`async` 和 `await`**
+* **協程**
+
+## 非同步程式碼
+
+非同步程式碼僅意味著程式語言 💬 有辦法告訴電腦/程式 🤖 在程式碼中的某個點,它 🤖 需要等待某些事情完成。讓我們假設這些事情被稱為「慢速檔案」📝。
+
+因此,在等待「慢速檔案」📝 完成的這段時間,電腦可以去處理一些其他工作。
+
+接著程式 🤖 會在有空檔時回來查看是否有等待的工作已經完成,並執行必要的後續操作。
+
+接下來,它 🤖 完成第一個工作(例如我們的「慢速檔案」📝)並繼續執行相關的所有操作。
+這個「等待其他事情」通常指的是一些相對較慢的(與處理器和 RAM 記憶體的速度相比)的
I/O 操作,比如說:
+
+* 透過網路傳送來自用戶端的資料
+* 從網路接收來自用戶端的資料
+* 從磁碟讀取檔案內容
+* 將內容寫入磁碟
+* 遠端 API 操作
+* 資料庫操作
+* 資料庫查詢
+* 等等
+
+由於大部分的執行時間都消耗在等待
I/O 操作上,因此這些操作被稱為 "I/O 密集型" 操作。
+
+之所以稱為「非同步」,是因為電腦/程式不需要與那些耗時的任務「同步」,等待任務完成的精確時間,然後才能取得結果並繼續工作。
+
+相反地,非同步系統在任務完成後,可以讓任務稍微等一下(幾微秒),等待電腦/程式完成手頭上的其他工作,然後再回來取得結果繼續進行。
+
+相對於「非同步」(asynchronous),「同步」(synchronous)也常被稱作「順序性」(sequential),因為電腦/程式會依序執行所有步驟,即便這些步驟涉及等待,才會切換到其他任務。
+
+### 並行與漢堡
+
+上述非同步程式碼的概念有時也被稱為「並行」,它不同於「平行」。
+
+並行和平行都與 "不同的事情或多或少同時發生" 有關。
+
+但並行和平行之間的細節是完全不同的。
+
+為了理解差異,請想像以下有關漢堡的故事:
+
+### 並行漢堡
+
+你和你的戀人去速食店,排隊等候時,收銀員正在幫排在你前面的人點餐。😍
+
+

+
+輪到你了,你給你與你的戀人點了兩個豪華漢堡。🍔🍔
+
+

+
+收銀員通知廚房準備你的漢堡(儘管他們還在為前面其他顧客準備食物)。
+
+

+
+之後你完成付款。💸
+
+收銀員給你一個號碼牌。
+
+

+
+在等待漢堡的同時,你可以與戀人選一張桌子,然後坐下來聊很長一段時間(因為漢堡十分豪華,準備特別費工。)
+
+這段時間,你還能欣賞你的戀人有多麼的可愛、聰明與迷人。✨😍✨
+
+

+
+當你和戀人邊聊天邊等待時,你會不時地查看櫃檯上的顯示的號碼,確認是否已經輪到你了。
+
+然後在某個時刻,終於輪到你了。你走到櫃檯,拿了漢堡,然後回到桌子上。
+
+

+
+你和戀人享用這頓大餐,整個過程十分開心✨
+
+

+
+/// info
+
+漂亮的插畫來自
Ketrina Thompson. 🎨
+
+///
+
+---
+
+想像你是故事中的電腦或程式 🤖。
+
+當你排隊時,你在放空😴,等待輪到你,沒有做任何「生產性」的事情。但這沒關係,因為收銀員只是接單(而不是準備食物),所以排隊速度很快。
+
+然後,當輪到你時,你開始做真正「有生產力」的工作,處理菜單,決定你想要什麼,替戀人選擇餐點,付款,確認你給了正確的帳單或信用卡,檢查你是否被正確收費,確認訂單中的項目是否正確等等。
+
+但是,即使你還沒有拿到漢堡,你與收銀員的工作已經「暫停」了 ⏸,因為你必須等待 🕙 漢堡準備好。
+
+但當你離開櫃檯,坐到桌子旁,拿著屬於你的號碼等待時,你可以把注意力 🔀 轉移到戀人身上,並開始「工作」⏯ 🤓——也就是和戀人調情 😍。這時你又開始做一些非常「有生產力」的事情。
+
+接著,收銀員 💁 將你的號碼顯示在櫃檯螢幕上,並告訴你「漢堡已經做好了」。但你不會瘋狂地立刻跳起來,因為顯示的號碼變成了你的。你知道沒有人會搶走你的漢堡,因為你有自己的號碼,他們也有他們的號碼。
+
+所以你會等戀人講完故事(完成當前的工作 ⏯/正在進行的任務 🤓),然後微笑著溫柔地說你要去拿漢堡了 ⏸。
+
+然後你走向櫃檯 🔀,回到已經完成的最初任務 ⏯,拿起漢堡,說聲謝謝,並帶回桌上。這就結束了與櫃檯的互動步驟/任務 ⏹,接下來會產生一個新的任務,「吃漢堡」 🔀 ⏯,而先前的「拿漢堡」任務已經完成了 ⏹。
+
+### 平行漢堡
+
+現在,讓我們來想像這裡不是「並行漢堡」,而是「平行漢堡」。
+
+你和戀人一起去吃平行的速食餐。
+
+你們站在隊伍中,前面有幾位(假設有 8 位)既是收銀員又是廚師的員工,他們同時接單並準備餐點。
+
+所有排在你前面的人都在等著他們的漢堡準備好後才會離開櫃檯,因為每位收銀員在接完單後,馬上會去準備漢堡,然後才回來處理下一個訂單。
+
+

+
+終於輪到你了,你為你和你的戀人點了兩個非常豪華的漢堡。
+
+你付款了 💸。
+
+

+
+收銀員走進廚房準備食物。
+
+你站在櫃檯前等待 🕙,以免其他人先拿走你的漢堡,因為這裡沒有號碼牌系統。
+
+

+
+由於你和戀人都忙著不讓別人搶走你的漢堡,等漢堡準備好時,你根本無法專心和戀人互動。😞
+
+這是「同步」(synchronous)工作,你和收銀員/廚師 👨🍳 是「同步化」的。你必須等到 🕙 收銀員/廚師 👨🍳 完成漢堡並交給你的那一刻,否則別人可能會拿走你的餐點。
+
+

+
+最終,經過長時間的等待 🕙,收銀員/廚師 👨🍳 拿著漢堡回來了。
+
+

+
+你拿著漢堡,和你的戀人回到餐桌。
+
+你們僅僅是吃完漢堡,然後就結束了。⏹
+
+

+
+整個過程中沒有太多的談情說愛,因為大部分時間 🕙 都花在櫃檯前等待。😞
+
+/// info
+
+漂亮的插畫來自
Ketrina Thompson. 🎨
+
+///
+
+---
+
+在這個平行漢堡的情境下,你是一個程式 🤖 且有兩個處理器(你和戀人),兩者都在等待 🕙 並專注於等待櫃檯上的餐點 🕙,等待的時間非常長。
+
+這家速食店有 8 個處理器(收銀員/廚師)。而並行漢堡店可能只有 2 個處理器(一位收銀員和一位廚師)。
+
+儘管如此,最終的體驗並不是最理想的。😞
+
+---
+
+這是與漢堡類似的故事。🍔
+
+一個更「現實」的例子,想像一間銀行。
+
+直到最近,大多數銀行都有多位出納員 👨💼👨💼👨💼👨💼,以及一條長長的隊伍 🕙🕙🕙🕙🕙🕙🕙🕙。
+
+所有的出納員都在一個接一個地滿足每位客戶的所有需求 👨💼⏯。
+
+你必須長時間排隊 🕙,不然就會失去機會。
+
+所以,你不會想帶你的戀人 😍 一起去銀行辦事 🏦。
+
+### 漢堡結論
+
+在「和戀人一起吃速食漢堡」的這個場景中,由於有大量的等待 🕙,使用並行系統 ⏸🔀⏯ 更有意義。
+
+這也是大多數 Web 應用的情況。
+
+許多用戶正在使用你的應用程式,而你的伺服器則在等待 🕙 這些用戶不那麼穩定的網路來傳送請求。
+
+接著,再次等待 🕙 回應。
+
+這種「等待」 🕙 通常以微秒來衡量,但累加起來,最終還是花費了很多等待時間。
+
+這就是為什麼對於 Web API 來說,使用非同步程式碼 ⏸🔀⏯ 是非常有意義的。
+
+這種類型的非同步性正是 NodeJS 成功的原因(儘管 NodeJS 不是平行的),這也是 Go 語言作為程式語言的一個強大優勢。
+
+這與 **FastAPI** 所能提供的性能水平相同。
+
+你可以同時利用並行性和平行性,進一步提升效能,這比大多數已測試的 NodeJS 框架都更快,並且與 Go 語言相當,而 Go 是一種更接近 C 的編譯語言(
感謝 Starlette)。
+
+### 並行比平行更好嗎?
+
+不是的!這不是故事的本意。
+
+並行與平行不同。並行在某些 **特定** 的需要大量等待的情境下表現更好。正因如此,並行在 Web 應用程式開發中通常比平行更有優勢。但並不是所有情境都如此。
+
+因此,為了平衡報導,想像下面這個短故事
+
+> 你需要打掃一間又大又髒的房子。
+
+*是的,這就是全部的故事。*
+
+---
+
+這裡沒有任何需要等待 🕙 的地方,只需要在房子的多個地方進行大量的工作。
+
+你可以像漢堡的例子那樣輪流進行,先打掃客廳,再打掃廚房,但由於你不需要等待 🕙 任何事情,只需要持續地打掃,輪流並不會影響任何結果。
+
+無論輪流執行與否(並行),你都需要相同的工時完成任務,同時需要執行相同工作量。
+
+但是,在這種情境下,如果你可以邀請8位前收銀員/廚師(現在是清潔工)來幫忙,每個人(加上你)負責房子的某個區域,這樣你就可以 **平行** 地更快完成工作。
+
+在這個場景中,每個清潔工(包括你)都是一個處理器,完成工作的一部分。
+
+由於大多數的執行時間都花在實際的工作上(而不是等待),而電腦中的工作由
CPU 完成,因此這些問題被稱為「CPU 密集型」。
+
+---
+
+常見的 CPU 密集型操作範例包括那些需要進行複雜數學計算的任務。
+
+例如:
+
+* **音訊**或**圖像處理**;
+* **電腦視覺**:一張圖片由數百萬個像素組成,每個像素有 3 個值/顏色,處理這些像素通常需要同時進行大量計算;
+* **機器學習**: 通常需要大量的「矩陣」和「向量」運算。想像一個包含數字的巨大電子表格,並所有的數字同時相乘;
+* **深度學習**: 這是機器學習的子領域,同樣適用。只不過這不僅僅是一張數字表格,而是大量的數據集合,並且在很多情況下,你會使用特殊的處理器來構建或使用這些模型。
+
+### 並行 + 平行: Web + 機器學習
+
+使用 **FastAPI**,你可以利用並行的優勢,這在 Web 開發中非常常見(這也是 NodeJS 的最大吸引力)。
+
+但你也可以利用平行與多行程 (multiprocessing)(讓多個行程同時運行) 的優勢來處理機器學習系統中的 **CPU 密集型**工作。
+
+這一點,再加上 Python 是 **資料科學**、機器學習,尤其是深度學習的主要語言,讓 **FastAPI** 成為資料科學/機器學習 Web API 和應用程式(以及許多其他應用程式)的絕佳選擇。
+
+想了解如何在生產環境中實現這種平行性,請參見 [部屬](deployment/index.md){.internal-link target=_blank}。
+
+## `async` 和 `await`
+
+現代 Python 版本提供一種非常直觀的方式定義非同步程式碼。這使得它看起來就像正常的「順序」程式碼,並在適當的時機「等待」。
+
+當某個操作需要等待才能回傳結果,並且支援這些新的 Python 特性時,你可以像這樣編寫程式碼:
+
+```Python
+burgers = await get_burgers(2)
+```
+
+這裡的關鍵是 `await`。它告訴 Python 必須等待 ⏸ `get_burgers(2)` 完成它的工作 🕙, 然後將結果儲存在 `burgers` 中。如此,Python 就可以在此期間去處理其他事情 🔀 ⏯ (例如接收另一個請求)。
+
+要讓 `await` 運作,它必須位於支持非同步功能的函式內。為此,只需使用 `async def` 宣告函式:
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # Do some asynchronous stuff to create the burgers
+ return burgers
+```
+
+...而不是 `def`:
+
+```Python hl_lines="2"
+# This is not asynchronous
+def get_sequential_burgers(number: int):
+ # Do some sequential stuff to create the burgers
+ return burgers
+```
+
+使用 `async def`,Python Python 知道在該函式內需要注意 `await`,並且它可以「暫停」 ⏸ 執行該函式,然後執行其他任務 🔀 後回來。
+
+當你想要呼叫 `async def` 函式時,必須使用「await」。因此,這樣寫將無法運行:
+
+```Python
+# This won't work, because get_burgers was defined with: async def
+burgers = get_burgers(2)
+```
+
+---
+
+如果你正在使用某個函式庫,它告訴你可以使用 `await` 呼叫它,那麼你需要用 `async def` 定義*路徑操作函式*,如:
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### 更多技術細節
+
+你可能已經注意到,`await` 只能在 `async def` 定義的函式內使用。
+
+但同時,使用 `async def` 定義的函式本身也必須被「等待」。所以,帶有 `async def` 函式只能在其他使用 `async def` 定義的函式內呼叫。
+
+那麼,這就像「先有雞還是先有蛋」的問題,要如何呼叫第一個 `async` 函式呢?
+
+如果你使用 FastAPI,無需擔心這個問題,因為「第一個」函式將是你的*路徑操作函式*,FastAPI 會知道如何正確處理這個問題。
+
+但如果你想在沒有 FastAPI 的情況下使用 `async` / `await`,你也可以這樣做。
+
+### 編寫自己的非同步程式碼
+
+Starlette (和 **FastAPI**) 是基於
AnyIO 實作的,這使得它們與 Python 標準函式庫相容
asyncio 和
Trio。
+
+特別是,你可以直接使用
AnyIO 來處理更複雜的並行使用案例,這些案例需要你在自己的程式碼中使用更高階的模式。
+
+即使你不使用 **FastAPI**,你也可以使用
AnyIO 來撰寫自己的非同步應用程式,並獲得高相容性及一些好處(例如結構化並行)。
+
+### 其他形式的非同步程式碼
+
+使用 `async` 和 `await` 的風格在語言中相對較新。
+
+但它使處理異步程式碼變得更加容易。
+
+相同的語法(或幾乎相同的語法)最近也被包含在現代 JavaScript(無論是瀏覽器還是 NodeJS)中。
+
+但在此之前,處理異步程式碼要更加複雜和困難。
+
+在較舊的 Python 版本中,你可能會使用多執行緒或
Gevent。但這些程式碼要更難以理解、調試和思考。
+
+在較舊的 NodeJS / 瀏覽器 JavaScript 中,你會使用「回呼」,這可能會導致
回呼地獄。
+
+## 協程
+
+**協程** 只是 `async def` 函式所回傳的非常特殊的事物名稱。Python 知道它是一個類似函式的東西,可以啟動它,並且在某個時刻它會結束,但它也可能在內部暫停 ⏸,只要遇到 `await`。
+
+這種使用 `async` 和 `await` 的非同步程式碼功能通常被概括為「協程」。這與 Go 語言的主要特性「Goroutines」相似。
+
+## 結論
+
+讓我們再次回顧之前的句子:
+
+> 現代版本的 Python 支持使用 **"協程"** 的 **`async` 和 `await`** 語法來寫 **"非同步程式碼"**。
+
+現在應該能明白其含意了。✨
+
+這些就是驅動 FastAPI(通過 Starlette)運作的原理,也讓它擁有如此驚人的效能。
+
+## 非常技術性的細節
+
+/// warning
+
+你大概可以跳過這段。
+
+這裡是有關 FastAPI 內部技術細節。
+
+如果你有相當多的技術背景(例如協程、執行緒、阻塞等),並且對 FastAPI 如何處理 `async def` 與常規 `def` 感到好奇,請繼續閱讀。
+
+///
+
+### 路徑操作函数
+
+當你使用 `def` 而不是 `async def` 宣告*路徑操作函式*時,該函式會在外部的執行緒池(threadpool)中執行,然後等待結果,而不是直接呼叫(因為這樣會阻塞伺服器)。
+
+如果你來自於其他不以這種方式運作的非同步框架,而且你習慣於使用普通的 `def` 定義僅進行簡單計算的*路徑操作函式*,目的是獲得微小的性能增益(大約 100 奈秒),請注意,在 FastAPI 中,效果會完全相反。在這些情況下,最好使用 `async def`除非你的*路徑操作函式*執行阻塞的
I/O 的程式碼。
+
+不過,在這兩種情況下,**FastAPI** [仍然很快](index.md#_11){.internal-link target=_blank}至少與你之前的框架相當(或者更快)。
+
+### 依賴項(Dependencies)
+
+同樣適用於[依賴項](tutorial/dependencies/index.md){.internal-link target=_blank}。如果依賴項是一個標準的 `def` 函式,而不是 `async def`,那麼它在外部的執行緒池被運行。
+
+### 子依賴項
+
+你可以擁有多個相互依賴的依賴項和[子依賴項](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} (作為函式定義的參數),其中一些可能是用 `async def` 宣告,也可能是用 `def` 宣告。它們仍然可以正常運作,用 `def` 定義的那些將會在外部的執行緒中呼叫(來自執行緒池),而不是被「等待」。
+
+### 其他輔助函式
+
+你可以直接呼叫任何使用 `def` 或 `async def` 建立的其他輔助函式,FastAPI 不會影響你呼叫它們的方式。
+
+這與 FastAPI 為你呼叫*路徑操作函式*和依賴項的邏輯有所不同。
+
+如果你的輔助函式是用 `def` 宣告的,它將會被直接呼叫(按照你在程式碼中撰寫的方式),而不是在執行緒池中。如果該函式是用 `async def` 宣告,那麼你在呼叫時應該使用 `await` 等待其結果。
+
+---
+
+再一次強調,這些都是非常技術性的細節,如果你特地在尋找這些資訊,這些內容可能會對你有幫助。
+
+否則,只需遵循上面提到的指引即可:
趕時間嗎?.
diff --git a/docs/zh-hant/docs/benchmarks.md b/docs/zh-hant/docs/benchmarks.md
new file mode 100644
index 000000000..c59e8e71c
--- /dev/null
+++ b/docs/zh-hant/docs/benchmarks.md
@@ -0,0 +1,34 @@
+# 基準測試
+
+由第三方機構 TechEmpower 的基準測試表明在 Uvicorn 下運行的 **FastAPI** 應用程式是
最快的 Python 可用框架之一,僅次於 Starlette 和 Uvicorn 本身(於 FastAPI 內部使用)。
+
+但是在查看基準得分和對比時,請注意以下幾點。
+
+## 基準測試和速度
+
+當你查看基準測試時,時常會見到幾個不同類型的工具被同時進行測試。
+
+具體來說,是將 Uvicorn、Starlette 和 FastAPI 同時進行比較(以及許多其他工具)。
+
+該工具解決的問題越簡單,其效能就越好。而且大多數基準測試不會測試該工具提供的附加功能。
+
+層次結構如下:
+
+* **Uvicorn**:ASGI 伺服器
+ * **Starlette**:(使用 Uvicorn)一個網頁微框架
+ * **FastAPI**:(使用 Starlette)一個 API 微框架,具有用於建立 API 的多個附加功能、資料驗證等。
+
+* **Uvicorn**:
+ * 具有最佳效能,因為除了伺服器本身之外,它沒有太多額外的程式碼。
+ * 你不會直接在 Uvicorn 中編寫應用程式。這意味著你的程式碼必須或多或少地包含 Starlette(或 **FastAPI**)提供的所有程式碼。如果你這樣做,你的最終應用程式將具有與使用框架相同的開銷並最大限度地減少應用程式程式碼和錯誤。
+ * 如果你要比較 Uvicorn,請將其與 Daphne、Hypercorn、uWSGI 等應用程式伺服器進行比較。
+* **Starlette**:
+ * 繼 Uvicorn 之後的次佳表現。事實上,Starlette 使用 Uvicorn 來運行。因此它將可能只透過執行更多程式碼而變得比 Uvicorn「慢」。
+ * 但它為你提供了建立簡單網頁應用程式的工具,以及基於路徑的路由等。
+ * 如果你要比較 Starlette,請將其與 Sanic、Flask、Django 等網頁框架(或微框架)進行比較。
+* **FastAPI**:
+ * 就像 Starlette 使用 Uvicorn 並不能比它更快一樣, **FastAPI** 使用 Starlette,所以它不能比它更快。
+ * FastAPI 在 Starlette 基礎之上提供了更多功能。包含建構 API 時所需要的功能,例如資料驗證和序列化。FastAPI 可以幫助你自動產生 API 文件,(應用程式啟動時將會自動生成文件,所以不會增加應用程式運行時的開銷)。
+ * 如果你沒有使用 FastAPI 而是直接使用 Starlette(或其他工具,如 Sanic、Flask、Responder 等),你將必須自行實現所有資料驗證和序列化。因此,你的最終應用程式仍然具有與使用 FastAPI 建置相同的開銷。在許多情況下,這種資料驗證和序列化是應用程式中編寫最大量的程式碼。
+ * 因此透過使用 FastAPI,你可以節省開發時間、錯誤與程式碼數量,並且相比不使用 FastAPI 你很大可能會獲得相同或更好的效能(因為那樣你必須在程式碼中實現所有相同的功能)。
+ * 如果你要與 FastAPI 比較,請將其與能夠提供資料驗證、序列化和文件的網頁應用程式框架(或工具集)進行比較,例如 Flask-apispec、NestJS、Molten 等框架。
diff --git a/docs/zh-hant/docs/deployment/cloud.md b/docs/zh-hant/docs/deployment/cloud.md
new file mode 100644
index 000000000..29ebe3ff5
--- /dev/null
+++ b/docs/zh-hant/docs/deployment/cloud.md
@@ -0,0 +1,17 @@
+# 在雲端部署 FastAPI
+
+你幾乎可以使用**任何雲端供應商**來部署你的 FastAPI 應用程式。
+
+在大多數情況下,主要的雲端供應商都有部署 FastAPI 的指南。
+
+## 雲端供應商 - 贊助商
+
+一些雲端供應商 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這確保了 FastAPI 及其**生態系統**持續健康地**發展**。
+
+這也展現了他們對 FastAPI 和其**社群**(包括你)的真正承諾,他們不僅希望為你提供**優質的服務**,還希望確保你擁有一個**良好且健康的框架**:FastAPI。🙇
+
+你可能會想嘗試他們的服務,以下有他們的指南:
+
+*
Platform.sh
+*
Porter
+*
Coherence
diff --git a/docs/zh-hant/docs/deployment/index.md b/docs/zh-hant/docs/deployment/index.md
new file mode 100644
index 000000000..1726562b4
--- /dev/null
+++ b/docs/zh-hant/docs/deployment/index.md
@@ -0,0 +1,21 @@
+# 部署
+
+部署 **FastAPI** 應用程式相對容易。
+
+## 部署是什麼意思
+
+**部署**應用程式指的是執行一系列必要的步驟,使其能夠**讓使用者存取和使用**。
+
+對於一個 **Web API**,部署通常涉及將其放置在**遠端伺服器**上,並使用性能優良且穩定的**伺服器程式**,確保使用者能夠高效、無中斷地存取應用程式,且不會遇到問題。
+
+這與**開發**階段形成鮮明對比,在**開發**階段,你會不斷更改程式碼、破壞程式碼、修復程式碼,然後停止和重新啟動伺服器等。
+
+## 部署策略
+
+根據你的使用場景和使用工具,有多種方法可以實現此目的。
+
+你可以使用一些工具自行**部署伺服器**,你也可以使用能為你完成部分工作的**雲端服務**,或其他可能的選項。
+
+我將向你展示在部署 **FastAPI** 應用程式時你可能應該記住的一些主要概念(儘管其中大部分適用於任何其他類型的 Web 應用程式)。
+
+在接下來的部分中,你將看到更多需要記住的細節以及一些技巧。 ✨
diff --git a/docs/zh-hant/docs/environment-variables.md b/docs/zh-hant/docs/environment-variables.md
new file mode 100644
index 000000000..a1598fc01
--- /dev/null
+++ b/docs/zh-hant/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# 環境變數
+
+/// tip
+
+如果你已經知道什麼是「環境變數」並且知道如何使用它們,你可以放心跳過這一部分。
+
+///
+
+環境變數(也稱為「**env var**」)是一個獨立於 Python 程式碼**之外**的變數,它存在於**作業系統**中,可以被你的 Python 程式碼(或其他程式)讀取。
+
+環境變數對於處理應用程式**設定**(作為 Python **安裝**的一部分等方面)非常有用。
+
+## 建立和使用環境變數
+
+你在 **shell(終端機)**中就可以**建立**和使用環境變數,並不需要用到 Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// 你可以使用以下指令建立一個名為 MY_NAME 的環境變數
+$ export MY_NAME="Wade Wilson"
+
+// 然後,你可以在其他程式中使用它,例如
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// 建立一個名為 MY_NAME 的環境變數
+$ $Env:MY_NAME = "Wade Wilson"
+
+// 在其他程式中使用它,例如
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## 在 Python 中讀取環境變數
+
+你也可以在 Python **之外**的終端機中建立環境變數(或使用其他方法),然後在 Python 中**讀取**它們。
+
+例如,你可以建立一個名為 `main.py` 的檔案,其中包含以下內容:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+第二個參數是
`os.getenv()` 的預設回傳值。
+
+如果沒有提供,預設值為 `None`,這裡我們提供 `"World"` 作為預設值。
+
+///
+
+然後你可以呼叫這個 Python 程式:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// 這裡我們還沒有設定環境變數
+$ python main.py
+
+// 因為我們沒有設定環境變數,所以我們得到的是預設值
+
+Hello World from Python
+
+// 但是如果我們事先建立過一個環境變數
+$ export MY_NAME="Wade Wilson"
+
+// 然後再次呼叫程式
+$ python main.py
+
+// 現在就可以讀取到環境變數了
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// 這裡我們還沒有設定環境變數
+$ python main.py
+
+// 因為我們沒有設定環境變數,所以我們得到的是預設值
+
+Hello World from Python
+
+// 但是如果我們事先建立過一個環境變數
+$ $Env:MY_NAME = "Wade Wilson"
+
+// 然後再次呼叫程式
+$ python main.py
+
+// 現在就可以讀取到環境變數了
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+由於環境變數可以在程式碼之外設定,但可以被程式碼讀取,並且不必與其他檔案一起儲存(提交到 `git`),因此通常用於配置或**設定**。
+
+你還可以為**特定的程式呼叫**建立特定的環境變數,該環境變數僅對該程式可用,且僅在其執行期間有效。
+
+要實現這一點,只需在同一行內(程式本身之前)建立它:
+
+
+
+```console
+// 在這個程式呼叫的同一行中建立一個名為 MY_NAME 的環境變數
+$ MY_NAME="Wade Wilson" python main.py
+
+// 現在就可以讀取到環境變數了
+
+Hello Wade Wilson from Python
+
+// 在此之後這個環境變數將不再存在
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip
+
+你可以在
The Twelve-Factor App: 配置中了解更多資訊。
+
+///
+
+## 型別和驗證
+
+這些環境變數只能處理**文字字串**,因為它們是位於 Python 範疇之外的,必須與其他程式和作業系統的其餘部分相容(甚至與不同的作業系統相容,如 Linux、Windows、macOS)。
+
+這意味著從環境變數中讀取的**任何值**在 Python 中都將是一個 `str`,任何型別轉換或驗證都必須在程式碼中完成。
+
+你將在[進階使用者指南 - 設定和環境變數](./advanced/settings.md)中了解更多關於使用環境變數處理**應用程式設定**的資訊。
+
+## `PATH` 環境變數
+
+有一個**特殊的**環境變數稱為 **`PATH`**,作業系統(Linux、macOS、Windows)用它來查找要執行的程式。
+
+`PATH` 變數的值是一個長字串,由 Linux 和 macOS 上的冒號 `:` 分隔的目錄組成,而在 Windows 上則是由分號 `;` 分隔的。
+
+例如,`PATH` 環境變數可能如下所示:
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+這意味著系統應該在以下目錄中查找程式:
+
+- `/usr/local/bin`
+- `/usr/bin`
+- `/bin`
+- `/usr/sbin`
+- `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
+```
+
+這意味著系統應該在以下目錄中查找程式:
+
+- `C:\Program Files\Python312\Scripts`
+- `C:\Program Files\Python312`
+- `C:\Windows\System32`
+
+////
+
+當你在終端機中輸入一個**指令**時,作業系統會在 `PATH` 環境變數中列出的**每個目錄**中**查找**程式。
+
+例如,當你在終端機中輸入 `python` 時,作業系統會在該列表中的**第一個目錄**中查找名為 `python` 的程式。
+
+如果找到了,那麼作業系統將**使用它**;否則,作業系統會繼續在**其他目錄**中查找。
+
+### 安裝 Python 並更新 `PATH`
+
+安裝 Python 時,可能會詢問你是否要更新 `PATH` 環境變數。
+
+//// tab | Linux, macOS
+
+假設你安裝了 Python,並將其安裝在目錄 `/opt/custompython/bin` 中。
+
+如果你選擇更新 `PATH` 環境變數,那麼安裝程式會將 `/opt/custompython/bin` 加入到 `PATH` 環境變數中。
+
+它看起來大致會是這樣:
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
+```
+
+如此一來,當你在終端機輸入 `python` 時,系統會在 `/opt/custompython/bin` 中找到 Python 程式(最後一個目錄)並使用它。
+
+////
+
+//// tab | Windows
+
+假設你安裝了 Python,並將其安裝在目錄 `C:\opt\custompython\bin` 中。
+
+如果你選擇更新 `PATH` 環境變數(在 Python 安裝程式中,這個選項是名為 `Add Python x.xx to PATH` 的勾選框——譯者註),那麼安裝程式會將 `C:\opt\custompython\bin` 加入到 `PATH` 環境變數中。
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
+```
+
+如此一來,當你在終端機輸入 `python` 時,系統會在 `C:\opt\custompython\bin` 中找到 Python 程式(最後一個目錄)並使用它。
+
+////
+
+因此,如果你輸入:
+
+
+
+```console
+$ python
+```
+
+
+
+//// tab | Linux, macOS
+
+系統會在 `/opt/custompython/bin` 中**找到** `python` 程式並執行它。
+
+這大致等同於輸入以下指令:
+
+
+
+```console
+$ /opt/custompython/bin/python
+```
+
+
+
+////
+
+//// tab | Windows
+
+系統會在 `C:\opt\custompython\bin\python` 中**找到** `python` 程式並執行它。
+
+這大致等同於輸入以下指令:
+
+
+
+```console
+$ C:\opt\custompython\bin\python
+```
+
+
+
+////
+
+當學習[虛擬環境](virtual-environments.md)時,這些資訊將會很有用。
+
+## 結論
+
+透過這個教學,你應該對**環境變數**是什麼以及如何在 Python 中使用它們有了基本的了解。
+
+你也可以在
環境變數 - 維基百科 (
Wikipedia for Environment Variable) 中了解更多關於它們的資訊。
+
+在許多情況下,環境變數的用途和適用性可能不會立刻顯現。但是在開發過程中,它們會在許多不同的場景中出現,因此瞭解它們是非常必要的。
+
+例如,你在接下來的[虛擬環境](virtual-environments.md)章節中將需要這些資訊。
diff --git a/docs/zh-hant/docs/fastapi-cli.md b/docs/zh-hant/docs/fastapi-cli.md
new file mode 100644
index 000000000..3c644ce46
--- /dev/null
+++ b/docs/zh-hant/docs/fastapi-cli.md
@@ -0,0 +1,83 @@
+# FastAPI CLI
+
+**FastAPI CLI** 是一個命令列程式,能用來運行你的 FastAPI 應用程式、管理你的 FastAPI 專案等。
+
+當你安裝 FastAPI(例如使用 `pip install "fastapi[standard]"`),它會包含一個叫做 `fastapi-cli` 的套件,這個套件提供了 `fastapi` 命令。
+
+要運行你的 FastAPI 應用程式來進行開發,你可以使用 `fastapi dev` 命令:
+
+
+
+```console
+$ fastapi dev main.py
+INFO Using path main.py
+INFO Resolved absolute path /home/user/code/awesomeapp/main.py
+INFO Searching for package file structure from directories with __init__.py files
+INFO Importing from /home/user/code/awesomeapp
+
+ ╭─ Python module file ─╮
+ │ │
+ │ 🐍 main.py │
+ │ │
+ ╰──────────────────────╯
+
+INFO Importing module main
+INFO Found importable FastAPI app
+
+ ╭─ Importable FastAPI app ─╮
+ │ │
+ │ from main import app │
+ │ │
+ ╰──────────────────────────╯
+
+INFO Using import string main:app
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2265862] using WatchFiles
+INFO: Started server process [2265873]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+`fastapi` 命令列程式就是 **FastAPI CLI**。
+
+FastAPI CLI 接收你的 Python 程式路徑(例如 `main.py`),並自動檢測 FastAPI 實例(通常命名為 `app`),確定正確的引入模組流程,然後運行該應用程式。
+
+在生產環境,你應該使用 `fastapi run` 命令。 🚀
+
+**FastAPI CLI** 內部使用了
Uvicorn,這是一個高效能、適合生產環境的 ASGI 伺服器。 😎
+
+## `fastapi dev`
+
+執行 `fastapi dev` 會啟動開發模式。
+
+預設情況下,**auto-reload** 功能是啟用的,當你對程式碼進行修改時,伺服器會自動重新載入。這會消耗較多資源,並且可能比禁用時更不穩定。因此,你應該只在開發環境中使用此功能。它也會在 IP 位址 `127.0.0.1` 上監聽,這是用於你的機器與自身通訊的 IP 位址(`localhost`)。
+
+## `fastapi run`
+
+執行 `fastapi run` 會以生產模式啟動 FastAPI。
+
+預設情況下,**auto-reload** 功能是禁用的。它也會在 IP 位址 `0.0.0.0` 上監聽,表示會監聽所有可用的 IP 地址,這樣任何能與該機器通訊的人都可以公開存取它。這通常是你在生產環境中運行應用程式的方式,例如在容器中運行時。
+
+在大多數情況下,你會(也應該)有一個「終止代理」來處理 HTTPS,這取決於你如何部署你的應用程式,你的服務供應商可能會為你做這件事,或者你需要自己設置它。
+
+/// tip
+
+你可以在[部署文件](deployment/index.md){.internal-link target=_blank}中了解更多相關資訊。
+
+///
diff --git a/docs/zh-hant/docs/features.md b/docs/zh-hant/docs/features.md
new file mode 100644
index 000000000..3a1392b51
--- /dev/null
+++ b/docs/zh-hant/docs/features.md
@@ -0,0 +1,207 @@
+# 特性
+
+## FastAPI 特性
+
+**FastAPI** 提供了以下内容:
+
+### 建立在開放標準的基礎上
+
+* 使用
OpenAPI 來建立 API,包含
路徑操作、參數、請求內文、安全性等聲明。
+* 使用
JSON Schema(因為 OpenAPI 本身就是基於 JSON Schema)自動生成資料模型文件。
+* 經過縝密的研究後圍繞這些標準進行設計,而不是事後在已有系統上附加的一層功能。
+* 這也讓我們在多種語言中可以使用自動**用戶端程式碼生成**。
+
+### 能夠自動生成文件
+
+FastAPI 能生成互動式 API 文件和探索性的 Web 使用者介面。由於該框架基於 OpenAPI,因此有多種選擇,預設提供了兩種。
+
+*
Swagger UI 提供互動式探索,讓你可以直接從瀏覽器呼叫並測試你的 API 。
+
+
+
+*
ReDoc 提供結構性的文件,讓你可以在瀏覽器中查看。
+
+
+
+
+### 現代 Python
+
+這一切都基於標準的 **Python 型別**宣告(感謝 Pydantic)。無需學習新的語法,只需使用標準的現代 Python。
+
+如果你需要 2 分鐘來學習如何使用 Python 型別(即使你不使用 FastAPI),可以看看這個簡短的教學:[Python 型別](python-types.md){.internal-link target=_blank}。
+
+如果你寫帶有 Python 型別的程式碼:
+
+```python
+from datetime import date
+
+from pydantic import BaseModel
+
+# 宣告一個變數為 string
+# 並在函式中獲得 editor support
+def main(user_id: str):
+ return user_id
+
+
+# 宣告一個 Pydantic model
+class User(BaseModel):
+ id: int
+ name: str
+ joined: date
+```
+
+
+可以像這樣來使用:
+
+```python
+my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
+
+second_user_data = {
+ "id": 4,
+ "name": "Mary",
+ "joined": "2018-11-30",
+}
+
+my_second_user: User = User(**second_user_data)
+```
+
+
+/// info
+
+`**second_user_data` 意思是:
+
+將 `second_user_data` 字典直接作為 key-value 引數傳遞,等同於:`User(id=4, name="Mary", joined="2018-11-30")`
+
+///
+
+### 多種編輯器支援
+
+整個框架的設計是為了讓使用變得簡單且直觀,在開始開發之前,所有決策都在多個編輯器上進行了測試,以確保提供最佳的開發體驗。
+
+在最近的 Python 開發者調查中,我們能看到
被使用最多的功能是 autocompletion,此功能可以預測將要輸入文字,並自動補齊。
+
+整個 **FastAPI** 框架就是基於這一點,任何地方都可以進行自動補齊。
+
+你幾乎不需要經常來回看文件。
+
+在這裡,你的編輯器可能會這樣幫助你:
+
+*
Visual Studio Code 中:
+
+
+
+*
PyCharm 中:
+
+
+
+你將能進行程式碼補齊,這是在之前你可能曾認為不可能的事。例如,請求 JSON body(可能是巢狀的)中的鍵 `price`。
+
+這樣比較不會輸錯鍵名,不用來回翻看文件,也不用來回滾動尋找你最後使用的 `username` 或者 `user_name`。
+
+
+
+### 簡潔
+
+FastAPI 為你提供了**預設值**,讓你不必在初期進行繁瑣的配置,一切都可以自動運作。如果你有更具體的需求,則可以進行調整和自定義,
+
+但在大多數情況下,你只需要直接使用預設值,就能順利完成 API 開發。
+
+### 驗證
+
+所有的驗證都由完善且強大的 **Pydantic** 處理。
+
+* 驗證大部分(甚至所有?)的 Python **資料型別**,包括:
+ * JSON 物件 (`dict`)。
+ * JSON 陣列 (`list`) 定義項目型別。
+ * 字串 (`str`) 欄位,定義最小或最大長度。
+ * 數字 (`int`, `float`) 與其最大值和最小值等。
+
+* 驗證外來的型別,比如:
+ * URL
+ * Email
+ * UUID
+
+
+### 安全性及身份驗證
+
+FastAPI 已經整合了安全性和身份驗證的功能,但不會強制與特定的資料庫或資料模型進行綁定。
+
+OpenAPI 中定義的安全模式,包括:
+
+* HTTP 基本認證。
+* **OAuth2**(也使用 **JWT tokens**)。在 [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank} 查看教學。
+* API 密鑰,在:
+ * 標頭(Header)
+ * 查詢參數
+ * Cookies,等等。
+
+加上来自 Starlette(包括 **session cookie**)的所有安全特性。
+
+所有的這些都是可重複使用的工具和套件,可以輕鬆與你的系統、資料儲存(Data Stores)、關聯式資料庫(RDBMS)以及非關聯式資料庫(NoSQL)等等整合。
+
+
+### 依賴注入(Dependency Injection)
+
+FastAPI 有一個使用簡單,但是非常強大的
依賴注入系統。
+
+* 依賴項甚至可以有自己的依賴,從而形成一個層級或**依賴圖**的結構。
+* 所有**自動化處理**都由框架完成。
+* 依賴項不僅能從請求中提取資料,還能**對 API 的路徑操作進行強化**,並自動生成文檔。
+* 即使是依賴項中定義的*路徑操作參數*,也會**自動進行驗證**。
+* 支持複雜的用戶身份驗證系統、**資料庫連接**等。
+* 不與資料庫、前端等進行強制綁定,但能輕鬆整合它們。
+
+
+### 無限制「擴充功能」
+
+或者說,無需其他額外配置,直接導入並使用你所需要的程式碼。
+
+任何整合都被設計得非常簡單易用(通過依賴注入),你只需用與*路徑操作*相同的結構和語法,用兩行程式碼就能為你的應用程式建立一個「擴充功能」。
+
+
+### 測試
+
+* 100% 的
測試覆蓋率。
+* 100% 的程式碼有
型別註釋。
+* 已能夠在生產環境應用程式中使用。
+
+## Starlette 特性
+
+**FastAPI** 完全相容且基於
Starlette。所以,你有其他的 Starlette 程式碼也能正常運作。FastAPI 繼承了 Starlette 的所有功能,如果你已經知道或者使用過 Starlette,大部分的功能會以相同的方式運作。
+
+通過 **FastAPI** 你可以獲得所有 **Starlette** 的特性(FastAPI 就像加強版的 Starlette):
+
+* 性能極其出色。它是
Python 可用的最快框架之一,和 **NodeJS** 及 **Go** 相當。
+* **支援 WebSocket**。
+* 能在行程內處理背景任務。
+* 支援啟動和關閉事件。
+* 有基於 HTTPX 的測試用戶端。
+* 支援 **CORS**、GZip、靜態檔案、串流回應。
+* 支援 **Session 和 Cookie** 。
+* 100% 測試覆蓋率。
+* 100% 型別註釋的程式碼庫。
+
+## Pydantic 特性
+
+**FastAPI** 完全相容且基於
Pydantic。所以,你有其他 Pydantic 程式碼也能正常工作。
+
+相容包括基於 Pydantic 的外部函式庫, 例如用於資料庫的
ORMs,
ODMs。
+
+這也意味著在很多情況下,你可以把從請求中獲得的物件**直接傳到資料庫**,因為所有資料都會自動進行驗證。
+
+反之亦然,在很多情況下,你也可以把從資料庫中獲取的物件**直接傳給客戶端**。
+
+通過 **FastAPI** 你可以獲得所有 **Pydantic** 的特性(FastAPI 基於 Pydantic 做了所有的資料處理):
+
+* **更簡單**:
+ * 不需要學習新的 micro-language 來定義結構。
+ * 如果你知道 Python 型別,你就知道如何使用 Pydantic。
+* 和你的 **
IDE/
linter/brain** 都能好好配合:
+ * 因為 Pydantic 的資料結構其實就是你自己定義的類別實例,所以自動補齊、linting、mypy 以及你的直覺都能很好地在經過驗證的資料上發揮作用。
+* 驗證**複雜結構**:
+ * 使用 Pydantic 模型時,你可以把資料結構分層設計,並且用 Python 的 `List` 和 `Dict` 等型別來定義。
+ * 驗證器讓我們可以輕鬆地定義和檢查複雜的資料結構,並把它們轉換成 JSON Schema 進行記錄。
+ * 你可以擁有深層**巢狀的 JSON** 物件,並對它們進行驗證和註釋。
+* **可擴展**:
+ * Pydantic 讓我們可以定義客製化的資料型別,或者你可以使用帶有 validator 裝飾器的方法來擴展模型中的驗證功能。
+* 100% 測試覆蓋率。
diff --git a/docs/zh-hant/docs/how-to/index.md b/docs/zh-hant/docs/how-to/index.md
new file mode 100644
index 000000000..db740140d
--- /dev/null
+++ b/docs/zh-hant/docs/how-to/index.md
@@ -0,0 +1,13 @@
+# 使用指南 - 範例集
+
+在這裡,你將會看到**不同主題**的範例或「如何使用」的指南。
+
+大多數這些想法都是**獨立**的,在大多數情況下,你只需要研究那些直接適用於**你的專案**的東西。
+
+如果有些東西看起來很有趣且對你的專案很有用的話再去讀它,否則你可能可以跳過它們。
+
+/// tip
+
+如果你想要以結構化的方式**學習 FastAPI**(推薦),請前往[教學 - 使用者指南](../tutorial/index.md){.internal-link target=_blank}逐章閱讀。
+
+///
diff --git a/docs/zh-hant/docs/index.md b/docs/zh-hant/docs/index.md
new file mode 100644
index 000000000..81d99ede4
--- /dev/null
+++ b/docs/zh-hant/docs/index.md
@@ -0,0 +1,468 @@
+
+
+
+
+ FastAPI 框架,高效能,易於學習,快速開發,適用於生產環境
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+**文件**:
https://fastapi.tiangolo.com
+
+**程式碼**:
https://github.com/fastapi/fastapi
+
+---
+
+FastAPI 是一個現代、快速(高效能)的 web 框架,用於 Python 並採用標準 Python 型別提示。
+
+主要特點包含:
+
+- **快速**: 非常高的效能,可與 **NodeJS** 和 **Go** 效能相當 (歸功於 Starlette and Pydantic)。 [FastAPI 是最快的 Python web 框架之一](#performance)。
+- **極速開發**: 提高開發功能的速度約 200% 至 300%。 \*
+- **更少的 Bug**: 減少約 40% 的人為(開發者)導致的錯誤。 \*
+- **直覺**: 具有出色的編輯器支援,處處都有
自動補全以減少偵錯時間。
+- **簡單**: 設計上易於使用和學習,大幅減少閱讀文件的時間。
+- **簡潔**: 最小化程式碼重複性。可以通過不同的參數聲明來實現更豐富的功能,和更少的錯誤。
+- **穩健**: 立即獲得生產級可用的程式碼,還有自動生成互動式文件。
+- **標準化**: 基於 (且完全相容於) OpenAPIs 的相關標準:
OpenAPI(之前被稱為 Swagger)和
JSON Schema。
+
+
\* 基於內部開發團隊在建立生產應用程式時的測試預估。
+
+## 贊助
+
+
+
+{% if sponsors %}
+{% for sponsor in sponsors.gold -%}
+

+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+

+{% endfor %}
+{% endif %}
+
+
+
+
其他贊助商
+
+## 評價
+
+"_[...] 近期大量的使用 **FastAPI**。 [...] 目前正在計畫在**微軟**團隊的**機器學習**服務中導入。其中一些正在整合到核心的 **Windows** 產品和一些 **Office** 產品。_"
+
+
Kabir Khan -
Microsoft (ref)
+
+---
+
+"_我們使用 **FastAPI** 來建立產生**預測**結果的 **REST** 伺服器。 [for Ludwig]_"
+
+
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
+
+---
+
+"_**Netflix** 很榮幸地宣布開源**危機管理**協調框架: **Dispatch**! [是使用 **FastAPI** 建構]_"
+
+
Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
+
+---
+
+"_我對 **FastAPI** 興奮得不得了。它太有趣了!_"
+
+
+
+---
+
+"_老實說,你建造的東西看起來非常堅固和精緻。在很多方面,這就是我想要的,看到有人建造它真的很鼓舞人心。_"
+
+
+
+---
+
+"_如果您想學習一種用於構建 REST API 的**現代框架**,不能錯過 **FastAPI** [...] 它非常快速、且易於使用和學習 [...]_"
+
+"_我們的 **APIs** 已經改用 **FastAPI** [...] 我想你會喜歡它 [...]_"
+
+
+
+---
+
+"_如果有人想要建立一個生產環境的 Python API,我強烈推薦 **FastAPI**,它**設計精美**,**使用簡單**且**高度可擴充**,它已成為我們 API 優先開發策略中的**關鍵組件**,並且驅動了許多自動化服務,例如我們的 Virtual TAC Engineer。_"
+
+
Deon Pillsbury -
Cisco (ref)
+
+---
+
+## **Typer**,命令列中的 FastAPI
+
+

+
+如果你不是在開發網頁 API,而是正在開發一個在終端機中運行的
命令列應用程式,不妨嘗試
**Typer**。
+
+**Typer** 是 FastAPI 的小兄弟。他立志成為命令列的 **FastAPI**。 ⌨️ 🚀
+
+## 安裝需求
+
+FastAPI 是站在以下巨人的肩膀上:
+
+-
Starlette 負責網頁的部分
+-
Pydantic 負責資料的部分
+
+## 安裝
+
+
+
+```console
+$ pip install fastapi
+
+---> 100%
+```
+
+
+
+你同時也會需要 ASGI 伺服器用於生產環境,像是
Uvicorn 或
Hypercorn。
+
+
+
+```console
+$ pip install "uvicorn[standard]"
+
+---> 100%
+```
+
+
+
+## 範例
+
+### 建立
+
+- 建立一個 python 檔案 `main.py`,並寫入以下程式碼:
+
+```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}
+```
+
+
+或可以使用 async def
...
+
+如果你的程式使用 `async` / `await`,請使用 `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}
+```
+
+**注意**:
+
+如果你不知道是否會用到,可以查看 _"In a hurry?"_ 章節中,關於 `async` 和 `await` 的部分。
+
+
+
+### 運行
+
+使用以下指令運行伺服器:
+
+
+
+```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.
+```
+
+
+
+
+關於指令 uvicorn main:app --reload
...
+
+該指令 `uvicorn main:app` 指的是:
+
+- `main`:`main.py` 檔案(一個 python 的 "模組")。
+- `app`:在 `main.py` 檔案中,使用 `app = FastAPI()` 建立的物件。
+- `--reload`:程式碼更改後會自動重新啟動,請僅在開發時使用此參數。
+
+
+
+### 檢查
+
+使用瀏覽器開啟
http://127.0.0.1:8000/items/5?q=somequery。
+
+你將會看到以下的 JSON 回應:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+你已經建立了一個具有以下功能的 API:
+
+- 透過路徑 `/` 和 `/items/{item_id}` 接受 HTTP 請求。
+- 以上路經都接受 `GET`
請求(也被稱為 HTTP _方法_)。
+- 路徑 `/items/{item_id}` 有一個 `int` 型別的 `item_id` 參數。
+- 路徑 `/items/{item_id}` 有一個 `str` 型別的查詢參數 `q`。
+
+### 互動式 API 文件
+
+使用瀏覽器開啟
http://127.0.0.1:8000/docs。
+
+你會看到自動生成的互動式 API 文件(由
Swagger UI 生成):
+
+
+
+### ReDoc API 文件
+
+使用瀏覽器開啟
http://127.0.0.1:8000/redoc。
+
+你將看到 ReDoc 文件 (由
ReDoc 生成):
+
+
+
+## 範例升級
+
+現在繼續修改 `main.py` 檔案,來接收一個帶有 body 的 `PUT` 請求。
+
+我們使用 Pydantic 來使用標準的 Python 型別聲明請求。
+
+```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}
+```
+
+伺服器將自動重新載入(因為在上一步中,你向 `uvicorn` 指令添加了 `--reload` 的選項)。
+
+### 互動式 API 文件升級
+
+使用瀏覽器開啟
http://127.0.0.1:8000/docs。
+
+- 互動式 API 文件會自動更新,並加入新的 body 請求:
+
+
+
+- 點擊 "Try it out" 按鈕, 你可以填寫參數並直接與 API 互動:
+
+
+
+- 然後點擊 "Execute" 按鈕,使用者介面將會向 API 發送請求,並將結果顯示在螢幕上:
+
+
+
+### ReDoc API 文件升級
+
+使用瀏覽器開啟
http://127.0.0.1:8000/redoc。
+
+- ReDoc API 文件會自動更新,並加入新的參數和 body 請求:
+
+
+
+### 總結
+
+總結來說, 你就像宣告函式的參數型別一樣,只宣告了一次請求參數和請求主體參數等型別。
+
+你使用 Python 標準型別來完成聲明。
+
+你不需要學習新的語法、類別、方法或函式庫等等。
+
+只需要使用 **Python 以上的版本**。
+
+舉個範例,比如宣告 int 的型別:
+
+```Python
+item_id: int
+```
+
+或是一個更複雜的 `Item` 模型:
+
+```Python
+item: Item
+```
+
+在進行一次宣告後,你將獲得:
+
+- 編輯器支援:
+ - 自動補全
+ - 型別檢查
+- 資料驗證:
+ - 驗證失敗時自動生成清楚的錯誤訊息
+ - 可驗證多層巢狀的 JSON 物件
+-
轉換輸入的資料: 轉換來自網路請求到 Python 資料型別。包含以下數據:
+ - JSON
+ - 路徑參數
+ - 查詢參數
+ - Cookies
+ - 請求標頭
+ - 表單
+ - 文件
+-
轉換輸出的資料: 轉換 Python 資料型別到網路傳輸的 JSON:
+ - 轉換 Python 型別 (`str`、 `int`、 `float`、 `bool`、 `list` 等)
+ - `datetime` 物件
+ - `UUID` 物件
+ - 數據模型
+ - ...還有其他更多
+- 自動生成的 API 文件,包含 2 種不同的使用介面:
+ - Swagger UI
+ - ReDoc
+
+---
+
+回到前面的的程式碼範例,**FastAPI** 還會:
+
+- 驗證 `GET` 和 `PUT` 請求路徑中是否包含 `item_id`。
+- 驗證 `GET` 和 `PUT` 請求中的 `item_id` 是否是 `int` 型別。
+ - 如果驗證失敗,將會返回清楚有用的錯誤訊息。
+- 查看 `GET` 請求中是否有命名為 `q` 的查詢參數 (例如 `http://127.0.0.1:8000/items/foo?q=somequery`)。
+ - 因為 `q` 參數被宣告為 `= None`,所以是選填的。
+ - 如果沒有宣告 `None`,則此參數將會是必填 (例如 `PUT` 範例的請求 body)。
+- 對於 `PUT` 的請求 `/items/{item_id}`,將會讀取 body 為 JSON:
+ - 驗證是否有必填屬性 `name` 且型別是 `str`。
+ - 驗證是否有必填屬性 `price` 且型別是 `float`。
+ - 驗證是否有選填屬性 `is_offer` 且型別是 `bool`。
+ - 以上驗證都適用於多層次巢狀 JSON 物件。
+- 自動轉換 JSON 格式。
+- 透過 OpenAPI 文件來記錄所有內容,可以被用於:
+ - 互動式文件系統。
+ - 自動為多種程式語言生成用戶端的程式碼。
+- 提供兩種交互式文件介面。
+
+---
+
+雖然我們只敘述了表面的功能,但其實你已經理解了它是如何執行。
+
+試著修改以下程式碼:
+
+```Python
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+從:
+
+```Python
+ ... "item_name": item.name ...
+```
+
+修改為:
+
+```Python
+ ... "item_price": item.price ...
+```
+
+然後觀察你的編輯器,會自動補全並且還知道他們的型別:
+
+
+
+有關更多功能的完整範例,可以參考
教學 - 使用者指南。
+
+**劇透警告**: 教學 - 使用者指南內容有:
+
+- 對來自不同地方的**參數**進行宣告:像是 **headers**, **cookies**, **form 表單**以及**上傳檔案**。
+- 如何設定 **驗證限制** 像是 `maximum_length` or `regex`。
+- 簡單且非常容易使用的 **
依賴注入** 系統。
+- 安全性和身份驗證,包含提供支援 **OAuth2**、**JWT tokens** 和 **HTTP Basic** 驗證。
+- 更進階 (但同樣簡單) 的宣告 **多層次的巢狀 JSON 格式** (感謝 Pydantic)。
+- **GraphQL** 與
Strawberry 以及其他的相關函式庫進行整合。
+- 更多其他的功能 (感謝 Starlette) 像是:
+ - **WebSockets**
+ - 於 HTTPX 和 `pytest` 的非常簡單測試
+ - **CORS**
+ - **Cookie Sessions**
+ - ...以及更多
+
+## 效能
+
+來自獨立機構 TechEmpower 的測試結果,顯示在 Uvicorn 執行下的 **FastAPI** 是
最快的 Python 框架之一, 僅次於 Starlette 和 Uvicorn 本身 (兩者是 FastAPI 的底層)。 (\*)
+
+想了解更多訊息,可以參考
測試結果。
+
+## 可選的依賴套件
+
+用於 Pydantic:
+
+-
email-validator
- 用於電子郵件驗證。
+-
pydantic-settings
- 用於設定管理。
+-
pydantic-extra-types
- 用於與 Pydantic 一起使用的額外型別。
+
+用於 Starlette:
+
+-
httpx
- 使用 `TestClient`時必須安裝。
+-
jinja2
- 使用預設的模板配置時必須安裝。
+-
python-multipart
- 需要使用 `request.form()` 對表單進行
"解析" 時安裝。
+-
itsdangerous
- 需要使用 `SessionMiddleware` 支援時安裝。
+-
pyyaml
- 用於支援 Starlette 的 `SchemaGenerator` (如果你使用 FastAPI,可能不需要它)。
+
+用於 FastAPI / Starlette:
+
+-
uvicorn
- 用於加載和運行應用程式的服務器。
+-
orjson
- 使用 `ORJSONResponse`時必須安裝。
+-
ujson
- 使用 `UJSONResponse` 時必須安裝。
+
+你可以使用 `pip install "fastapi[all]"` 來安裝這些所有依賴套件。
+
+## 授權
+
+該項目遵循 MIT 許可協議。
diff --git a/docs/zh-hant/docs/learn/index.md b/docs/zh-hant/docs/learn/index.md
new file mode 100644
index 000000000..eb7d7096a
--- /dev/null
+++ b/docs/zh-hant/docs/learn/index.md
@@ -0,0 +1,5 @@
+# 學習
+
+以下是學習 FastAPI 的入門介紹和教學。
+
+你可以將其視為一本**書籍**或一門**課程**,這是**官方**認可並推薦的 FastAPI 學習方式。 😎
diff --git a/docs/zh-hant/docs/resources/index.md b/docs/zh-hant/docs/resources/index.md
new file mode 100644
index 000000000..f4c70a3a0
--- /dev/null
+++ b/docs/zh-hant/docs/resources/index.md
@@ -0,0 +1,3 @@
+# 資源
+
+額外的資源、外部連結、文章等。 ✈️
diff --git a/docs/zh-hant/docs/tutorial/first-steps.md b/docs/zh-hant/docs/tutorial/first-steps.md
new file mode 100644
index 000000000..a557fa369
--- /dev/null
+++ b/docs/zh-hant/docs/tutorial/first-steps.md
@@ -0,0 +1,331 @@
+# 第一步
+
+最簡單的 FastAPI 檔案可能看起來像這樣:
+
+{* ../../docs_src/first_steps/tutorial001.py *}
+
+將其複製到一個名為 `main.py` 的文件中。
+
+執行即時重新載入伺服器(live server):
+
+
+
+```console
+$ fastapi dev main.py
+INFO Using path main.py
+INFO Resolved absolute path /home/user/code/awesomeapp/main.py
+INFO Searching for package file structure from directories with __init__.py files
+INFO Importing from /home/user/code/awesomeapp
+
+ ╭─ Python module file ─╮
+ │ │
+ │ 🐍 main.py │
+ │ │
+ ╰──────────────────────╯
+
+INFO Importing module main
+INFO Found importable FastAPI app
+
+ ╭─ Importable FastAPI app ─╮
+ │ │
+ │ from main import app │
+ │ │
+ ╰──────────────────────────╯
+
+INFO Using import string main:app
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2265862] using WatchFiles
+INFO: Started server process [2265873]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+在輸出中,有一列類似於:
+
+```hl_lines="4"
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+那列顯示了你的應用程式正在本地端機器上運行的 URL。
+
+### 查看它
+
+在瀏覽器中打開
http://127.0.0.1:8000.
+
+你將看到如下的 JSON 回應:
+
+```JSON
+{"message": "Hello World"}
+```
+
+### 互動式 API 文件
+
+現在,前往
http://127.0.0.1:8000/docs.
+
+你將看到自動的互動式 API 文件(由
Swagger UI 提供):
+
+
+
+### 替代 API 文件
+
+現在,前往
http://127.0.0.1:8000/redoc.
+
+你將看到另一種自動文件(由
ReDoc 提供):
+
+
+
+### OpenAPI
+
+**FastAPI** 使用定義 API 的 **OpenAPI** 標準來生成一個 「schema」 與你的所有 API。
+
+#### 「Schema」
+
+「schema」是對某個事物的定義或描述。它並不是實作它的程式碼,而僅僅是一個抽象的描述。
+
+#### API 「schema」
+
+在這種情況下,
OpenAPI 是一個規範,它規定了如何定義 API 的 schema。
+
+這個 schema 定義包含了你的 API 路徑、可能接收的參數等內容。
+
+#### 資料 「schema」
+
+「schema」這個術語也可能指某些資料的結構,比如 JSON 內容的結構。
+
+在這種情況下,它指的是 JSON 的屬性、資料型別等。
+
+#### OpenAPI 和 JSON Schema
+
+OpenAPI 定義了 API 的 schema。這個 schema 包含了使用 **JSON Schema** 定義的資料,這是 JSON 資料 schema 的標準。
+
+#### 檢查 `openapi.json`
+
+如果你好奇原始的 OpenAPI schema 長什麼樣子,FastAPI 會自動生成一個包含所有 API 描述的 JSON (schema)。
+
+你可以直接在
http://127.0.0.1:8000/openapi.json 查看它。
+
+它會顯示一個 JSON,類似於:
+
+```JSON
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+
+
+
+...
+```
+
+#### OpenAPI 的用途
+
+OpenAPI schema 驅動了兩個互動式文件系統。
+
+而且有許多替代方案,所有這些都是基於 OpenAPI。你可以輕鬆地將任何這些替代方案添加到使用 **FastAPI** 建置的應用程式中。
+
+你也可以用它自動生成程式碼,讓前端、手機應用程式或物聯網設備等與你的 API 進行通訊。
+
+## 逐步回顧
+
+### 第一步:引入 `FastAPI`
+
+{* ../../docs_src/first_steps/tutorial001.py h1[1] *}
+
+`FastAPI` 是一個 Python 類別,提供所有 API 的全部功能。
+
+/// note | Technical Details
+
+`FastAPI` 是一個直接繼承自 `Starlette` 的類別。
+
+你同樣可以透過 `FastAPI` 來使用
Starlette 所有的功能。
+
+///
+
+### 第二步:建立一個 `FastAPI` 「實例」
+
+{* ../../docs_src/first_steps/tutorial001.py h1[3] *}
+
+這裡的 `app` 變數將會是 `FastAPI` 類別的「實例」。
+
+這將是你建立所有 API 的主要互動點。
+
+### 第三步:建立一個 *路徑操作*
+
+#### 路徑
+
+這裡的「路徑」指的是 URL 中自第一個 `/` 以後的部分。
+
+例如,在 URL 中:
+
+```
+https://example.com/items/foo
+```
+
+……的路徑將會是:
+
+```
+/items/foo
+```
+
+/// info
+
+「路徑」也常被稱為「端點 endpoint」或「路由 route」。
+
+///
+
+在建置 API 時,「路徑」是分離「關注點」和「資源」的主要方式。
+
+#### 操作
+
+這裡的「操作」指的是 HTTP 的「方法」之一。
+
+其中包括:
+
+* `POST`
+* `GET`
+* `PUT`
+* `DELETE`
+
+……以及更少見的:
+
+* `OPTIONS`
+* `HEAD`
+* `PATCH`
+* `TRACE`
+
+在 HTTP 協定中,你可以使用這些「方法」之一(或更多)與每個路徑進行通信。
+
+---
+
+在建置 API 時,你通常使用這些特定的 HTTP 方法來執行特定的動作。
+
+通常你使用:
+
+* `POST`:用來建立資料。
+* `GET`:用來讀取資料。
+* `PUT`:用來更新資料。
+* `DELETE`:用來刪除資料。
+
+所以,在 OpenAPI 中,每個 HTTP 方法都被稱為「操作」。
+
+我們將會稱它們為「**操作**」。
+
+#### 定義一個 *路徑操作裝飾器*
+
+{* ../../docs_src/first_steps/tutorial001.py h1[6] *}
+
+`@app.get("/")` 告訴 **FastAPI** 那個函式負責處理請求:
+
+* 路徑 `/`
+* 使用
get
操作
+
+/// info | `@decorator` Info
+
+Python 中的 `@something` 語法被稱為「裝飾器」。
+
+你把它放在一個函式上面。像一個漂亮的裝飾帽子(我猜這是術語的來源)。
+
+一個「裝飾器」會對下面的函式做一些事情。
+
+在這種情況下,這個裝飾器告訴 **FastAPI** 那個函式對應於 **路徑** `/` 和 **操作** `get`.
+
+這就是「**路徑操作裝飾器**」。
+
+///
+
+你也可以使用其他的操作:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+以及更少見的:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+/// tip
+
+你可以自由地使用每個操作(HTTP 方法)。
+
+**FastAPI** 不強制任何特定的意義。
+
+這裡的資訊作為一個指南,而不是要求。
+
+例如,當使用 GraphQL 時,你通常只使用 `POST` 操作。
+
+///
+
+### 第四步:定義 **路徑操作函式**
+
+這是我們的「**路徑操作函式**」:
+
+* **path**: 是 `/`.
+* **operation**: 是 `get`.
+* **function**: 是裝飾器下面的函式(在 `@app.get("/")` 下面)。
+
+{* ../../docs_src/first_steps/tutorial001.py h1[7] *}
+
+這就是一個 Python 函式。
+
+它將會在 **FastAPI** 收到一個請求時被呼叫,使用 `GET` 操作。
+
+在這種情況下,它是一個 `async` 函式。
+
+---
+
+你可以將它定義為一個正常的函式,而不是 `async def`:
+
+{* ../../docs_src/first_steps/tutorial003.py h1[7] *}
+
+/// note
+
+如果你不知道差別,請查看 [Async: *"In a hurry?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+///
+
+### 第五步:回傳內容
+
+{* ../../docs_src/first_steps/tutorial001.py h1[8] *}
+
+你可以返回一個 `dict`、`list`、單個值作為 `str`、`int` 等。
+
+你也可以返回 Pydantic 模型(稍後你會看到更多關於這方面的內容)。
+
+有很多其他物件和模型會自動轉換為 JSON(包括 ORMs,等等)。試用你最喜歡的,很有可能它們已經有支援。
+
+## 回顧
+
+* 引入 `FastAPI`.
+* 建立一個 `app` 實例。
+* 寫一個 **路徑操作裝飾器** 使用裝飾器像 `@app.get("/")`。
+* 定義一個 **路徑操作函式**;例如,`def root(): ...`。
+* 使用命令 `fastapi dev` 執行開發伺服器。
diff --git a/docs/zh-hant/docs/tutorial/index.md b/docs/zh-hant/docs/tutorial/index.md
new file mode 100644
index 000000000..ae0056f52
--- /dev/null
+++ b/docs/zh-hant/docs/tutorial/index.md
@@ -0,0 +1,102 @@
+# 教學 - 使用者指南
+
+本教學將一步一步展示如何使用 **FastAPI** 及其大多數功能。
+
+每個部分都是在前一部分的基礎上逐步建置的,但內容結構是按主題分開的,因此你可以直接跳到任何特定的部分,解決你具體的 API 需求。
+
+它也被設計成可作為未來的參考,讓你隨時回來查看所需的內容。
+
+## 運行程式碼
+
+所有程式碼區塊都可以直接複製和使用(它們實際上是經過測試的 Python 檔案)。
+
+要運行任何範例,請將程式碼複製到 `main.py` 檔案,並使用以下命令啟動 `fastapi dev`:
+
+
+
+```console
+$ fastapi dev main.py
+INFO Using path main.py
+INFO Resolved absolute path /home/user/code/awesomeapp/main.py
+INFO Searching for package file structure from directories with __init__.py files
+INFO Importing from /home/user/code/awesomeapp
+
+ ╭─ Python module file ─╮
+ │ │
+ │ 🐍 main.py │
+ │ │
+ ╰──────────────────────╯
+
+INFO Importing module main
+INFO Found importable FastAPI app
+
+ ╭─ Importable FastAPI app ─╮
+ │ │
+ │ from main import app │
+ │ │
+ ╰──────────────────────────╯
+
+INFO Using import string main:app
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2265862] using WatchFiles
+INFO: Started server process [2265873]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+
+```
+
+
+
+**強烈建議**你編寫或複製程式碼、進行修改並在本地端運行。
+
+在編輯器中使用它,才能真正體會到 FastAPI 的好處,可以看到你只需編寫少量程式碼,以及所有的型別檢查、自動補齊等功能。
+
+---
+
+## 安裝 FastAPI
+
+第一步是安裝 FastAPI。
+
+確保你建立一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},啟用它,然後**安裝 FastAPI**:
+
+
+
+```console
+$ pip install "fastapi[standard]"
+
+---> 100%
+```
+
+
+
+/// note
+
+當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準依賴項。
+
+如果你不想包含那些可選的依賴項,你可以使用 `pip install fastapi` 來安裝。
+
+///
+
+## 進階使用者指南
+
+還有一個**進階使用者指南**你可以稍後閱讀。
+
+**進階使用者指南**建立在這個教學之上,使用相同的概念,並教你一些額外的功能。
+
+但首先你應該閱讀**教學 - 使用者指南**(你正在閱讀的內容)。
+
+它被設計成你可以使用**教學 - 使用者指南**來建立一個完整的應用程式,然後根據你的需求,使用一些額外的想法來擴展它。
diff --git a/docs/zh-hant/docs/tutorial/query-param-models.md b/docs/zh-hant/docs/tutorial/query-param-models.md
new file mode 100644
index 000000000..76ee74016
--- /dev/null
+++ b/docs/zh-hant/docs/tutorial/query-param-models.md
@@ -0,0 +1,68 @@
+# 查詢參數模型
+
+如果你有一組具有相關性的**查詢參數**,你可以建立一個 **Pydantic 模型**來聲明它們。
+
+這將允許你在**多個地方**去**重複使用模型**,並且一次性為所有參數聲明驗證和元資料 (metadata)。😎
+
+/// note
+
+FastAPI 從 `0.115.0` 版本開始支援這個特性。🤓
+
+///
+
+## 使用 Pydantic 模型的查詢參數
+
+在一個 **Pydantic 模型**中聲明你需要的**查詢參數**,然後將參數聲明為 `Query`:
+
+{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
+
+**FastAPI** 將會從請求的**查詢參數**中**提取**出**每個欄位**的資料,並將其提供給你定義的 Pydantic 模型。
+
+## 查看文件
+
+你可以在 `/docs` 頁面的 UI 中查看查詢參數:
+
+
+

+
+
+## 禁止額外的查詢參數
+
+在一些特殊的使用場景中(可能不是很常見),你可能希望**限制**你要收到的查詢參數。
+
+你可以使用 Pydantic 的模型設定來 `forbid`(禁止)任何 `extra`(額外)欄位:
+
+{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
+
+如果客戶端嘗試在**查詢參數**中發送一些**額外的**資料,他們將會收到一個**錯誤**回應。
+
+例如,如果客戶端嘗試發送一個值為 `plumbus` 的 `tool` 查詢參數,如:
+
+```http
+https://example.com/items/?limit=10&tool=plumbus
+```
+
+他們將收到一個**錯誤**回應,告訴他們查詢參數 `tool` 是不允許的:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["query", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus"
+ }
+ ]
+}
+```
+
+## 總結
+
+你可以使用 **Pydantic 模型**在 **FastAPI** 中聲明**查詢參數**。😎
+
+/// tip
+
+劇透警告:你也可以使用 Pydantic 模型來聲明 cookie 和 headers,但你將在本教學的後面部分閱讀到這部分內容。🤫
+
+///
diff --git a/docs/zh-hant/docs/virtual-environments.md b/docs/zh-hant/docs/virtual-environments.md
new file mode 100644
index 000000000..d8e31e08e
--- /dev/null
+++ b/docs/zh-hant/docs/virtual-environments.md
@@ -0,0 +1,844 @@
+# 虛擬環境
+
+當你在 Python 專案中工作時,你可能會需要使用一個**虛擬環境**(或類似的機制)來隔離你為每個專案安裝的套件。
+
+/// info
+
+如果你已經了解虛擬環境,知道如何建立和使用它們,你可以考慮跳過這一部分。🤓
+
+///
+
+/// tip
+
+**虛擬環境**和**環境變數**是不同的。
+
+**環境變數**是系統中的一個變數,可以被程式使用。
+
+**虛擬環境**是一個包含一些檔案的目錄。
+
+///
+
+/// info
+
+這個頁面將教你如何使用**虛擬環境**以及了解它們的工作原理。
+
+如果你計畫使用一個**可以為你管理一切的工具**(包括安裝 Python),試試
uv。
+
+///
+
+## 建立一個專案
+
+首先,為你的專案建立一個目錄。
+
+我(指原作者 —— 譯者注)通常會在我的主目錄下建立一個名為 `code` 的目錄。
+
+在這個目錄下,我再為每個專案建立一個目錄。
+
+
+
+```console
+// 進入主目錄
+$ cd
+// 建立一個用於存放所有程式碼專案的目錄
+$ mkdir code
+// 進入 code 目錄
+$ cd code
+// 建立一個用於存放這個專案的目錄
+$ mkdir awesome-project
+// 進入這個專案的目錄
+$ cd awesome-project
+```
+
+
+
+## 建立一個虛擬環境
+
+在開始一個 Python 專案的**第一時間**,**
在你的專案內部**建立一個虛擬環境。
+
+/// tip
+
+你只需要**在每個專案中操作一次**,而不是每次工作時都操作。
+
+///
+
+//// tab | `venv`
+
+你可以使用 Python 自帶的 `venv` 模組來建立一個虛擬環境。
+
+
+
+```console
+$ python -m venv .venv
+```
+
+
+
+/// details | 上述命令的含義
+
+* `python`: 使用名為 `python` 的程式
+* `-m`: 以腳本的方式呼叫一個模組,我們將告訴它接下來使用哪個模組
+* `venv`: 使用名為 `venv` 的模組,這個模組通常隨 Python 一起安裝
+* `.venv`: 在新目錄 `.venv` 中建立虛擬環境
+
+///
+
+////
+
+//// tab | `uv`
+
+如果你安裝了
`uv`,你也可以使用它來建立一個虛擬環境。
+
+
+
+```console
+$ uv venv
+```
+
+
+
+/// tip
+
+預設情況下,`uv` 會在一個名為 `.venv` 的目錄中建立一個虛擬環境。
+
+但你可以透過傳遞一個額外的引數來自訂它,指定目錄的名稱。
+
+///
+
+////
+
+這個命令會在一個名為 `.venv` 的目錄中建立一個新的虛擬環境。
+
+/// details | `.venv`,或是其他名稱
+
+你可以在不同的目錄下建立虛擬環境,但通常我們會把它命名為 `.venv`。
+
+///
+
+## 啟動虛擬環境
+
+啟動新的虛擬環境來確保你運行的任何 Python 指令或安裝的套件都能使用到它。
+
+/// tip
+
+**每次**開始一個**新的終端會話**來在這個專案工作時,你都需要執行這個操作。
+
+///
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+或者,如果你在 Windows 上使用 Bash(例如
Git Bash):
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+/// tip
+
+每次你在這個環境中安裝一個**新的套件**時,都需要**重新啟動**這個環境。
+
+這麼做確保了當你使用一個由這個套件安裝的**終端(
CLI)程式**時,你使用的是你的虛擬環境中的程式,而不是全域安裝、可能版本不同的程式。
+
+///
+
+## 檢查虛擬環境是否啟動
+
+檢查虛擬環境是否啟動(前面的指令是否生效)。
+
+/// tip
+
+這是**非必需的**,但這是一個很好的方法,可以**檢查**一切是否按預期工作,以及你是否使用了你打算使用的虛擬環境。
+
+///
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+如果它顯示了在你專案(在這個例子中是 `awesome-project`)的 `.venv/bin/python` 中的 `python` 二進位檔案,那麼它就生效了。🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+如果它顯示了在你專案(在這個例子中是 `awesome-project`)的 `.venv\Scripts\python` 中的 `python` 二進位檔案,那麼它就生效了。🎉
+
+////
+
+## 升級 `pip`
+
+/// tip
+
+如果你使用
`uv` 來安裝內容,而不是 `pip`,那麼你就不需要升級 `pip`。😎
+
+///
+
+如果你使用 `pip` 來安裝套件(它是 Python 的預設元件),你應該將它**升級**到最新版本。
+
+在安裝套件時出現的許多奇怪的錯誤都可以透過先升級 `pip` 來解決。
+
+/// tip
+
+通常你只需要在建立虛擬環境後**執行一次**這個操作。
+
+///
+
+確保虛擬環境是啟動的(使用上面的指令),然後運行:
+
+
+
+```console
+$ python -m pip install --upgrade pip
+
+---> 100%
+```
+
+
+
+## 加入 `.gitignore`
+
+如果你使用 **Git**(這是你應該使用的),加入一個 `.gitignore` 檔案來排除你的 `.venv` 中的所有內容。
+
+/// tip
+
+如果你使用
`uv` 來建立虛擬環境,它會自動為你完成這個操作,你可以跳過這一步。😎
+
+///
+
+/// tip
+
+通常你只需要在建立虛擬環境後**執行一次**這個操作。
+
+///
+
+
+
+```console
+$ echo "*" > .venv/.gitignore
+```
+
+
+
+/// details | 上述指令的含義
+
+- `echo "*"`: 將在終端中「顯示」文本 `*`(接下來的部分會對這個操作進行一些修改)
+- `>`: 使左邊的指令顯示到終端的任何內容實際上都不會被顯示,而是會被寫入到右邊的檔案中
+- `.gitignore`: 被寫入文本的檔案的名稱
+
+而 `*` 對於 Git 來說意味著「所有內容」。所以,它會忽略 `.venv` 目錄中的所有內容。
+
+該指令會建立一個名為 .gitignore 的檔案,內容如下:
+
+```gitignore
+*
+```
+
+///
+
+## 安裝套件
+
+在啟用虛擬環境後,你可以在其中安裝套件。
+
+/// tip
+
+當你需要安裝或升級套件時,執行本操作**一次**;
+
+如果你需要再升級版本或新增套件,你可以**再次執行此操作**。
+
+///
+
+### 直接安裝套件
+
+如果你急於安裝,不想使用檔案來聲明專案的套件依賴,你可以直接安裝它們。
+
+/// tip
+
+將程式所需的套件及其版本放在檔案中(例如 `requirements.txt` 或 `pyproject.toml`)是個好(而且非常好)的主意。
+
+///
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install "fastapi[standard]"
+
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+如果你有
`uv`:
+
+
+
+```console
+$ uv pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+////
+
+### 從 `requirements.txt` 安裝
+
+如果你有一個 `requirements.txt` 檔案,你可以使用它來安裝其中的套件。
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+如果你有
`uv`:
+
+
+
+```console
+$ uv pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+/// details | 關於 `requirements.txt`
+
+一個包含一些套件的 `requirements.txt` 檔案看起來應該是這樣的:
+
+```requirements.txt
+fastapi[standard]==0.113.0
+pydantic==2.8.0
+```
+
+///
+
+## 執行程式
+
+在啟用虛擬環境後,你可以執行你的程式,它將使用虛擬環境中的 Python 和你在其中安裝的套件。
+
+
+
+```console
+$ python main.py
+
+Hello World
+```
+
+
+
+## 設定編輯器
+
+你可能會用到編輯器,請確保設定它使用你建立的相同虛擬環境(它可能會自動偵測到),以便你可以獲得自動完成和内嵌錯誤提示。
+
+例如:
+
+*
VS Code
+*
PyCharm
+
+/// tip
+
+通常你只需要在建立虛擬環境時執行此操作**一次**。
+
+///
+
+## 退出虛擬環境
+
+當你完成工作後,你可以**退出**虛擬環境。
+
+
+
+```console
+$ deactivate
+```
+
+
+
+這樣,當你執行 `python` 時它不會嘗試從已安裝套件的虛擬環境中執行。
+
+## 開始工作
+
+現在你已經準備好開始你的工作了。
+
+
+
+/// tip
+
+你想要理解上面的所有內容嗎?
+
+繼續閱讀。👇🤓
+
+///
+
+## 為什麼要使用虛擬環境
+
+你需要安裝
Python 才能使用 FastAPI。
+
+接下來,你需要**安裝** FastAPI 以及你想使用的其他**套件**。
+
+要安裝套件,你通常會使用隨 Python 一起提供的 `pip` 指令(或類似的替代工具)。
+
+然而,如果你直接使用 `pip`,套件將會安裝在你的**全域 Python 環境**中(即 Python 的全域安裝)。
+
+### 存在的問題
+
+那麼,在全域 Python 環境中安裝套件有什麼問題呢?
+
+有時候,你可能會開發許多不同的程式,而這些程式各自依賴於**不同的套件**;有些專案甚至需要依賴於**相同套件的不同版本**。😱
+
+例如,你可能會建立一個名為 `philosophers-stone` 的專案,這個程式依賴於另一個名為 **`harry` 的套件,並使用版本 `1`**。因此,你需要安裝 `harry`。
+
+```mermaid
+flowchart LR
+ stone(philosophers-stone) -->|需要| harry-1[harry v1]
+```
+
+然而,在此之後,你又建立了另一個名為 `prisoner-of-azkaban` 的專案,而這個專案也依賴於 `harry`,但需要的是 **`harry` 版本 `3`**。
+
+```mermaid
+flowchart LR
+ azkaban(prisoner-of-azkaban) --> |需要| harry-3[harry v3]
+```
+
+現在的問題是,如果你在全域環境中安裝套件而不是在本地**虛擬環境**中,你將面臨選擇安裝哪個版本的 `harry` 的困境。
+
+如果你想運行 `philosophers-stone`,你需要先安裝 `harry` 版本 `1`,例如:
+
+
+
+```console
+$ pip install "harry==1"
+```
+
+
+
+然後你會在全域 Python 環境中安裝 `harry` 版本 `1`。
+
+```mermaid
+flowchart LR
+ subgraph global[全域環境]
+ harry-1[harry v1]
+ end
+ subgraph stone-project[專案 philosophers-stone]
+ stone(philosophers-stone) -->|需要| harry-1
+ end
+```
+
+但如果你想運行 `prisoner-of-azkaban`,你需要解除安裝 `harry` 版本 `1` 並安裝 `harry` 版本 `3`(或者只要你安裝版本 `3`,版本 `1` 就會自動移除)。
+
+
+
+```console
+$ pip install "harry==3"
+```
+
+
+
+於是,你在全域 Python 環境中安裝了 `harry` 版本 `3`。
+
+如果你再次嘗試運行 `philosophers-stone`,很可能會**無法正常運作**,因為它需要的是 `harry` 版本 `1`。
+
+```mermaid
+flowchart LR
+ subgraph global[全域環境]
+ harry-1[
harry v1]
+ style harry-1 fill:#ccc,stroke-dasharray: 5 5
+ harry-3[harry v3]
+ end
+ subgraph stone-project[專案 philosophers-stone]
+ stone(philosophers-stone) -.-x|⛔️| harry-1
+ end
+ subgraph azkaban-project[專案 prisoner-of-azkaban]
+ azkaban(prisoner-of-azkaban) --> |需要| harry-3
+ end
+```
+
+/// tip
+
+Python 套件在推出**新版本**時通常會儘量**避免破壞性更改**,但最好還是要謹慎,在安裝新版本前進行測試,以確保一切能正常運行。
+
+///
+
+現在,想像一下如果有**許多**其他**套件**,它們都是你的**專案所依賴的**。這樣是非常難以管理的。你可能會發現有些專案使用了一些**不相容的套件版本**,而無法得知為什麼某些程式無法正常運作。
+
+此外,取決於你的操作系統(例如 Linux、Windows、macOS),它可能已經預先安裝了 Python。在這種情況下,它可能已經有一些系統所需的套件和特定版本。如果你在全域 Python 環境中安裝套件,可能會**破壞**某些隨作業系統一起安裝的程式。
+
+## 套件安裝在哪裡
+
+當你安裝 Python 時,它會在你的電腦中建立一些目錄並放置一些檔案。
+
+其中一些目錄專門用來存放你所安裝的所有套件。
+
+當你運行:
+
+
+
+```console
+// 先別去運行這個指令,這只是個示例 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+這會從
PyPI 下載一個壓縮檔案,其中包含 FastAPI 的程式碼。
+
+它還會**下載** FastAPI 所依賴的其他套件的檔案。
+
+接著,它會**解壓**所有這些檔案,並將它們放在你的電腦中的某個目錄中。
+
+預設情況下,這些下載和解壓的檔案會放置於隨 Python 安裝的目錄中,即**全域環境**。
+
+## 什麼是虛擬環境
+
+解決套件都安裝在全域環境中的問題方法是為你所做的每個專案使用一個**虛擬環境**。
+
+虛擬環境是一個**目錄**,與全域環境非常相似,你可以在其中針對某個專案安裝套件。
+
+這樣,每個專案都會有自己的虛擬環境(`.venv` 目錄),其中包含自己的套件。
+
+```mermaid
+flowchart TB
+ subgraph stone-project[專案 philosophers-stone]
+ stone(philosophers-stone) --->|需要| harry-1
+ subgraph venv1[.venv]
+ harry-1[harry v1]
+ end
+ end
+ subgraph azkaban-project[專案 prisoner-of-azkaban]
+ azkaban(prisoner-of-azkaban) --->|需要| harry-3
+ subgraph venv2[.venv]
+ harry-3[harry v3]
+ end
+ end
+ stone-project ~~~ azkaban-project
+```
+
+## 啟用虛擬環境意味著什麼
+
+當你啟用了虛擬環境,例如:
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+或者如果你在 Windows 上使用 Bash(例如
Git Bash):
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+這個命令會建立或修改一些[環境變數](environment-variables.md){.internal-link target=_blank},這些環境變數將在接下來的指令中可用。
+
+其中之一是 `PATH` 變數。
+
+/// tip
+
+你可以在 [環境變數](environment-variables.md#path-environment-variable){.internal-link target=_blank} 部分了解更多關於 `PATH` 環境變數的內容。
+
+///
+
+啟用虛擬環境會將其路徑 `.venv/bin`(在 Linux 和 macOS 上)或 `.venv\Scripts`(在 Windows 上)加入到 `PATH` 環境變數中。
+
+假設在啟用環境之前,`PATH` 變數看起來像這樣:
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+這意味著系統會在以下目錄中查找程式:
+
+* `/usr/bin`
+* `/bin`
+* `/usr/sbin`
+* `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Windows\System32
+```
+
+這意味著系統會在以下目錄中查找程式:
+
+* `C:\Windows\System32`
+
+////
+
+啟用虛擬環境後,`PATH` 變數會變成這樣:
+
+//// tab | Linux, macOS
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+這意味著系統現在會首先在以下目錄中查找程式:
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin
+```
+
+然後再在其他目錄中查找。
+
+因此,當你在終端機中輸入 `python` 時,系統會在以下目錄中找到 Python 程式:
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+並使用這個。
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
+```
+
+這意味著系統現在會首先在以下目錄中查找程式:
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts
+```
+
+然後再在其他目錄中查找。
+
+因此,當你在終端機中輸入 `python` 時,系統會在以下目錄中找到 Python 程式:
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+並使用這個。
+
+////
+
+一個重要的細節是,虛擬環境路徑會被放在 `PATH` 變數的**開頭**。系統會在找到任何其他可用的 Python **之前**找到它。這樣,當你運行 `python` 時,它會使用**虛擬環境中的** Python,而不是任何其他 `python`(例如,全域環境中的 `python`)。
+
+啟用虛擬環境還會改變其他一些內容,但這是它所做的最重要的事情之一。
+
+## 檢查虛擬環境
+
+當你檢查虛擬環境是否啟動時,例如:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+這表示將使用的 `python` 程式是**在虛擬環境中**的那一個。
+
+在 Linux 和 macOS 中使用 `which`,在 Windows PowerShell 中使用 `Get-Command`。
+
+這個指令的運作方式是,它會在 `PATH` 環境變數中搜尋,依序**逐個路徑**查找名為 `python` 的程式。一旦找到,它會**顯示該程式的路徑**。
+
+最重要的是,當你呼叫 `python` 時,將執行的就是這個確切的 "`python`"。
+
+因此,你可以確認是否在正確的虛擬環境中。
+
+/// tip
+
+啟動一個虛擬環境,取得一個 Python,然後**切換到另一個專案**是件很容易的事;
+
+但如果第二個專案**無法正常運作**,那可能是因為你使用了來自其他專案的虛擬環境的、**不正確的 Python**。
+
+因此,檢查正在使用的 `python` 是非常實用的。🤓
+
+///
+
+## 為什麼要停用虛擬環境
+
+例如,你可能正在一個專案 `philosophers-stone` 上工作,**啟動了該虛擬環境**,安裝了套件並使用了該環境,
+
+然後你想要在**另一個專案** `prisoner-of-azkaban` 上工作,
+
+你進入那個專案:
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+```
+
+
+
+如果你不去停用 `philosophers-stone` 的虛擬環境,當你在終端中執行 `python` 時,它會嘗試使用 `philosophers-stone` 中的 Python。
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+$ python main.py
+
+// 匯入 sirius 錯誤,未安裝 😱
+Traceback (most recent call last):
+ File "main.py", line 1, in
+ import sirius
+```
+
+
+
+但如果你停用虛擬環境並啟用 `prisoner-of-askaban` 的新虛擬環境,那麼當你執行 `python` 時,它會使用 `prisoner-of-askaban` 中虛擬環境的 Python。
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// 你不需要在舊目錄中操作停用,你可以在任何地方操作停用,甚至在切換到另一個專案之後 😎
+$ deactivate
+
+// 啟用 prisoner-of-azkaban/.venv 中的虛擬環境 🚀
+$ source .venv/bin/activate
+
+// 現在當你執行 python 時,它會在這個虛擬環境中找到已安裝的 sirius 套件 ✨
+$ python main.py
+
+I solemnly swear 🐺
+```
+
+
+
+## 替代方案
+
+這是一個簡單的指南,幫助你入門並教會你如何理解一切**底層**的原理。
+
+有許多**替代方案**來管理虛擬環境、套件依賴(requirements)、專案。
+
+當你準備好並想要使用一個工具來**管理整個專案**、套件依賴、虛擬環境等,建議你嘗試
uv。
+
+`uv` 可以執行許多操作,它可以:
+
+* 為你**安裝 Python**,包括不同的版本
+* 為你的專案管理**虛擬環境**
+* 安裝**套件**
+* 為你的專案管理套件的**依賴和版本**
+* 確保你有一個**精確**的套件和版本集合來安裝,包括它們的依賴項,這樣你可以確保專案在生產環境中運行的狀態與開發時在你的電腦上運行的狀態完全相同,這被稱為**鎖定**
+* 還有很多其他功能
+
+## 結論
+
+如果你讀過並理解了所有這些,現在**你對虛擬環境的了解已超過許多開發者**。🤓
+
+未來當你為看起來複雜的問題除錯時,了解這些細節很可能會有所幫助,你會知道**它是如何在底層運作的**。😎
diff --git a/docs/zh-hant/mkdocs.yml b/docs/zh-hant/mkdocs.yml
new file mode 100644
index 000000000..de18856f4
--- /dev/null
+++ b/docs/zh-hant/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/zh/docs/advanced/additional-responses.md b/docs/zh/docs/advanced/additional-responses.md
new file mode 100644
index 000000000..362ef9460
--- /dev/null
+++ b/docs/zh/docs/advanced/additional-responses.md
@@ -0,0 +1,221 @@
+# OPENAPI 中的其他响应
+
+您可以声明附加响应,包括附加状态代码、媒体类型、描述等。
+
+这些额外的响应将包含在OpenAPI模式中,因此它们也将出现在API文档中。
+
+但是对于那些额外的响应,你必须确保你直接返回一个像 `JSONResponse` 一样的 `Response` ,并包含你的状态代码和内容。
+
+## `model`附加响应
+您可以向路径操作装饰器传递参数 `responses` 。
+
+它接收一个 `dict`,键是每个响应的状态代码(如`200`),值是包含每个响应信息的其他 `dict`。
+
+每个响应字典都可以有一个关键模型,其中包含一个 `Pydantic` 模型,就像 `response_model` 一样。
+
+**FastAPI**将采用该模型,生成其`JSON Schema`并将其包含在`OpenAPI`中的正确位置。
+
+例如,要声明另一个具有状态码 `404` 和`Pydantic`模型 `Message` 的响应,可以写:
+{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+
+/// note
+
+请记住,您必须直接返回 `JSONResponse` 。
+
+///
+
+/// info
+
+`model` 密钥不是OpenAPI的一部分。
+**FastAPI**将从那里获取`Pydantic`模型,生成` JSON Schema` ,并将其放在正确的位置。
+- 正确的位置是:
+ - 在键 `content` 中,其具有另一个`JSON`对象( `dict` )作为值,该`JSON`对象包含:
+ - 媒体类型的密钥,例如 `application/json` ,它包含另一个`JSON`对象作为值,该对象包含:
+ - 一个键` schema` ,它的值是来自模型的`JSON Schema`,正确的位置在这里。
+ - **FastAPI**在这里添加了对OpenAPI中另一个地方的全局JSON模式的引用,而不是直接包含它。这样,其他应用程序和客户端可以直接使用这些JSON模式,提供更好的代码生成工具等。
+
+///
+
+**在OpenAPI中为该路径操作生成的响应将是:**
+
+```json hl_lines="3-12"
+{
+ "responses": {
+ "404": {
+ "description": "Additional Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Message"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Item"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+}
+
+```
+**模式被引用到OpenAPI模式中的另一个位置:**
+```json hl_lines="4-16"
+{
+ "components": {
+ "schemas": {
+ "Message": {
+ "title": "Message",
+ "required": [
+ "message"
+ ],
+ "type": "object",
+ "properties": {
+ "message": {
+ "title": "Message",
+ "type": "string"
+ }
+ }
+ },
+ "Item": {
+ "title": "Item",
+ "required": [
+ "id",
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "title": "Id",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "type": "string"
+ }
+ }
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": [
+ "loc",
+ "msg",
+ "type"
+ ],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "msg": {
+ "title": "Message",
+ "type": "string"
+ },
+ "type": {
+ "title": "Error Type",
+ "type": "string"
+ }
+ }
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+```
+## 主响应的其他媒体类型
+
+您可以使用相同的 `responses` 参数为相同的主响应添加不同的媒体类型。
+
+例如,您可以添加一个额外的媒体类型` image/png` ,声明您的路径操作可以返回JSON对象(媒体类型 `application/json` )或PNG图像:
+
+{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
+
+/// note
+
+- 请注意,您必须直接使用 `FileResponse` 返回图像。
+
+///
+
+/// info
+
+- 除非在 `responses` 参数中明确指定不同的媒体类型,否则**FastAPI**将假定响应与主响应类具有相同的媒体类型(默认为` application/json` )。
+- 但是如果您指定了一个自定义响应类,并将 `None `作为其媒体类型,**FastAPI**将使用 `application/json` 作为具有关联模型的任何其他响应。
+
+///
+
+## 组合信息
+您还可以联合接收来自多个位置的响应信息,包括 `response_model `、 `status_code` 和 `responses `参数。
+
+您可以使用默认的状态码 `200` (或者您需要的自定义状态码)声明一个 `response_model `,然后直接在OpenAPI模式中在 `responses` 中声明相同响应的其他信息。
+
+**FastAPI**将保留来自 `responses` 的附加信息,并将其与模型中的JSON Schema结合起来。
+
+例如,您可以使用状态码 `404` 声明响应,该响应使用`Pydantic`模型并具有自定义的` description` 。
+
+以及一个状态码为 `200` 的响应,它使用您的 `response_model` ,但包含自定义的 `example` :
+
+{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+
+所有这些都将被合并并包含在您的OpenAPI中,并在API文档中显示:
+
+## 联合预定义响应和自定义响应
+
+您可能希望有一些应用于许多路径操作的预定义响应,但是你想将不同的路径和自定义的相应组合在一块。
+对于这些情况,你可以使用Python的技术,将 `dict` 与 `**dict_to_unpack` 解包:
+```Python
+old_dict = {
+ "old key": "old value",
+ "second old key": "second old value",
+}
+new_dict = {**old_dict, "new key": "new value"}
+```
+
+这里, new_dict 将包含来自 old_dict 的所有键值对加上新的键值对:
+```python
+{
+ "old key": "old value",
+ "second old key": "second old value",
+ "new key": "new value",
+}
+```
+您可以使用该技术在路径操作中重用一些预定义的响应,并将它们与其他自定义响应相结合。
+**例如:**
+{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
+## 有关OpenAPI响应的更多信息
+
+要了解您可以在响应中包含哪些内容,您可以查看OpenAPI规范中的以下部分:
+ + [OpenAPI响应对象](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responsesObject),它包括 Response Object 。
+ + [OpenAPI响应对象](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responseObject),您可以直接在 `responses` 参数中的每个响应中包含任何内容。包括 `description` 、 `headers` 、 `content` (其中是声明不同的媒体类型和JSON Schemas)和 `links` 。
diff --git a/docs/zh/docs/advanced/additional-status-codes.md b/docs/zh/docs/advanced/additional-status-codes.md
index 54ec9775b..b048a2a17 100644
--- a/docs/zh/docs/advanced/additional-status-codes.md
+++ b/docs/zh/docs/advanced/additional-status-codes.md
@@ -14,21 +14,25 @@
要实现它,导入 `JSONResponse`,然后在其中直接返回你的内容,并将 `status_code` 设置为为你要的值。
-```Python hl_lines="4 25"
-{!../../../docs_src/additional_status_codes/tutorial001.py!}
-```
+{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *}
-!!! warning "警告"
- 当你直接返回一个像上面例子中的 `Response` 对象时,它会直接返回。
+/// warning | 警告
- FastAPI 不会用模型等对该响应进行序列化。
+当你直接返回一个像上面例子中的 `Response` 对象时,它会直接返回。
- 确保其中有你想要的数据,且返回的值为合法的 JSON(如果你使用 `JSONResponse` 的话)。
+FastAPI 不会用模型等对该响应进行序列化。
-!!! note "技术细节"
- 你也可以使用 `from starlette.responses import JSONResponse`。
+确保其中有你想要的数据,且返回的值为合法的 JSON(如果你使用 `JSONResponse` 的话)。
- 出于方便,**FastAPI** 为开发者提供同 `starlette.responses` 一样的 `fastapi.responses`。但是大多数可用的响应都是直接来自 Starlette。`status` 也是一样。
+///
+
+/// note | 技术细节
+
+你也可以使用 `from starlette.responses import JSONResponse`。
+
+出于方便,**FastAPI** 为开发者提供同 `starlette.responses` 一样的 `fastapi.responses`。但是大多数可用的响应都是直接来自 Starlette。`status` 也是一样。
+
+///
## OpenAPI 和 API 文档
diff --git a/docs/zh/docs/advanced/advanced-dependencies.md b/docs/zh/docs/advanced/advanced-dependencies.md
new file mode 100644
index 000000000..8375bd48e
--- /dev/null
+++ b/docs/zh/docs/advanced/advanced-dependencies.md
@@ -0,0 +1,65 @@
+# 高级依赖项
+
+## 参数化的依赖项
+
+我们之前看到的所有依赖项都是写死的函数或类。
+
+但也可以为依赖项设置参数,避免声明多个不同的函数或类。
+
+假设要创建校验查询参数 `q` 是否包含固定内容的依赖项。
+
+但此处要把待检验的固定内容定义为参数。
+
+## **可调用**实例
+
+Python 可以把类实例变为**可调用项**。
+
+这里说的不是类本身(类本就是可调用项),而是类实例。
+
+为此,需要声明 `__call__` 方法:
+
+{* ../../docs_src/dependencies/tutorial011.py hl[10] *}
+
+本例中,**FastAPI** 使用 `__call__` 检查附加参数及子依赖项,稍后,还要调用它向*路径操作函数*传递值。
+
+## 参数化实例
+
+接下来,使用 `__init__` 声明用于**参数化**依赖项的实例参数:
+
+{* ../../docs_src/dependencies/tutorial011.py hl[7] *}
+
+本例中,**FastAPI** 不使用 `__init__`,我们要直接在代码中使用。
+
+## 创建实例
+
+使用以下代码创建类实例:
+
+{* ../../docs_src/dependencies/tutorial011.py hl[16] *}
+
+这样就可以**参数化**依赖项,它包含 `checker.fixed_content` 的属性 - `"bar"`。
+
+## 把实例作为依赖项
+
+然后,不要再在 `Depends(checker)` 中使用 `Depends(FixedContentQueryChecker)`, 而是要使用 `checker`,因为依赖项是类实例 - `checker`,不是类。
+
+处理依赖项时,**FastAPI** 以如下方式调用 `checker`:
+
+```Python
+checker(q="somequery")
+```
+
+……并用*路径操作函数*的参数 `fixed_content_included` 返回依赖项的值:
+
+{* ../../docs_src/dependencies/tutorial011.py hl[20] *}
+
+/// tip | 提示
+
+本章示例有些刻意,也看不出有什么用处。
+
+这个简例只是为了说明高级依赖项的运作机制。
+
+在有关安全的章节中,工具函数将以这种方式实现。
+
+只要能理解本章内容,就能理解安全工具背后的运行机制。
+
+///
diff --git a/docs/zh/docs/advanced/async-tests.md b/docs/zh/docs/advanced/async-tests.md
new file mode 100644
index 000000000..b5ac15b5b
--- /dev/null
+++ b/docs/zh/docs/advanced/async-tests.md
@@ -0,0 +1,99 @@
+# 异步测试
+
+您已经了解了如何使用 `TestClient` 测试 **FastAPI** 应用程序。但是到目前为止,您只了解了如何编写同步测试,而没有使用 `async` 异步函数。
+
+在测试中能够使用异步函数可能会很有用,比如当您需要异步查询数据库的时候。想象一下,您想要测试向 FastAPI 应用程序发送请求,然后验证您的后端是否成功在数据库中写入了正确的数据,与此同时您使用了异步的数据库的库。
+
+让我们看看如何才能实现这一点。
+
+## pytest.mark.anyio
+
+如果我们想在测试中调用异步函数,那么我们的测试函数必须是异步的。 AnyIO 为此提供了一个简洁的插件,它允许我们指定一些测试函数要异步调用。
+
+## HTTPX
+
+即使您的 **FastAPI** 应用程序使用普通的 `def` 函数而不是 `async def` ,它本质上仍是一个 `async` 异步应用程序。
+
+`TestClient` 在内部通过一些“魔法”操作,使得您可以在普通的 `def` 测试函数中调用异步的 FastAPI 应用程序,并使用标准的 pytest。但当我们在异步函数中使用它时,这种“魔法”就不再生效了。由于测试以异步方式运行,我们无法在测试函数中继续使用 `TestClient`。
+
+`TestClient` 是基于
HTTPX 的。幸运的是,我们可以直接使用它来测试API。
+
+## 示例
+
+举个简单的例子,让我们来看一个[更大的应用](../tutorial/bigger-applications.md){.internal-link target=_blank}和[测试](../tutorial/testing.md){.internal-link target=_blank}中描述的类似文件结构:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+文件 `main.py` 将包含:
+
+{* ../../docs_src/async_tests/main.py *}
+
+文件 `test_main.py` 将包含针对 `main.py` 的测试,现在它可能看起来如下:
+
+{* ../../docs_src/async_tests/test_main.py *}
+
+## 运行测试
+
+您可以通过以下方式照常运行测试:
+
+
+
+```console
+$ pytest
+
+---> 100%
+```
+
+
+
+## 详细说明
+
+这个标记 `@pytest.mark.anyio` 会告诉 pytest 该测试函数应该被异步调用:
+
+{* ../../docs_src/async_tests/test_main.py hl[7] *}
+
+/// tip
+
+请注意,测试函数现在用的是 `async def`,而不是像以前使用 `TestClient` 时那样只是 `def` 。
+
+///
+
+我们现在可以使用应用程序创建一个 `AsyncClient` ,并使用 `await` 向其发送异步请求。
+
+{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+
+这相当于:
+
+```Python
+response = client.get('/')
+```
+
+我们曾经通过它向 `TestClient` 发出请求。
+
+/// tip
+
+请注意,我们正在将 async/await 与新的 `AsyncClient` 一起使用——请求是异步的。
+
+///
+
+/// warning
+
+如果您的应用程序依赖于生命周期事件, `AsyncClient` 将不会触发这些事件。为了确保它们被触发,请使用
florimondmanca/asgi-lifespan 中的 `LifespanManager` 。
+
+///
+
+## 其他异步函数调用
+
+由于测试函数现在是异步的,因此除了在测试中向 FastAPI 应用程序发送请求之外,您现在还可以调用(和使用 `await` 等待)其他 `async` 异步函数,就和您在代码中的其他任何地方调用它们的方法一样。
+
+/// tip
+
+如果您在测试程序中集成异步函数调用的时候遇到一个 `RuntimeError: Task attached to a different loop` 的报错(例如,使用
MongoDB 的 MotorClient 时),请记住,只能在异步函数中实例化需要事件循环的对象,例如通过 `'@app.on_event("startup")` 回调函数进行初始化。
+
+///
diff --git a/docs/zh/docs/advanced/behind-a-proxy.md b/docs/zh/docs/advanced/behind-a-proxy.md
new file mode 100644
index 000000000..f8f61c8a3
--- /dev/null
+++ b/docs/zh/docs/advanced/behind-a-proxy.md
@@ -0,0 +1,357 @@
+# 使用代理
+
+有些情况下,您可能要使用 Traefik 或 Nginx 等**代理**服务器,并添加应用不能识别的附加路径前缀配置。
+
+此时,要使用 `root_path` 配置应用。
+
+`root_path` 是 ASGI 规范提供的机制,FastAPI 就是基于此规范开发的(通过 Starlette)。
+
+`root_path` 用于处理这些特定情况。
+
+在挂载子应用时,也可以在内部使用。
+
+## 移除路径前缀的代理
+
+本例中,移除路径前缀的代理是指在代码中声明路径 `/app`,然后在应用顶层添加代理,把 **FastAPI** 应用放在 `/api/v1` 路径下。
+
+本例的原始路径 `/app` 实际上是在 `/api/v1/app` 提供服务。
+
+哪怕所有代码都假设只有 `/app`。
+
+代理只在把请求传送给 Uvicorn 之前才会**移除路径前缀**,让应用以为它是在 `/app` 提供服务,因此不必在代码中加入前缀 `/api/v1`。
+
+但之后,在(前端)打开 API 文档时,代理会要求在 `/openapi.json`,而不是 `/api/v1/openapi.json` 中提取 OpenAPI 概图。
+
+因此, (运行在浏览器中的)前端会尝试访问 `/openapi.json`,但没有办法获取 OpenAPI 概图。
+
+这是因为应用使用了以 `/api/v1` 为路径前缀的代理,前端要从 `/api/v1/openapi.json` 中提取 OpenAPI 概图。
+
+```mermaid
+graph LR
+
+browser("Browser")
+proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
+server["Server on http://127.0.0.1:8000/app"]
+
+browser --> proxy
+proxy --> server
+```
+
+/// tip | 提示
+
+IP `0.0.0.0` 常用于指程序监听本机或服务器上的所有有效 IP。
+
+///
+
+API 文档还需要 OpenAPI 概图声明 API `server` 位于 `/api/v1`(使用代理时的 URL)。例如:
+
+```JSON hl_lines="4-8"
+{
+ "openapi": "3.0.2",
+ // More stuff here
+ "servers": [
+ {
+ "url": "/api/v1"
+ }
+ ],
+ "paths": {
+ // More stuff here
+ }
+}
+```
+
+本例中的 `Proxy` 是 **Traefik**,`server` 是运行 FastAPI 应用的 **Uvicorn**。
+
+### 提供 `root_path`
+
+为此,要以如下方式使用命令行选项 `--root-path`:
+
+
+
+```console
+$ uvicorn main:app --root-path /api/v1
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Hypercorn 也支持 `--root-path `选项。
+
+/// note | 技术细节
+
+ASGI 规范定义的 `root_path` 就是为了这种用例。
+
+并且 `--root-path` 命令行选项支持 `root_path`。
+
+///
+
+### 查看当前的 `root_path`
+
+获取应用为每个请求使用的当前 `root_path`,这是 `scope` 字典的内容(也是 ASGI 规范的内容)。
+
+我们在这里的信息里包含 `roo_path` 只是为了演示。
+
+{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
+
+然后,用以下命令启动 Uvicorn:
+
+
+
+```console
+$ uvicorn main:app --root-path /api/v1
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+返回的响应如下:
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+### 在 FastAPI 应用里设置 `root_path`
+
+还有一种方案,如果不能提供 `--root-path` 或等效的命令行选项,则在创建 FastAPI 应用时要设置 `root_path` 参数。
+
+{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
+
+传递 `root_path` 给 `FastAPI` 与传递 `--root-path` 命令行选项给 Uvicorn 或 Hypercorn 一样。
+
+### 关于 `root_path`
+
+注意,服务器(Uvicorn)只是把 `root_path` 传递给应用。
+
+在浏览器中输入
http://127.0.0.1:8000/app 时能看到标准响应:
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+它不要求访问 `http://127.0.0.1:800/api/v1/app`。
+
+Uvicorn 预期代理在 `http://127.0.0.1:8000/app` 访问 Uvicorn,而在顶部添加 `/api/v1` 前缀是代理要做的事情。
+
+## 关于移除路径前缀的代理
+
+注意,移除路径前缀的代理只是配置代理的方式之一。
+
+大部分情况下,代理默认都不会移除路径前缀。
+
+(未移除路径前缀时)代理监听 `https://myawesomeapp.com` 等对象,如果浏览器跳转到 `https://myawesomeapp.com/api/v1/app`,且服务器(例如 Uvicorn)监听 `http://127.0.0.1:8000` 代理(未移除路径前缀) 会在同样的路径:`http://127.0.0.1:8000/api/v1/app` 访问 Uvicorn。
+
+## 本地测试 Traefik
+
+您可以轻易地在本地使用
Traefik 运行移除路径前缀的试验。
+
+
下载 Traefik,这是一个二进制文件,需要解压文件,并在 Terminal 中直接运行。
+
+然后创建包含如下内容的 `traefik.toml` 文件:
+
+```TOML hl_lines="3"
+[entryPoints]
+ [entryPoints.http]
+ address = ":9999"
+
+[providers]
+ [providers.file]
+ filename = "routes.toml"
+```
+
+这个文件把 Traefik 监听端口设置为 `9999`,并设置要使用另一个文件 `routes.toml`。
+
+/// tip | 提示
+
+使用端口 9999 代替标准的 HTTP 端口 80,这样就不必使用管理员权限运行(`sudo`)。
+
+///
+
+接下来,创建 `routes.toml`:
+
+```TOML hl_lines="5 12 20"
+[http]
+ [http.middlewares]
+
+ [http.middlewares.api-stripprefix.stripPrefix]
+ prefixes = ["/api/v1"]
+
+ [http.routers]
+
+ [http.routers.app-http]
+ entryPoints = ["http"]
+ service = "app"
+ rule = "PathPrefix(`/api/v1`)"
+ middlewares = ["api-stripprefix"]
+
+ [http.services]
+
+ [http.services.app]
+ [http.services.app.loadBalancer]
+ [[http.services.app.loadBalancer.servers]]
+ url = "http://127.0.0.1:8000"
+```
+
+这个文件配置 Traefik 使用路径前缀 `/api/v1`。
+
+然后,它把请求重定位到运行在 `http://127.0.0.1:8000` 上的 Uvicorn。
+
+现在,启动 Traefik:
+
+
+
+```console
+$ ./traefik --configFile=traefik.toml
+
+INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
+```
+
+
+
+接下来,使用 Uvicorn 启动应用,并使用 `--root-path` 选项:
+
+
+
+```console
+$ uvicorn main:app --root-path /api/v1
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### 查看响应
+
+访问含 Uvicorn 端口的 URL:
http://127.0.0.1:8000/app,就能看到标准响应:
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+/// tip | 提示
+
+注意,就算访问 `http://127.0.0.1:8000/app`,也显示从选项 `--root-path` 中提取的 `/api/v1`,这是 `root_path` 的值。
+
+///
+
+打开含 Traefik 端口的 URL,包含路径前缀:
http://127.0.0.1:9999/api/v1/app。
+
+得到同样的响应:
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+但这一次 URL 包含了代理提供的路径前缀:`/api/v1`。
+
+当然,这是通过代理访问应用的方式,因此,路径前缀 `/app/v1` 版本才是**正确**的。
+
+而不带路径前缀的版本(`http://127.0.0.1:8000/app`),则由 Uvicorn 直接提供,专供*代理*(Traefik)访问。
+
+这演示了代理(Traefik)如何使用路径前缀,以及服务器(Uvicorn)如何使用选项 `--root-path` 中的 `root_path`。
+
+### 查看文档
+
+但这才是有趣的地方 ✨
+
+访问应用的**官方**方式是通过含路径前缀的代理。因此,不出所料,如果没有在 URL 中添加路径前缀,直接访问通过 Uvicorn 运行的 API 文档,不能正常访问,因为需要通过代理才能访问。
+
+输入
http://127.0.0.1:8000/docs 查看 API 文档:
+
+

+
+但输入**官方**链接 `/api/v1/docs`,并使用端口 `9999` 访问 API 文档,就能正常运行了!🎉
+
+输入
http://127.0.0.1:9999/api/v1/docs 查看文档:
+
+

+
+一切正常。 ✔️
+
+这是因为 FastAPI 在 OpenAPI 里使用 `root_path` 提供的 URL 创建默认 `server`。
+
+## 附加的服务器
+
+/// warning | 警告
+
+此用例较难,可以跳过。
+
+///
+
+默认情况下,**FastAPI** 使用 `root_path` 的链接在 OpenAPI 概图中创建 `server`。
+
+但也可以使用其它备选 `servers`,例如,需要同一个 API 文档与 staging 和生产环境交互。
+
+如果传递自定义 `servers` 列表,并有 `root_path`( 因为 API 使用了代理),**FastAPI** 会在列表开头使用这个 `root_path` 插入**服务器**。
+
+例如:
+
+{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
+
+这段代码生产如下 OpenAPI 概图:
+
+```JSON hl_lines="5-7"
+{
+ "openapi": "3.0.2",
+ // More stuff here
+ "servers": [
+ {
+ "url": "/api/v1"
+ },
+ {
+ "url": "https://stag.example.com",
+ "description": "Staging environment"
+ },
+ {
+ "url": "https://prod.example.com",
+ "description": "Production environment"
+ }
+ ],
+ "paths": {
+ // More stuff here
+ }
+}
+```
+
+/// tip | 提示
+
+注意,自动生成服务器时,`url` 的值 `/api/v1` 提取自 `roog_path`。
+
+///
+
+
http://127.0.0.1:9999/api/v1/docs 的 API 文档所示如下:
+
+

+
+/// tip | 提示
+
+API 文档与所选的服务器进行交互。
+
+///
+
+### 从 `root_path` 禁用自动服务器
+
+如果不想让 **FastAPI** 包含使用 `root_path` 的自动服务器,则要使用参数 `root_path_in_servers=False`:
+
+{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
+
+这样,就不会在 OpenAPI 概图中包含服务器了。
+
+## 挂载子应用
+
+如需挂载子应用(详见 [子应用 - 挂载](sub-applications.md){.internal-link target=_blank}),也要通过 `root_path` 使用代理,这与正常应用一样,别无二致。
+
+FastAPI 在内部使用 `root_path`,因此子应用也可以正常运行。✨
diff --git a/docs/zh/docs/advanced/custom-response.md b/docs/zh/docs/advanced/custom-response.md
index 155ce2882..22a9b4b51 100644
--- a/docs/zh/docs/advanced/custom-response.md
+++ b/docs/zh/docs/advanced/custom-response.md
@@ -12,8 +12,11 @@
并且如果该 `Response` 有一个 JSON 媒体类型(`application/json`),比如使用 `JSONResponse` 或者 `UJSONResponse` 的时候,返回的数据将使用你在路径操作装饰器中声明的任何 Pydantic 的 `response_model` 自动转换(和过滤)。
-!!! note "说明"
- 如果你使用不带有任何媒体类型的响应类,FastAPI 认为你的响应没有任何内容,所以不会在生成的OpenAPI文档中记录响应格式。
+/// note | 说明
+
+如果你使用不带有任何媒体类型的响应类,FastAPI 认为你的响应没有任何内容,所以不会在生成的OpenAPI文档中记录响应格式。
+
+///
## 使用 `ORJSONResponse`
@@ -21,21 +24,23 @@
导入你想要使用的 `Response` 类(子类)然后在 *路径操作装饰器* 中声明它。
-```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001b.py!}
-```
+{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
+
+/// info | 提示
-!!! info "提示"
- 参数 `response_class` 也会用来定义响应的「媒体类型」。
+参数 `response_class` 也会用来定义响应的「媒体类型」。
- 在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `application/json`。
+在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `application/json`。
- 并且在 OpenAPI 文档中也会这样记录。
+并且在 OpenAPI 文档中也会这样记录。
-!!! tip "小贴士"
- `ORJSONResponse` 目前只在 FastAPI 中可用,而在 Starlette 中不可用。
+///
+/// tip | 小贴士
+`ORJSONResponse` 目前只在 FastAPI 中可用,而在 Starlette 中不可用。
+
+///
## HTML 响应
@@ -44,16 +49,17 @@
* 导入 `HTMLResponse`。
* 将 `HTMLResponse` 作为你的 *路径操作* 的 `response_class` 参数传入。
-```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial002.py!}
-```
+{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
+
+/// info | 提示
-!!! info "提示"
- 参数 `response_class` 也会用来定义响应的「媒体类型」。
+参数 `response_class` 也会用来定义响应的「媒体类型」。
- 在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `text/html`。
+在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `text/html`。
- 并且在 OpenAPI 文档中也会这样记录。
+并且在 OpenAPI 文档中也会这样记录。
+
+///
### 返回一个 `Response`
@@ -61,15 +67,19 @@
和上面一样的例子,返回一个 `HTMLResponse` 看起来可能是这样:
-```Python hl_lines="2 7 19"
-{!../../../docs_src/custom_response/tutorial003.py!}
-```
+{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
+
+/// warning | 警告
+
+*路径操作函数* 直接返回的 `Response` 不会被 OpenAPI 的文档记录(比如,`Content-Type` 不会被文档记录),并且在自动化交互文档中也是不可见的。
+
+///
-!!! warning "警告"
- *路径操作函数* 直接返回的 `Response` 不会被 OpenAPI 的文档记录(比如,`Content-Type` 不会被文档记录),并且在自动化交互文档中也是不可见的。
+/// info | 提示
-!!! info "提示"
- 当然,实际的 `Content-Type` 头,状态码等等,将来自于你返回的 `Response` 对象。
+当然,实际的 `Content-Type` 头,状态码等等,将来自于你返回的 `Response` 对象。
+
+///
### OpenAPI 中的文档和重载 `Response`
@@ -81,9 +91,7 @@
比如像这样:
-```Python hl_lines="7 23 21"
-{!../../../docs_src/custom_response/tutorial004.py!}
-```
+{* ../../docs_src/custom_response/tutorial004.py hl[7,23,21] *}
在这个例子中,函数 `generate_html_response()` 已经生成并返回 `Response` 对象而不是在 `str` 中返回 HTML。
@@ -99,10 +107,13 @@
要记得你可以使用 `Response` 来返回任何其他东西,甚至创建一个自定义的子类。
-!!! note "技术细节"
- 你也可以使用 `from starlette.responses import HTMLResponse`。
+/// note | 技术细节
+
+你也可以使用 `from starlette.responses import HTMLResponse`。
+
+**FastAPI** 提供了同 `fastapi.responses` 相同的 `starlette.responses` 只是为了方便开发者。但大多数可用的响应都直接来自 Starlette。
- **FastAPI** 提供了同 `fastapi.responses` 相同的 `starlette.responses` 只是为了方便开发者。但大多数可用的响应都直接来自 Starlette。
+///
### `Response`
@@ -120,9 +131,7 @@
FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它还将包含一个基于 media_type 的 Content-Type 头,并为文本类型附加一个字符集。
-```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
-```
+{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
### `HTMLResponse`
@@ -132,9 +141,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
接受文本或字节并返回纯文本响应。
-```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial005.py!}
-```
+{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
### `JSONResponse`
@@ -151,31 +158,31 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
`UJSONResponse` 是一个使用
`ujson` 的可选 JSON 响应。
-!!! warning "警告"
- 在处理某些边缘情况时,`ujson` 不如 Python 的内置实现那么谨慎。
+/// warning | 警告
+
+在处理某些边缘情况时,`ujson` 不如 Python 的内置实现那么谨慎。
+
+///
-```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001.py!}
-```
+{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
-!!! tip "小贴士"
- `ORJSONResponse` 可能是一个更快的选择。
+/// tip | 小贴士
+
+`ORJSONResponse` 可能是一个更快的选择。
+
+///
### `RedirectResponse`
返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。
-```Python hl_lines="2 9"
-{!../../../docs_src/custom_response/tutorial006.py!}
-```
+{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
### `StreamingResponse`
采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。
-```Python hl_lines="2 14"
-{!../../../docs_src/custom_response/tutorial007.py!}
-```
+{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
#### 对类似文件的对象使用 `StreamingResponse`
@@ -183,12 +190,13 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
包括许多与云存储,视频处理等交互的库。
-```Python hl_lines="2 10-12 14"
-{!../../../docs_src/custom_response/tutorial008.py!}
-```
+{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
+
+/// tip | 小贴士
+
+注意在这里,因为我们使用的是不支持 `async` 和 `await` 的标准 `open()`,我们使用普通的 `def` 声明了路径操作。
-!!! tip "小贴士"
- 注意在这里,因为我们使用的是不支持 `async` 和 `await` 的标准 `open()`,我们使用普通的 `def` 声明了路径操作。
+///
### `FileResponse`
@@ -203,9 +211,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
文件响应将包含适当的 `Content-Length`,`Last-Modified` 和 `ETag` 的响应头。
-```Python hl_lines="2 10"
-{!../../../docs_src/custom_response/tutorial009.py!}
-```
+{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
## 额外文档
diff --git a/docs/zh/docs/advanced/dataclasses.md b/docs/zh/docs/advanced/dataclasses.md
new file mode 100644
index 000000000..c74ce65c3
--- /dev/null
+++ b/docs/zh/docs/advanced/dataclasses.md
@@ -0,0 +1,97 @@
+# 使用数据类
+
+FastAPI 基于 **Pydantic** 构建,前文已经介绍过如何使用 Pydantic 模型声明请求与响应。
+
+但 FastAPI 还可以使用数据类(
`dataclasses`):
+
+{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
+
+这还是借助于 **Pydantic** 及其
内置的 `dataclasses`。
+
+因此,即便上述代码没有显式使用 Pydantic,FastAPI 仍会使用 Pydantic 把标准数据类转换为 Pydantic 数据类(`dataclasses`)。
+
+并且,它仍然支持以下功能:
+
+* 数据验证
+* 数据序列化
+* 数据存档等
+
+数据类的和运作方式与 Pydantic 模型相同。实际上,它的底层使用的也是 Pydantic。
+
+/// info | 说明
+
+注意,数据类不支持 Pydantic 模型的所有功能。
+
+因此,开发时仍需要使用 Pydantic 模型。
+
+但如果数据类很多,这一技巧能给 FastAPI 开发 Web API 增添不少助力。🤓
+
+///
+
+## `response_model` 使用数据类
+
+在 `response_model` 参数中使用 `dataclasses`:
+
+{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
+
+本例把数据类自动转换为 Pydantic 数据类。
+
+API 文档中也会显示相关概图:
+
+

+
+## 在嵌套数据结构中使用数据类
+
+您还可以把 `dataclasses` 与其它类型注解组合在一起,创建嵌套数据结构。
+
+还有一些情况也可以使用 Pydantic 的 `dataclasses`。例如,在 API 文档中显示错误。
+
+本例把标准的 `dataclasses` 直接替换为 `pydantic.dataclasses`:
+
+```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
+{!../../docs_src/dataclasses/tutorial003.py!}
+```
+
+1. 本例依然要从标准的 `dataclasses` 中导入 `field`;
+
+2. 使用 `pydantic.dataclasses` 直接替换 `dataclasses`;
+
+3. `Author` 数据类包含 `Item` 数据类列表;
+
+4. `Author` 数据类用于 `response_model` 参数;
+
+5. 其它带有数据类的标准类型注解也可以作为请求体;
+
+ 本例使用的是 `Item` 数据类列表;
+
+6. 这行代码返回的是包含 `items` 的字典,`items` 是数据类列表;
+
+ FastAPI 仍能把数据
序列化为 JSON;
+
+7. 这行代码中,`response_model` 的类型注解是 `Author` 数据类列表;
+
+ 再一次,可以把 `dataclasses` 与标准类型注解一起使用;
+
+8. 注意,*路径操作函数*使用的是普通函数,不是异步函数;
+
+ 与往常一样,在 FastAPI 中,可以按需组合普通函数与异步函数;
+
+ 如果不清楚何时使用异步函数或普通函数,请参阅**急不可待?**一节中对
`async` 与 `await` 的说明;
+
+9. *路径操作函数*返回的不是数据类(虽然它可以返回数据类),而是返回内含数据的字典列表;
+
+ FastAPI 使用(包含数据类的) `response_model` 参数转换响应。
+
+把 `dataclasses` 与其它类型注解组合在一起,可以组成不同形式的复杂数据结构。
+
+更多内容详见上述代码内的注释。
+
+## 深入学习
+
+您还可以把 `dataclasses` 与其它 Pydantic 模型组合在一起,继承合并的模型,把它们包含在您自己的模型里。
+
+详见
Pydantic 官档 - 数据类。
+
+## 版本
+
+本章内容自 FastAPI `0.67.0` 版起生效。🔖
diff --git a/docs/zh/docs/advanced/events.md b/docs/zh/docs/advanced/events.md
new file mode 100644
index 000000000..5ade0f0ff
--- /dev/null
+++ b/docs/zh/docs/advanced/events.md
@@ -0,0 +1,173 @@
+# 生命周期事件
+
+你可以定义在应用**启动**前执行的逻辑(代码)。这意味着在应用**开始接收请求**之前,这些代码只会被执行**一次**。
+
+同样地,你可以定义在应用**关闭**时应执行的逻辑。在这种情况下,这段代码将在**处理可能的多次请求后**执行**一次**。
+
+因为这段代码在应用开始接收请求**之前**执行,也会在处理可能的若干请求**之后**执行,它覆盖了整个应用程序的**生命周期**("生命周期"这个词很重要😉)。
+
+这对于设置你需要在整个应用中使用的**资源**非常有用,这些资源在请求之间**共享**,你可能需要在之后进行**释放**。例如,数据库连接池,或加载一个共享的机器学习模型。
+
+## 用例
+
+让我们从一个示例用例开始,看看如何解决它。
+
+假设你有几个**机器学习的模型**,你想要用它们来处理请求。
+
+相同的模型在请求之间是共享的,因此并非每个请求或每个用户各自拥有一个模型。
+
+假设加载模型可能**需要相当长的时间**,因为它必须从**磁盘**读取大量数据。因此你不希望每个请求都加载它。
+
+你可以在模块/文件的顶部加载它,但这也意味着即使你只是在运行一个简单的自动化测试,它也会**加载模型**,这样测试将**变慢**,因为它必须在能够独立运行代码的其他部分之前等待模型加载完成。
+
+这就是我们要解决的问题——在处理请求前加载模型,但只是在应用开始接收请求前,而不是代码执行时。
+
+## 生命周期 lifespan
+
+你可以使用`FastAPI()`应用的`lifespan`参数和一个上下文管理器(稍后我将为你展示)来定义**启动**和**关闭**的逻辑。
+
+让我们从一个例子开始,然后详细介绍。
+
+我们使用`yield`创建了一个异步函数`lifespan()`像这样:
+
+```Python hl_lines="16 19"
+{!../../docs_src/events/tutorial003.py!}
+```
+
+在这里,我们在 `yield` 之前将(虚拟的)模型函数放入机器学习模型的字典中,以此模拟加载模型的耗时**启动**操作。这段代码将在应用程序**开始处理请求之前**执行,即**启动**期间。
+
+然后,在 `yield` 之后,我们卸载模型。这段代码将会在应用程序**完成处理请求后**执行,即在**关闭**之前。这可以释放诸如内存或 GPU 之类的资源。
+
+/// tip | 提示
+
+**关闭**事件只会在你停止应用时触发。
+
+可能你需要启动一个新版本,或者你只是你厌倦了运行它。 🤷
+
+///
+
+## 生命周期函数
+
+首先要注意的是,我们定义了一个带有 `yield` 的异步函数。这与带有 `yield` 的依赖项非常相似。
+
+```Python hl_lines="14-19"
+{!../../docs_src/events/tutorial003.py!}
+```
+
+这个函数在 `yield`之前的部分,会在应用启动前执行。
+
+剩下的部分在 `yield` 之后,会在应用完成后执行。
+
+## 异步上下文管理器
+
+如你所见,这个函数有一个装饰器 `@asynccontextmanager` 。
+
+它将函数转化为所谓的“**异步上下文管理器**”。
+
+```Python hl_lines="1 13"
+{!../../docs_src/events/tutorial003.py!}
+```
+
+在 Python 中, **上下文管理器**是一个你可以在 `with` 语句中使用的东西,例如,`open()` 可以作为上下文管理器使用。
+
+```Python
+with open("file.txt") as file:
+ file.read()
+```
+
+Python 的最近几个版本也有了一个**异步上下文管理器**,你可以通过 `async with` 来使用:
+
+```Python
+async with lifespan(app):
+ await do_stuff()
+```
+
+你可以像上面一样创建了一个上下文管理器或者异步上下文管理器,它的作用是在进入 `with` 块时,执行 `yield` 之前的代码,并且在离开 `with` 块时,执行 `yield` 后面的代码。
+
+但在我们上面的例子里,我们并不是直接使用,而是传递给 FastAPI 来供其使用。
+
+`FastAPI()` 的 `lifespan` 参数接受一个**异步上下文管理器**,所以我们可以把我们新定义的上下文管理器 `lifespan` 传给它。
+
+```Python hl_lines="22"
+{!../../docs_src/events/tutorial003.py!}
+```
+
+## 替代事件(弃用)
+
+/// warning | 警告
+
+配置**启动**和**关闭**事件的推荐方法是使用 `FastAPI()` 应用的 `lifespan` 参数,如前所示。如果你提供了一个 `lifespan` 参数,启动(`startup`)和关闭(`shutdown`)事件处理器将不再生效。要么使用 `lifespan`,要么配置所有事件,两者不能共用。
+
+你可以跳过这一部分。
+
+///
+
+有一种替代方法可以定义在**启动**和**关闭**期间执行的逻辑。
+
+**FastAPI** 支持定义在应用启动前,或应用关闭时执行的事件处理器(函数)。
+
+事件函数既可以声明为异步函数(`async def`),也可以声明为普通函数(`def`)。
+
+### `startup` 事件
+
+使用 `startup` 事件声明 `app` 启动前运行的函数:
+
+{* ../../docs_src/events/tutorial001.py hl[8] *}
+
+本例中,`startup` 事件处理器函数为项目数据库(只是**字典**)提供了一些初始值。
+
+**FastAPI** 支持多个事件处理器函数。
+
+只有所有 `startup` 事件处理器运行完毕,**FastAPI** 应用才开始接收请求。
+
+### `shutdown` 事件
+
+使用 `shutdown` 事件声明 `app` 关闭时运行的函数:
+
+{* ../../docs_src/events/tutorial002.py hl[6] *}
+
+此处,`shutdown` 事件处理器函数在 `log.txt` 中写入一行文本 `Application shutdown`。
+
+/// info | 说明
+
+`open()` 函数中,`mode="a"` 指的是**追加**。因此这行文本会添加在文件已有内容之后,不会覆盖之前的内容。
+
+///
+
+/// tip | 提示
+
+注意,本例使用 Python `open()` 标准函数与文件交互。
+
+这个函数执行 I/O(输入/输出)操作,需要等待内容写进磁盘。
+
+但 `open()` 函数不支持使用 `async` 与 `await`。
+
+因此,声明事件处理函数要使用 `def`,不能使用 `asnyc def`。
+
+///
+
+### `startup` 和 `shutdown` 一起使用
+
+启动和关闭的逻辑很可能是连接在一起的,你可能希望启动某个东西然后结束它,获取一个资源然后释放它等等。
+
+在不共享逻辑或变量的不同函数中处理这些逻辑比较困难,因为你需要在全局变量中存储值或使用类似的方式。
+
+因此,推荐使用 `lifespan` 。
+
+## 技术细节
+
+只是为好奇者提供的技术细节。🤓
+
+在底层,这部分是
生命周期协议的一部分,参见 ASGI 技术规范,定义了称为启动(`startup`)和关闭(`shutdown`)的事件。
+
+/// info | 说明
+
+有关事件处理器的详情,请参阅
Starlette 官档 - 事件。
+
+包括如何处理生命周期状态,这可以用于程序的其他部分。
+
+///
+
+## 子应用
+
+🚨 **FastAPI** 只会触发主应用中的生命周期事件,不包括[子应用 - 挂载](sub-applications.md){.internal-link target=_blank}中的。
diff --git a/docs/zh/docs/advanced/generate-clients.md b/docs/zh/docs/advanced/generate-clients.md
new file mode 100644
index 000000000..bcb9ba2bf
--- /dev/null
+++ b/docs/zh/docs/advanced/generate-clients.md
@@ -0,0 +1,237 @@
+# 生成客户端
+
+因为 **FastAPI** 是基于OpenAPI规范的,自然您可以使用许多相匹配的工具,包括自动生成API文档 (由 Swagger UI 提供)。
+
+一个不太明显而又特别的优势是,你可以为你的API针对不同的**编程语言**来**生成客户端**(有时候被叫做
**SDKs** )。
+
+## OpenAPI 客户端生成
+
+有许多工具可以从**OpenAPI**生成客户端。
+
+一个常见的工具是
OpenAPI Generator。
+
+如果您正在开发**前端**,一个非常有趣的替代方案是
openapi-ts。
+
+## 生成一个 TypeScript 前端客户端
+
+让我们从一个简单的 FastAPI 应用开始:
+
+{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
+
+请注意,*路径操作* 定义了他们所用于请求数据和回应数据的模型,所使用的模型是`Item` 和 `ResponseMessage`。
+
+### API 文档
+
+如果您访问API文档,您将看到它具有在请求中发送和在响应中接收数据的**模式(schemas)**:
+
+

+
+您可以看到这些模式,因为它们是用程序中的模型声明的。
+
+那些信息可以在应用的 **OpenAPI模式** 被找到,然后显示在API文档中(通过Swagger UI)。
+
+OpenAPI中所包含的模型里有相同的信息可以用于 **生成客户端代码**。
+
+### 生成一个TypeScript 客户端
+
+现在我们有了带有模型的应用,我们可以为前端生成客户端代码。
+
+#### 安装 `openapi-ts`
+
+您可以使用以下工具在前端代码中安装 `openapi-ts`:
+
+
+
+```console
+$ npm install @hey-api/openapi-ts --save-dev
+
+---> 100%
+```
+
+
+
+#### 生成客户端代码
+
+要生成客户端代码,您可以使用现在将要安装的命令行应用程序 `openapi-ts`。
+
+因为它安装在本地项目中,所以您可能无法直接使用此命令,但您可以将其放在 `package.json` 文件中。
+
+它可能看起来是这样的:
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "@hey-api/openapi-ts": "^0.27.38",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+在这里添加 NPM `generate-client` 脚本后,您可以使用以下命令运行它:
+
+
+
+```console
+$ npm run generate-client
+
+frontend-app@1.0.0 generate-client /home/user/code/frontend-app
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
+```
+
+
+
+此命令将在 `./src/client` 中生成代码,并将在其内部使用 `axios`(前端HTTP库)。
+
+### 尝试客户端代码
+
+现在您可以导入并使用客户端代码,它可能看起来像这样,请注意,您可以为这些方法使用自动补全:
+
+

+
+您还将自动补全要发送的数据:
+
+

+
+/// tip
+
+请注意, `name` 和 `price` 的自动补全,是通过其在`Item`模型(FastAPI)中的定义实现的。
+
+///
+
+如果发送的数据字段不符,你也会看到编辑器的错误提示:
+
+

+
+响应(response)对象也拥有自动补全:
+
+

+
+## 带有标签的 FastAPI 应用
+
+在许多情况下,你的FastAPI应用程序会更复杂,你可能会使用标签来分隔不同组的*路径操作(path operations)*。
+
+例如,您可以有一个用 `items` 的部分和另一个用于 `users` 的部分,它们可以用标签来分隔:
+
+{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
+
+### 生成带有标签的 TypeScript 客户端
+
+如果您使用标签为FastAPI应用生成客户端,它通常也会根据标签分割客户端代码。
+
+通过这种方式,您将能够为客户端代码进行正确地排序和分组:
+
+

+
+在这个案例中,您有:
+
+* `ItemsService`
+* `UsersService`
+
+### 客户端方法名称
+
+现在生成的方法名像 `createItemItemsPost` 看起来不太简洁:
+
+```TypeScript
+ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
+```
+
+...这是因为客户端生成器为每个 *路径操作* 使用OpenAPI的内部 **操作 ID(operation ID)**。
+
+OpenAPI要求每个操作 ID 在所有 *路径操作* 中都是唯一的,因此 FastAPI 使用**函数名**、**路径**和**HTTP方法/操作**来生成此操作ID,因为这样可以确保这些操作 ID 是唯一的。
+
+但接下来我会告诉你如何改进。 🤓
+
+## 自定义操作ID和更好的方法名
+
+您可以**修改**这些操作ID的**生成**方式,以使其更简洁,并在客户端中具有**更简洁的方法名称**。
+
+在这种情况下,您必须确保每个操作ID在其他方面是**唯一**的。
+
+例如,您可以确保每个*路径操作*都有一个标签,然后根据**标签**和*路径操作***名称**(函数名)来生成操作ID。
+
+### 自定义生成唯一ID函数
+
+FastAPI为每个*路径操作*使用一个**唯一ID**,它用于**操作ID**,也用于任何所需自定义模型的名称,用于请求或响应。
+
+你可以自定义该函数。它接受一个 `APIRoute` 对象作为输入,并输出一个字符串。
+
+例如,以下是一个示例,它使用第一个标签(你可能只有一个标签)和*路径操作*名称(函数名)。
+
+然后,你可以将这个自定义函数作为 `generate_unique_id_function` 参数传递给 **FastAPI**:
+
+{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
+
+### 使用自定义操作ID生成TypeScript客户端
+
+现在,如果你再次生成客户端,你会发现它具有改善的方法名称:
+
+

+
+正如你所见,现在方法名称中只包含标签和函数名,不再包含URL路径和HTTP操作的信息。
+
+### 预处理用于客户端生成器的OpenAPI规范
+
+生成的代码仍然存在一些**重复的信息**。
+
+我们已经知道该方法与 **items** 相关,因为它在 `ItemsService` 中(从标签中获取),但方法名中仍然有标签名作为前缀。😕
+
+一般情况下对于OpenAPI,我们可能仍然希望保留它,因为这将确保操作ID是**唯一的**。
+
+但对于生成的客户端,我们可以在生成客户端之前**修改** OpenAPI 操作ID,以使方法名称更加美观和**简洁**。
+
+我们可以将 OpenAPI JSON 下载到一个名为`openapi.json`的文件中,然后使用以下脚本**删除此前缀的标签**:
+
+{* ../../docs_src/generate_clients/tutorial004.py *}
+
+通过这样做,操作ID将从类似于 `items-get_items` 的名称重命名为 `get_items` ,这样客户端生成器就可以生成更简洁的方法名称。
+
+### 使用预处理的OpenAPI生成TypeScript客户端
+
+现在,由于最终结果保存在文件openapi.json中,你可以修改 package.json 文件以使用此本地文件,例如:
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "@hey-api/openapi-ts": "^0.27.38",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+生成新的客户端之后,你现在将拥有**清晰的方法名称**,具备**自动补全**、**错误提示**等功能:
+
+

+
+## 优点
+
+当使用自动生成的客户端时,你将获得以下的自动补全功能:
+
+* 方法。
+* 请求体中的数据、查询参数等。
+* 响应数据。
+
+你还将获得针对所有内容的错误提示。
+
+每当你更新后端代码并**重新生成**前端代码时,新的*路径操作*将作为方法可用,旧的方法将被删除,并且其他任何更改将反映在生成的代码中。 🤓
+
+这也意味着如果有任何更改,它将自动**反映**在客户端代码中。如果你**构建**客户端,在使用的数据上存在**不匹配**时,它将报错。
+
+因此,你将在开发周期的早期**检测到许多错误**,而不必等待错误在生产环境中向最终用户展示,然后尝试调试问题所在。 ✨
diff --git a/docs/zh/docs/advanced/index.md b/docs/zh/docs/advanced/index.md
index d71838cd7..6525802fc 100644
--- a/docs/zh/docs/advanced/index.md
+++ b/docs/zh/docs/advanced/index.md
@@ -1,18 +1,21 @@
-# 高级用户指南 - 简介
+# 高级用户指南
## 额外特性
-主要的教程 [教程 - 用户指南](../tutorial/){.internal-link target=_blank} 应该足以让你了解 **FastAPI** 的所有主要特性。
+主要的教程 [教程 - 用户指南](../tutorial/index.md){.internal-link target=_blank} 应该足以让你了解 **FastAPI** 的所有主要特性。
你会在接下来的章节中了解到其他的选项、配置以及额外的特性。
-!!! tip
- 接下来的章节**并不一定是**「高级的」。
+/// tip
- 而且对于你的使用场景来说,解决方案很可能就在其中。
+接下来的章节**并不一定是**「高级的」。
+
+而且对于你的使用场景来说,解决方案很可能就在其中。
+
+///
## 先阅读教程
-你可能仍会用到 **FastAPI** 主教程 [教程 - 用户指南](../tutorial/){.internal-link target=_blank} 中的大多数特性。
+你可能仍会用到 **FastAPI** 主教程 [教程 - 用户指南](../tutorial/index.md){.internal-link target=_blank} 中的大多数特性。
-接下来的章节我们认为你已经读过 [教程 - 用户指南](../tutorial/){.internal-link target=_blank},并且假设你已经知晓其中主要思想。
+接下来的章节我们认为你已经读过 [教程 - 用户指南](../tutorial/index.md){.internal-link target=_blank},并且假设你已经知晓其中主要思想。
diff --git a/docs/zh/docs/advanced/middleware.md b/docs/zh/docs/advanced/middleware.md
new file mode 100644
index 000000000..c7b15b929
--- /dev/null
+++ b/docs/zh/docs/advanced/middleware.md
@@ -0,0 +1,95 @@
+# 高级中间件
+
+用户指南介绍了如何为应用添加[自定义中间件](../tutorial/middleware.md){.internal-link target=_blank} 。
+
+以及如何[使用 `CORSMiddleware` 处理 CORS](../tutorial/cors.md){.internal-link target=_blank}。
+
+本章学习如何使用其它中间件。
+
+## 添加 ASGI 中间件
+
+因为 **FastAPI** 基于 Starlette,且执行
ASGI 规范,所以可以使用任意 ASGI 中间件。
+
+中间件不必是专为 FastAPI 或 Starlette 定制的,只要遵循 ASGI 规范即可。
+
+总之,ASGI 中间件是类,并把 ASGI 应用作为第一个参数。
+
+因此,有些第三方 ASGI 中间件的文档推荐以如下方式使用中间件:
+
+```Python
+from unicorn import UnicornMiddleware
+
+app = SomeASGIApp()
+
+new_app = UnicornMiddleware(app, some_config="rainbow")
+```
+
+但 FastAPI(实际上是 Starlette)提供了一种更简单的方式,能让内部中间件在处理服务器错误的同时,还能让自定义异常处理器正常运作。
+
+为此,要使用 `app.add_middleware()` (与 CORS 中的示例一样)。
+
+```Python
+from fastapi import FastAPI
+from unicorn import UnicornMiddleware
+
+app = FastAPI()
+
+app.add_middleware(UnicornMiddleware, some_config="rainbow")
+```
+
+`app.add_middleware()` 的第一个参数是中间件的类,其它参数则是要传递给中间件的参数。
+
+## 集成中间件
+
+**FastAPI** 为常见用例提供了一些中间件,下面介绍怎么使用这些中间件。
+
+/// note | 技术细节
+
+以下几个示例中也可以使用 `from starlette.middleware.something import SomethingMiddleware`。
+
+**FastAPI** 在 `fastapi.middleware` 中提供的中间件只是为了方便开发者使用,但绝大多数可用的中间件都直接继承自 Starlette。
+
+///
+
+## `HTTPSRedirectMiddleware`
+
+强制所有传入请求必须是 `https` 或 `wss`。
+
+任何传向 `http` 或 `ws` 的请求都会被重定向至安全方案。
+
+{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
+
+## `TrustedHostMiddleware`
+
+强制所有传入请求都必须正确设置 `Host` 请求头,以防 HTTP 主机头攻击。
+
+{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
+
+支持以下参数:
+
+* `allowed_hosts` - 允许的域名(主机名)列表。`*.example.com` 等通配符域名可以匹配子域名,或使用 `allowed_hosts=["*"]` 允许任意主机名,或省略中间件。
+
+如果传入的请求没有通过验证,则发送 `400` 响应。
+
+## `GZipMiddleware`
+
+处理 `Accept-Encoding` 请求头中包含 `gzip` 请求的 GZip 响应。
+
+中间件会处理标准响应与流响应。
+
+{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
+
+支持以下参数:
+
+* `minimum_size` - 小于最小字节的响应不使用 GZip。 默认值是 `500`。
+
+## 其它中间件
+
+除了上述中间件外,FastAPI 还支持其它ASGI 中间件。
+
+例如:
+
+*
Uvicorn 的 `ProxyHeadersMiddleware`
+*
MessagePack
+
+其它可用中间件详见
Starlette 官档 - 中间件 及
ASGI Awesome 列表。
diff --git a/docs/zh/docs/advanced/openapi-callbacks.md b/docs/zh/docs/advanced/openapi-callbacks.md
new file mode 100644
index 000000000..f021eb10a
--- /dev/null
+++ b/docs/zh/docs/advanced/openapi-callbacks.md
@@ -0,0 +1,186 @@
+# OpenAPI 回调
+
+您可以创建触发外部 API 请求的*路径操作* API,这个外部 API 可以是别人创建的,也可以是由您自己创建的。
+
+API 应用调用外部 API 时的流程叫做**回调**。因为外部开发者编写的软件发送请求至您的 API,然后您的 API 要进行回调,并把请求发送至外部 API。
+
+此时,我们需要存档外部 API 的*信息*,比如应该有哪些*路径操作*,返回什么样的请求体,应该返回哪种响应等。
+
+## 使用回调的应用
+
+示例如下。
+
+假设要开发一个创建发票的应用。
+
+发票包括 `id`、`title`(可选)、`customer`、`total` 等属性。
+
+API 的用户 (外部开发者)要在您的 API 内使用 POST 请求创建一条发票记录。
+
+(假设)您的 API 将:
+
+* 把发票发送至外部开发者的消费者
+* 归集现金
+* 把通知发送至 API 的用户(外部开发者)
+ * 通过(从您的 API)发送 POST 请求至外部 API (即**回调**)来完成
+
+## 常规 **FastAPI** 应用
+
+添加回调前,首先看下常规 API 应用是什么样子。
+
+常规 API 应用包含接收 `Invoice` 请求体的*路径操作*,还有包含回调 URL 的查询参数 `callback_url`。
+
+这部分代码很常规,您对绝大多数代码应该都比较熟悉了:
+
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[10:14,37:54] *}
+
+/// tip | 提示
+
+`callback_url` 查询参数使用 Pydantic 的
URL 类型。
+
+///
+
+此处唯一比较新的内容是*路径操作装饰器*中的 `callbacks=invoices_callback_router.routes` 参数,下文介绍。
+
+## 存档回调
+
+实际的回调代码高度依赖于您自己的 API 应用。
+
+并且可能每个应用都各不相同。
+
+回调代码可能只有一两行,比如:
+
+```Python
+callback_url = "https://example.com/api/v1/invoices/events/"
+requests.post(callback_url, json={"description": "Invoice paid", "paid": True})
+```
+
+但回调最重要的部分可能是,根据 API 要发送给回调请求体的数据等内容,确保您的 API 用户(外部开发者)正确地实现*外部 API*。
+
+因此,我们下一步要做的就是添加代码,为从 API 接收回调的*外部 API*存档。
+
+这部分文档在 `/docs` 下的 Swagger API 文档中显示,并且会告诉外部开发者如何构建*外部 API*。
+
+本例没有实现回调本身(只是一行代码),只有文档部分。
+
+/// tip | 提示
+
+实际的回调只是 HTTP 请求。
+
+实现回调时,要使用
HTTPX 或
Requests。
+
+///
+
+## 编写回调文档代码
+
+应用不执行这部分代码,只是用它来*记录 外部 API* 。
+
+但,您已经知道用 **FastAPI** 创建自动 API 文档有多简单了。
+
+我们要使用与存档*外部 API* 相同的知识……通过创建外部 API 要实现的*路径操作*(您的 API 要调用的)。
+
+/// tip | 提示
+
+编写存档回调的代码时,假设您是*外部开发者*可能会用的上。并且您当前正在实现的是*外部 API*,不是*您自己的 API*。
+
+临时改变(为外部开发者的)视角能让您更清楚该如何放置*外部 API* 响应和请求体的参数与 Pydantic 模型等。
+
+///
+
+### 创建回调的 `APIRouter`
+
+首先,新建包含一些用于回调的 `APIRouter`。
+
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[5,26] *}
+
+### 创建回调*路径操作*
+
+创建回调*路径操作*也使用之前创建的 `APIRouter`。
+
+它看起来和常规 FastAPI *路径操作*差不多:
+
+* 声明要接收的请求体,例如,`body: InvoiceEvent`
+* 还要声明要返回的响应,例如,`response_model=InvoiceEventReceived`
+
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[17:19,22:23,29:33] *}
+
+回调*路径操作*与常规*路径操作*有两点主要区别:
+
+* 它不需要任何实际的代码,因为应用不会调用这段代码。它只是用于存档*外部 API*。因此,函数的内容只需要 `pass` 就可以了
+* *路径*可以包含
OpenAPI 3 表达式(详见下文),可以使用带参数的变量,以及发送至您的 API 的原始请求的部分
+
+### 回调路径表达式
+
+回调*路径*支持包含发送给您的 API 的原始请求的部分的
OpenAPI 3 表达式。
+
+本例中是**字符串**:
+
+```Python
+"{$callback_url}/invoices/{$request.body.id}"
+```
+
+因此,如果您的 API 用户(外部开发者)发送请求到您的 API:
+
+```
+https://yourapi.com/invoices/?callback_url=https://www.external.org/events
+```
+
+使用如下 JSON 请求体:
+
+```JSON
+{
+ "id": "2expen51ve",
+ "customer": "Mr. Richie Rich",
+ "total": "9999"
+}
+```
+
+然后,您的 API 就会处理发票,并在某个点之后,发送回调请求至 `callback_url`(外部 API):
+
+```
+https://www.external.org/events/invoices/2expen51ve
+```
+
+JSON 请求体包含如下内容:
+
+```JSON
+{
+ "description": "Payment celebration",
+ "paid": true
+}
+```
+
+它会预期*外部 API* 的响应包含如下 JSON 请求体:
+
+```JSON
+{
+ "ok": true
+}
+```
+
+/// tip | 提示
+
+注意,回调 URL包含 `callback_url` (`https://www.external.org/events`)中的查询参数,还有 JSON 请求体内部的发票 ID(`2expen51ve`)。
+
+///
+
+### 添加回调路由
+
+至此,在上文创建的回调路由里就包含了*回调路径操作*(外部开发者要在外部 API 中实现)。
+
+现在使用 API *路径操作装饰器*的参数 `callbacks`,从回调路由传递属性 `.routes`(实际上只是路由/路径操作的**列表**):
+
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[36] *}
+
+/// tip | 提示
+
+注意,不能把路由本身(`invoices_callback_router`)传递给 `callback=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。
+
+///
+
+### 查看文档
+
+现在,使用 Uvicorn 启动应用,打开
http://127.0.0.1:8000/docs。
+
+就能看到文档的*路径操作*已经包含了**回调**的内容以及*外部 API*:
+
+

diff --git a/docs/zh/docs/advanced/openapi-webhooks.md b/docs/zh/docs/advanced/openapi-webhooks.md
new file mode 100644
index 000000000..92ae8db15
--- /dev/null
+++ b/docs/zh/docs/advanced/openapi-webhooks.md
@@ -0,0 +1,55 @@
+# OpenAPI 网络钩子
+
+有些情况下,您可能想告诉您的 API **用户**,您的应用程序可以携带一些数据调用*他们的*应用程序(给它们发送请求),通常是为了**通知**某种**事件**。
+
+这意味着,除了您的用户向您的 API 发送请求的一般情况,**您的 API**(或您的应用)也可以向**他们的系统**(他们的 API、他们的应用)**发送请求**。
+
+这通常被称为**网络钩子**(Webhook)。
+
+## 使用网络钩子的步骤
+
+通常的过程是**您**在代码中**定义**要发送的消息,即**请求的主体**。
+
+您还需要以某种方式定义您的应用程序将在**何时**发送这些请求或事件。
+
+**用户**会以某种方式(例如在某个网页仪表板上)定义您的应用程序发送这些请求应该使用的 **URL**。
+
+所有关于注册网络钩子的 URL 的**逻辑**以及发送这些请求的实际代码都由您决定。您可以在**自己的代码**中以任何想要的方式来编写它。
+
+## 使用 `FastAPI` 和 OpenAPI 文档化网络钩子
+
+使用 **FastAPI**,您可以利用 OpenAPI 来自定义这些网络钩子的名称、您的应用可以发送的 HTTP 操作类型(例如 `POST`、`PUT` 等)以及您的应用将发送的**请求体**。
+
+这能让您的用户更轻松地**实现他们的 API** 来接收您的**网络钩子**请求,他们甚至可能能够自动生成一些自己的 API 代码。
+
+/// info
+
+网络钩子在 OpenAPI 3.1.0 及以上版本中可用,FastAPI `0.99.0` 及以上版本支持。
+
+///
+
+## 带有网络钩子的应用程序
+
+当您创建一个 **FastAPI** 应用程序时,有一个 `webhooks` 属性可以用来定义网络钩子,方式与您定义*路径操作*的时候相同,例如使用 `@app.webhooks.post()` 。
+
+{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
+
+您定义的网络钩子将被包含在 `OpenAPI` 的架构中,并出现在自动生成的**文档 UI** 中。
+
+/// info
+
+`app.webhooks` 对象实际上只是一个 `APIRouter` ,与您在使用多个文件来构建应用程序时所使用的类型相同。
+
+///
+
+请注意,使用网络钩子时,您实际上并没有声明一个*路径*(比如 `/items/` ),您传递的文本只是这个网络钩子的**标识符**(事件的名称)。例如在 `@app.webhooks.post("new-subscription")` 中,网络钩子的名称是 `new-subscription` 。
+
+这是因为我们预计**您的用户**会以其他方式(例如通过网页仪表板)来定义他们希望接收网络钩子的请求的实际 **URL 路径**。
+
+### 查看文档
+
+现在您可以启动您的应用程序并访问
http://127.0.0.1:8000/docs.
+
+您会看到您的文档不仅有正常的*路径操作*显示,现在还多了一些**网络钩子**:
+
+

diff --git a/docs/zh/docs/advanced/path-operation-advanced-configuration.md b/docs/zh/docs/advanced/path-operation-advanced-configuration.md
index 7da9f251e..12600eddb 100644
--- a/docs/zh/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/zh/docs/advanced/path-operation-advanced-configuration.md
@@ -2,16 +2,17 @@
## OpenAPI 的 operationId
-!!! warning
- 如果你并非 OpenAPI 的「专家」,你可能不需要这部分内容。
+/// warning
+
+如果你并非 OpenAPI 的「专家」,你可能不需要这部分内容。
+
+///
你可以在路径操作中通过参数 `operation_id` 设置要使用的 OpenAPI `operationId`。
务必确保每个操作路径的 `operation_id` 都是唯一的。
-```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
### 使用 *路径操作函数* 的函数名作为 operationId
@@ -19,25 +20,27 @@
你应该在添加了所有 *路径操作* 之后执行此操作。
-```Python hl_lines="2 12 13 14 15 16 17 18 19 20 21 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12,13,14,15,16,17,18,19,20,21,24] *}
+
+/// tip
+
+如果你手动调用 `app.openapi()`,你应该在此之前更新 `operationId`。
+
+///
+
+/// warning
-!!! tip
- 如果你手动调用 `app.openapi()`,你应该在此之前更新 `operationId`。
+如果你这样做,务必确保你的每个 *路径操作函数* 的名字唯一。
-!!! warning
- 如果你这样做,务必确保你的每个 *路径操作函数* 的名字唯一。
+即使它们在不同的模块中(Python 文件)。
- 即使它们在不同的模块中(Python 文件)。
+///
## 从 OpenAPI 中排除
使用参数 `include_in_schema` 并将其设置为 `False` ,来从生成的 OpenAPI 方案中排除一个 *路径操作*(这样一来,就从自动化文档系统中排除掉了)。
-```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
## docstring 的高级描述
@@ -48,6 +51,4 @@
剩余部分不会出现在文档中,但是其他工具(比如 Sphinx)可以使用剩余部分。
-```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19,20,21,22,23,24,25,26,27,28,29] *}
diff --git a/docs/zh/docs/advanced/response-change-status-code.md b/docs/zh/docs/advanced/response-change-status-code.md
new file mode 100644
index 000000000..cc1f2a73e
--- /dev/null
+++ b/docs/zh/docs/advanced/response-change-status-code.md
@@ -0,0 +1,29 @@
+# 响应 - 更改状态码
+
+你可能之前已经了解到,你可以设置默认的[响应状态码](../tutorial/response-status-code.md){.internal-link target=_blank}。
+
+但在某些情况下,你需要返回一个不同于默认值的状态码。
+
+## 使用场景
+
+例如,假设你想默认返回一个HTTP状态码为“OK”`200`。
+
+但如果数据不存在,你想创建它,并返回一个HTTP状态码为“CREATED”`201`。
+
+但你仍然希望能够使用`response_model`过滤和转换你返回的数据。
+
+对于这些情况,你可以使用一个`Response`参数。
+
+## 使用 `Response` 参数
+
+你可以在你的*路径操作函数*中声明一个`Response`类型的参数(就像你可以为cookies和头部做的那样)。
+
+然后你可以在这个*临时*响应对象中设置`status_code`。
+
+{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
+
+然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。
+
+**FastAPI**将使用这个临时响应来提取状态码(也包括cookies和头部),并将它们放入包含你返回的值的最终响应中,该响应由任何`response_model`过滤。
+
+你也可以在依赖项中声明`Response`参数,并在其中设置状态码。但请注意,最后设置的状态码将会生效。
diff --git a/docs/zh/docs/advanced/response-cookies.md b/docs/zh/docs/advanced/response-cookies.md
index 3e53c5319..d4b93d003 100644
--- a/docs/zh/docs/advanced/response-cookies.md
+++ b/docs/zh/docs/advanced/response-cookies.md
@@ -4,9 +4,7 @@
你可以在 *路径函数* 中定义一个类型为 `Response`的参数,这样你就可以在这个临时响应对象中设置cookie了。
-```Python hl_lines="1 8-9"
-{!../../../docs_src/response_cookies/tutorial002.py!}
-```
+{* ../../docs_src/response_cookies/tutorial002.py hl[1,8:9] *}
而且你还可以根据你的需要响应不同的对象,比如常用的 `dict`,数据库model等。
@@ -24,24 +22,28 @@
然后设置Cookies,并返回:
-```Python hl_lines="10-12"
-{!../../../docs_src/response_cookies/tutorial001.py!}
-```
+{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
-!!! tip
- 需要注意,如果你直接反馈一个response对象,而不是使用`Response`入参,FastAPI则会直接反馈你封装的response对象。
+/// tip
- 所以你需要确保你响应数据类型的正确性,如:你可以使用`JSONResponse`来兼容JSON的场景。
+需要注意,如果你直接反馈一个response对象,而不是使用`Response`入参,FastAPI则会直接反馈你封装的response对象。
- 同时,你也应当仅反馈通过`response_model`过滤过的数据。
+所以你需要确保你响应数据类型的正确性,如:你可以使用`JSONResponse`来兼容JSON的场景。
+
+同时,你也应当仅反馈通过`response_model`过滤过的数据。
+
+///
### 更多信息
-!!! note "技术细节"
- 你也可以使用`from starlette.responses import Response` 或者 `from starlette.responses import JSONResponse`。
+/// note | 技术细节
+
+你也可以使用`from starlette.responses import Response` 或者 `from starlette.responses import JSONResponse`。
+
+为了方便开发者,**FastAPI** 封装了相同数据类型,如`starlette.responses` 和 `fastapi.responses`。不过大部分response对象都是直接引用自Starlette。
- 为了方便开发者,**FastAPI** 封装了相同数据类型,如`starlette.responses` 和 `fastapi.responses`。不过大部分response对象都是直接引用自Starlette。
+因为`Response`对象可以非常便捷的设置headers和cookies,所以 **FastAPI** 同时也封装了`fastapi.Response`。
- 因为`Response`对象可以非常便捷的设置headers和cookies,所以 **FastAPI** 同时也封装了`fastapi.Response`。
+///
如果你想查看所有可用的参数和选项,可以参考
Starlette帮助文档
diff --git a/docs/zh/docs/advanced/response-directly.md b/docs/zh/docs/advanced/response-directly.md
index 797a878eb..4d9cd53f2 100644
--- a/docs/zh/docs/advanced/response-directly.md
+++ b/docs/zh/docs/advanced/response-directly.md
@@ -14,8 +14,11 @@
事实上,你可以返回任意 `Response` 或者任意 `Response` 的子类。
-!!! tip "小贴士"
- `JSONResponse` 本身是一个 `Response` 的子类。
+/// tip | 小贴士
+
+`JSONResponse` 本身是一个 `Response` 的子类。
+
+///
当你返回一个 `Response` 时,**FastAPI** 会直接传递它。
@@ -32,14 +35,15 @@
对于这些情况,在将数据传递给响应之前,你可以使用 `jsonable_encoder` 来转换你的数据。
-```Python hl_lines="4 6 20 21"
-{!../../../docs_src/response_directly/tutorial001.py!}
-```
+{* ../../docs_src/response_directly/tutorial001.py hl[4,6,20,21] *}
+
+/// note | 技术细节
+
+你也可以使用 `from starlette.responses import JSONResponse`。
-!!! note "技术细节"
- 你也可以使用 `from starlette.responses import JSONResponse`。
+出于方便,**FastAPI** 会提供与 `starlette.responses` 相同的 `fastapi.responses` 给开发者。但是大多数可用的响应都直接来自 Starlette。
- 出于方便,**FastAPI** 会提供与 `starlette.responses` 相同的 `fastapi.responses` 给开发者。但是大多数可用的响应都直接来自 Starlette。
+///
## 返回自定义 `Response`
@@ -51,9 +55,7 @@
你可以把你的 XML 内容放到一个字符串中,放到一个 `Response` 中,然后返回。
-```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
-```
+{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
## 说明
diff --git a/docs/zh/docs/advanced/response-headers.md b/docs/zh/docs/advanced/response-headers.md
new file mode 100644
index 000000000..fe2cb0da8
--- /dev/null
+++ b/docs/zh/docs/advanced/response-headers.md
@@ -0,0 +1,39 @@
+# 响应头
+
+## 使用 `Response` 参数
+
+你可以在你的*路径操作函数*中声明一个`Response`类型的参数(就像你可以为cookies做的那样)。
+
+然后你可以在这个*临时*响应对象中设置头部。
+{* ../../docs_src/response_headers/tutorial002.py hl[1,7:8] *}
+
+然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。
+
+**FastAPI**将使用这个临时响应来提取头部(也包括cookies和状态码),并将它们放入包含你返回的值的最终响应中,该响应由任何`response_model`过滤。
+
+你也可以在依赖项中声明`Response`参数,并在其中设置头部(和cookies)。
+
+## 直接返回 `Response`
+
+你也可以在直接返回`Response`时添加头部。
+
+按照[直接返回响应](response-directly.md){.internal-link target=_blank}中所述创建响应,并将头部作为附加参数传递:
+
+{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
+
+
+/// note | 技术细节
+
+你也可以使用`from starlette.responses import Response`或`from starlette.responses import JSONResponse`。
+
+**FastAPI**提供了与`fastapi.responses`相同的`starlette.responses`,只是为了方便开发者。但是,大多数可用的响应都直接来自Starlette。
+
+由于`Response`经常用于设置头部和cookies,因此**FastAPI**还在`fastapi.Response`中提供了它。
+
+///
+
+## 自定义头部
+
+请注意,可以使用'X-'前缀添加自定义专有头部。
+
+但是,如果你有自定义头部,你希望浏览器中的客户端能够看到它们,你需要将它们添加到你的CORS配置中(在[CORS(跨源资源共享)](../tutorial/cors.md){.internal-link target=_blank}中阅读更多),使用在
Starlette的CORS文档中记录的`expose_headers`参数。
diff --git a/docs/zh/docs/advanced/security/http-basic-auth.md b/docs/zh/docs/advanced/security/http-basic-auth.md
new file mode 100644
index 000000000..599429f9d
--- /dev/null
+++ b/docs/zh/docs/advanced/security/http-basic-auth.md
@@ -0,0 +1,107 @@
+# HTTP 基础授权
+
+最简单的用例是使用 HTTP 基础授权(HTTP Basic Auth)。
+
+在 HTTP 基础授权中,应用需要请求头包含用户名与密码。
+
+如果没有接收到 HTTP 基础授权,就返回 HTTP 401 `"Unauthorized"` 错误。
+
+并返回含 `Basic` 值的请求头 `WWW-Authenticate`以及可选的 `realm` 参数。
+
+HTTP 基础授权让浏览器显示内置的用户名与密码提示。
+
+输入用户名与密码后,浏览器会把它们自动发送至请求头。
+
+## 简单的 HTTP 基础授权
+
+* 导入 `HTTPBasic` 与 `HTTPBasicCredentials`
+* 使用 `HTTPBasic` 创建**安全概图**
+* 在*路径操作*的依赖项中使用 `security`
+* 返回类型为 `HTTPBasicCredentials` 的对象:
+ * 包含发送的 `username` 与 `password`
+
+{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
+
+第一次打开 URL(或在 API 文档中点击 **Execute** 按钮)时,浏览器要求输入用户名与密码:
+
+

+
+## 检查用户名
+
+以下是更完整的示例。
+
+使用依赖项检查用户名与密码是否正确。
+
+为此要使用 Python 标准模块
`secrets` 检查用户名与密码。
+
+`secrets.compare_digest()` 需要仅包含 ASCII 字符(英语字符)的 `bytes` 或 `str`,这意味着它不适用于像`á`一样的字符,如 `Sebastián`。
+
+为了解决这个问题,我们首先将 `username` 和 `password` 转换为使用 UTF-8 编码的 `bytes` 。
+
+然后我们可以使用 `secrets.compare_digest()` 来确保 `credentials.username` 是 `"stanleyjobson"`,且 `credentials.password` 是`"swordfish"`。
+
+{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
+
+这类似于:
+
+```Python
+if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
+ # Return some error
+ ...
+```
+
+但使用 `secrets.compare_digest()`,可以防御**时差攻击**,更加安全。
+
+### 时差攻击
+
+什么是**时差攻击**?
+
+假设攻击者试图猜出用户名与密码。
+
+他们发送用户名为 `johndoe`,密码为 `love123` 的请求。
+
+然后,Python 代码执行如下操作:
+
+```Python
+if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+但就在 Python 比较完 `johndoe` 的第一个字母 `j` 与 `stanleyjobson` 的 `s` 时,Python 就已经知道这两个字符串不相同了,它会这么想,**没必要浪费更多时间执行剩余字母的对比计算了**。应用立刻就会返回**错误的用户或密码**。
+
+但接下来,攻击者继续尝试 `stanleyjobsox` 和 密码 `love123`。
+
+应用代码会执行类似下面的操作:
+
+```Python
+if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+此时,Python 要对比 `stanleyjobsox` 与 `stanleyjobson` 中的 `stanleyjobso`,才能知道这两个字符串不一样。因此会多花费几微秒来返回**错误的用户或密码**。
+
+#### 反应时间对攻击者的帮助
+
+通过服务器花费了更多微秒才发送**错误的用户或密码**响应,攻击者会知道猜对了一些内容,起码开头字母是正确的。
+
+然后,他们就可以放弃 `johndoe`,再用类似 `stanleyjobsox` 的内容进行尝试。
+
+#### **专业**攻击
+
+当然,攻击者不用手动操作,而是编写每秒能执行成千上万次测试的攻击程序,每次都会找到更多正确字符。
+
+但是,在您的应用的**帮助**下,攻击者利用时间差,就能在几分钟或几小时内,以这种方式猜出正确的用户名和密码。
+
+#### 使用 `secrets.compare_digest()` 修补
+
+在此,代码中使用了 `secrets.compare_digest()`。
+
+简单的说,它使用相同的时间对比 `stanleyjobsox` 和 `stanleyjobson`,还有 `johndoe` 和 `stanleyjobson`。对比密码时也一样。
+
+在代码中使用 `secrets.compare_digest()` ,就可以安全地防御全面攻击了。
+
+### 返回错误
+
+检测到凭证不正确后,返回 `HTTPException` 及状态码 401(与无凭证时返回的内容一样),并添加请求头 `WWW-Authenticate`,让浏览器再次显示登录提示:
+
+{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
diff --git a/docs/zh/docs/advanced/security/index.md b/docs/zh/docs/advanced/security/index.md
new file mode 100644
index 000000000..267e7ced7
--- /dev/null
+++ b/docs/zh/docs/advanced/security/index.md
@@ -0,0 +1,19 @@
+# 高级安全
+
+## 附加特性
+
+除 [教程 - 用户指南: 安全性](../../tutorial/security/index.md){.internal-link target=_blank} 中涵盖的功能之外,还有一些额外的功能来处理安全性.
+
+/// tip | 小贴士
+
+接下来的章节 **并不一定是 "高级的"**.
+
+而且对于你的使用场景来说,解决方案很可能就在其中。
+
+///
+
+## 先阅读教程
+
+接下来的部分假设你已经阅读了主要的 [教程 - 用户指南: 安全性](../../tutorial/security/index.md){.internal-link target=_blank}.
+
+它们都基于相同的概念,但支持一些额外的功能.
diff --git a/docs/zh/docs/advanced/security/oauth2-scopes.md b/docs/zh/docs/advanced/security/oauth2-scopes.md
new file mode 100644
index 000000000..784c38490
--- /dev/null
+++ b/docs/zh/docs/advanced/security/oauth2-scopes.md
@@ -0,0 +1,274 @@
+# OAuth2 作用域
+
+**FastAPI** 无缝集成 OAuth2 作用域(`Scopes`),可以直接使用。
+
+作用域是更精密的权限系统,遵循 OAuth2 标准,与 OpenAPI 应用(和 API 自动文档)集成。
+
+OAuth2 也是脸书、谷歌、GitHub、微软、推特等第三方身份验证应用使用的机制。这些身份验证应用在用户登录应用时使用 OAuth2 提供指定权限。
+
+脸书、谷歌、GitHub、微软、推特就是 OAuth2 作用域登录。
+
+本章介绍如何在 **FastAPI** 应用中使用 OAuth2 作用域管理验证与授权。
+
+/// warning | 警告
+
+本章内容较难,刚接触 FastAPI 的新手可以跳过。
+
+OAuth2 作用域不是必需的,没有它,您也可以处理身份验证与授权。
+
+但 OAuth2 作用域与 API(通过 OpenAPI)及 API 文档集成地更好。
+
+不管怎么说,**FastAPI** 支持在代码中使用作用域或其它安全/授权需求项。
+
+很多情况下,OAuth2 作用域就像一把牛刀。
+
+但如果您确定要使用作用域,或对它有兴趣,请继续阅读。
+
+///
+
+## OAuth2 作用域与 OpenAPI
+
+OAuth2 规范的**作用域**是由空格分割的字符串组成的列表。
+
+这些字符串支持任何格式,但不能包含空格。
+
+作用域表示的是**权限**。
+
+OpenAPI 中(例如 API 文档)可以定义**安全方案**。
+
+这些安全方案在使用 OAuth2 时,还可以声明和使用作用域。
+
+**作用域**只是(不带空格的)字符串。
+
+常用于声明特定安全权限,例如:
+
+* 常见用例为,`users:read` 或 `users:write`
+* 脸书和 Instagram 使用 `instagram_basic`
+* 谷歌使用 `https://www.googleapis.com/auth/drive`
+
+/// info | 说明
+
+OAuth2 中,**作用域**只是声明特定权限的字符串。
+
+是否使用冒号 `:` 等符号,或是不是 URL 并不重要。
+
+这些细节只是特定的实现方式。
+
+对 OAuth2 来说,它们都只是字符串而已。
+
+///
+
+## 全局纵览
+
+首先,快速浏览一下以下代码与**用户指南**中 [OAuth2 实现密码哈希与 Bearer JWT 令牌验证](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}一章中代码的区别。以下代码使用 OAuth2 作用域:
+
+{* ../../docs_src/security/tutorial005.py hl[2,4,8,12,46,64,105,107:115,121:124,128:134,139,153] *}
+
+下面,我们逐步说明修改的代码内容。
+
+## OAuth2 安全方案
+
+第一个修改的地方是,使用两个作用域 `me` 和 `items ` 声明 OAuth2 安全方案。
+
+`scopes` 参数接收**字典**,键是作用域、值是作用域的描述:
+
+{* ../../docs_src/security/tutorial005.py hl[62:65] *}
+
+因为声明了作用域,所以登录或授权时会在 API 文档中显示。
+
+此处,选择给予访问权限的作用域: `me` 和 `items`。
+
+这也是使用脸书、谷歌、GitHub 登录时的授权机制。
+
+

+
+## JWT 令牌作用域
+
+现在,修改令牌*路径操作*,返回请求的作用域。
+
+此处仍然使用 `OAuth2PasswordRequestForm`。它包含类型为**字符串列表**的 `scopes` 属性,且`scopes` 属性中包含要在请求里接收的每个作用域。
+
+这样,返回的 JWT 令牌中就包含了作用域。
+
+/// danger | 危险
+
+为了简明起见,本例把接收的作用域直接添加到了令牌里。
+
+但在您的应用中,为了安全,应该只把作用域添加到确实需要作用域的用户,或预定义的用户。
+
+///
+
+{* ../../docs_src/security/tutorial005.py hl[153] *}
+
+## 在*路径操作*与依赖项中声明作用域
+
+接下来,为*路径操作* `/users/me/items/` 声明作用域 `items`。
+
+为此,要从 `fastapi` 中导入并使用 `Security` 。
+
+`Security` 声明依赖项的方式和 `Depends` 一样,但 `Security` 还能接收作用域(字符串)列表类型的参数 `scopes`。
+
+此处使用与 `Depends` 相同的方式,把依赖项函数 `get_current_active_user` 传递给 `Security`。
+
+同时,还传递了作用域**列表**,本例中只传递了一个作用域:`items`(此处支持传递更多作用域)。
+
+依赖项函数 `get_current_active_user` 还能声明子依赖项,不仅可以使用 `Depends`,也可以使用 `Security`。声明子依赖项函数(`get_current_user`)及更多作用域。
+
+本例要求使用作用域 `me`(还可以使用更多作用域)。
+
+/// note | 笔记
+
+不必在不同位置添加不同的作用域。
+
+本例使用的这种方式只是为了展示 **FastAPI** 如何处理在不同层级声明的作用域。
+
+///
+
+{* ../../docs_src/security/tutorial005.py hl[4,139,166] *}
+
+/// info | 技术细节
+
+`Security` 实际上是 `Depends` 的子类,而且只比 `Depends` 多一个参数。
+
+但使用 `Security` 代替 `Depends`,**FastAPI** 可以声明安全作用域,并在内部使用这些作用域,同时,使用 OpenAPI 存档 API。
+
+但实际上,从 `fastapi` 导入的 `Query`、`Path`、`Depends`、`Security` 等对象,只是返回特殊类的函数。
+
+///
+
+## 使用 `SecurityScopes`
+
+修改依赖项 `get_current_user`。
+
+这是上面的依赖项使用的依赖项。
+
+这里使用的也是之前创建的 OAuth2 方案,并把它声明为依赖项:`oauth2_scheme`。
+
+该依赖项函数本身不需要作用域,因此,可以使用 `Depends` 和 `oauth2_scheme`。不需要指定安全作用域时,不必使用 `Security`。
+
+此处还声明了从 `fastapi.security` 导入的 `SecurityScopes` 类型的特殊参数。
+
+`SecuriScopes` 类与 `Request` 类似(`Request` 用于直接提取请求对象)。
+
+{* ../../docs_src/security/tutorial005.py hl[8,105] *}
+
+## 使用 `scopes`
+
+参数 `security_scopes` 的类型是 `SecurityScopes`。
+
+它的属性 `scopes` 是作用域列表,所有依赖项都把它作为子依赖项。也就是说所有**依赖**……这听起来有些绕,后文会有解释。
+
+(类 `SecurityScopes` 的)`security_scopes` 对象还提供了单字符串类型的属性 `scope_str`,该属性是(要在本例中使用的)用空格分割的作用域。
+
+此处还创建了后续代码中要复用(`raise`)的 `HTTPException` 。
+
+该异常包含了作用域所需的(如有),以空格分割的字符串(使用 `scope_str`)。该字符串要放到包含作用域的 `WWW-Authenticate` 请求头中(这也是规范的要求)。
+
+{* ../../docs_src/security/tutorial005.py hl[105,107:115] *}
+
+## 校验 `username` 与数据形状
+
+我们可以校验是否获取了 `username`,并抽取作用域。
+
+然后,使用 Pydantic 模型校验数据(捕获 `ValidationError` 异常),如果读取 JWT 令牌或使用 Pydantic 模型验证数据时出错,就会触发之前创建的 `HTTPException` 异常。
+
+对此,要使用新的属性 `scopes` 更新 Pydantic 模型 `TokenData`。
+
+使用 Pydantic 验证数据可以确保数据中含有由作用域组成的**字符串列表**,以及 `username` 字符串等内容。
+
+反之,如果使用**字典**或其它数据结构,就有可能在后面某些位置破坏应用,形成安全隐患。
+
+还可以使用用户名验证用户,如果没有用户,也会触发之前创建的异常。
+
+{* ../../docs_src/security/tutorial005.py hl[46,116:127] *}
+
+## 校验 `scopes`
+
+接下来,校验所有依赖项和依赖要素(包括*路径操作*)所需的作用域。这些作用域包含在令牌的 `scopes` 里,如果不在其中就会触发 `HTTPException` 异常。
+
+为此,要使用包含所有作用域**字符串列表**的 `security_scopes.scopes`, 。
+
+{* ../../docs_src/security/tutorial005.py hl[128:134] *}
+
+## 依赖项树与作用域
+
+再次查看这个依赖项树与作用域。
+
+`get_current_active_user` 依赖项包含子依赖项 `get_current_user`,并在 `get_current_active_user`中声明了作用域 `"me"` 包含所需作用域列表 ,在 `security_scopes.scopes` 中传递给 `get_current_user`。
+
+*路径操作*自身也声明了作用域,`"items"`,这也是 `security_scopes.scopes` 列表传递给 `get_current_user` 的。
+
+依赖项与作用域的层级架构如下:
+
+* *路径操作* `read_own_items` 包含:
+ * 依赖项所需的作用域 `["items"]`:
+ * `get_current_active_user`:
+ * 依赖项函数 `get_current_active_user` 包含:
+ * 所需的作用域 `"me"` 包含依赖项:
+ * `get_current_user`:
+ * 依赖项函数 `get_current_user` 包含:
+ * 没有作用域需求其自身
+ * 依赖项使用 `oauth2_scheme`
+ * `security_scopes` 参数的类型是 `SecurityScopes`:
+ * `security_scopes` 参数的属性 `scopes` 是包含上述声明的所有作用域的**列表**,因此:
+ * `security_scopes.scopes` 包含用于*路径操作*的 `["me", "items"]`
+ * `security_scopes.scopes` 包含*路径操作* `read_users_me` 的 `["me"]`,因为它在依赖项里被声明
+ * `security_scopes.scopes` 包含用于*路径操作* `read_system_status` 的 `[]`(空列表),并且它的依赖项 `get_current_user` 也没有声明任何 `scope`
+
+/// tip | 提示
+
+此处重要且**神奇**的事情是,`get_current_user` 检查每个*路径操作*时可以使用不同的 `scopes` 列表。
+
+所有这些都依赖于在每个*路径操作*和指定*路径操作*的依赖树中的每个依赖项。
+
+///
+
+## `SecurityScopes` 的更多细节
+
+您可以任何位置或多个位置使用 `SecurityScopes`,不一定非得在**根**依赖项中使用。
+
+它总是在当前 `Security` 依赖项中和所有依赖因子对于**特定** *路径操作*和**特定**依赖树中安全作用域
+
+因为 `SecurityScopes` 包含所有由依赖项声明的作用域,可以在核心依赖函数中用它验证所需作用域的令牌,然后再在不同的*路径操作*中声明不同作用域需求。
+
+它们会为每个*路径操作*进行单独检查。
+
+## 查看文档
+
+打开 API 文档,进行身份验证,并指定要授权的作用域。
+
+

+
+没有选择任何作用域,也可以进行**身份验证**,但访问 `/uses/me` 或 `/users/me/items` 时,会显示没有足够的权限。但仍可以访问 `/status/`。
+
+如果选择了作用域 `me`,但没有选择作用域 `items`,则可以访问 `/users/me/`,但不能访问 `/users/me/items`。
+
+这就是通过用户提供的令牌使用第三方应用访问这些*路径操作*时会发生的情况,具体怎样取决于用户授予第三方应用的权限。
+
+## 关于第三方集成
+
+本例使用 OAuth2 **密码**流。
+
+这种方式适用于登录我们自己的应用,最好使用我们自己的前端。
+
+因为我们能控制自己的前端应用,可以信任它接收 `username` 与 `password`。
+
+但如果构建的是连接其它应用的 OAuth2 应用,比如具有与脸书、谷歌、GitHub 相同功能的第三方身份验证应用。那您就应该使用其它安全流。
+
+最常用的是隐式流。
+
+最安全的是代码流,但实现起来更复杂,而且需要更多步骤。因为它更复杂,很多第三方身份验证应用最终建议使用隐式流。
+
+/// note | 笔记
+
+每个身份验证应用都会采用不同方式会命名流,以便融合入自己的品牌。
+
+但归根结底,它们使用的都是 OAuth2 标准。
+
+///
+
+**FastAPI** 的 `fastapi.security.oauth2` 里包含了所有 OAuth2 身份验证流工具。
+
+## 装饰器 `dependencies` 中的 `Security`
+
+同样,您可以在装饰器的 `dependencies` 参数中定义 `Depends` 列表,(详见[路径操作装饰器依赖项](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank})),也可以把 `scopes` 与 `Security` 一起使用。
diff --git a/docs/zh/docs/advanced/settings.md b/docs/zh/docs/advanced/settings.md
new file mode 100644
index 000000000..e33da136f
--- /dev/null
+++ b/docs/zh/docs/advanced/settings.md
@@ -0,0 +1,397 @@
+# 设置和环境变量
+
+在许多情况下,您的应用程序可能需要一些外部设置或配置,例如密钥、数据库凭据、电子邮件服务的凭据等等。
+
+这些设置中的大多数是可变的(可以更改的),比如数据库的 URL。而且许多设置可能是敏感的,比如密钥。
+
+因此,通常会将它们提供为由应用程序读取的环境变量。
+
+## 环境变量
+
+/// tip
+
+如果您已经知道什么是"环境变量"以及如何使用它们,请随意跳到下面的下一节。
+
+///
+
+环境变量(也称为"env var")是一种存在于 Python 代码之外、存在于操作系统中的变量,可以被您的 Python 代码(或其他程序)读取。
+
+您可以在 shell 中创建和使用环境变量,而无需使用 Python:
+
+//// tab | Linux、macOS、Windows Bash
+
+
+
+```console
+// 您可以创建一个名为 MY_NAME 的环境变量
+$ export MY_NAME="Wade Wilson"
+
+// 然后您可以与其他程序一起使用它,例如
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// 创建一个名为 MY_NAME 的环境变量
+$ $Env:MY_NAME = "Wade Wilson"
+
+// 与其他程序一起使用它,例如
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+### 在 Python 中读取环境变量
+
+您还可以在 Python 之外的地方(例如终端中或使用任何其他方法)创建环境变量,然后在 Python 中读取它们。
+
+例如,您可以有一个名为 `main.py` 的文件,其中包含以下内容:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+
`os.getenv()` 的第二个参数是要返回的默认值。
+
+如果没有提供默认值,默认为 `None`,此处我们提供了 `"World"` 作为要使用的默认值。
+
+///
+
+然后,您可以调用该 Python 程序:
+
+
+
+```console
+// 这里我们还没有设置环境变量
+$ python main.py
+
+// 因为我们没有设置环境变量,所以我们得到默认值
+
+Hello World from Python
+
+// 但是如果我们先创建一个环境变量
+$ export MY_NAME="Wade Wilson"
+
+// 然后再次调用程序
+$ python main.py
+
+// 现在它可以读取环境变量
+
+Hello Wade Wilson from Python
+```
+
+
+
+由于环境变量可以在代码之外设置,但可以由代码读取,并且不需要与其他文件一起存储(提交到 `git`),因此通常将它们用于配置或设置。
+
+
+
+您还可以仅为特定程序调用创建一个环境变量,该环境变量仅对该程序可用,并且仅在其运行期间有效。
+
+要做到这一点,在程序本身之前的同一行创建它:
+
+
+
+```console
+// 在此程序调用行中创建一个名为 MY_NAME 的环境变量
+$ MY_NAME="Wade Wilson" python main.py
+
+// 现在它可以读取环境变量
+
+Hello Wade Wilson from Python
+
+// 之后环境变量不再存在
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip
+
+您可以在
Twelve-Factor App: Config 中阅读更多相关信息。
+
+///
+
+### 类型和验证
+
+这些环境变量只能处理文本字符串,因为它们是外部于 Python 的,并且必须与其他程序和整个系统兼容(甚至与不同的操作系统,如 Linux、Windows、macOS)。
+
+这意味着从环境变量中在 Python 中读取的任何值都将是 `str` 类型,任何类型的转换或验证都必须在代码中完成。
+
+## Pydantic 的 `Settings`
+
+幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的设置,即
Pydantic: Settings management。
+
+### 创建 `Settings` 对象
+
+从 Pydantic 导入 `BaseSettings` 并创建一个子类,与 Pydantic 模型非常相似。
+
+与 Pydantic 模型一样,您使用类型注释声明类属性,还可以指定默认值。
+
+您可以使用与 Pydantic 模型相同的验证功能和工具,比如不同的数据类型和使用 `Field()` 进行附加验证。
+
+{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
+
+/// tip
+
+如果您需要一个快速的复制粘贴示例,请不要使用此示例,而应使用下面的最后一个示例。
+
+///
+
+然后,当您创建该 `Settings` 类的实例(在此示例中是 `settings` 对象)时,Pydantic 将以不区分大小写的方式读取环境变量,因此,大写的变量 `APP_NAME` 仍将为属性 `app_name` 读取。
+
+然后,它将转换和验证数据。因此,当您使用该 `settings` 对象时,您将获得您声明的类型的数据(例如 `items_per_user` 将为 `int` 类型)。
+
+### 使用 `settings`
+
+然后,您可以在应用程序中使用新的 `settings` 对象:
+
+{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
+
+### 运行服务器
+
+接下来,您将运行服务器,并将配置作为环境变量传递。例如,您可以设置一个 `ADMIN_EMAIL` 和 `APP_NAME`,如下所示:
+
+
+
+```console
+$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+/// tip
+
+要为单个命令设置多个环境变量,只需用空格分隔它们,并将它们全部放在命令之前。
+
+///
+
+然后,`admin_email` 设置将为 `"deadpool@example.com"`。
+
+`app_name` 将为 `"ChimichangApp"`。
+
+而 `items_per_user` 将保持其默认值为 `50`。
+
+## 在另一个模块中设置
+
+您可以将这些设置放在另一个模块文件中,就像您在[Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}中所见的那样。
+
+例如,您可以创建一个名为 `config.py` 的文件,其中包含以下内容:
+
+{* ../../docs_src/settings/app01/config.py *}
+
+然后在一个名为 `main.py` 的文件中使用它:
+
+{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+
+/// tip
+
+您还需要一个名为 `__init__.py` 的文件,就像您在[Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。
+
+///
+
+## 在依赖项中使用设置
+
+在某些情况下,从依赖项中提供设置可能比在所有地方都使用全局对象 `settings` 更有用。
+
+这在测试期间尤其有用,因为很容易用自定义设置覆盖依赖项。
+
+### 配置文件
+
+根据前面的示例,您的 `config.py` 文件可能如下所示:
+
+{* ../../docs_src/settings/app02/config.py hl[10] *}
+
+请注意,现在我们不创建默认实例 `settings = Settings()`。
+
+### 主应用程序文件
+
+现在我们创建一个依赖项,返回一个新的 `config.Settings()`。
+
+{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
+
+/// tip
+
+我们稍后会讨论 `@lru_cache`。
+
+目前,您可以将 `get_settings()` 视为普通函数。
+
+///
+
+然后,我们可以将其作为依赖项从“路径操作函数”中引入,并在需要时使用它。
+
+{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
+
+### 设置和测试
+
+然后,在测试期间,通过创建 `get_settings` 的依赖项覆盖,很容易提供一个不同的设置对象:
+
+{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
+
+在依赖项覆盖中,我们在创建新的 `Settings` 对象时为 `admin_email` 设置了一个新值,然后返回该新对象。
+
+然后,我们可以测试它是否被使用。
+
+## 从 `.env` 文件中读取设置
+
+如果您有许多可能经常更改的设置,可能在不同的环境中,将它们放在一个文件中,然后从该文件中读取它们,就像它们是环境变量一样,可能非常有用。
+
+这种做法相当常见,有一个名称,这些环境变量通常放在一个名为 `.env` 的文件中,该文件被称为“dotenv”。
+
+/// tip
+
+以点 (`.`) 开头的文件是 Unix-like 系统(如 Linux 和 macOS)中的隐藏文件。
+
+但是,dotenv 文件实际上不一定要具有确切的文件名。
+
+///
+
+Pydantic 支持使用外部库从这些类型的文件中读取。您可以在
Pydantic 设置: Dotenv (.env) 支持中阅读更多相关信息。
+
+/// tip
+
+要使其工作,您需要执行 `pip install python-dotenv`。
+
+///
+
+### `.env` 文件
+
+您可以使用以下内容创建一个名为 `.env` 的文件:
+
+```bash
+ADMIN_EMAIL="deadpool@example.com"
+APP_NAME="ChimichangApp"
+```
+
+### 从 `.env` 文件中读取设置
+
+然后,您可以使用以下方式更新您的 `config.py`:
+
+{* ../../docs_src/settings/app03/config.py hl[9:10] *}
+
+在这里,我们在 Pydantic 的 `Settings` 类中创建了一个名为 `Config` 的类,并将 `env_file` 设置为我们想要使用的 dotenv 文件的文件名。
+
+/// tip
+
+`Config` 类仅用于 Pydantic 配置。您可以在
Pydantic Model Config中阅读更多相关信息。
+
+///
+
+### 使用 `lru_cache` 仅创建一次 `Settings`
+
+从磁盘中读取文件通常是一项耗时的(慢)操作,因此您可能希望仅在首次读取后并重复使用相同的设置对象,而不是为每个请求都读取它。
+
+但是,每次执行以下操作:
+
+```Python
+Settings()
+```
+
+都会创建一个新的 `Settings` 对象,并且在创建时会再次读取 `.env` 文件。
+
+如果依赖项函数只是这样的:
+
+```Python
+def get_settings():
+ return Settings()
+```
+
+我们将为每个请求创建该对象,并且将在每个请求中读取 `.env` 文件。 ⚠️
+
+但是,由于我们在顶部使用了 `@lru_cache` 装饰器,因此只有在第一次调用它时,才会创建 `Settings` 对象一次。 ✔️
+
+{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
+
+然后,在下一次请求的依赖项中对 `get_settings()` 进行任何后续调用时,它不会执行 `get_settings()` 的内部代码并创建新的 `Settings` 对象,而是返回在第一次调用时返回的相同对象,一次又一次。
+
+#### `lru_cache` 技术细节
+
+`@lru_cache` 修改了它所装饰的函数,以返回第一次返回的相同值,而不是再次计算它,每次都执行函数的代码。
+
+因此,下面的函数将对每个参数组合执行一次。然后,每个参数组合返回的值将在使用完全相同的参数组合调用函数时再次使用。
+
+例如,如果您有一个函数:
+```Python
+@lru_cache
+def say_hi(name: str, salutation: str = "Ms."):
+ return f"Hello {salutation} {name}"
+```
+
+您的程序可以像这样执行:
+
+```mermaid
+sequenceDiagram
+
+participant code as Code
+participant function as say_hi()
+participant execute as Execute function
+
+ rect rgba(0, 255, 0, .1)
+ code ->> function: say_hi(name="Camila")
+ function ->> execute: 执行函数代码
+ execute ->> code: 返回结果
+ end
+
+ rect rgba(0, 255, 255, .1)
+ code ->> function: say_hi(name="Camila")
+ function ->> code: 返回存储的结果
+ end
+
+ rect rgba(0, 255, 0, .1)
+ code ->> function: say_hi(name="Rick")
+ function ->> execute: 执行函数代码
+ execute ->> code: 返回结果
+ end
+
+ rect rgba(0, 255, 0, .1)
+ code ->> function: say_hi(name="Rick", salutation="Mr.")
+ function ->> execute: 执行函数代码
+ execute ->> code: 返回结果
+ end
+
+ rect rgba(0, 255, 255, .1)
+ code ->> function: say_hi(name="Rick")
+ function ->> code: 返回存储的结果
+ end
+
+ rect rgba(0, 255, 255, .1)
+ code ->> function: say_hi(name="Camila")
+ function ->> code: 返回存储的结果
+ end
+```
+
+对于我们的依赖项 `get_settings()`,该函数甚至不接受任何参数,因此它始终返回相同的值。
+
+这样,它的行为几乎就像是一个全局变量。但是由于它使用了依赖项函数,因此我们可以轻松地进行测试时的覆盖。
+
+`@lru_cache` 是 `functools` 的一部分,它是 Python 标准库的一部分,您可以在
Python 文档中了解有关 `@lru_cache` 的更多信息。
+
+## 小结
+
+您可以使用 Pydantic 设置处理应用程序的设置或配置,利用 Pydantic 模型的所有功能。
+
+* 通过使用依赖项,您可以简化测试。
+* 您可以使用 `.env` 文件。
+* 使用 `@lru_cache` 可以避免为每个请求重复读取 dotenv 文件,同时允许您在测试时进行覆盖。
diff --git a/docs/zh/docs/advanced/sub-applications.md b/docs/zh/docs/advanced/sub-applications.md
new file mode 100644
index 000000000..c42be2849
--- /dev/null
+++ b/docs/zh/docs/advanced/sub-applications.md
@@ -0,0 +1,67 @@
+# 子应用 - 挂载
+
+如果需要两个独立的 FastAPI 应用,拥有各自独立的 OpenAPI 与文档,则需设置一个主应用,并**挂载**一个(或多个)子应用。
+
+## 挂载 **FastAPI** 应用
+
+**挂载**是指在特定路径中添加完全**独立**的应用,然后在该路径下使用*路径操作*声明的子应用处理所有事务。
+
+### 顶层应用
+
+首先,创建主(顶层)**FastAPI** 应用及其*路径操作*:
+
+{* ../../docs_src/sub_applications/tutorial001.py hl[3,6:8] *}
+
+### 子应用
+
+接下来,创建子应用及其*路径操作*。
+
+子应用只是另一个标准 FastAPI 应用,但这个应用是被**挂载**的应用:
+
+{* ../../docs_src/sub_applications/tutorial001.py hl[11,14:16] *}
+
+### 挂载子应用
+
+在顶层应用 `app` 中,挂载子应用 `subapi`。
+
+本例的子应用挂载在 `/subapi` 路径下:
+
+{* ../../docs_src/sub_applications/tutorial001.py hl[11,19] *}
+
+### 查看文档
+
+如果主文件是 `main.py`,则用以下 `uvicorn` 命令运行主应用:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+查看文档
http://127.0.0.1:8000/docs。
+
+下图显示的是主应用 API 文档,只包括其自有的*路径操作*。
+
+

+
+然后查看子应用文档
http://127.0.0.1:8000/subapi/docs。
+
+下图显示的是子应用的 API 文档,也是只包括其自有的*路径操作*,所有这些路径操作都在 `/subapi` 子路径前缀下。
+
+

+
+两个用户界面都可以正常运行,因为浏览器能够与每个指定的应用或子应用会话。
+
+### 技术细节:`root_path`
+
+以上述方式挂载子应用时,FastAPI 使用 ASGI 规范中的 `root_path` 机制处理挂载子应用路径之间的通信。
+
+这样,子应用就可以为自动文档使用路径前缀。
+
+并且子应用还可以再挂载子应用,一切都会正常运行,FastAPI 可以自动处理所有 `root_path`。
+
+关于 `root_path` 及如何显式使用 `root_path` 的内容,详见[使用代理](behind-a-proxy.md){.internal-link target=_blank}一章。
diff --git a/docs/zh/docs/advanced/templates.md b/docs/zh/docs/advanced/templates.md
new file mode 100644
index 000000000..8b7019ede
--- /dev/null
+++ b/docs/zh/docs/advanced/templates.md
@@ -0,0 +1,125 @@
+# 模板
+
+**FastAPI** 支持多种模板引擎。
+
+Flask 等工具使用的 Jinja2 是最用的模板引擎。
+
+在 Starlette 的支持下,**FastAPI** 应用可以直接使用工具轻易地配置 Jinja2。
+
+## 安装依赖项
+
+安装 `jinja2`:
+
+
+
+```console
+$ pip install jinja2
+
+---> 100%
+```
+
+
+
+## 使用 `Jinja2Templates`
+
+* 导入 `Jinja2Templates`
+* 创建可复用的 `templates` 对象
+* 在返回模板的*路径操作*中声明 `Request` 参数
+* 使用 `templates` 渲染并返回 `TemplateResponse`, 传递模板的名称、request对象以及一个包含多个键值对(用于Jinja2模板)的"context"字典,
+
+{* ../../docs_src/templates/tutorial001.py hl[4,11,15:16] *}
+
+/// note | 笔记
+
+在FastAPI 0.108.0,Starlette 0.29.0之前,`name`是第一个参数。
+并且,在此之前,`request`对象是作为context的一部分以键值对的形式传递的。
+
+///
+
+/// tip | 提示
+
+通过声明 `response_class=HTMLResponse`,API 文档就能识别响应的对象是 HTML。
+
+///
+
+/// note | 技术细节
+
+您还可以使用 `from starlette.templating import Jinja2Templates`。
+
+**FastAPI** 的 `fastapi.templating` 只是为开发者提供的快捷方式。实际上,绝大多数可用响应都直接继承自 Starlette。 `Request` 与 `StaticFiles` 也一样。
+
+///
+
+## 编写模板
+
+编写模板 `templates/item.html`,代码如下:
+
+```jinja hl_lines="7"
+{!../../docs_src/templates/templates/item.html!}
+```
+
+### 模板上下文
+
+在包含如下语句的html中:
+
+{% raw %}
+
+```jinja
+Item ID: {{ id }}
+```
+
+{% endraw %}
+
+...这将显示你从"context"字典传递的 `id`:
+
+```Python
+{"id": id}
+```
+
+例如。当ID为 `42`时, 会渲染成:
+
+```html
+Item ID: 42
+```
+
+### 模板 `url_for` 参数
+
+你还可以在模板内使用 `url_for()`,其参数与*路径操作函数*的参数相同.
+
+所以,该部分:
+
+{% raw %}
+
+```jinja
+
+```
+
+{% endraw %}
+
+...将生成一个与处理*路径操作函数* `read_item(id=id)`的URL相同的链接
+
+例如。当ID为 `42`时, 会渲染成:
+
+```html
+
+```
+
+## 模板与静态文件
+
+你还可以在模板内部将 `url_for()`用于静态文件,例如你挂载的 `name="static"`的 `StaticFiles`。
+
+```jinja hl_lines="4"
+{!../../docs_src/templates/templates/item.html!}
+```
+
+本例中,它将链接到 `static/styles.css`中的CSS文件:
+
+```CSS hl_lines="4"
+{!../../docs_src/templates/static/styles.css!}
+```
+
+因为使用了 `StaticFiles`, **FastAPI** 应用会自动提供位于 URL `/static/styles.css`的 CSS 文件。
+
+## 更多说明
+
+包括测试模板等更多详情,请参阅 Starlette 官方文档 - 模板。
diff --git a/docs/zh/docs/advanced/testing-dependencies.md b/docs/zh/docs/advanced/testing-dependencies.md
new file mode 100644
index 000000000..8d53a6d49
--- /dev/null
+++ b/docs/zh/docs/advanced/testing-dependencies.md
@@ -0,0 +1,53 @@
+# 测试依赖项
+
+## 测试时覆盖依赖项
+
+有些场景下,您可能需要在测试时覆盖依赖项。
+
+即不希望运行原有依赖项(及其子依赖项)。
+
+反之,要在测试期间(或只是为某些特定测试)提供只用于测试的依赖项,并使用此依赖项的值替换原有依赖项的值。
+
+### 用例:外部服务
+
+常见实例是调用外部第三方身份验证应用。
+
+向第三方应用发送令牌,然后返回经验证的用户。
+
+但第三方服务商处理每次请求都可能会收费,并且耗时通常也比调用写死的模拟测试用户更长。
+
+一般只要测试一次外部验证应用就够了,不必每次测试都去调用。
+
+此时,最好覆盖调用外部验证应用的依赖项,使用返回模拟测试用户的自定义依赖项就可以了。
+
+### 使用 `app.dependency_overrides` 属性
+
+对于这些用例,**FastAPI** 应用支持 `app.dependency_overrides` 属性,该属性就是**字典**。
+
+要在测试时覆盖原有依赖项,这个字典的键应当是原依赖项(函数),值是覆盖依赖项(另一个函数)。
+
+这样一来,**FastAPI** 就会调用覆盖依赖项,不再调用原依赖项。
+
+{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *}
+
+/// tip | 提示
+
+**FastAPI** 应用中的任何位置都可以实现覆盖依赖项。
+
+原依赖项可用于*路径操作函数*、*路径操作装饰器*(不需要返回值时)、`.include_router()` 调用等。
+
+FastAPI 可以覆盖这些位置的依赖项。
+
+///
+
+然后,使用 `app.dependency_overrides` 把覆盖依赖项重置为空**字典**:
+
+```Python
+app.dependency_overrides = {}
+```
+
+/// tip | 提示
+
+如果只在某些测试时覆盖依赖项,您可以在测试开始时(在测试函数内)设置覆盖依赖项,并在结束时(在测试函数结尾)重置覆盖依赖项。
+
+///
diff --git a/docs/zh/docs/advanced/testing-events.md b/docs/zh/docs/advanced/testing-events.md
new file mode 100644
index 000000000..71b3739c3
--- /dev/null
+++ b/docs/zh/docs/advanced/testing-events.md
@@ -0,0 +1,5 @@
+# 测试事件:启动 - 关闭
+
+使用 `TestClient` 和 `with` 语句,在测试中运行事件处理器(`startup` 与 `shutdown`)。
+
+{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
diff --git a/docs/zh/docs/advanced/testing-websockets.md b/docs/zh/docs/advanced/testing-websockets.md
new file mode 100644
index 000000000..5d713d5f7
--- /dev/null
+++ b/docs/zh/docs/advanced/testing-websockets.md
@@ -0,0 +1,13 @@
+# 测试 WebSockets
+
+测试 WebSockets 也使用 `TestClient`。
+
+为此,要在 `with` 语句中使用 `TestClient` 连接 WebSocket。
+
+{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
+
+/// note | 笔记
+
+更多细节详见
Starlette 官档 - 测试 WebSockets。
+
+///
diff --git a/docs/zh/docs/advanced/using-request-directly.md b/docs/zh/docs/advanced/using-request-directly.md
new file mode 100644
index 000000000..db0fcafdf
--- /dev/null
+++ b/docs/zh/docs/advanced/using-request-directly.md
@@ -0,0 +1,56 @@
+# 直接使用请求
+
+至此,我们已经使用多种类型声明了请求的各种组件。
+
+并从以下对象中提取数据:
+
+* 路径参数
+* 请求头
+* Cookies
+* 等
+
+**FastAPI** 使用这种方式验证数据、转换数据,并自动生成 API 文档。
+
+但有时,我们也需要直接访问 `Request` 对象。
+
+## `Request` 对象的细节
+
+实际上,**FastAPI** 的底层是 **Starlette**,**FastAPI** 只不过是在 **Starlette** 顶层提供了一些工具,所以能直接使用 Starlette 的
`Request` 对象。
+
+但直接从 `Request` 对象提取数据时(例如,读取请求体),**FastAPI** 不会验证、转换和存档数据(为 API 文档使用 OpenAPI)。
+
+不过,仍可以验证、转换与注释(使用 Pydantic 模型的请求体等)其它正常声明的参数。
+
+但在某些特定情况下,还是需要提取 `Request` 对象。
+
+## 直接使用 `Request` 对象
+
+假设要在*路径操作函数*中获取客户端 IP 地址和主机。
+
+此时,需要直接访问请求。
+
+{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
+
+把*路径操作函数*的参数类型声明为 `Request`,**FastAPI** 就能把 `Request` 传递到参数里。
+
+/// tip | 提示
+
+注意,本例除了声明请求参数之外,还声明了路径参数。
+
+因此,能够提取、验证路径参数、并转换为指定类型,还可以用 OpenAPI 注释。
+
+同样,您也可以正常声明其它参数,而且还可以提取 `Request`。
+
+///
+
+## `Request` 文档
+
+更多细节详见
Starlette 官档 - `Request` 对象。
+
+/// note | 技术细节
+
+您也可以使用 `from starlette.requests import Request`。
+
+**FastAPI** 的 `from fastapi import Request` 只是为开发者提供的快捷方式,但其实它直接继承自 Starlette。
+
+///
diff --git a/docs/zh/docs/advanced/websockets.md b/docs/zh/docs/advanced/websockets.md
new file mode 100644
index 000000000..d91aacc03
--- /dev/null
+++ b/docs/zh/docs/advanced/websockets.md
@@ -0,0 +1,176 @@
+# WebSockets
+
+您可以在 **FastAPI** 中使用 [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)。
+
+## 安装 `WebSockets`
+
+首先,您需要安装 `WebSockets`:
+
+```console
+$ pip install websockets
+
+---> 100%
+```
+
+## WebSockets 客户端
+
+### 在生产环境中
+
+在您的生产系统中,您可能使用现代框架(如React、Vue.js或Angular)创建了一个前端。
+
+要使用 WebSockets 与后端进行通信,您可能会使用前端的工具。
+
+或者,您可能有一个原生移动应用程序,直接使用原生代码与 WebSocket 后端通信。
+
+或者,您可能有其他与 WebSocket 终端通信的方式。
+
+---
+
+但是,在本示例中,我们将使用一个非常简单的HTML文档,其中包含一些JavaScript,全部放在一个长字符串中。
+
+当然,这并不是最优的做法,您不应该在生产环境中使用它。
+
+在生产环境中,您应该选择上述任一选项。
+
+但这是一种专注于 WebSockets 的服务器端并提供一个工作示例的最简单方式:
+
+{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
+
+## 创建 `websocket`
+
+在您的 **FastAPI** 应用程序中,创建一个 `websocket`:
+
+{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
+
+/// note | 技术细节
+
+您也可以使用 `from starlette.websockets import WebSocket`。
+
+**FastAPI** 直接提供了相同的 `WebSocket`,只是为了方便开发人员。但它直接来自 Starlette。
+
+///
+
+## 等待消息并发送消息
+
+在您的 WebSocket 路由中,您可以使用 `await` 等待消息并发送消息。
+
+{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
+
+您可以接收和发送二进制、文本和 JSON 数据。
+
+## 尝试一下
+
+如果您的文件名为 `main.py`,请使用以下命令运行应用程序:
+
+```console
+$ uvicorn main:app --reload
+
+
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+在浏览器中打开
http://127.0.0.1:8000。
+
+您将看到一个简单的页面,如下所示:
+
+

+
+您可以在输入框中输入消息并发送:
+
+

+
+您的 **FastAPI** 应用程序将回复:
+
+

+
+您可以发送(和接收)多条消息:
+
+

+
+所有这些消息都将使用同一个 WebSocket 连
+
+接。
+
+## 使用 `Depends` 和其他依赖项
+
+在 WebSocket 端点中,您可以从 `fastapi` 导入并使用以下内容:
+
+* `Depends`
+* `Security`
+* `Cookie`
+* `Header`
+* `Path`
+* `Query`
+
+它们的工作方式与其他 FastAPI 端点/ *路径操作* 相同:
+
+{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
+
+/// info
+
+由于这是一个 WebSocket,抛出 `HTTPException` 并不是很合理,而是抛出 `WebSocketException`。
+
+您可以使用
规范中定义的有效代码。
+
+///
+
+### 尝试带有依赖项的 WebSockets
+
+如果您的文件名为 `main.py`,请使用以下命令运行应用程序:
+
+```console
+$ uvicorn main:app --reload
+
+
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+在浏览器中打开
http://127.0.0.1:8000。
+
+在页面中,您可以设置:
+
+* "Item ID",用于路径。
+* "Token",作为查询参数。
+
+/// tip
+
+注意,查询参数 `token` 将由依赖项处理。
+
+///
+
+通过这样,您可以连接 WebSocket,然后发送和接收消息:
+
+

+
+## 处理断开连接和多个客户端
+
+当 WebSocket 连接关闭时,`await websocket.receive_text()` 将引发 `WebSocketDisconnect` 异常,您可以捕获并处理该异常,就像本示例中的示例一样。
+
+{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
+
+尝试以下操作:
+
+* 使用多个浏览器选项卡打开应用程序。
+* 从这些选项卡中发送消息。
+* 然后关闭其中一个选项卡。
+
+这将引发 `WebSocketDisconnect` 异常,并且所有其他客户端都会收到类似以下的消息:
+
+```
+Client #1596980209979 left the chat
+```
+
+/// tip
+
+上面的应用程序是一个最小和简单的示例,用于演示如何处理和向多个 WebSocket 连接广播消息。
+
+但请记住,由于所有内容都在内存中以单个列表的形式处理,因此它只能在进程运行时工作,并且只能使用单个进程。
+
+如果您需要与 FastAPI 集成更简单但更强大的功能,支持 Redis、PostgreSQL 或其他功能,请查看 [encode/broadcaster](https://github.com/encode/broadcaster)。
+
+///
+
+## 更多信息
+
+要了解更多选项,请查看 Starlette 的文档:
+
+* [WebSocket 类](https://www.starlette.io/websockets/)
+* [基于类的 WebSocket 处理](https://www.starlette.io/endpoints/#websocketendpoint)。
diff --git a/docs/zh/docs/advanced/wsgi.md b/docs/zh/docs/advanced/wsgi.md
index ad71280fc..363025a34 100644
--- a/docs/zh/docs/advanced/wsgi.md
+++ b/docs/zh/docs/advanced/wsgi.md
@@ -1,6 +1,6 @@
# 包含 WSGI - Flask,Django,其它
-您可以挂载多个 WSGI 应用,正如您在 [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](./behind-a-proxy.md){.internal-link target=_blank} 中所看到的那样。
+您可以挂载多个 WSGI 应用,正如您在 [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank} 中所看到的那样。
为此, 您可以使用 `WSGIMiddleware` 来包装你的 WSGI 应用,如:Flask,Django,等等。
@@ -12,9 +12,7 @@
之后将其挂载到某一个路径下。
-```Python hl_lines="2-3 22"
-{!../../../docs_src/wsgi/tutorial001.py!}
-```
+{* ../../docs_src/wsgi/tutorial001.py hl[2:3,22] *}
## 检查
diff --git a/docs/zh/docs/async.md b/docs/zh/docs/async.md
new file mode 100644
index 000000000..9e6962eb1
--- /dev/null
+++ b/docs/zh/docs/async.md
@@ -0,0 +1,444 @@
+# 并发 async / await
+
+有关路径操作函数的 `async def` 语法以及异步代码、并发和并行的一些背景知识。
+
+## 赶时间吗?
+
+
TL;DR:
+
+如果你正在使用第三方库,它们会告诉你使用 `await` 关键字来调用它们,就像这样:
+
+```Python
+results = await some_library()
+```
+
+然后,通过 `async def` 声明你的 *路径操作函数*:
+
+```Python hl_lines="2"
+@app.get('/')
+async def read_results():
+ results = await some_library()
+ return results
+```
+
+/// note
+
+你只能在被 `async def` 创建的函数内使用 `await`
+
+///
+
+---
+
+如果你正在使用一个第三方库和某些组件(比如:数据库、API、文件系统...)进行通信,第三方库又不支持使用 `await` (目前大多数数据库三方库都是这样),这种情况你可以像平常那样使用 `def` 声明一个路径操作函数,就像这样:
+
+```Python hl_lines="2"
+@app.get('/')
+def results():
+ results = some_library()
+ return results
+```
+
+---
+
+如果你的应用程序不需要与其他任何东西通信而等待其响应,请使用 `async def`。
+
+---
+
+如果你不清楚,使用 `def` 就好.
+
+---
+
+**注意**:你可以根据需要在路径操作函数中混合使用 `def` 和 `async def`,并使用最适合你的方式去定义每个函数。FastAPI 将为他们做正确的事情。
+
+无论如何,在上述任何情况下,FastAPI 仍将异步工作,速度也非常快。
+
+但是,通过遵循上述步骤,它将能够进行一些性能优化。
+
+## 技术细节
+
+Python 的现代版本支持通过一种叫**"协程"**——使用 `async` 和 `await` 语法的东西来写**”异步代码“**。
+
+让我们在下面的部分中逐一介绍:
+
+* **异步代码**
+* **`async` 和 `await`**
+* **协程**
+
+## 异步代码
+
+异步代码仅仅意味着编程语言 💬 有办法告诉计算机/程序 🤖 在代码中的某个点,它 🤖 将不得不等待在某些地方完成一些事情。让我们假设一些事情被称为 "慢文件"📝.
+
+所以,在等待"慢文件"📝完成的这段时间,计算机可以做一些其他工作。
+
+然后计算机/程序 🤖 每次有机会都会回来,因为它又在等待,或者它 🤖 完成了当前所有的工作。而且它 🤖 将查看它等待的所有任务中是否有已经完成的,做它必须做的任何事情。
+
+接下来,它 🤖 完成第一个任务(比如是我们的"慢文件"📝) 并继续与之相关的一切。
+
+这个"等待其他事情"通常指的是一些相对较慢(与处理器和 RAM 存储器的速度相比)的
I/O 操作,比如说:
+
+* 通过网络发送来自客户端的数据
+* 客户端接收来自网络中的数据
+* 磁盘中要由系统读取并提供给程序的文件的内容
+* 程序提供给系统的要写入磁盘的内容
+* 一个 API 的远程调用
+* 一个数据库操作,直到完成
+* 一个数据库查询,直到返回结果
+* 等等.
+
+这个执行的时间大多是在等待
I/O 操作,因此它们被叫做 "I/O 密集型" 操作。
+
+它被称为"异步"的原因是因为计算机/程序不必与慢任务"同步",去等待任务完成的确切时刻,而在此期间不做任何事情直到能够获取任务结果才继续工作。
+
+相反,作为一个"异步"系统,一旦完成,任务就可以排队等待一段时间(几微秒),等待计算机程序完成它要做的任何事情,然后回来获取结果并继续处理它们。
+
+对于"同步"(与"异步"相反),他们通常也使用"顺序"一词,因为计算机程序在切换到另一个任务之前是按顺序执行所有步骤,即使这些步骤涉及到等待。
+
+### 并发与汉堡
+
+上述异步代码的思想有时也被称为“并发”,它不同于“并行”。
+
+并发和并行都与“不同的事情或多或少同时发生”有关。
+
+但是并发和并行之间的细节是完全不同的。
+
+要了解差异,请想象以下关于汉堡的故事:
+
+### 并发汉堡
+
+你和你的恋人一起去快餐店,你排队在后面,收银员从你前面的人接单。😍
+
+

+
+然后轮到你了,你为你的恋人和你选了两个非常豪华的汉堡。🍔🍔
+
+

+
+收银员对厨房里的厨师说了一些话,让他们知道他们必须为你准备汉堡(尽管他们目前正在为之前的顾客准备汉堡)。
+
+

+
+你付钱了。 💸
+
+收银员给你轮到的号码。
+
+

+
+当你在等待的时候,你和你的恋人一起去挑选一张桌子,然后你们坐下来聊了很长时间(因为汉堡很豪华,需要一些时间来准备)。
+
+当你和你的恋人坐在桌子旁,等待汉堡的时候,你可以用这段时间来欣赏你的恋人是多么的棒、可爱和聪明✨😍✨。
+
+

+
+在等待中和你的恋人交谈时,你会不时地查看柜台上显示的号码,看看是否已经轮到你了。
+
+然后在某个时刻,终于轮到你了。你去柜台拿汉堡然后回到桌子上。
+
+

+
+你们享用了汉堡,整个过程都很开心。✨
+
+

+
+/// info
+
+漂亮的插画来自
Ketrina Thompson. 🎨
+
+///
+
+---
+
+在那个故事里,假设你是计算机程序 🤖 。
+
+当你在排队时,你只是闲着😴, 轮到你前不做任何事情(仅排队)。但排队很快,因为收银员只接订单(不准备订单),所以这一切都还好。
+
+然后,当轮到你时,需要你做一些实际性的工作,比如查看菜单,决定你想要什么,让你的恋人选择,支付,检查你是否提供了正确的账单或卡,检查你的收费是否正确,检查订单是否有正确的项目,等等。
+
+此时,即使你仍然没有汉堡,你和收银员的工作也"暂停"了⏸, 因为你必须等待一段时间 🕙 让你的汉堡做好。
+
+但是,当你离开柜台并坐在桌子旁,在轮到你的号码前的这段时间,你可以将焦点切换到 🔀 你的恋人上,并做一些"工作"⏯ 🤓。你可以做一些非常"有成效"的事情,比如和你的恋人调情😍.
+
+之后,收银员 💁 把号码显示在显示屏上,并说到 "汉堡做好了",而当显示的号码是你的号码时,你不会立刻疯狂地跳起来。因为你知道没有人会偷你的汉堡,因为你有你的号码,而其他人又有他们自己的号码。
+
+所以你要等待你的恋人完成故事(完成当前的工作⏯ /正在做的事🤓), 轻轻微笑,说你要吃汉堡⏸.
+
+然后你去柜台🔀, 到现在初始任务已经完成⏯, 拿起汉堡,说声谢谢,然后把它们送到桌上。这就完成了与计数器交互的步骤/任务⏹. 这反过来又产生了一项新任务,即"吃汉堡"🔀 ⏯, 上一个"拿汉堡"的任务已经结束了⏹.
+
+### 并行汉堡
+
+现在让我们假设不是"并发汉堡",而是"并行汉堡"。
+
+你和你的恋人一起去吃并行快餐。
+
+你站在队伍中,同时是厨师的几个收银员(比方说8个)从前面的人那里接单。
+
+你之前的每个人都在等待他们的汉堡准备好后才离开柜台,因为8名收银员都会在下一份订单前马上准备好汉堡。
+
+

+
+然后,终于轮到你了,你为你的恋人和你订购了两个非常精美的汉堡。
+
+你付钱了 💸。
+
+

+
+收银员去厨房。
+
+你站在柜台前 🕙等待着,这样就不会有人在你之前抢走你的汉堡,因为没有轮流的号码。
+
+

+
+当你和你的恋人忙于不让任何人出现在你面前,并且在他们到来的时候拿走你的汉堡时,你无法关注到你的恋人。😞
+
+这是"同步"的工作,你被迫与服务员/厨师 👨🍳"同步"。你在此必须等待 🕙 ,在收银员/厨师 👨🍳 完成汉堡并将它们交给你的确切时间到达之前一直等待,否则其他人可能会拿走它们。
+
+

+
+你经过长时间的等待 🕙 ,收银员/厨师 👨🍳终于带着汉堡回到了柜台。
+
+

+
+你拿着汉堡,和你的情人一起上桌。
+
+你们仅仅是吃了它们,就结束了。⏹
+
+

+
+没有太多的交谈或调情,因为大部分时间 🕙 都在柜台前等待😞。
+
+/// info
+
+漂亮的插画来自
Ketrina Thompson. 🎨
+
+///
+
+---
+
+在这个并行汉堡的场景中,你是一个计算机程序 🤖 且有两个处理器(你和你的恋人),都在等待 🕙 ,并投入他们的注意力 ⏯ 在柜台上等待了很长一段时间。
+
+这家快餐店有 8 个处理器(收银员/厨师)。而并发汉堡店可能只有 2 个(一个收银员和一个厨师)。
+
+但最终的体验仍然不是最好的。😞
+
+---
+
+这将是与汉堡的类似故事。🍔
+
+一种更"贴近生活"的例子,想象一家银行。
+
+直到最近,大多数银行都有多个出纳员 👨💼👨💼👨💼👨💼 还有一条长长排队队伍🕙🕙🕙🕙🕙🕙🕙🕙。
+
+所有收银员都是一个接一个的在客户面前做完所有的工作👨💼⏯.
+
+你必须经过 🕙 较长时间排队,否则你就没机会了。
+
+你可不会想带你的恋人 😍 和你一起去银行办事🏦.
+
+### 汉堡结论
+
+在"你与恋人一起吃汉堡"的这个场景中,因为有很多人在等待🕙, 使用并发系统更有意义⏸🔀⏯.
+
+大多数 Web 应用都是这样的。
+
+你的服务器正在等待很多很多用户通过他们不太好的网络发送来的请求。
+
+然后再次等待 🕙 响应回来。
+
+这个"等待" 🕙 是以微秒为单位测量的,但总的来说,最后还是等待很久。
+
+这就是为什么使用异步对于 Web API 很有意义的原因 ⏸🔀⏯。
+
+这种异步机制正是 NodeJS 受到欢迎的原因(尽管 NodeJS 不是并行的),以及 Go 作为编程语言的优势所在。
+
+这与 **FastAPI** 的性能水平相同。
+
+你可以同时拥有并行性和异步性,你可以获得比大多数经过测试的 NodeJS 框架更高的性能,并且与 Go 不相上下, Go 是一种更接近于 C 的编译语言(
全部归功于 Starlette)。
+
+### 并发比并行好吗?
+
+不!这不是故事的本意。
+
+并发不同于并行。而是在需要大量等待的特定场景下效果更好。因此,在 Web 应用程序开发中,它通常比并行要好得多,但这并不意味着全部。
+
+因此,为了平衡这一点,想象一下下面的短篇故事:
+
+> 你必须打扫一个又大又脏的房子。
+
+*是的,这就是完整的故事。*
+
+---
+
+在任何地方, 都不需要等待 🕙 ,只需要在房子的多个地方做着很多工作。
+
+你可以像汉堡的例子那样轮流执行,先是客厅,然后是厨房,但因为你不需要等待 🕙 ,对于任何事情都是清洁,清洁,还是清洁,轮流不会影响任何事情。
+
+无论是否轮流执行(并发),都需要相同的时间来完成,而你也会完成相同的工作量。
+
+但在这种情况下,如果你能带上 8 名前收银员/厨师,现在是清洁工一起清扫,他们中的每一个人(加上你)都能占据房子的一个区域来清扫,你就可以在额外的帮助下并行的更快地完成所有工作。
+
+在这个场景中,每个清洁工(包括你)都将是一个处理器,完成这个工作的一部分。
+
+由于大多数执行时间是由实际工作(而不是等待)占用的,并且计算机中的工作是由
CPU 完成的,所以他们称这些问题为"CPU 密集型"。
+
+---
+
+CPU 密集型操作的常见示例是需要复杂的数学处理。
+
+例如:
+
+* **音频**或**图像**处理;
+* **计算机视觉**: 一幅图像由数百万像素组成,每个像素有3种颜色值,处理通常需要同时对这些像素进行计算;
+* **机器学习**: 它通常需要大量的"矩阵"和"向量"乘法。想象一个包含数字的巨大电子表格,并同时将所有数字相乘;
+* **深度学习**: 这是机器学习的一个子领域,同样适用。只是没有一个数字的电子表格可以相乘,而是一个庞大的数字集合,在很多情况下,你需要使用一个特殊的处理器来构建和使用这些模型。
+
+### 并发 + 并行: Web + 机器学习
+
+使用 **FastAPI**,你可以利用 Web 开发中常见的并发机制的优势(NodeJS 的主要吸引力)。
+
+并且,你也可以利用并行和多进程(让多个进程并行运行)的优点来处理与机器学习系统中类似的 **CPU 密集型** 工作。
+
+这一点,再加上 Python 是**数据科学**、机器学习(尤其是深度学习)的主要语言这一简单事实,使得 **FastAPI** 与数据科学/机器学习 Web API 和应用程序(以及其他许多应用程序)非常匹配。
+
+了解如何在生产环境中实现这种并行性,可查看此文 [Deployment](deployment/index.md){.internal-link target=_blank}。
+
+## `async` 和 `await`
+
+现代版本的 Python 有一种非常直观的方式来定义异步代码。这使它看起来就像正常的"顺序"代码,并在适当的时候"等待"。
+
+当有一个操作需要等待才能给出结果,且支持这个新的 Python 特性时,你可以编写如下代码:
+
+```Python
+burgers = await get_burgers(2)
+```
+
+这里的关键是 `await`。它告诉 Python 它必须等待 ⏸ `get_burgers(2)` 完成它的工作 🕙 ,然后将结果存储在 `burgers` 中。这样,Python 就会知道此时它可以去做其他事情 🔀 ⏯ (比如接收另一个请求)。
+
+要使 `await` 工作,它必须位于支持这种异步机制的函数内。因此,只需使用 `async def` 声明它:
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # Do some asynchronous stuff to create the burgers
+ return burgers
+```
+
+...而不是 `def`:
+
+```Python hl_lines="2"
+# This is not asynchronous
+def get_sequential_burgers(number: int):
+ # Do some sequential stuff to create the burgers
+ return burgers
+```
+
+使用 `async def`,Python 就知道在该函数中,它将遇上 `await`,并且它可以"暂停" ⏸ 执行该函数,直至执行其他操作 🔀 后回来。
+
+当你想调用一个 `async def` 函数时,你必须"等待"它。因此,这不会起作用:
+
+```Python
+# This won't work, because get_burgers was defined with: async def
+burgers = get_burgers(2)
+```
+
+---
+
+因此,如果你使用的库告诉你可以使用 `await` 调用它,则需要使用 `async def` 创建路径操作函数 ,如:
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### 更多技术细节
+
+你可能已经注意到,`await` 只能在 `async def` 定义的函数内部使用。
+
+但与此同时,必须"等待"通过 `async def` 定义的函数。因此,带 `async def` 的函数也只能在 `async def` 定义的函数内部调用。
+
+那么,这关于先有鸡还是先有蛋的问题,如何调用第一个 `async` 函数?
+
+如果你使用 **FastAPI**,你不必担心这一点,因为"第一个"函数将是你的路径操作函数,FastAPI 将知道如何做正确的事情。
+
+但如果你想在没有 FastAPI 的情况下使用 `async` / `await`,则可以这样做。
+
+### 编写自己的异步代码
+
+Starlette (和 **FastAPI**) 是基于
AnyIO 实现的,这使得它们可以兼容 Python 的标准库
asyncio 和
Trio。
+
+特别是,你可以直接使用
AnyIO 来处理高级的并发用例,这些用例需要在自己的代码中使用更高级的模式。
+
+即使你没有使用 **FastAPI**,你也可以使用
AnyIO 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如, 结构化并发)。
+
+我(指原作者 —— 译者注)基于 AnyIO 新建了一个库,作为一个轻量级的封装层,用来优化类型注解,同时提供了更好的**自动补全**、**内联错误提示**等功能。这个库还附带了一个友好的入门指南和教程,能帮助你**理解**并编写**自己的异步代码**:
Asyncer。如果你有**结合使用异步代码和常规**(阻塞/同步)代码的需求,这个库会特别有用。
+
+### 其他形式的异步代码
+
+这种使用 `async` 和 `await` 的风格在语言中相对较新。
+
+但它使处理异步代码变得容易很多。
+
+这种相同的语法(或几乎相同)最近也包含在现代版本的 JavaScript 中(在浏览器和 NodeJS 中)。
+
+但在此之前,处理异步代码非常复杂和困难。
+
+在以前版本的 Python,你可以使用多线程或者
Gevent。但代码的理解、调试和思考都要复杂许多。
+
+在以前版本的 NodeJS / 浏览器 JavaScript 中,你会使用"回调",因此也可能导致
回调地狱。
+
+## 协程
+
+**协程**只是 `async def` 函数返回的一个非常奇特的东西的称呼。Python 知道它有点像一个函数,它可以启动,也会在某个时刻结束,而且它可能会在内部暂停 ⏸ ,只要内部有一个 `await`。
+
+通过使用 `async` 和 `await` 的异步代码的所有功能大多数被概括为"协程"。它可以与 Go 的主要关键特性 "Goroutines" 相媲美。
+
+## 结论
+
+让我们再来回顾下上文所说的:
+
+> Python 的现代版本可以通过使用 `async` 和 `await` 语法创建**协程**,并用于支持**异步代码**。
+
+现在应该能明白其含义了。✨
+
+所有这些使得 FastAPI(通过 Starlette)如此强大,也是它拥有如此令人印象深刻的性能的原因。
+
+## 非常技术性的细节
+
+/// warning
+
+你可以跳过这里。
+
+这些都是 FastAPI 如何在内部工作的技术细节。
+
+如果你有相当多的技术知识(协程、线程、阻塞等),并且对 FastAPI 如何处理 `async def` 与常规 `def` 感到好奇,请继续。
+
+///
+
+### 路径操作函数
+
+当你使用 `def` 而不是 `async def` 来声明一个*路径操作函数*时,它运行在外部的线程池中并等待其结果,而不是直接调用(因为它会阻塞服务器)。
+
+如果你使用过另一个不以上述方式工作的异步框架,并且你习惯于用普通的 `def` 定义普通的仅计算路径操作函数,以获得微小的性能增益(大约100纳秒),请注意,在 FastAPI 中,效果将完全相反。在这些情况下,最好使用 `async def`,除非路径操作函数内使用执行阻塞
I/O 的代码。
+
+在这两种情况下,与你之前的框架相比,**FastAPI** 可能[仍然很快](index.md#_11){.internal-link target=_blank}。
+
+### 依赖
+
+这同样适用于[依赖](tutorial/dependencies/index.md){.internal-link target=_blank}。如果一个依赖是标准的 `def` 函数而不是 `async def`,它将被运行在外部线程池中。
+
+### 子依赖
+
+你可以拥有多个相互依赖的依赖以及[子依赖](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} (作为函数的参数),它们中的一些可能是通过 `async def` 声明,也可能是通过 `def` 声明。它们仍然可以正常工作,这些通过 `def` 声明的函数将会在外部线程中调用(来自线程池),而不是"被等待"。
+
+### 其他函数
+
+你可直接调用通过 `def` 或 `async def` 创建的任何其他函数,FastAPI 不会影响你调用它们的方式。
+
+这与 FastAPI 为你调用*路径操作函数*和依赖项的逻辑相反。
+
+如果你的函数是通过 `def` 声明的,它将被直接调用(在代码中编写的地方),而不会在线程池中,如果这个函数通过 `async def` 声明,当在代码中调用时,你就应该使用 `await` 等待函数的结果。
+
+---
+
+再次提醒,这些是非常技术性的细节,如果你来搜索它可能对你有用。
+
+否则,你最好应该遵守的指导原则
赶时间吗?.
diff --git a/docs/zh/docs/benchmarks.md b/docs/zh/docs/benchmarks.md
index 8991c72cd..71e8d4838 100644
--- a/docs/zh/docs/benchmarks.md
+++ b/docs/zh/docs/benchmarks.md
@@ -1,6 +1,6 @@
# 基准测试
-第三方机构 TechEmpower 的基准测试表明在 Uvicorn 下运行的 **FastAPI** 应用程序是
可用的最快的 Python 框架之一,仅次与 Starlette 和 Uvicorn 本身 (由 FastAPI 内部使用)。(*)
+第三方机构 TechEmpower 的基准测试表明在 Uvicorn 下运行的 **FastAPI** 应用程序是
可用的最快的 Python 框架之一,仅次于 Starlette 和 Uvicorn 本身 (由 FastAPI 内部使用)。(*)
但是在查看基准得分和对比时,请注意以下几点。
diff --git a/docs/zh/docs/contributing.md b/docs/zh/docs/contributing.md
deleted file mode 100644
index 36c3631c4..000000000
--- a/docs/zh/docs/contributing.md
+++ /dev/null
@@ -1,468 +0,0 @@
-# 开发 - 贡献
-
-首先,你最好先了解 [帮助 FastAPI 及获取帮助](help-fastapi.md){.internal-link target=_blank}的基本方式。
-
-## 开发
-
-如果你已经克隆了源码仓库,并且需要深入研究代码,下面是设置开发环境的指南。
-
-### 通过 `venv` 管理虚拟环境
-
-你可以使用 Python 的 `venv` 模块在一个目录中创建虚拟环境:
-
-
-
-```console
-$ python -m venv env
-```
-
-
-
-这将使用 Python 程序创建一个 `./env/` 目录,然后你将能够为这个隔离的环境安装软件包。
-
-### 激活虚拟环境
-
-使用以下方法激活新环境:
-
-=== "Linux, macOS"
-
-
-
- ```console
- $ source ./env/bin/activate
- ```
-
-
-
-=== "Windows PowerShell"
-
-
-
- ```console
- $ .\env\Scripts\Activate.ps1
- ```
-
-
-
-=== "Windows Bash"
-
- Or if you use Bash for Windows (e.g.
Git Bash):
-
-
-
- ```console
- $ source ./env/Scripts/activate
- ```
-
-
-
-要检查操作是否成功,运行:
-
-=== "Linux, macOS, Windows Bash"
-
-
-
- ```console
- $ which pip
-
- some/directory/fastapi/env/bin/pip
- ```
-
-
-
-=== "Windows PowerShell"
-
-
-
- ```console
- $ Get-Command pip
-
- some/directory/fastapi/env/bin/pip
- ```
-
-
-
-如果显示 `pip` 程序文件位于 `env/bin/pip` 则说明激活成功。 🎉
-
-
-!!! tip
- 每一次你在该环境下使用 `pip` 安装了新软件包时,请再次激活该环境。
-
- 这样可以确保你在使用由该软件包安装的终端程序时使用的是当前虚拟环境中的程序,而不是其他的可能是全局安装的程序。
-
-### pip
-
-如上所述激活环境后:
-
-
-
-```console
-$ pip install -e ."[dev,doc,test]"
-
----> 100%
-```
-
-
-
-这将在虚拟环境中安装所有依赖和本地版本的 FastAPI。
-
-#### 使用本地 FastAPI
-
-如果你创建一个导入并使用 FastAPI 的 Python 文件,然后使用虚拟环境中的 Python 运行它,它将使用你本地的 FastAPI 源码。
-
-并且如果你更改该本地 FastAPI 的源码,由于它是通过 `-e` 安装的,当你再次运行那个 Python 文件,它将使用你刚刚编辑过的最新版本的 FastAPI。
-
-这样,你不必再去重新"安装"你的本地版本即可测试所有更改。
-
-### 格式化
-
-你可以运行下面的脚本来格式化和清理所有代码:
-
-
-
-```console
-$ bash scripts/format.sh
-```
-
-
-
-它还会自动对所有导入代码进行整理。
-
-为了使整理正确进行,你需要在当前环境中安装本地的 FastAPI,即在运行上述段落中的命令时添加 `-e`。
-
-### 格式化导入
-
-还有另一个脚本可以格式化所有导入,并确保你没有未使用的导入代码:
-
-
-
-```console
-$ bash scripts/format-imports.sh
-```
-
-
-
-由于它依次运行了多个命令,并修改和还原了许多文件,所以运行时间会更长一些,因此经常地使用 `scripts/format.sh` 然后仅在提交前执行 `scripts/format-imports.sh` 会更好一些。
-
-## 文档
-
-首先,请确保按上述步骤设置好环境,这将安装所有需要的依赖。
-
-文档使用
MkDocs 生成。
-
-并且在 `./scripts/docs.py` 中还有适用的额外工具/脚本来处理翻译。
-
-!!! tip
- 你不需要去了解 `./scripts/docs.py` 中的代码,只需在命令行中使用它即可。
-
-所有文档均在 `./docs/en/` 目录中以 Markdown 文件格式保存。
-
-许多的教程章节里包含有代码块。
-
-在大多数情况下,这些代码块是可以直接运行的真实完整的应用程序。
-
-实际上,这些代码块不是写在 Markdown 文件内的,它们是位于 `./docs_src/` 目录中的 Python 文件。
-
-生成站点时,这些 Python 文件会被包含/注入到文档中。
-
-### 用于测试的文档
-
-大多数的测试实际上都是针对文档中的示例源文件运行的。
-
-这有助于确保:
-
-* 文档始终是最新的。
-* 文档示例可以直接运行。
-* 绝大多数特性既在文档中得以阐述,又通过测试覆盖进行保障。
-
-在本地开发期间,有一个脚本可以实时重载地构建站点并用来检查所做的任何更改:
-
-
-
-```console
-$ python ./scripts/docs.py live
-
-[INFO] Serving on http://127.0.0.1:8008
-[INFO] Start watching changes
-[INFO] Start detecting changes
-```
-
-
-
-它将在 `http://127.0.0.1:8008` 提供对文档的访问。
-
-这样,你可以编辑文档/源文件并实时查看更改。
-
-#### Typer CLI (可选)
-
-本指引向你展示了如何直接用 `python` 程序运行 `./scripts/docs.py` 中的脚本。
-
-但你也可以使用
Typer CLI,而且在安装了补全功能后,你将可以在终端中对命令进行自动补全。
-
-如果你打算安装 Typer CLI ,可以使用以下命令安装自动补全功能:
-
-
-
-```console
-$ typer --install-completion
-
-zsh completion installed in /home/user/.bashrc.
-Completion will take effect once you restart the terminal.
-```
-
-
-
-### 应用和文档同时运行
-
-如果你使用以下方式运行示例程序:
-
-
-
-```console
-$ uvicorn tutorial001:app --reload
-
-INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
-
-
-
-由于 Uvicorn 默认使用 `8000` 端口 ,因此运行在 `8008` 端口上的文档不会与之冲突。
-
-### 翻译
-
-非常感谢你能够参与文档的翻译!这项工作需要社区的帮助才能完成。 🌎 🚀
-
-以下是参与帮助翻译的步骤。
-
-#### 建议和指南
-
-* 在当前
已有的 pull requests 中查找你使用的语言,添加要求修改或同意合并的评审意见。
-
-!!! tip
- 你可以为已有的 pull requests
添加包含修改建议的评论。
-
- 详情可查看关于
添加 pull request 评审意见 以同意合并或要求修改的文档。
-
-* 在
issues 中查找是否有对你所用语言所进行的协作翻译。
-
-* 每翻译一个页面新增一个 pull request。这将使其他人更容易对其进行评审。
-
-对于我(译注:作者使用西班牙语和英语)不懂的语言,我将在等待其他人评审翻译之后将其合并。
-
-* 你还可以查看是否有你所用语言的翻译,并对其进行评审,这将帮助我了解翻译是否正确以及能否将其合并。
-
-* 使用相同的 Python 示例并且仅翻译文档中的文本。无需进行任何其他更改示例也能正常工作。
-
-* 使用相同的图片、文件名以及链接地址。无需进行任何其他调整来让它们兼容。
-
-* 你可以从
ISO 639-1 代码列表 表中查找你想要翻译语言的两位字母代码。
-
-#### 已有的语言
-
-假设你想将某个页面翻译成已经翻译了一些页面的语言,例如西班牙语。
-
-对于西班牙语来说,它的两位字母代码是 `es`。所以西班牙语翻译的目录位于 `docs/es/`。
-
-!!! tip
- 主要("官方")语言是英语,位于 `docs/en/`目录。
-
-现在为西班牙语文档运行实时服务器:
-
-
-
-```console
-// Use the command "live" and pass the language code as a CLI argument
-$ python ./scripts/docs.py live es
-
-[INFO] Serving on http://127.0.0.1:8008
-[INFO] Start watching changes
-[INFO] Start detecting changes
-```
-
-
-
-现在你可以访问
http://127.0.0.1:8008 实时查看你所做的更改。
-
-如果你查看 FastAPI 的线上文档网站,会看到每种语言都有所有页面。但是某些页面并未被翻译并且会有一处关于缺少翻译的提示。
-
-但是当你像上面这样在本地运行文档时,你只会看到已经翻译的页面。
-
-现在假设你要为 [Features](features.md){.internal-link target=_blank} 章节添加翻译。
-
-* 复制下面的文件:
-
-```
-docs/en/docs/features.md
-```
-
-* 粘贴到你想要翻译语言目录的相同位置,比如:
-
-```
-docs/es/docs/features.md
-```
-
-!!! tip
- 注意路径和文件名的唯一变化是语言代码,从 `en` 更改为 `es`。
-
-* 现在打开位于英语文档目录下的 MkDocs 配置文件:
-
-```
-docs/en/docs/mkdocs.yml
-```
-
-* 在配置文件中找到 `docs/features.md` 所在的位置。结果像这样:
-
-```YAML hl_lines="8"
-site_name: FastAPI
-# More stuff
-nav:
-- FastAPI: index.md
-- Languages:
- - en: /
- - es: /es/
-- features.md
-```
-
-* 打开你正在编辑的语言目录中的 MkDocs 配置文件,例如:
-
-```
-docs/es/docs/mkdocs.yml
-```
-
-* 将其添加到与英语文档完全相同的位置,例如:
-
-```YAML hl_lines="8"
-site_name: FastAPI
-# More stuff
-nav:
-- FastAPI: index.md
-- Languages:
- - en: /
- - es: /es/
-- features.md
-```
-
-如果配置文件中还有其他条目,请确保你所翻译的新条目和它们之间的顺序与英文版本完全相同。
-
-打开浏览器,现在你将看到文档展示了你所加入的新章节。 🎉
-
-现在,你可以将它全部翻译完并在保存文件后进行预览。
-
-#### 新语言
-
-假设你想要为尚未有任何页面被翻译的语言添加翻译。
-
-假设你想要添加克里奥尔语翻译,而且文档中还没有该语言的翻译。
-
-点击上面提到的链接,可以查到"克里奥尔语"的代码为 `ht`。
-
-下一步是运行脚本以生成新的翻译目录:
-
-
-
-```console
-// Use the command new-lang, pass the language code as a CLI argument
-$ python ./scripts/docs.py new-lang ht
-
-Successfully initialized: docs/ht
-Updating ht
-Updating en
-```
-
-
-
-现在,你可以在编辑器中查看新创建的目录 `docs/ht/`。
-
-!!! tip
- 在添加实际的翻译之前,仅以此创建首个 pull request 来设定新语言的配置。
-
- 这样当你在翻译第一个页面时,其他人可以帮助翻译其他页面。🚀
-
-首先翻译文档主页 `docs/ht/index.md`。
-
-然后,你可以根据上面的"已有语言"的指引继续进行翻译。
-
-##### 不支持的新语言
-
-如果在运行实时服务器脚本时收到关于不支持该语言的错误,类似于:
-
-```
- raise TemplateNotFound(template)
-jinja2.exceptions.TemplateNotFound: partials/language/xx.html
-```
-
-这意味着文档的主题不支持该语言(在这种例子中,编造的语言代码是 `xx`)。
-
-但是别担心,你可以将主题语言设置为英语,然后翻译文档的内容。
-
-如果你需要这么做,编辑新语言目录下的 `mkdocs.yml`,它将有类似下面的内容:
-
-```YAML hl_lines="5"
-site_name: FastAPI
-# More stuff
-theme:
- # More stuff
- language: xx
-```
-
-将其中的 language 项从 `xx`(你的语言代码)更改为 `en`。
-
-然后,你就可以再次启动实时服务器了。
-
-#### 预览结果
-
-当你通过 `live` 命令使用 `./scripts/docs.py` 中的脚本时,该脚本仅展示当前语言已有的文件和翻译。
-
-但是当你完成翻译后,你可以像在线上展示一样测试所有内容。
-
-为此,首先构建所有文档:
-
-
-
-```console
-// Use the command "build-all", this will take a bit
-$ python ./scripts/docs.py build-all
-
-Updating es
-Updating en
-Building docs for: en
-Building docs for: es
-Successfully built docs for: es
-Copying en index.md to README.md
-```
-
-
-
-这将在 `./docs_build/` 目录中为每一种语言生成全部的文档。还包括添加所有缺少翻译的文件,并带有一条"此文件还没有翻译"的提醒。但是你不需要对该目录执行任何操作。
-
-然后,它针对每种语言构建独立的 MkDocs 站点,将它们组合在一起,并在 `./site/` 目录中生成最终的输出。
-
-然后你可以使用命令 `serve` 来运行生成的站点:
-
-
-
-```console
-// Use the command "serve" after running "build-all"
-$ python ./scripts/docs.py serve
-
-Warning: this is a very simple server. For development, use mkdocs serve instead.
-This is here only to preview a site with translations already built.
-Make sure you run the build-all command first.
-Serving at: http://127.0.0.1:8008
-```
-
-
-
-## 测试
-
-你可以在本地运行下面的脚本来测试所有代码并生成 HTML 格式的覆盖率报告:
-
-
-
-```console
-$ bash scripts/test-cov-html.sh
-```
-
-
-
-该命令生成了一个 `./htmlcov/` 目录,如果你在浏览器中打开 `./htmlcov/index.html` 文件,你可以交互式地浏览被测试所覆盖的代码区块,并注意是否缺少了任何区块。
diff --git a/docs/zh/docs/deployment/cloud.md b/docs/zh/docs/deployment/cloud.md
new file mode 100644
index 000000000..b086b7b6b
--- /dev/null
+++ b/docs/zh/docs/deployment/cloud.md
@@ -0,0 +1,16 @@
+# 在云上部署 FastAPI
+
+您几乎可以使用**任何云服务商**来部署 FastAPI 应用程序。
+
+在大多数情况下,主要的云服务商都有部署 FastAPI 的指南。
+
+## 云服务商 - 赞助商
+
+一些云服务商 ✨ [**赞助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,这确保了FastAPI 及其**生态系统**持续健康地**发展**。
+
+这表明了他们对 FastAPI 及其**社区**(您)的真正承诺,因为他们不仅想为您提供**良好的服务**,而且还想确保您拥有一个**良好且健康的框架**:FastAPI。 🙇
+
+您可能想尝试他们的服务并阅读他们的指南:
+
+*
Platform.sh
+*
Porter
diff --git a/docs/zh/docs/deployment/concepts.md b/docs/zh/docs/deployment/concepts.md
new file mode 100644
index 000000000..f7208da7c
--- /dev/null
+++ b/docs/zh/docs/deployment/concepts.md
@@ -0,0 +1,330 @@
+# 部署概念
+
+在部署 **FastAPI** 应用程序或任何类型的 Web API 时,有几个概念值得了解,通过掌握这些概念您可以找到**最合适的**方法来**部署您的应用程序**。
+
+一些重要的概念是:
+
+* 安全性 - HTTPS
+* 启动时运行
+* 重新启动
+* 复制(运行的进程数)
+* 内存
+* 开始前的先前步骤
+
+我们接下来了解它们将如何影响**部署**。
+
+我们的最终目标是能够以**安全**的方式**为您的 API 客户端**提供服务,同时要**避免中断**,并且尽可能高效地利用**计算资源**( 例如服务器CPU资源)。 🚀
+
+我将在这里告诉您更多关于这些**概念**的信息,希望能给您提供**直觉**来决定如何在非常不同的环境中部署 API,甚至在是尚不存在的**未来**的环境里。
+
+通过考虑这些概念,您将能够**评估和设计**部署**您自己的 API**的最佳方式。
+
+在接下来的章节中,我将为您提供更多部署 FastAPI 应用程序的**具体方法**。
+
+但现在,让我们仔细看一下这些重要的**概念**。 这些概念也适用于任何其他类型的 Web API。 💡
+
+## 安全性 - HTTPS
+
+在[上一章有关 HTTPS](https.md){.internal-link target=_blank} 中,我们了解了 HTTPS 如何为您的 API 提供加密。
+
+我们还看到,HTTPS 通常由应用程序服务器的**外部**组件(**TLS 终止代理**)提供。
+
+并且必须有某个东西负责**更新 HTTPS 证书**,它可以是相同的组件,也可以是不同的组件。
+
+
+### HTTPS 示例工具
+
+您可以用作 TLS 终止代理的一些工具包括:
+
+* Traefik
+ * 自动处理证书更新 ✨
+* Caddy
+ * 自动处理证书更新 ✨
+* Nginx
+ * 使用 Certbot 等外部组件进行证书更新
+* HAProxy
+ * 使用 Certbot 等外部组件进行证书更新
+* 带有 Ingress Controller(如Nginx) 的 Kubernetes
+ * 使用诸如 cert-manager 之类的外部组件来进行证书更新
+* 由云服务商内部处理,作为其服务的一部分(请阅读下文👇)
+
+另一种选择是您可以使用**云服务**来完成更多工作,包括设置 HTTPS。 它可能有一些限制或向您收取更多费用等。但在这种情况下,您不必自己设置 TLS 终止代理。
+
+我将在接下来的章节中向您展示一些具体示例。
+
+---
+
+接下来要考虑的概念都是关于运行实际 API 的程序(例如 Uvicorn)。
+
+## 程序和进程
+
+我们将讨论很多关于正在运行的“**进程**”的内容,因此弄清楚它的含义以及与“**程序**”这个词有什么区别是很有用的。
+
+### 什么是程序
+
+**程序**这个词通常用来描述很多东西:
+
+* 您编写的 **代码**,**Python 文件**。
+* 操作系统可以**执行**的**文件**,例如:`python`、`python.exe`或`uvicorn`。
+* 在操作系统上**运行**、使用CPU 并将内容存储在内存上的特定程序。 这也被称为**进程**。
+
+### 什么是进程
+
+**进程** 这个词通常以更具体的方式使用,仅指在操作系统中运行的东西(如上面的最后一点):
+
+* 在操作系统上**运行**的特定程序。
+ * 这不是指文件,也不是指代码,它**具体**指的是操作系统正在**执行**和管理的东西。
+* 任何程序,任何代码,**只有在执行时才能做事**。 因此,是当有**进程正在运行**时。
+* 该进程可以由您或操作系统**终止**(或“杀死”)。 那时,它停止运行/被执行,并且它可以**不再做事情**。
+* 您计算机上运行的每个应用程序背后都有一些进程,每个正在运行的程序,每个窗口等。并且通常在计算机打开时**同时**运行许多进程。
+* **同一程序**可以有**多个进程**同时运行。
+
+如果您检查操作系统中的“任务管理器”或“系统监视器”(或类似工具),您将能够看到许多正在运行的进程。
+
+例如,您可能会看到有多个进程运行同一个浏览器程序(Firefox、Chrome、Edge 等)。 他们通常每个tab运行一个进程,再加上一些其他额外的进程。
+
+

+
+---
+
+现在我们知道了术语“进程”和“程序”之间的区别,让我们继续讨论部署。
+
+## 启动时运行
+
+在大多数情况下,当您创建 Web API 时,您希望它**始终运行**、不间断,以便您的客户端始终可以访问它。 这是当然的,除非您有特定原因希望它仅在某些情况下运行,但大多数时候您希望它不断运行并且**可用**。
+
+### 在远程服务器中
+
+当您设置远程服务器(云服务器、虚拟机等)时,您可以做的最简单的事情就是手动运行 Uvicorn(或类似的),就像本地开发时一样。
+
+它将会在**开发过程中**发挥作用并发挥作用。
+
+但是,如果您与服务器的连接丢失,**正在运行的进程**可能会终止。
+
+如果服务器重新启动(例如更新后或从云提供商迁移后),您可能**不会注意到它**。 因此,您甚至不知道必须手动重新启动该进程。 所以,你的 API 将一直处于挂掉的状态。 😱
+
+
+### 启动时自动运行
+
+一般来说,您可能希望服务器程序(例如 Uvicorn)在服务器启动时自动启动,并且不需要任何**人为干预**,让进程始终与您的 API 一起运行(例如 Uvicorn 运行您的 FastAPI 应用程序) 。
+
+### 单独的程序
+
+为了实现这一点,您通常会有一个**单独的程序**来确保您的应用程序在启动时运行。 在许多情况下,它还可以确保其他组件或应用程序也运行,例如数据库。
+
+### 启动时运行的示例工具
+
+可以完成这项工作的工具的一些示例是:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker in Swarm Mode
+* Systemd
+* Supervisor
+* 作为其服务的一部分由云提供商内部处理
+* 其他的...
+
+我将在接下来的章节中为您提供更具体的示例。
+
+
+## 重新启动
+
+与确保应用程序在启动时运行类似,您可能还想确保它在挂掉后**重新启动**。
+
+### 我们会犯错误
+
+作为人类,我们总是会犯**错误**。 软件几乎*总是*在不同的地方隐藏着**bug**。 🐛
+
+作为开发人员,当我们发现这些bug并实现新功能(也可能添加新bug😅)时,我们会不断改进代码。
+
+### 自动处理小错误
+
+使用 FastAPI 构建 Web API 时,如果我们的代码中存在错误,FastAPI 通常会将其包含到触发错误的单个请求中。 🛡
+
+对于该请求,客户端将收到 **500 内部服务器错误**,但应用程序将继续处理下一个请求,而不是完全崩溃。
+
+### 更大的错误 - 崩溃
+
+尽管如此,在某些情况下,我们编写的一些代码可能会导致整个应用程序崩溃,从而导致 Uvicorn 和 Python 崩溃。 💥
+
+尽管如此,您可能不希望应用程序因为某个地方出现错误而保持死机状态,您可能希望它**继续运行**,至少对于未破坏的*路径操作*。
+
+### 崩溃后重新启动
+
+但在那些严重错误导致正在运行的**进程**崩溃的情况下,您需要一个外部组件来负责**重新启动**进程,至少尝试几次......
+
+/// tip
+
+...尽管如果整个应用程序只是**立即崩溃**,那么永远重新启动它可能没有意义。 但在这些情况下,您可能会在开发过程中注意到它,或者至少在部署后立即注意到它。
+
+ 因此,让我们关注主要情况,在**未来**的某些特定情况下,它可能会完全崩溃,但重新启动它仍然有意义。
+
+///
+
+您可能希望让这个东西作为 **外部组件** 负责重新启动您的应用程序,因为到那时,使用 Uvicorn 和 Python 的同一应用程序已经崩溃了,因此同一应用程序的相同代码中没有东西可以对此做出什么。
+
+### 自动重新启动的示例工具
+
+在大多数情况下,用于**启动时运行程序**的同一工具也用于处理自动**重新启动**。
+
+例如,可以通过以下方式处理:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker in Swarm mode
+* Systemd
+* Supervisor
+* 作为其服务的一部分由云提供商内部处理
+* 其他的...
+
+## 复制 - 进程和内存
+
+对于 FastAPI 应用程序,使用像 Uvicorn 这样的服务器程序,在**一个进程**中运行一次就可以同时为多个客户端提供服务。
+
+但在许多情况下,您会希望同时运行多个工作进程。
+
+### 多进程 - Workers
+
+如果您的客户端数量多于单个进程可以处理的数量(例如,如果虚拟机不是太大),并且服务器的 CPU 中有 **多个核心**,那么您可以让 **多个进程** 运行 同时处理同一个应用程序,并在它们之间分发所有请求。
+
+当您运行同一 API 程序的**多个进程**时,它们通常称为 **workers**。
+
+### 工作进程和端口
+
+还记得文档 [About HTTPS](https.md){.internal-link target=_blank} 中只有一个进程可以侦听服务器中的端口和 IP 地址的一种组合吗?
+
+现在仍然是对的。
+
+因此,为了能够同时拥有**多个进程**,必须有一个**单个进程侦听端口**,然后以某种方式将通信传输到每个工作进程。
+
+### 每个进程的内存
+
+现在,当程序将内容加载到内存中时,例如,将机器学习模型加载到变量中,或者将大文件的内容加载到变量中,所有这些都会消耗服务器的一点内存 (RAM) 。
+
+多个进程通常**不共享任何内存**。 这意味着每个正在运行的进程都有自己的东西、变量和内存。 如果您的代码消耗了大量内存,**每个进程**将消耗等量的内存。
+
+### 服务器内存
+
+例如,如果您的代码加载 **1 GB 大小**的机器学习模型,则当您使用 API 运行一个进程时,它将至少消耗 1 GB RAM。 如果您启动 **4 个进程**(4 个工作进程),每个进程将消耗 1 GB RAM。 因此,您的 API 总共将消耗 **4 GB RAM**。
+
+如果您的远程服务器或虚拟机只有 3 GB RAM,尝试加载超过 4 GB RAM 将导致问题。 🚨
+
+
+### 多进程 - 一个例子
+
+在此示例中,有一个 **Manager Process** 启动并控制两个 **Worker Processes**。
+
+该管理器进程可能是监听 IP 中的 **端口** 的进程。 它将所有通信传输到工作进程。
+
+这些工作进程将是运行您的应用程序的进程,它们将执行主要计算以接收 **请求** 并返回 **响应**,并且它们将加载您放入 RAM 中的变量中的任何内容。
+
+

+
+当然,除了您的应用程序之外,同一台机器可能还运行**其他进程**。
+
+一个有趣的细节是,随着时间的推移,每个进程使用的 **CPU 百分比可能会发生很大变化,但内存 (RAM) 通常会或多或少保持稳定**。
+
+如果您有一个每次执行相当数量的计算的 API,并且您有很多客户端,那么 **CPU 利用率** 可能也会保持稳定(而不是不断快速上升和下降)。
+
+### 复制工具和策略示例
+
+可以通过多种方法来实现这一目标,我将在接下来的章节中向您详细介绍具体策略,例如在谈论 Docker 和容器时。
+
+要考虑的主要限制是必须有一个**单个**组件来处理**公共IP**中的**端口**。 然后它必须有一种方法将通信**传输**到复制的**进程/worker**。
+
+以下是一些可能的组合和策略:
+
+* **Gunicorn** 管理 **Uvicorn workers**
+ * Gunicorn 将是监听 **IP** 和 **端口** 的 **进程管理器**,复制将通过 **多个 Uvicorn 工作进程** 进行
+* **Uvicorn** 管理 **Uvicorn workers**
+ * 一个 Uvicorn **进程管理器** 将监听 **IP** 和 **端口**,并且它将启动 **多个 Uvicorn 工作进程**
+* **Kubernetes** 和其他分布式 **容器系统**
+ * **Kubernetes** 层中的某些东西将侦听 **IP** 和 **端口**。 复制将通过拥有**多个容器**,每个容器运行**一个 Uvicorn 进程**
+* **云服务** 为您处理此问题
+ * 云服务可能**为您处理复制**。 它可能会让您定义 **要运行的进程**,或要使用的 **容器映像**,在任何情况下,它很可能是 **单个 Uvicorn 进程**,并且云服务将负责复制它。
+
+
+
+/// tip
+
+如果这些关于 **容器**、Docker 或 Kubernetes 的内容还没有多大意义,请不要担心。
+
+ 我将在以后的章节中向您详细介绍容器镜像、Docker、Kubernetes 等:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
+
+///
+
+## 启动之前的步骤
+
+在很多情况下,您希望在**启动**应用程序之前执行一些步骤。
+
+例如,您可能想要运行**数据库迁移**。
+
+但在大多数情况下,您只想执行这些步骤**一次**。
+
+因此,在启动应用程序之前,您将需要一个**单个进程**来执行这些**前面的步骤**。
+
+而且您必须确保它是运行前面步骤的单个进程, *即使*之后您为应用程序本身启动**多个进程**(多个worker)。 如果这些步骤由**多个进程**运行,它们会通过在**并行**运行来**重复**工作,并且如果这些步骤像数据库迁移一样需要小心处理,它们可能会导致每个进程和其他进程发生冲突。
+
+当然,也有一些情况,多次运行前面的步骤也没有问题,这样的话就好办多了。
+
+/// tip
+
+另外,请记住,根据您的设置,在某些情况下,您在开始应用程序之前**可能甚至不需要任何先前的步骤**。
+
+ 在这种情况下,您就不必担心这些。 🤷
+
+///
+
+### 前面步骤策略的示例
+
+这将在**很大程度上取决于您部署系统的方式**,并且可能与您启动程序、处理重启等的方式有关。
+
+以下是一些可能的想法:
+
+* Kubernetes 中的“Init Container”在应用程序容器之前运行
+* 一个 bash 脚本,运行前面的步骤,然后启动您的应用程序
+ * 您仍然需要一种方法来启动/重新启动 bash 脚本、检测错误等。
+
+/// tip
+
+我将在以后的章节中为您提供使用容器执行此操作的更具体示例:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
+
+///
+
+## 资源利用率
+
+您的服务器是一个**资源**,您可以通过您的程序消耗或**利用**CPU 上的计算时间以及可用的 RAM 内存。
+
+您想要消耗/利用多少系统资源? 您可能很容易认为“不多”,但实际上,您可能希望在不崩溃的情况下**尽可能多地消耗**。
+
+如果您支付了 3 台服务器的费用,但只使用了它们的一点点 RAM 和 CPU,那么您可能**浪费金钱** 💸,并且可能 **浪费服务器电力** 🌎,等等。
+
+在这种情况下,最好只拥有 2 台服务器并使用更高比例的资源(CPU、内存、磁盘、网络带宽等)。
+
+另一方面,如果您有 2 台服务器,并且正在使用 **100% 的 CPU 和 RAM**,则在某些时候,一个进程会要求更多内存,并且服务器将不得不使用磁盘作为“内存” (这可能会慢数千倍),甚至**崩溃**。 或者一个进程可能需要执行一些计算,并且必须等到 CPU 再次空闲。
+
+在这种情况下,最好购买**一台额外的服务器**并在其上运行一些进程,以便它们都有**足够的 RAM 和 CPU 时间**。
+
+由于某种原因,您的 API 的使用量也有可能出现**激增**。 也许它像病毒一样传播开来,或者也许其他一些服务或机器人开始使用它。 在这些情况下,您可能需要额外的资源来保证安全。
+
+您可以将一个**任意数字**设置为目标,例如,资源利用率**在 50% 到 90%** 之间。 重点是,这些可能是您想要衡量和用来调整部署的主要内容。
+
+您可以使用“htop”等简单工具来查看服务器中使用的 CPU 和 RAM 或每个进程使用的数量。 或者您可以使用更复杂的监控工具,这些工具可能分布在服务器等上。
+
+
+## 回顾
+
+您在这里阅读了一些在决定如何部署应用程序时可能需要牢记的主要概念:
+
+* 安全性 - HTTPS
+* 启动时运行
+* 重新启动
+* 复制(运行的进程数)
+* 内存
+* 开始前的先前步骤
+
+了解这些想法以及如何应用它们应该会给您足够的直觉在配置和调整部署时做出任何决定。 🤓
+
+在接下来的部分中,我将为您提供更具体的示例,说明您可以遵循的可能策略。 🚀
diff --git a/docs/zh/docs/deployment/docker.md b/docs/zh/docs/deployment/docker.md
new file mode 100644
index 000000000..f120ebfb8
--- /dev/null
+++ b/docs/zh/docs/deployment/docker.md
@@ -0,0 +1,760 @@
+# 容器中的 FastAPI - Docker
+
+部署 FastAPI 应用程序时,常见的方法是构建 **Linux 容器镜像**。 通常使用
**Docker** 完成。 然后,你可以通过几种可能的方式之一部署该容器镜像。
+
+使用 Linux 容器有几个优点,包括**安全性**、**可复制性**、**简单性**等。
+
+/// tip
+
+赶时间并且已经知道这些东西了? 跳转到下面的 [`Dockerfile` 👇](#fastapi-docker_1)。
+
+///
+
+
+Dockerfile Preview 👀
+
+```Dockerfile
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+COPY ./app /code/app
+
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+
+# If running behind a proxy like Nginx or Traefik add --proxy-headers
+# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]
+```
+
+
+
+## 什么是容器
+
+容器(主要是 Linux 容器)是一种非常**轻量级**的打包应用程序的方式,其包括所有依赖项和必要的文件,同时它们可以和同一系统中的其他容器(或者其他应用程序/组件)相互隔离。
+
+Linux 容器使用宿主机(如物理服务器、虚拟机、云服务器等)的Linux 内核运行。 这意味着它们非常轻量(与模拟整个操作系统的完整虚拟机相比)。
+
+通过这样的方式,容器消耗**很少的资源**,与直接运行进程相当(虚拟机会消耗更多)。
+
+容器的进程(通常只有一个)、文件系统和网络都运行在隔离的环境,这简化了部署、安全、开发等。
+
+## 什么是容器镜像
+
+**容器**是从**容器镜像**运行的。
+
+容器镜像是容器中文件、环境变量和默认命令/程序的**静态**版本。 **静态**这里的意思是容器**镜像**还没有运行,只是打包的文件和元数据。
+
+与存储静态内容的“**容器镜像**”相反,“**容器**”通常指正在运行的实例,即正在**执行的**。
+
+当**容器**启动并运行时(从**容器镜像**启动),它可以创建或更改文件、环境变量等。这些更改将仅存在于该容器中,而不会持久化到底层的容器镜像中(不会保存到磁盘)。
+
+容器镜像相当于**程序**和文件,例如 `python`命令 和某些文件 如`main.py`。
+
+而**容器**本身(与**容器镜像**相反)是镜像的实际运行实例,相当于**进程**。 事实上,容器仅在有**进程运行**时才运行(通常它只是一个单独的进程)。 当容器中没有进程运行时,容器就会停止。
+
+
+
+## 容器镜像
+
+Docker 一直是创建和管理**容器镜像**和**容器**的主要工具之一。
+
+还有一个公共
Docker Hub ,其中包含预制的 **官方容器镜像**, 适用于许多工具、环境、数据库和应用程序。
+
+例如,有一个官方的
Python 镜像。
+
+还有许多其他镜像用于不同的需要(例如数据库),例如:
+
+
+*
PostgreSQL
+*
MySQL
+*
MongoDB
+*
Redis, etc.
+
+
+通过使用预制的容器镜像,可以非常轻松地**组合**并使用不同的工具。 例如,尝试一个新的数据库。 在大多数情况下,你可以使用**官方镜像**,只需为其配置环境变量即可。
+
+这样,在许多情况下,你可以了解容器和 Docker,并通过许多不同的工具和组件重复使用这些知识。
+
+因此,你可以运行带有不同内容的**多个容器**,例如数据库、Python 应用程序、带有 React 前端应用程序的 Web 服务器,并通过内部网络将它们连接在一起。
+
+所有容器管理系统(如 Docker 或 Kubernetes)都集成了这些网络功能。
+
+## 容器和进程
+
+**容器镜像**通常在其元数据中包含启动**容器**时应运行的默认程序或命令以及要传递给该程序的参数。 与在命令行中的情况非常相似。
+
+当 **容器** 启动时,它将运行该命令/程序(尽管你可以覆盖它并使其运行不同的命令/程序)。
+
+只要**主进程**(命令或程序)在运行,容器就在运行。
+
+容器通常有一个**单个进程**,但也可以从主进程启动子进程,这样你就可以在同一个容器中拥有**多个进程**。
+
+但是,如果没有**至少一个正在运行的进程**,就不可能有一个正在运行的容器。 如果主进程停止,容器也会停止。
+
+
+## 为 FastAPI 构建 Docker 镜像
+
+好吧,让我们现在构建一些东西! 🚀
+
+我将向你展示如何基于 **官方 Python** 镜像 **从头开始** 为 FastAPI 构建 **Docker 镜像**。
+
+这是你在**大多数情况**下想要做的,例如:
+
+* 使用 **Kubernetes** 或类似工具
+* 在 **Raspberry Pi** 上运行时
+* 使用可为你运行容器镜像的云服务等。
+
+### 依赖项
+
+你通常会在某个文件中包含应用程序的**依赖项**。
+
+具体做法取决于你**安装**这些依赖时所使用的工具。
+
+最常见的方法是创建一个`requirements.txt`文件,其中每行包含一个包名称和它的版本。
+
+你当然也可以使用在[关于 FastAPI 版本](versions.md){.internal-link target=_blank} 中讲到的方法来设置版本范围。
+
+例如,你的`requirements.txt`可能如下所示:
+
+
+```
+fastapi>=0.68.0,<0.69.0
+pydantic>=1.8.0,<2.0.0
+uvicorn>=0.15.0,<0.16.0
+```
+
+你通常会使用`pip`安装这些依赖项:
+
+
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic uvicorn
+```
+
+
+
+/// info
+
+还有其他文件格式和工具来定义和安装依赖项。
+
+ 我将在下面的部分中向你展示一个使用 Poetry 的示例。 👇
+
+///
+
+### 创建 **FastAPI** 代码
+
+* 创建`app`目录并进入。
+* 创建一个空文件`__init__.py`。
+* 创建一个 `main.py` 文件:
+
+
+
+```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}
+```
+
+### Dockerfile
+
+现在在相同的project目录创建一个名为`Dockerfile`的文件:
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9
+
+# (2)
+WORKDIR /code
+
+# (3)
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)
+COPY ./app /code/app
+
+# (6)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. 从官方Python基础镜像开始。
+
+2. 将当前工作目录设置为`/code`。
+
+ 这是我们放置`requirements.txt`文件和`app`目录的位置。
+
+3. 将符合要求的文件复制到`/code`目录中。
+
+ 首先仅复制requirements.txt文件,而不复制其余代码。
+
+ 由于此文件**不经常更改**,Docker 将检测到它并在这一步中使用**缓存**,从而为下一步启用缓存。
+
+4. 安装需求文件中的包依赖项。
+
+ `--no-cache-dir` 选项告诉 `pip` 不要在本地保存下载的包,因为只有当 `pip` 再次运行以安装相同的包时才会这样,但在与容器一起工作时情况并非如此。
+
+ /// note | 笔记
+
+ `--no-cache-dir` 仅与 `pip` 相关,与 Docker 或容器无关。
+
+ ///
+
+ `--upgrade` 选项告诉 `pip` 升级软件包(如果已经安装)。
+
+ 因为上一步复制文件可以被 **Docker 缓存** 检测到,所以此步骤也将 **使用 Docker 缓存**(如果可用)。
+
+ 在开发过程中一次又一次构建镜像时,在此步骤中使用缓存将为你节省大量**时间**,而不是**每次**都**下载和安装**所有依赖项。
+
+
+5. 将“./app”目录复制到“/code”目录中。
+
+ 由于其中包含**更改最频繁**的所有代码,因此 Docker **缓存**不会轻易用于此操作或任何**后续步骤**。
+
+ 因此,将其放在`Dockerfile`**接近最后**的位置非常重要,以优化容器镜像的构建时间。
+
+6. 设置**命令**来运行 `uvicorn` 服务器。
+
+ `CMD` 接受一个字符串列表,每个字符串都是你在命令行中输入的内容,并用空格分隔。
+
+ 该命令将从 **当前工作目录** 运行,即你上面使用`WORKDIR /code`设置的同一`/code`目录。
+
+ 因为程序将从`/code`启动,并且其中包含你的代码的目录`./app`,所以**Uvicorn**将能够从`app.main`中查看并**import**`app`。
+
+/// tip
+
+通过单击代码中的每个数字气泡来查看每行的作用。 👆
+
+///
+
+你现在应该具有如下目录结构:
+```
+.
+├── app
+│ ├── __init__.py
+│ └── main.py
+├── Dockerfile
+└── requirements.txt
+```
+
+
+#### 在 TLS 终止代理后面
+
+如果你在 Nginx 或 Traefik 等 TLS 终止代理(负载均衡器)后面运行容器,请添加选项 `--proxy-headers`,这将告诉 Uvicorn 信任该代理发送的标头,告诉它应用程序正在 HTTPS 后面运行等信息
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+#### Docker 缓存
+
+这个`Dockerfile`中有一个重要的技巧,我们首先只单独复制**包含依赖项的文件**,而不是其余代码。 让我来告诉你这是为什么。
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+Docker之类的构建工具是通过**增量**的方式来构建这些容器镜像的。具体做法是从`Dockerfile`顶部开始,每一条指令生成的文件都是镜像的“一层”,同过把这些“层”一层一层地叠加到基础镜像上,最后我们就得到了最终的镜像。
+
+Docker 和类似工具在构建镜像时也会使用**内部缓存**,如果自上次构建容器镜像以来文件没有更改,那么它将**重新使用上次创建的同一层**,而不是再次复制文件并从头开始创建新层。
+
+仅仅避免文件的复制不一定会有太多速度提升,但是如果在这一步使用了缓存,那么才可以**在下一步中使用缓存**。 例如,可以使用安装依赖项那条指令的缓存:
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+```
+
+
+包含包依赖项的文件**不会频繁更改**。 只复制该文件(不复制其他的应用代码),Docker 才能在这一步**使用缓存**。
+
+Docker 进而能**使用缓存进行下一步**,即下载并安装这些依赖项。 这才是我们**节省大量时间**的地方。 ✨ ...可以避免无聊的等待。 😪😆
+
+下载和安装依赖项**可能需要几分钟**,但使用**缓存**最多**只需要几秒钟**。
+
+由于你在开发过程中会一次又一次地构建容器镜像以检查代码更改是否有效,因此可以累计节省大量时间。
+
+在`Dockerfile`末尾附近,我们再添加复制代码的指令。 由于代码是**更改最频繁的**,所以将其放在最后,因为这一步之后的内容基本上都是无法使用缓存的。
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### 构建 Docker 镜像
+
+现在所有文件都已就位,让我们构建容器镜像。
+
+* 转到项目目录(在`Dockerfile`所在的位置,包含`app`目录)。
+* 构建你的 FastAPI 镜像:
+
+
+
+
+```console
+$ docker build -t myimage .
+
+---> 100%
+```
+
+
+
+
+/// tip
+
+注意最后的 `.`,它相当于`./`,它告诉 Docker 用于构建容器镜像的目录。
+
+在本例中,它是相同的当前目录(`.`)。
+
+///
+
+### 启动 Docker 容器
+
+* 根据你的镜像运行容器:
+
+
+
+```console
+$ docker run -d --name mycontainer -p 80:80 myimage
+```
+
+
+
+## 检查一下
+
+
+你应该能在Docker容器的URL中检查它,例如:
http://192.168.99.100/items/5?q=somequery 或
http://127.0.0.1/items/5?q=somequery (或其他等价的,使用 Docker 主机).
+
+你会看到类似内容:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+## 交互式 API 文档
+
+现在你可以转到
http://192.168.99.100/docs 或
http://127.0.0.1/docs (或其他等价的,使用 Docker 主机)。
+
+你将看到自动交互式 API 文档(由
Swagger UI):
+
+
+
+## 备选的 API 文档
+
+你还可以访问
http://192.168.99.100/redoc 或
http://127.0.0.1/redoc (或其他等价的,使用 Docker 主机)。
+
+你将看到备选的自动文档(由
ReDoc 提供):
+
+
+
+## 使用单文件 FastAPI 构建 Docker 镜像
+
+如果你的 FastAPI 是单个文件,例如没有`./app`目录的`main.py`,则你的文件结构可能如下所示:
+
+```
+.
+├── Dockerfile
+├── main.py
+└── requirements.txt
+```
+
+然后你只需更改相应的路径即可将文件复制到`Dockerfile`中:
+
+```{ .dockerfile .annotate hl_lines="10 13" }
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (1)
+COPY ./main.py /code/
+
+# (2)
+CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. 直接将`main.py`文件复制到`/code`目录中(不包含任何`./app`目录)。
+
+2. 运行 Uvicorn 并告诉它从 `main` 导入 `app` 对象(而不是从 `app.main` 导入)。
+
+然后调整Uvicorn命令使用新模块`main`而不是`app.main`来导入FastAPI 实例`app`。
+
+## 部署概念
+
+我们再谈谈容器方面的一些相同的[部署概念](concepts.md){.internal-link target=_blank}。
+
+容器主要是一种简化**构建和部署**应用程序的过程的工具,但它们并不强制执行特定的方法来处理这些**部署概念**,并且有几种可能的策略。
+
+**好消息**是,对于每种不同的策略,都有一种方法可以涵盖所有部署概念。 🎉
+
+让我们从容器的角度回顾一下这些**部署概念**:
+
+* HTTPS
+* 启动时运行
+* 重新启动
+* 复制(运行的进程数)
+* 内存
+* 开始前的先前步骤
+
+
+## HTTPS
+
+如果我们只关注 FastAPI 应用程序的 **容器镜像**(以及稍后运行的 **容器**),HTTPS 通常会由另一个工具在 **外部** 处理。
+
+它可以是另一个容器,例如使用
Traefik,处理 **HTTPS** 和 **自动**获取**证书**。
+
+/// tip
+
+Traefik可以与 Docker、Kubernetes 等集成,因此使用它为容器设置和配置 HTTPS 非常容易。
+
+///
+
+或者,HTTPS 可以由云服务商作为其服务之一进行处理(同时仍在容器中运行应用程序)。
+
+## 在启动和重新启动时运行
+
+通常还有另一个工具负责**启动和运行**你的容器。
+
+它可以直接是**Docker**, 或者**Docker Compose**、**Kubernetes**、**云服务**等。
+
+在大多数(或所有)情况下,有一个简单的选项可以在启动时运行容器并在失败时重新启动。 例如,在 Docker 中,它是命令行选项 `--restart`。
+
+如果不使用容器,让应用程序在启动时运行并重新启动可能会很麻烦且困难。 但在大多数情况下,当**使用容器**时,默认情况下会包含该功能。 ✨
+
+## 复制 - 进程数
+
+如果你有一个
集群, 比如 **Kubernetes**、Docker Swarm、Nomad 或其他类似的复杂系统来管理多台机器上的分布式容器,那么你可能希望在**集群级别**处理复制**,而不是在每个容器中使用**进程管理器**(如带有Worker的 Gunicorn) 。
+
+像 Kubernetes 这样的分布式容器管理系统通常有一些集成的方法来处理**容器的复制**,同时仍然支持传入请求的**负载均衡**。 全部都在**集群级别**。
+
+在这些情况下,你可能希望从头开始构建一个 **Docker 镜像**,如[上面所解释](#dockerfile)的那样,安装依赖项并运行 **单个 Uvicorn 进程**,而不是运行 Gunicorn 和 Uvicorn workers这种。
+
+
+### 负载均衡器
+
+使用容器时,通常会有一些组件**监听主端口**。 它可能是处理 **HTTPS** 的 **TLS 终止代理** 或一些类似的工具的另一个容器。
+
+由于该组件将接受请求的**负载**并(希望)以**平衡**的方式在worker之间分配该请求,因此它通常也称为**负载均衡器**。
+
+/// tip
+
+用于 HTTPS **TLS 终止代理** 的相同组件也可能是 **负载均衡器**。
+
+///
+
+当使用容器时,你用来启动和管理容器的同一系统已经具有内部工具来传输来自该**负载均衡器**(也可以是**TLS 终止代理**) 的**网络通信**(例如HTTP请求)到你的应用程序容器。
+
+### 一个负载均衡器 - 多个worker容器
+
+当使用 **Kubernetes** 或类似的分布式容器管理系统时,使用其内部网络机制将允许单个在主 **端口** 上侦听的 **负载均衡器** 将通信(请求)传输到可能的 **多个** 运行你应用程序的容器。
+
+运行你的应用程序的每个容器通常**只有一个进程**(例如,运行 FastAPI 应用程序的 Uvicorn 进程)。 它们都是**相同的容器**,运行相同的东西,但每个容器都有自己的进程、内存等。这样你就可以在 CPU 的**不同核心**, 甚至在**不同的机器**充分利用**并行化(parallelization)**。
+
+具有**负载均衡器**的分布式容器系统将**将请求轮流分配**给你的应用程序的每个容器。 因此,每个请求都可以由运行你的应用程序的多个**复制容器**之一来处理。
+
+通常,这个**负载均衡器**能够处理发送到集群中的*其他*应用程序的请求(例如发送到不同的域,或在不同的 URL 路径前缀下),并正确地将该通信传输到在集群中运行的*其他*应用程序的对应容器。
+
+
+
+
+
+
+### 每个容器一个进程
+
+在这种类型的场景中,你可能希望**每个容器有一个(Uvicorn)进程**,因为你已经在集群级别处理复制。
+
+因此,在这种情况下,你**不会**希望拥有像 Gunicorn 和 Uvicorn worker一样的进程管理器,或者 Uvicorn 使用自己的 Uvicorn worker。 你可能希望每个容器(但可能有多个容器)只有一个**单独的 Uvicorn 进程**。
+
+在容器内拥有另一个进程管理器(就像使用 Gunicorn 或 Uvicorn 管理 Uvicorn 工作线程一样)只会增加**不必要的复杂性**,而你很可能已经在集群系统中处理这些复杂性了。
+
+### 具有多个进程的容器
+
+当然,在某些**特殊情况**,你可能希望拥有 **一个容器**,其中包含 **Gunicorn 进程管理器**,并在其中启动多个 **Uvicorn worker进程**。
+
+在这些情况下,你可以使用 **官方 Docker 镜像**,其中包含 **Gunicorn** 作为运行多个 **Uvicorn 工作进程** 的进程管理器,以及一些默认设置来根据当前情况调整工作进程数量 自动CPU核心。 我将在下面的 [Gunicorn - Uvicorn 官方 Docker 镜像](#official-docker-image-with-gunicorn-uvicorn) 中告诉你更多相关信息。
+
+下面一些什么时候这种做法有意义的示例:
+
+
+#### 一个简单的应用程序
+
+如果你的应用程序**足够简单**,你不需要(至少现在不需要)过多地微调进程数量,并且你可以使用自动默认值,那么你可能需要容器中的进程管理器 (使用官方 Docker 镜像),并且你在**单个服务器**而不是集群上运行它。
+
+#### Docker Compose
+
+你可以使用 **Docker Compose** 部署到**单个服务器**(而不是集群),因此你没有一种简单的方法来管理容器的复制(使用 Docker Compose),同时保留共享网络和 **负载均衡**。
+
+然后,你可能希望拥有一个**单个容器**,其中有一个**进程管理器**,在其中启动**多个worker进程**。
+
+#### Prometheus和其他原因
+
+你还可能有**其他原因**,这将使你更容易拥有一个带有**多个进程**的**单个容器**,而不是拥有每个容器中都有**单个进程**的**多个容器**。
+
+例如(取决于你的设置)你可以在同一个容器中拥有一些工具,例如 Prometheus exporter,该工具应该有权访问**每个请求**。
+
+在这种情况下,如果你有**多个容器**,默认情况下,当 Prometheus 来**读取metrics**时,它每次都会获取**单个容器**的metrics(对于处理该特定请求的容器),而不是获取所有复制容器的**累积metrics**。
+
+在这种情况, 这种做法会更加简单:让**一个容器**具有**多个进程**,并在同一个容器上使用本地工具(例如 Prometheus exporter)收集所有内部进程的 Prometheus 指标并公开单个容器上的这些指标。
+
+---
+
+要点是,这些都**不是**你必须盲目遵循的**一成不变的规则**。 你可以根据这些思路**评估你自己的场景**并决定什么方法是最适合你的的系统,考虑如何管理以下概念:
+
+* 安全性 - HTTPS
+* 启动时运行
+* 重新启动
+* 复制(运行的进程数)
+* 内存
+* 开始前的先前步骤
+
+## 内存
+
+如果你**每个容器运行一个进程**,那么每个容器所消耗的内存或多或少是定义明确的、稳定的且有限的(如果它们是复制的,则不止一个)。
+
+然后,你可以在容器管理系统的配置中设置相同的内存限制和要求(例如在 **Kubernetes** 中)。 这样,它将能够在**可用机器**中**复制容器**,同时考虑容器所需的内存量以及集群中机器中的可用内存量。
+
+如果你的应用程序很**简单**,这可能**不是问题**,并且你可能不需要指定内存限制。 但是,如果你**使用大量内存**(例如使用**机器学习**模型),则应该检查你消耗了多少内存并调整**每台机器**中运行的**容器数量**(也许可以向集群添加更多机器)。
+
+如果你**每个容器运行多个进程**(例如使用官方 Docker 镜像),你必须确保启动的进程数量不会消耗比可用内存**更多的内存**。
+
+## 启动之前的步骤和容器
+
+如果你使用容器(例如 Docker、Kubernetes),那么你可以使用两种主要方法。
+
+
+### 多个容器
+
+如果你有 **多个容器**,可能每个容器都运行一个 **单个进程**(例如,在 **Kubernetes** 集群中),那么你可能希望有一个 **单独的容器** 执行以下操作: 在单个容器中运行单个进程执行**先前步骤**,即运行复制的worker容器之前。
+
+/// info
+
+如果你使用 Kubernetes,这可能是
Init Container。
+
+///
+
+如果在你的用例中,运行前面的步骤**并行多次**没有问题(例如,如果你没有运行数据库迁移,而只是检查数据库是否已准备好),那么你也可以将它们放在开始主进程之前在每个容器中。
+
+### 单容器
+
+如果你有一个简单的设置,使用一个**单个容器**,然后启动多个**工作进程**(或者也只是一个进程),那么你可以在启动进程之前在应用程序同一个容器中运行先前的步骤。 官方 Docker 镜像内部支持这一点。
+
+## 带有 Gunicorn 的官方 Docker 镜像 - Uvicorn
+
+有一个官方 Docker 镜像,其中包含与 Uvicorn worker一起运行的 Gunicorn,如上一章所述:[服务器工作线程 - Gunicorn 与 Uvicorn](server-workers.md){.internal-link target=_blank}。
+
+该镜像主要在上述情况下有用:[具有多个进程和特殊情况的容器](#containers-with-multiple-processes-and-special-cases)。
+
+
+
+*
tiangolo/uvicorn-gunicorn-fastapi.
+
+
+/// warning
+
+你很有可能不需要此基础镜像或任何其他类似的镜像,最好从头开始构建镜像,如[上面所述:为 FastAPI 构建 Docker 镜像](#build-a-docker-image-for-fastapi)。
+
+///
+
+该镜像包含一个**自动调整**机制,用于根据可用的 CPU 核心设置**worker进程数**。
+
+它具有**合理的默认值**,但你仍然可以使用**环境变量**或配置文件更改和更新所有配置。
+
+它还支持通过一个脚本运行
**开始前的先前步骤** 。
+
+/// tip
+
+要查看所有配置和选项,请转到 Docker 镜像页面:
tiangolo/uvicorn-gunicorn-fastapi。
+
+///
+
+### 官方 Docker 镜像上的进程数
+
+此镜像上的**进程数**是根据可用的 CPU **核心**自动计算的。
+
+这意味着它将尝试尽可能多地**榨取**CPU 的**性能**。
+
+你还可以使用 **环境变量** 等配置来调整它。
+
+但这也意味着,由于进程数量取决于容器运行的 CPU,因此**消耗的内存量**也将取决于该数量。
+
+因此,如果你的应用程序消耗大量内存(例如机器学习模型),并且你的服务器有很多 CPU 核心**但内存很少**,那么你的容器最终可能会尝试使用比实际情况更多的内存 可用,并且性能会下降很多(甚至崩溃)。 🚨
+
+### 创建一个`Dockerfile`
+
+以下是如何根据此镜像创建`Dockerfile`:
+
+
+```Dockerfile
+FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
+
+COPY ./requirements.txt /app/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+
+COPY ./app /app
+```
+
+### 更大的应用程序
+
+如果你按照有关创建[具有多个文件的更大应用程序](../tutorial/bigger-applications.md){.internal-link target=_blank}的部分进行操作,你的`Dockerfile`可能看起来这样:
+
+```Dockerfile hl_lines="7"
+FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
+
+COPY ./requirements.txt /app/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+
+COPY ./app /app/app
+```
+
+### 何时使用
+
+如果你使用 **Kubernetes** (或其他)并且你已经在集群级别设置 **复制**,并且具有多个 **容器**。 在这些情况下,你最好按照上面的描述 **从头开始构建镜像**:[为 FastAPI 构建 Docker 镜像](#build-a-docker-image-for-fastapi)。
+
+该镜像主要在[具有多个进程的容器和特殊情况](#containers-with-multiple-processes-and-special-cases)中描述的特殊情况下有用。 例如,如果你的应用程序**足够简单**,基于 CPU 设置默认进程数效果很好,你不想在集群级别手动配置复制,并且不会运行更多进程, 或者你使用 **Docker Compose** 进行部署,在单个服务器上运行等。
+
+## 部署容器镜像
+
+拥有容器(Docker)镜像后,有多种方法可以部署它。
+
+例如:
+
+* 在单个服务器中使用 **Docker Compose**
+* 使用 **Kubernetes** 集群
+* 使用 Docker Swarm 模式集群
+* 使用Nomad等其他工具
+* 使用云服务获取容器镜像并部署它
+
+## Docker 镜像与Poetry
+
+如果你使用
Poetry 来管理项目的依赖项,你可以使用 Docker 多阶段构建:
+
+
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9 as requirements-stage
+
+# (2)
+WORKDIR /tmp
+
+# (3)
+RUN pip install poetry
+
+# (4)
+COPY ./pyproject.toml ./poetry.lock* /tmp/
+
+# (5)
+RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
+
+# (6)
+FROM python:3.9
+
+# (7)
+WORKDIR /code
+
+# (8)
+COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt
+
+# (9)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (10)
+COPY ./app /code/app
+
+# (11)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. 这是第一阶段,称为`requirements-stage`。
+
+2. 将 `/tmp` 设置为当前工作目录。
+
+ 这是我们生成文件`requirements.txt`的地方
+
+3. 在此阶段安装Poetry。
+
+4. 将`pyproject.toml`和`poetry.lock`文件复制到`/tmp`目录。
+
+ 因为它使用 `./poetry.lock*` (以 `*` 结尾),所以如果该文件尚不可用,它不会崩溃。
+
+5. 生成`requirements.txt`文件。
+
+6. 这是最后阶段,这里的任何内容都将保留在最终的容器镜像中。
+
+7. 将当前工作目录设置为`/code`。
+
+8. 将 `requirements.txt` 文件复制到 `/code` 目录。
+
+ 该文件仅存在于前一个阶段,这就是为什么我们使用 `--from-requirements-stage` 来复制它。
+
+9. 安装生成的`requirements.txt`文件中的依赖项。
+
+10. 将`app`目录复制到`/code`目录。
+
+11. 运行`uvicorn`命令,告诉它使用从`app.main`导入的`app`对象。
+
+/// tip
+
+单击气泡数字可查看每行的作用。
+
+///
+
+**Docker stage** 是 `Dockerfile` 的一部分,用作 **临时容器镜像**,仅用于生成一些稍后使用的文件。
+
+第一阶段仅用于 **安装 Poetry** 并使用 Poetry 的 `pyproject.toml` 文件中的项目依赖项 **生成 `requirements.txt`**。
+
+此`requirements.txt`文件将在**下一阶段**与`pip`一起使用。
+
+在最终的容器镜像中**仅保留最后阶段**。 之前的阶段将被丢弃。
+
+使用 Poetry 时,使用 **Docker 多阶段构建** 是有意义的,因为你实际上并不需要在最终的容器镜像中安装 Poetry 及其依赖项,你 **只需要** 生成用于安装项目依赖项的`requirements.txt`文件。
+
+然后,在下一个(也是最后一个)阶段,你将或多或少地以与前面描述的相同的方式构建镜像。
+
+### 在TLS 终止代理后面 - Poetry
+
+同样,如果你在 Nginx 或 Traefik 等 TLS 终止代理(负载均衡器)后面运行容器,请将选项`--proxy-headers`添加到命令中:
+
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+## 回顾
+
+使用容器系统(例如使用**Docker**和**Kubernetes**),处理所有**部署概念**变得相当简单:
+
+* HTTPS
+* 启动时运行
+* 重新启动
+* 复制(运行的进程数)
+* 内存
+* 开始前的先前步骤
+
+在大多数情况下,你可能不想使用任何基础镜像,而是基于官方 Python Docker 镜像 **从头开始构建容器镜像** 。
+
+处理好`Dockerfile`和 **Docker 缓存**中指令的**顺序**,你可以**最小化构建时间**,从而最大限度地提高生产力(并避免无聊)。 😎
+
+在某些特殊情况下,你可能需要使用 FastAPI 的官方 Docker 镜像。 🤓
diff --git a/docs/zh/docs/deployment/https.md b/docs/zh/docs/deployment/https.md
new file mode 100644
index 000000000..d994c4add
--- /dev/null
+++ b/docs/zh/docs/deployment/https.md
@@ -0,0 +1,201 @@
+# 关于 HTTPS
+
+人们很容易认为 HTTPS 仅仅是“启用”或“未启用”的东西。
+
+但实际情况比这复杂得多。
+
+/// note | 提示
+
+如果你很赶时间或不在乎,请继续阅读下一部分,下一部分会提供一个step-by-step的教程,告诉你怎么使用不同技术来把一切都配置好。
+
+///
+
+要从用户的视角**了解 HTTPS 的基础知识**,请查看
https://howhttps.works/。
+
+现在,从**开发人员的视角**,在了解 HTTPS 时需要记住以下几点:
+
+* 要使用 HTTPS,**服务器**需要拥有由**第三方**生成的**"证书(certificate)"**。
+ * 这些证书实际上是从第三方**获取**的,而不是“生成”的。
+* 证书有**生命周期**。
+ * 它们会**过期**。
+ * 然后它们需要**更新**,**再次从第三方获取**。
+* 连接的加密发生在 **TCP 层**。
+ * 这是 HTTP 协议**下面的一层**。
+ * 因此,**证书和加密**处理是在 **HTTP之前**完成的。
+* **TCP 不知道域名**。 仅仅知道 IP 地址。
+ * 有关所请求的 **特定域名** 的信息位于 **HTTP 数据**中。
+* **HTTPS 证书**“证明”**某个域名**,但协议和加密发生在 TCP 层,在知道正在处理哪个域名**之前**。
+* **默认情况下**,这意味着你**每个 IP 地址只能拥有一个 HTTPS 证书**。
+ * 无论你的服务器有多大,或者服务器上的每个应用程序有多小。
+ * 不过,对此有一个**解决方案**。
+* **TLS** 协议(在 HTTP 之下的TCP 层处理加密的协议)有一个**扩展**,称为 **
SNI**。
+ * SNI 扩展允许一台服务器(具有 **单个 IP 地址**)拥有 **多个 HTTPS 证书** 并提供 **多个 HTTPS 域名/应用程序**。
+ * 为此,服务器上会有**单独**的一个组件(程序)侦听**公共 IP 地址**,这个组件必须拥有服务器中的**所有 HTTPS 证书**。
+* **获得安全连接后**,通信协议**仍然是HTTP**。
+ * 内容是 **加密过的**,即使它们是通过 **HTTP 协议** 发送的。
+
+通常的做法是在服务器上运行**一个程序/HTTP 服务器**并**管理所有 HTTPS 部分**:接收**加密的 HTTPS 请求**, 将 **解密的 HTTP 请求** 发送到在同一服务器中运行的实际 HTTP 应用程序(在本例中为 **FastAPI** 应用程序),从应用程序中获取 **HTTP 响应**, 使用适当的 **HTTPS 证书**对其进行加密并使用 **HTTPS** 将其发送回客户端。 此服务器通常被称为 **
TLS 终止代理(TLS Termination Proxy)**。
+
+你可以用作 TLS 终止代理的一些选项包括:
+
+* Traefik(也可以处理证书更新)
+* Caddy(也可以处理证书更新)
+* Nginx
+* HAProxy
+
+## Let's Encrypt
+
+在 Let's Encrypt 之前,这些 **HTTPS 证书** 由受信任的第三方出售。
+
+过去,获得这些证书的过程非常繁琐,需要大量的文书工作,而且证书非常昂贵。
+
+但随后 **
Let's Encrypt** 创建了。
+
+它是 Linux 基金会的一个项目。 它以自动方式免费提供 **HTTPS 证书**。 这些证书可以使用所有符合标准的安全加密,并且有效期很短(大约 3 个月),因此**安全性实际上更好**,因为它们的生命周期缩短了。
+
+域可以被安全地验证并自动生成证书。 这还允许自动更新这些证书。
+
+我们的想法是自动获取和更新这些证书,以便你可以永远免费拥有**安全的 HTTPS**。
+
+## 面向开发人员的 HTTPS
+
+这里有一个 HTTPS API 看起来是什么样的示例,我们会分步说明,并且主要关注对开发人员重要的部分。
+
+
+### 域名
+
+第一步我们要先**获取**一些**域名(Domain Name)**。 然后可以在 DNS 服务器(可能是你的同一家云服务商提供的)中配置它。
+
+你可能拥有一个云服务器(虚拟机)或类似的东西,并且它会有一个
固定 **公共IP地址**。
+
+在 DNS 服务器中,你可以配置一条记录(“A 记录”)以将 **你的域名** 指向你服务器的公共 **IP 地址**。
+
+这个操作一般只需要在最开始执行一次。
+
+/// tip
+
+域名这部分发生在 HTTPS 之前,由于这一切都依赖于域名和 IP 地址,所以先在这里提一下。
+
+///
+
+### DNS
+
+现在让我们关注真正的 HTTPS 部分。
+
+首先,浏览器将通过 **DNS 服务器** 查询**域名的IP** 是什么,在本例中为 `someapp.example.com`。
+
+DNS 服务器会告诉浏览器使用某个特定的 **IP 地址**。 这将是你在 DNS 服务器中为你的服务器配置的公共 IP 地址。
+
+

+
+### TLS 握手开始
+
+然后,浏览器将在**端口 443**(HTTPS 端口)上与该 IP 地址进行通信。
+
+通信的第一部分只是建立客户端和服务器之间的连接并决定它们将使用的加密密钥等。
+
+

+
+客户端和服务器之间建立 TLS 连接的过程称为 **TLS 握手**。
+
+### 带有 SNI 扩展的 TLS
+
+**服务器中只有一个进程**可以侦听特定 **IP 地址**的特定 **端口**。 可能有其他进程在同一 IP 地址的其他端口上侦听,但每个 IP 地址和端口组合只有一个进程。
+
+TLS (HTTPS) 默认使用端口`443`。 这就是我们需要的端口。
+
+由于只有一个进程可以监听此端口,因此监听端口的进程将是 **TLS 终止代理**。
+
+TLS 终止代理可以访问一个或多个 **TLS 证书**(HTTPS 证书)。
+
+使用上面讨论的 **SNI 扩展**,TLS 终止代理将检查应该用于此连接的可用 TLS (HTTPS) 证书,并使用与客户端期望的域名相匹配的证书。
+
+在这种情况下,它将使用`someapp.example.com`的证书。
+
+

+
+客户端已经**信任**生成该 TLS 证书的实体(在本例中为 Let's Encrypt,但我们稍后会看到),因此它可以**验证**该证书是否有效。
+
+然后,通过使用证书,客户端和 TLS 终止代理 **决定如何加密** **TCP 通信** 的其余部分。 这就完成了 **TLS 握手** 部分。
+
+此后,客户端和服务器就拥有了**加密的 TCP 连接**,这就是 TLS 提供的功能。 然后他们可以使用该连接来启动实际的 **HTTP 通信**。
+
+这就是 **HTTPS**,它只是 **安全 TLS 连接** 内的普通 **HTTP**,而不是纯粹的(未加密的)TCP 连接。
+
+/// tip
+
+请注意,通信加密发生在 **TCP 层**,而不是 HTTP 层。
+
+///
+
+### HTTPS 请求
+
+现在客户端和服务器(特别是浏览器和 TLS 终止代理)具有 **加密的 TCP 连接**,它们可以开始 **HTTP 通信**。
+
+接下来,客户端发送一个 **HTTPS 请求**。 这其实只是一个通过 TLS 加密连接的 HTTP 请求。
+
+

+
+### 解密请求
+
+TLS 终止代理将使用协商好的加密算法**解密请求**,并将**(解密的)HTTP 请求**传输到运行应用程序的进程(例如运行 FastAPI 应用的 Uvicorn 进程)。
+
+

+
+### HTTP 响应
+
+应用程序将处理请求并向 TLS 终止代理发送**(未加密)HTTP 响应**。
+
+

+
+### HTTPS 响应
+
+然后,TLS 终止代理将使用之前协商的加密算法(以`someapp.example.com`的证书开头)对响应进行加密,并将其发送回浏览器。
+
+接下来,浏览器将验证响应是否有效和是否使用了正确的加密密钥等。然后它会**解密响应**并处理它。
+
+

+
+客户端(浏览器)将知道响应来自正确的服务器,因为它使用了他们之前使用 **HTTPS 证书** 协商出的加密算法。
+
+### 多个应用程序
+
+在同一台(或多台)服务器中,可能存在**多个应用程序**,例如其他 API 程序或数据库。
+
+只有一个进程可以处理特定的 IP 和端口(在我们的示例中为 TLS 终止代理),但其他应用程序/进程也可以在服务器上运行,只要它们不尝试使用相同的 **公共 IP 和端口的组合**。
+
+

+
+这样,TLS 终止代理就可以为多个应用程序处理**多个域名**的 HTTPS 和证书,然后在每种情况下将请求传输到正确的应用程序。
+
+### 证书更新
+
+在未来的某个时候,每个证书都会**过期**(大约在获得证书后 3 个月)。
+
+然后,会有另一个程序(在某些情况下是另一个程序,在某些情况下可能是同一个 TLS 终止代理)与 Let's Encrypt 通信并更新证书。
+
+

+
+**TLS 证书** **与域名相关联**,而不是与 IP 地址相关联。
+
+因此,要更新证书,更新程序需要向权威机构(Let's Encrypt)**证明**它确实**“拥有”并控制该域名**。
+
+有多种方法可以做到这一点。 一些流行的方式是:
+
+* **修改一些DNS记录**。
+ * 为此,续订程序需要支持 DNS 提供商的 API,因此,要看你使用的 DNS 提供商是否提供这一功能。
+* **在与域名关联的公共 IP 地址上作为服务器运行**(至少在证书获取过程中)。
+ * 正如我们上面所说,只有一个进程可以监听特定的 IP 和端口。
+ * 这就是当同一个 TLS 终止代理还负责证书续订过程时它非常有用的原因之一。
+ * 否则,你可能需要暂时停止 TLS 终止代理,启动续订程序以获取证书,然后使用 TLS 终止代理配置它们,然后重新启动 TLS 终止代理。 这并不理想,因为你的应用程序在 TLS 终止代理关闭期间将不可用。
+
+通过拥有一个**单独的系统来使用 TLS 终止代理来处理 HTTPS**, 而不是直接将 TLS 证书与应用程序服务器一起使用 (例如 Uvicorn),你可以在
+更新证书的过程中同时保持提供服务。
+
+## 回顾
+
+拥有**HTTPS** 非常重要,并且在大多数情况下相当**关键**。 作为开发人员,你围绕 HTTPS 所做的大部分努力就是**理解这些概念**以及它们的工作原理。
+
+一旦你了解了**面向开发人员的 HTTPS** 的基础知识,你就可以轻松组合和配置不同的工具,以帮助你以简单的方式管理一切。
+
+在接下来的一些章节中,我将向你展示几个为 **FastAPI** 应用程序设置 **HTTPS** 的具体示例。 🔒
diff --git a/docs/zh/docs/deployment/index.md b/docs/zh/docs/deployment/index.md
new file mode 100644
index 000000000..1ec0c5c5b
--- /dev/null
+++ b/docs/zh/docs/deployment/index.md
@@ -0,0 +1,21 @@
+# 部署
+
+部署 **FastAPI** 应用程序相对容易。
+
+## 部署是什么意思
+
+**部署**应用程序意味着执行必要的步骤以使其**可供用户使用**。
+
+对于**Web API**来说,通常涉及将上传到**云服务器**中,搭配一个性能和稳定性都不错的**服务器程序**,以便你的**用户**可以高效地**访问**你的应用程序,而不会出现中断或其他问题。
+
+这与**开发**阶段形成鲜明对比,在**开发**阶段,你不断更改代码、破坏代码、修复代码, 来回停止和重启服务器等。
+
+## 部署策略
+
+根据你的使用场景和使用的工具,有多种方法可以实现此目的。
+
+你可以使用一些工具自行**部署服务器**,你也可以使用能为你完成部分工作的**云服务**,或其他可能的选项。
+
+我将向你展示在部署 **FastAPI** 应用程序时你可能应该记住的一些主要概念(尽管其中大部分适用于任何其他类型的 Web 应用程序)。
+
+在接下来的部分中,你将看到更多需要记住的细节以及一些技巧。 ✨
diff --git a/docs/zh/docs/deployment/manually.md b/docs/zh/docs/deployment/manually.md
new file mode 100644
index 000000000..3dc5942e3
--- /dev/null
+++ b/docs/zh/docs/deployment/manually.md
@@ -0,0 +1,158 @@
+# 手动运行服务器
+
+## 使用 `fastapi run` 命令
+
+简而言之,使用 `fastapi run` 来运行您的 FastAPI 应用程序:
+
+
+
+```console
+$ fastapi run main.py
+
+ FastAPI Starting production server 🚀
+
+ Searching for package file structure from directories
+ with __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with
+ the following code:
+
+ from main import app
+
+ app Using import string: main:app
+
+ server Server started at http://0.0.0.0:8000
+ server Documentation at http://0.0.0.0:8000/docs
+
+ Logs:
+
+ INFO Started server process [2306215]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+ INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C
+ to quit)
+```
+
+
+
+这在大多数情况下都能正常运行。😎
+
+例如,您可以使用该命令在容器、服务器等环境中启动您的 **FastAPI** 应用。
+
+## ASGI 服务器
+
+让我们深入了解一些细节。
+
+FastAPI 使用了一种用于构建 Python Web 框架和服务器的标准,称为
ASGI。FastAPI 本质上是一个 ASGI Web 框架。
+
+要在远程服务器上运行 **FastAPI** 应用(或任何其他 ASGI 应用),您需要一个 ASGI 服务器程序,例如 **Uvicorn**。它是 `fastapi` 命令默认使用的 ASGI 服务器。
+
+除此之外,还有其他一些可选的 ASGI 服务器,例如:
+
+*
Uvicorn:高性能 ASGI 服务器。
+*
Hypercorn:与 HTTP/2 和 Trio 等兼容的 ASGI 服务器。
+*
Daphne:为 Django Channels 构建的 ASGI 服务器。
+*
Granian:基于 Rust 的 HTTP 服务器,专为 Python 应用设计。
+*
NGINX Unit:NGINX Unit 是一个轻量级且灵活的 Web 应用运行时环境。
+
+## 服务器主机和服务器程序
+
+关于名称,有一个小细节需要记住。 💡
+
+“**服务器**”一词通常用于指远程/云计算机(物理机或虚拟机)以及在该计算机上运行的程序(例如 Uvicorn)。
+
+请记住,当您一般读到“服务器”这个名词时,它可能指的是这两者之一。
+
+当提到远程主机时,通常将其称为**服务器**,但也称为**机器**(machine)、**VM**(虚拟机)、**节点**。 这些都是指某种类型的远程计算机,通常运行 Linux,您可以在其中运行程序。
+
+
+## 安装服务器程序
+
+当您安装 FastAPI 时,它自带一个生产环境服务器——Uvicorn,并且您可以使用 `fastapi run` 命令来启动它。
+
+不过,您也可以手动安装 ASGI 服务器。
+
+请确保您创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装服务器应用程序。
+
+例如,要安装 Uvicorn,可以运行以下命令:
+
+
+
+```console
+$ pip install "uvicorn[standard]"
+
+---> 100%
+```
+
+
+
+类似的流程也适用于任何其他 ASGI 服务器程序。
+
+/// tip
+
+通过添加 `standard` 选项,Uvicorn 将安装并使用一些推荐的额外依赖项。
+
+其中包括 `uvloop`,这是 `asyncio` 的高性能替代方案,能够显著提升并发性能。
+
+当您使用 `pip install "fastapi[standard]"` 安装 FastAPI 时,实际上也会安装 `uvicorn[standard]`。
+
+///
+
+## 运行服务器程序
+
+如果您手动安装了 ASGI 服务器,通常需要以特定格式传递一个导入字符串,以便服务器能够正确导入您的 FastAPI 应用:
+
+
+
+```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)
+```
+
+
+
+/// note
+
+命令 `uvicorn main:app` 的含义如下:
+
+* `main`:指的是 `main.py` 文件(即 Python “模块”)。
+* `app`:指的是 `main.py` 文件中通过 `app = FastAPI()` 创建的对象。
+
+它等价于以下导入语句:
+
+```Python
+from main import app
+```
+
+///
+
+每种 ASGI 服务器程序通常都会有类似的命令,您可以在它们的官方文档中找到更多信息。
+
+/// warning
+
+Uvicorn 和其他服务器支持 `--reload` 选项,该选项在开发过程中非常有用。
+
+但 `--reload` 选项会消耗更多资源,且相对不稳定。
+
+它对于**开发阶段**非常有帮助,但在**生产环境**中**不应该**使用。
+
+///
+
+## 部署概念
+
+这些示例运行服务器程序(例如 Uvicorn),启动**单个进程**,在所有 IP(`0.0.0.0`)上监听预定义端口(例如`80`)。
+
+这是基本思路。 但您可能需要处理一些其他事情,例如:
+
+* 安全性 - HTTPS
+* 启动时运行
+* 重新启动
+* 复制(运行的进程数)
+* 内存
+* 开始前的步骤
+
+在接下来的章节中,我将向您详细介绍每个概念、如何思考它们,以及一些具体示例以及处理它们的策略。 🚀
diff --git a/docs/zh/docs/deployment/server-workers.md b/docs/zh/docs/deployment/server-workers.md
new file mode 100644
index 000000000..e46ba7a09
--- /dev/null
+++ b/docs/zh/docs/deployment/server-workers.md
@@ -0,0 +1,139 @@
+# 服务器工作进程(Workers) - 使用 Uvicorn 的多工作进程模式
+
+让我们回顾一下之前的部署概念:
+
+* 安全性 - HTTPS
+* 启动时运行
+* 重新启动
+* **复制(运行的进程数)**
+* 内存
+* 启动前的先前步骤
+
+到目前为止,在文档中的所有教程中,您可能一直是在运行一个**服务器程序**,例如使用 `fastapi` 命令来启动 Uvicorn,而它默认运行的是**单进程模式**。
+
+部署应用程序时,您可能希望进行一些**进程复制**,以利用**多核** CPU 并能够处理更多请求。
+
+正如您在上一章有关[部署概念](concepts.md){.internal-link target=_blank}中看到的,您可以使用多种策略。
+
+在本章节中,我将向您展示如何使用 `fastapi` 命令或直接使用 `uvicorn` 命令以**多工作进程模式**运行 **Uvicorn**。
+
+/// info
+
+如果您正在使用容器,例如 Docker 或 Kubernetes,我将在下一章中告诉您更多相关信息:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
+
+比较特别的是,在 **Kubernetes** 环境中运行时,您通常**不需要**使用多个工作进程,而是**每个容器运行一个 Uvicorn 进程**。不过,我会在本章节的后续部分详细介绍这一点。
+
+///
+
+## 多个工作进程
+
+您可以使用 `--workers` 命令行选项来启动多个工作进程:
+
+//// tab | `fastapi`
+
+如果您使用 `fastapi` 命令:
+
+
+
+```console
+$ fastapi run --workers 4 main.py
+
+ FastAPI Starting production server 🚀
+
+ Searching for package file structure from directories with
+ __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with the
+ following code:
+
+ from main import app
+
+ app Using import string: main:app
+
+ server Server started at http://0.0.0.0:8000
+ server Documentation at http://0.0.0.0:8000/docs
+
+ Logs:
+
+ INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to
+ quit)
+ INFO Started parent process [27365]
+ INFO Started server process [27368]
+ INFO Started server process [27369]
+ INFO Started server process [27370]
+ INFO Started server process [27367]
+ INFO Waiting for application startup.
+ INFO Waiting for application startup.
+ INFO Waiting for application startup.
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+ INFO Application startup complete.
+ INFO Application startup complete.
+ INFO Application startup complete.
+```
+
+
+
+////
+
+//// tab | `uvicorn`
+
+如果您更想要直接使用 `uvicorn` 命令:
+
+
+
+```console
+$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
+INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
+INFO: Started parent process [27365]
+INFO: Started server process [27368]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+INFO: Started server process [27369]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+INFO: Started server process [27370]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+INFO: Started server process [27367]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+////
+
+这里唯一的新选项是 `--workers` 告诉 Uvicorn 启动 4 个工作进程。
+
+您还可以看到它显示了每个进程的 **PID**,父进程(这是**进程管理器**)的 PID 为`27365`,每个工作进程的 PID 为:`27368`、`27369`, `27370`和`27367`。
+
+## 部署概念
+
+在这里,您学习了如何使用多个**工作进程(workers)**来让应用程序的执行**并行化**,充分利用 CPU 的**多核性能**,并能够处理**更多的请求**。
+
+从上面的部署概念列表来看,使用worker主要有助于**复制**部分,并对**重新启动**有一点帮助,但您仍然需要照顾其他部分:
+
+* **安全 - HTTPS**
+* **启动时运行**
+* ***重新启动***
+* 复制(运行的进程数)
+* **内存**
+* **启动之前的先前步骤**
+
+## 容器和 Docker
+
+在关于 [容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank} 的下一章中,我将介绍一些可用于处理其他**部署概念**的策略。
+
+我将向您展示如何**从零开始构建自己的镜像**,以运行一个单独的 Uvicorn 进程。这个过程相对简单,并且在使用 **Kubernetes** 等分布式容器管理系统时,这通常是您需要采取的方法。
+
+## 回顾
+
+您可以在使用 `fastapi` 或 `uvicorn` 命令时,通过 `--workers` CLI 选项启用多个工作进程(workers),以充分利用**多核 CPU**,以**并行运行多个进程**。
+
+如果您要设置**自己的部署系统**,同时自己处理其他部署概念,则可以使用这些工具和想法。
+
+请查看下一章,了解带有容器(例如 Docker 和 Kubernetes)的 **FastAPI**。 您将看到这些工具也有简单的方法来解决其他**部署概念**。 ✨
diff --git a/docs/zh/docs/deployment/versions.md b/docs/zh/docs/deployment/versions.md
new file mode 100644
index 000000000..228bb0765
--- /dev/null
+++ b/docs/zh/docs/deployment/versions.md
@@ -0,0 +1,93 @@
+# 关于 FastAPI 版本
+
+**FastAPI** 已在许多应用程序和系统的生产环境中使用。 并且测试覆盖率保持在100%。 但其开发进度仍在快速推进。
+
+经常添加新功能,定期修复错误,并且代码仍在持续改进。
+
+这就是为什么当前版本仍然是`0.x.x`,这反映出每个版本都可能有Breaking changes。 这遵循
语义版本控制的约定。
+
+你现在就可以使用 **FastAPI** 创建生产环境应用程序(你可能已经这样做了一段时间),你只需确保使用的版本可以与其余代码正确配合即可。
+
+## 固定你的 `fastapi` 版本
+
+你应该做的第一件事是将你正在使用的 **FastAPI** 版本“固定”到你知道适用于你的应用程序的特定最新版本。
+
+例如,假设你在应用程序中使用版本`0.45.0`。
+
+如果你使用`requirements.txt`文件,你可以使用以下命令指定版本:
+
+````txt
+fastapi==0.45.0
+````
+
+这意味着你将使用版本`0.45.0`。
+
+或者你也可以将其固定为:
+
+````txt
+fastapi>=0.45.0,<0.46.0
+````
+
+这意味着你将使用`0.45.0`或更高版本,但低于`0.46.0`,例如,版本`0.45.2`仍会被接受。
+
+如果你使用任何其他工具来管理你的安装,例如 Poetry、Pipenv 或其他工具,它们都有一种定义包的特定版本的方法。
+
+## 可用版本
+
+你可以在[发行说明](../release-notes.md){.internal-link target=_blank}中查看可用版本(例如查看当前最新版本)。
+
+## 关于版本
+
+遵循语义版本控制约定,任何低于`1.0.0`的版本都可能会添加 breaking changes。
+
+FastAPI 还遵循这样的约定:任何`PATCH`版本更改都是为了bug修复和non-breaking changes。
+
+/// tip
+
+"PATCH"是最后一个数字,例如,在`0.2.3`中,PATCH版本是`3`。
+
+///
+
+因此,你应该能够固定到如下版本:
+
+```txt
+fastapi>=0.45.0,<0.46.0
+```
+
+"MINOR"版本中会添加breaking changes和新功能。
+
+/// tip
+
+"MINOR"是中间的数字,例如,在`0.2.3`中,MINOR版本是`2`。
+
+///
+
+## 升级FastAPI版本
+
+你应该为你的应用程序添加测试。
+
+使用 **FastAPI** 编写测试非常简单(感谢 Starlette),请参考文档:[测试](../tutorial/testing.md){.internal-link target=_blank}
+
+添加测试后,你可以将 **FastAPI** 版本升级到更新版本,并通过运行测试来确保所有代码都能正常工作。
+
+如果一切正常,或者在进行必要的更改之后,并且所有测试都通过了,那么你可以将`fastapi`固定到新的版本。
+
+## 关于Starlette
+
+你不应该固定`starlette`的版本。
+
+不同版本的 **FastAPI** 将使用特定的较新版本的 Starlette。
+
+因此,**FastAPI** 自己可以使用正确的 Starlette 版本。
+
+## 关于 Pydantic
+
+Pydantic 包含针对 **FastAPI** 的测试及其自己的测试,因此 Pydantic 的新版本(`1.0.0`以上)始终与 FastAPI 兼容。
+
+你可以将 Pydantic 固定到适合你的`1.0.0`以上和`2.0.0`以下的任何版本。
+
+例如:
+
+````txt
+pydantic>=1.2.0,<2.0.0
+````
diff --git a/docs/zh/docs/environment-variables.md b/docs/zh/docs/environment-variables.md
new file mode 100644
index 000000000..812278051
--- /dev/null
+++ b/docs/zh/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# 环境变量
+
+/// tip
+
+如果你已经知道什么是“环境变量”并且知道如何使用它们,你可以放心跳过这一部分。
+
+///
+
+环境变量(也称为“**env var**”)是一个独立于 Python 代码**之外**的变量,它存在于**操作系统**中,可以被你的 Python 代码(或其他程序)读取。
+
+环境变量对于处理应用程序**设置**、作为 Python **安装**的一部分等方面非常有用。
+
+## 创建和使用环境变量
+
+你在 **shell(终端)**中就可以**创建**和使用环境变量,并不需要用到 Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// 你可以使用以下命令创建一个名为 MY_NAME 的环境变量
+$ export MY_NAME="Wade Wilson"
+
+// 然后,你可以在其他程序中使用它,例如
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// 创建一个名为 MY_NAME 的环境变量
+$ $Env:MY_NAME = "Wade Wilson"
+
+// 在其他程序中使用它,例如
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## 在 Python 中读取环境变量
+
+你也可以在 Python **之外**的终端中创建环境变量(或使用任何其他方法),然后在 Python 中**读取**它们。
+
+例如,你可以创建一个名为 `main.py` 的文件,其中包含以下内容:
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip
+
+第二个参数是
`os.getenv()` 的默认返回值。
+
+如果没有提供,默认值为 `None`,这里我们提供 `"World"` 作为默认值。
+
+///
+
+然后你可以调用这个 Python 程序:
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// 这里我们还没有设置环境变量
+$ python main.py
+
+// 因为我们没有设置环境变量,所以我们得到的是默认值
+
+Hello World from Python
+
+// 但是如果我们事先创建过一个环境变量
+$ export MY_NAME="Wade Wilson"
+
+// 然后再次调用程序
+$ python main.py
+
+// 现在就可以读取到环境变量了
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// 这里我们还没有设置环境变量
+$ python main.py
+
+// 因为我们没有设置环境变量,所以我们得到的是默认值
+
+Hello World from Python
+
+// 但是如果我们事先创建过一个环境变量
+$ $Env:MY_NAME = "Wade Wilson"
+
+// 然后再次调用程序
+$ python main.py
+
+// 现在就可以读取到环境变量了
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+由于环境变量可以在代码之外设置、但可以被代码读取,并且不必与其他文件一起存储(提交到 `git`),因此通常用于配置或**设置**。
+
+你还可以为**特定的程序调用**创建特定的环境变量,该环境变量仅对该程序可用,且仅在其运行期间有效。
+
+要实现这一点,只需在同一行内、程序本身之前创建它:
+
+
+
+```console
+// 在这个程序调用的同一行中创建一个名为 MY_NAME 的环境变量
+$ MY_NAME="Wade Wilson" python main.py
+
+// 现在就可以读取到环境变量了
+
+Hello Wade Wilson from Python
+
+// 在此之后这个环境变量将不会依然存在
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip
+
+你可以在
The Twelve-Factor App: 配置中了解更多信息。
+
+///
+
+## 类型和验证
+
+这些环境变量只能处理**文本字符串**,因为它们是处于 Python 范畴之外的,必须与其他程序和操作系统的其余部分兼容(甚至与不同的操作系统兼容,如 Linux、Windows、macOS)。
+
+这意味着从环境变量中读取的**任何值**在 Python 中都将是一个 `str`,任何类型转换或验证都必须在代码中完成。
+
+你将在[高级用户指南 - 设置和环境变量](./advanced/settings.md)中了解更多关于使用环境变量处理**应用程序设置**的信息。
+
+## `PATH` 环境变量
+
+有一个**特殊的**环境变量称为 **`PATH`**,操作系统(Linux、macOS、Windows)用它来查找要运行的程序。
+
+`PATH` 变量的值是一个长字符串,由 Linux 和 macOS 上的冒号 `:` 分隔的目录组成,而在 Windows 上则是由分号 `;` 分隔的。
+
+例如,`PATH` 环境变量可能如下所示:
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+这意味着系统应该在以下目录中查找程序:
+
+- `/usr/local/bin`
+- `/usr/bin`
+- `/bin`
+- `/usr/sbin`
+- `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
+```
+
+这意味着系统应该在以下目录中查找程序:
+
+- `C:\Program Files\Python312\Scripts`
+- `C:\Program Files\Python312`
+- `C:\Windows\System32`
+
+////
+
+当你在终端中输入一个**命令**时,操作系统会在 `PATH` 环境变量中列出的**每个目录**中**查找**程序。
+
+例如,当你在终端中输入 `python` 时,操作系统会在该列表中的**第一个目录**中查找名为 `python` 的程序。
+
+如果找到了,那么操作系统将**使用它**;否则,操作系统会继续在**其他目录**中查找。
+
+### 安装 Python 和更新 `PATH`
+
+安装 Python 时,可能会询问你是否要更新 `PATH` 环境变量。
+
+//// tab | Linux, macOS
+
+假设你安装 Python 并最终将其安装在了目录 `/opt/custompython/bin` 中。
+
+如果你同意更新 `PATH` 环境变量,那么安装程序将会将 `/opt/custompython/bin` 添加到 `PATH` 环境变量中。
+
+它看起来大概会像这样:
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
+```
+
+如此一来,当你在终端中输入 `python` 时,系统会在 `/opt/custompython/bin` 中找到 Python 程序(最后一个目录)并使用它。
+
+////
+
+//// tab | Windows
+
+假设你安装 Python 并最终将其安装在了目录 `C:\opt\custompython\bin` 中。
+
+如果你同意更新 `PATH` 环境变量 (在 Python 安装程序中,这个操作是名为 `Add Python x.xx to PATH` 的复选框 —— 译者注),那么安装程序将会将 `C:\opt\custompython\bin` 添加到 `PATH` 环境变量中。
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
+```
+
+如此一来,当你在终端中输入 `python` 时,系统会在 `C:\opt\custompython\bin` 中找到 Python 程序(最后一个目录)并使用它。
+
+////
+
+因此,如果你输入:
+
+
+
+```console
+$ python
+```
+
+
+
+//// tab | Linux, macOS
+
+系统会在 `/opt/custompython/bin` 中**找到** `python` 程序并运行它。
+
+这和输入以下命令大致等价:
+
+
+
+```console
+$ /opt/custompython/bin/python
+```
+
+
+
+////
+
+//// tab | Windows
+
+系统会在 `C:\opt\custompython\bin\python` 中**找到** `python` 程序并运行它。
+
+这和输入以下命令大致等价:
+
+
+
+```console
+$ C:\opt\custompython\bin\python
+```
+
+
+
+////
+
+当学习[虚拟环境](virtual-environments.md)时,这些信息将会很有用。
+
+## 结论
+
+通过这个教程,你应该对**环境变量**是什么以及如何在 Python 中使用它们有了基本的了解。
+
+你也可以在
环境变量 - 维基百科 (
Wikipedia for Environment Variable) 中了解更多关于它们的信息。
+
+在许多情况下,环境变量的用途和适用性并不是很明显。但是在开发过程中,它们会在许多不同的场景中出现,因此了解它们是很有必要的。
+
+例如,你将在下一节关于[虚拟环境](virtual-environments.md)中需要这些信息。
diff --git a/docs/zh/docs/fastapi-cli.md b/docs/zh/docs/fastapi-cli.md
new file mode 100644
index 000000000..8a70e1d80
--- /dev/null
+++ b/docs/zh/docs/fastapi-cli.md
@@ -0,0 +1,79 @@
+# FastAPI CLI
+
+**FastAPI CLI** 是一个命令行程序,你可以用它来部署和运行你的 FastAPI 应用程序,管理你的 FastAPI 项目,等等。
+
+当你安装 FastAPI 时(例如使用 `pip install FastAPI` 命令),会包含一个名为 `fastapi-cli` 的软件包,该软件包在终端中提供 `fastapi` 命令。
+
+要在开发环境中运行你的 FastAPI 应用,你可以使用 `fastapi dev` 命令:
+
+
+
+```console
+$ fastapi dev main.py
+
+ FastAPI Starting development server 🚀
+
+ Searching for package file structure from directories with
+ __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with the
+ following code:
+
+ from main import app
+
+ app Using import string: main:app
+
+ server Server started at http://127.0.0.1:8000
+ server Documentation at http://127.0.0.1:8000/docs
+
+ tip Running in development mode, for production use:
+ fastapi run
+
+ Logs:
+
+ INFO Will watch for changes in these directories:
+ ['/home/user/code/awesomeapp']
+ INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to
+ quit)
+ INFO Started reloader process [383138] using WatchFiles
+ INFO Started server process [383153]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+```
+
+
+
+该命令行程序 `fastapi` 就是 **FastAPI CLI**。
+
+FastAPI CLI 接收你的 Python 程序路径,自动检测包含 FastAPI 的变量(通常命名为 `app`)及其导入方式,然后启动服务。
+
+在生产环境中,你应该使用 `fastapi run` 命令。🚀
+
+在内部,**FastAPI CLI** 使用了
Uvicorn,这是一个高性能、适用于生产环境的 ASGI 服务器。😎
+
+## `fastapi dev`
+
+当你运行 `fastapi dev` 时,它将以开发模式运行。
+
+默认情况下,它会启用**自动重载**,因此当你更改代码时,它会自动重新加载服务器。该功能是资源密集型的,且相较不启用时更不稳定,因此你应该仅在开发环境下使用它。
+
+默认情况下,它将监听 IP 地址 `127.0.0.1`,这是你的机器与自身通信的 IP 地址(`localhost`)。
+
+## `fastapi run`
+
+当你运行 `fastapi run` 时,它默认以生产环境模式运行。
+
+默认情况下,**自动重载是禁用的**。
+
+它将监听 IP 地址 `0.0.0.0`,即所有可用的 IP 地址,这样任何能够与该机器通信的人都可以公开访问它。这通常是你在生产环境中运行它的方式,例如在容器中运行。
+
+在大多数情况下,你会(且应该)有一个“终止代理”在上层为你处理 HTTPS,这取决于你如何部署应用程序,你的服务提供商可能会为你处理此事,或者你可能需要自己设置。
+
+/// tip | 提示
+
+你可以在 [deployment documentation](deployment/index.md){.internal-link target=_blank} 获得更多信息。
+
+///
diff --git a/docs/zh/docs/fastapi-people.md b/docs/zh/docs/fastapi-people.md
deleted file mode 100644
index 5d7b0923f..000000000
--- a/docs/zh/docs/fastapi-people.md
+++ /dev/null
@@ -1,178 +0,0 @@
-# FastAPI 社区
-
-FastAPI 有一个非常棒的社区,它欢迎来自各个领域和背景的朋友。
-
-## 创建者 & 维护者
-
-嘿! 👋
-
-这就是我:
-
-{% if people %}
-
-{% for user in people.maintainers %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-我是 **FastAPI** 的创建者和维护者. 你能在 [帮助 FastAPI - 获取帮助 - 与作者联系](help-fastapi.md#connect-with-the-author){.internal-link target=_blank} 阅读有关此内容的更多信息。
-
-...但是在这里我想向您展示社区。
-
----
-
-**FastAPI** 得到了社区的大力支持。因此我想突出他们的贡献。
-
-这些人:
-
-* [帮助他人解决 GitHub 的 issues](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}。
-* [创建 Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}。
-* 审核 Pull Requests, 对于 [翻译](contributing.md#translations){.internal-link target=_blank} 尤为重要。
-
-向他们致以掌声。 👏 🙇
-
-## 上个月最活跃的用户
-
-上个月这些用户致力于 [帮助他人解决 GitHub 的 issues](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}。
-
-{% if people %}
-
-{% for user in people.last_month_active %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## 专家组
-
-以下是 **FastAPI 专家**。 🤓
-
-这些用户一直以来致力于 [帮助他人解决 GitHub 的 issues](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}。
-
-他们通过帮助许多人而被证明是专家。✨
-
-{% if people %}
-
-{% for user in people.experts %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## 杰出贡献者
-
-以下是 **杰出的贡献者**。 👷
-
-这些用户 [创建了最多已被合并的 Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}。
-
-他们贡献了源代码,文档,翻译等。 📦
-
-{% if people %}
-
-{% for user in people.top_contributors %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-还有很多其他贡献者(超过100个),你可以在
FastAPI GitHub 贡献者页面 中看到他们。👷
-
-## 杰出审核者
-
-以下用户是「杰出的评审者」。 🕵️
-
-### 翻译审核
-
-我只会说少数几种语言(而且还不是很流利 😅)。所以,具备[能力去批准文档翻译](contributing.md#translations){.internal-link target=_blank} 是这些评审者们。如果没有它们,就不会有多语言文档。
-
----
-
-**杰出的评审者** 🕵️ 评审了最多来自他人的 Pull Requests,他们保证了代码、文档尤其是 **翻译** 的质量。
-
-{% if people %}
-
-{% for user in people.top_reviewers %}
-
-
-{% endfor %}
-
-
-{% endif %}
-
-## 赞助商
-
-以下是 **赞助商** 。😎
-
-他们主要通过
GitHub Sponsors支持我在 **FastAPI** (和其他项目)的工作。
-
-{% if sponsors %}
-
-{% if sponsors.gold %}
-
-### 金牌赞助商
-
-{% for sponsor in sponsors.gold -%}
-

-{% endfor %}
-{% endif %}
-
-{% if sponsors.silver %}
-
-### 银牌赞助商
-
-{% for sponsor in sponsors.silver -%}
-

-{% endfor %}
-{% endif %}
-
-{% if sponsors.bronze %}
-
-### 铜牌赞助商
-
-{% for sponsor in sponsors.bronze -%}
-

-{% endfor %}
-{% endif %}
-
-{% endif %}
-
-### 个人赞助
-
-{% if github_sponsors %}
-{% for group in github_sponsors.sponsors %}
-
-
-
-{% for user in group %}
-{% if user.login not in sponsors_badge.logins %}
-
-
-
-{% endif %}
-{% endfor %}
-
-
-
-{% endfor %}
-{% endif %}
-
-## 关于数据 - 技术细节
-
-该页面的目的是突出社区为帮助他人而付出的努力。
-
-尤其是那些不引人注目且涉及更困难的任务,例如帮助他人解决问题或者评审翻译 Pull Requests。
-
-该数据每月计算一次,您可以阅读
源代码。
-
-这里也强调了赞助商的贡献。
-
-我也保留更新算法,栏目,统计阈值等的权利(以防万一🤷)。
diff --git a/docs/zh/docs/features.md b/docs/zh/docs/features.md
index 2db7f852a..24dc3e8ce 100644
--- a/docs/zh/docs/features.md
+++ b/docs/zh/docs/features.md
@@ -65,10 +65,13 @@ my_second_user: User = User(**second_user_data)
```
-!!! info
- `**second_user_data` 意思是:
+/// info
- 直接将`second_user_data`字典的键和值直接作为key-value参数传递,等同于:`User(id=4, name="Mary", joined="2018-11-30")`
+`**second_user_data` 意思是:
+
+直接将`second_user_data`字典的键和值直接作为key-value参数传递,等同于:`User(id=4, name="Mary", joined="2018-11-30")`
+
+///
### 编辑器支持
@@ -179,7 +182,7 @@ FastAPI 有一个使用非常简单,但是非常强大的
IDE/
linter/brain** 适配:
* 因为 pydantic 数据结构仅仅是你定义的类的实例;自动补全,linting,mypy 以及你的直觉应该可以和你验证的数据一起正常工作。
-* **更快**:
- * 在
基准测试 中,Pydantic 比其他被测试的库都要快。
* 验证**复杂结构**:
* 使用分层的 Pydantic 模型, Python `typing`的 `List` 和 `Dict` 等等。
* 验证器使我们能够简单清楚的将复杂的数据模式定义、检查并记录为 JSON Schema。
diff --git a/docs/zh/docs/help-fastapi.md b/docs/zh/docs/help-fastapi.md
index 2a99950e3..09f37a44b 100644
--- a/docs/zh/docs/help-fastapi.md
+++ b/docs/zh/docs/help-fastapi.md
@@ -12,7 +12,7 @@
## 订阅新闻邮件
-您可以订阅 [**FastAPI 和它的小伙伴** 新闻邮件](/newsletter/){.internal-link target=_blank}(不会经常收到)
+您可以订阅 [**FastAPI 和它的小伙伴** 新闻邮件](newsletter.md){.internal-link target=_blank}(不会经常收到)
* FastAPI 及其小伙伴的新闻 🚀
* 指南 📝
@@ -26,13 +26,13 @@
## 在 GitHub 上为 **FastAPI** 加星
-您可以在 GitHub 上 **Star** FastAPI(只要点击右上角的星星就可以了):
https://github.com/tiangolo/fastapi。⭐️
+您可以在 GitHub 上 **Star** FastAPI(只要点击右上角的星星就可以了):
https://github.com/fastapi/fastapi。⭐️
**Star** 以后,其它用户就能更容易找到 FastAPI,并了解到已经有其他用户在使用它了。
## 关注 GitHub 资源库的版本发布
-您还可以在 GitHub 上 **Watch** FastAPI,(点击右上角的 **Watch** 按钮)
https://github.com/tiangolo/fastapi。👀
+您还可以在 GitHub 上 **Watch** FastAPI,(点击右上角的 **Watch** 按钮)
https://github.com/fastapi/fastapi。👀
您可以选择只关注发布(**Releases only**)。
@@ -59,7 +59,7 @@
## Tweet about **FastAPI**
-
Tweet about **FastAPI** 让我和大家知道您为什么喜欢 FastAPI。🎉
+
Tweet about **FastAPI** 让我和大家知道您为什么喜欢 FastAPI。🎉
知道有人使用 **FastAPI**,我会很开心,我也想知道您为什么喜欢 FastAPI,以及您在什么项目/哪些公司使用 FastAPI,等等。
@@ -70,13 +70,13 @@
## 在 GitHub 上帮助其他人解决问题
-您可以查看
现有 issues,并尝试帮助其他人解决问题,说不定您能解决这些问题呢。🤓
+您可以查看
现有 issues,并尝试帮助其他人解决问题,说不定您能解决这些问题呢。🤓
-如果帮助很多人解决了问题,您就有可能成为 [FastAPI 的官方专家](fastapi-people.md#experts){.internal-link target=_blank}。🎉
+如果帮助很多人解决了问题,您就有可能成为 [FastAPI 的官方专家](fastapi-people.md#_3){.internal-link target=_blank}。🎉
## 监听 GitHub 资源库
-您可以在 GitHub 上「监听」FastAPI(点击右上角的 "watch" 按钮):
https://github.com/tiangolo/fastapi. 👀
+您可以在 GitHub 上「监听」FastAPI(点击右上角的 "watch" 按钮):
https://github.com/fastapi/fastapi. 👀
如果您选择 "Watching" 而不是 "Releases only",有人创建新 Issue 时,您会接收到通知。
@@ -84,7 +84,7 @@
## 创建 Issue
-您可以在 GitHub 资源库中
创建 Issue,例如:
+您可以在 GitHub 资源库中
创建 Issue,例如:
* 提出**问题**或**意见**
* 提出新**特性**建议
@@ -96,9 +96,9 @@
您可以创建 PR 为源代码做[贡献](contributing.md){.internal-link target=_blank},例如:
* 修改文档错别字
-*
编辑这个文件,分享 FastAPI 的文章、视频、博客,不论是您自己的,还是您看到的都成
+*
编辑这个文件,分享 FastAPI 的文章、视频、博客,不论是您自己的,还是您看到的都成
* 注意,添加的链接要放在对应区块的开头
-* [翻译文档](contributing.md#translations){.internal-link target=_blank}
+* [翻译文档](contributing.md#_8){.internal-link target=_blank}
* 审阅别人翻译的文档
* 添加新的文档内容
* 修复现有问题/Bug
@@ -108,13 +108,13 @@
快加入 👥
Discord 聊天服务器 👥 和 FastAPI 社区里的小伙伴一起哈皮吧。
-!!! tip "提示"
+/// tip | 提示
- 如有问题,请在
GitHub Issues 里提问,在这里更容易得到 [FastAPI 专家](fastapi-people.md#experts){.internal-link target=_blank}的帮助。
+如有问题,请在
GitHub Issues 里提问,在这里更容易得到 [FastAPI 专家](fastapi-people.md#_3){.internal-link target=_blank}的帮助。
- 聊天室仅供闲聊。
+聊天室仅供闲聊。
-我们之前还使用过
Gitter chat,但它不支持频道等高级功能,聊天也比较麻烦,所以现在推荐使用 Discord。
+///
### 别在聊天室里提问
@@ -122,7 +122,7 @@
GitHub Issues 里提供了模板,指引您提出正确的问题,有利于获得优质的回答,甚至可能解决您还没有想到的问题。而且就算答疑解惑要耗费不少时间,我还是会尽量在 GitHub 里回答问题。但在聊天室里,我就没功夫这么做了。😅
-聊天室里的聊天内容也不如 GitHub 里好搜索,聊天里的问答很容易就找不到了。只有在 GitHub Issues 里的问答才能帮助您成为 [FastAPI 专家](fastapi-people.md#experts){.internal-link target=_blank},在 GitHub Issues 中为您带来更多关注。
+聊天室里的聊天内容也不如 GitHub 里好搜索,聊天里的问答很容易就找不到了。只有在 GitHub Issues 里的问答才能帮助您成为 [FastAPI 专家](fastapi-people.md#_3){.internal-link target=_blank},在 GitHub Issues 中为您带来更多关注。
另一方面,聊天室里有成千上万的用户,在这里,您有很大可能遇到聊得来的人。😄
diff --git a/docs/zh/docs/history-design-future.md b/docs/zh/docs/history-design-future.md
new file mode 100644
index 000000000..48cfef524
--- /dev/null
+++ b/docs/zh/docs/history-design-future.md
@@ -0,0 +1,78 @@
+# 历史、设计、未来
+
+不久前,
曾有 **FastAPI** 用户问过:
+
+> 这个项目有怎样的历史?好像它只用了几周就从默默无闻变得众所周知……
+
+在此,我们简单回顾一下 **FastAPI** 的历史。
+
+## 备选方案
+
+有那么几年,我曾领导数个开发团队为诸多复杂需求创建各种 API,这些需求包括机器学习、分布系统、异步任务、NoSQL 数据库等领域。
+
+作为工作的一部分,我需要调研很多备选方案、还要测试并且使用这些备选方案。
+
+**FastAPI** 其实只是延续了这些前辈的历史。
+
+正如[备选方案](alternatives.md){.internal-link target=_blank}一章所述:
+
+
+没有大家之前所做的工作,**FastAPI** 就不会存在。
+
+以前创建的这些工具为它的出现提供了灵感。
+
+在那几年中,我一直回避创建新的框架。首先,我尝试使用各种框架、插件、工具解决 **FastAPI** 现在的功能。
+
+但到了一定程度之后,我别无选择,只能从之前的工具中汲取最优思路,并以尽量好的方式把这些思路整合在一起,使用之前甚至是不支持的语言特性(Python 3.6+ 的类型提示),从而创建一个能满足我所有需求的框架。
+
+
+
+## 调研
+
+通过使用之前所有的备选方案,我有机会从它们之中学到了很多东西,获取了很多想法,并以我和我的开发团队能想到的最好方式把这些思路整合成一体。
+
+例如,大家都清楚,在理想状态下,它应该基于标准的 Python 类型提示。
+
+而且,最好的方式是使用现有的标准。
+
+因此,甚至在开发 **FastAPI** 前,我就花了几个月的时间研究 OpenAPI、JSON Schema、OAuth2 等规范。深入理解它们之间的关系、重叠及区别之处。
+
+## 设计
+
+然后,我又花了一些时间从用户角度(使用 FastAPI 的开发者)设计了开发者 **API**。
+
+同时,我还在最流行的 Python 代码编辑器中测试了很多思路,包括 PyCharm、VS Code、基于 Jedi 的编辑器。
+
+根据最新
Python 开发者调研报告显示,这几种编辑器覆盖了约 80% 的用户。
+
+也就是说,**FastAPI** 针对差不多 80% 的 Python 开发者使用的编辑器进行了测试,而且其它大多数编辑器的工作方式也与之类似,因此,**FastAPI** 的优势几乎能在所有编辑器上体现。
+
+通过这种方式,我就能找到尽可能减少代码重复的最佳方式,进而实现处处都有自动补全、类型提示与错误检查等支持。
+
+所有这些都是为了给开发者提供最佳的开发体验。
+
+## 需求项
+
+经过测试多种备选方案,我最终决定使用
**Pydantic**,并充分利用它的优势。
+
+我甚至为它做了不少贡献,让它完美兼容了 JSON Schema,支持多种方式定义约束声明,并基于多个编辑器,改进了它对编辑器支持(类型检查、自动补全)。
+
+在开发期间,我还为
**Starlette** 做了不少贡献,这是另一个关键需求项。
+
+## 开发
+
+当我启动 **FastAPI** 开发的时候,绝大多数部件都已经就位,设计已经定义,需求项和工具也已经准备就绪,相关标准与规范的知识储备也非常清晰而新鲜。
+
+## 未来
+
+至此,**FastAPI** 及其理念已经为很多人所用。
+
+对于很多用例,它比以前很多备选方案都更适用。
+
+很多开发者和开发团队已经依赖 **FastAPI** 开发他们的项目(包括我和我的团队)。
+
+但,**FastAPI** 仍有很多改进的余地,也还需要添加更多的功能。
+
+总之,**FastAPI** 前景光明。
+
+在此,我们衷心感谢[您的帮助](help-fastapi.md){.internal-link target=_blank}。
diff --git a/docs/zh/docs/how-to/configure-swagger-ui.md b/docs/zh/docs/how-to/configure-swagger-ui.md
new file mode 100644
index 000000000..108e0cb95
--- /dev/null
+++ b/docs/zh/docs/how-to/configure-swagger-ui.md
@@ -0,0 +1,70 @@
+# 配置 Swagger UI
+
+你可以配置一些额外的
Swagger UI 参数.
+
+如果需要配置它们,可以在创建 `FastAPI()` 应用对象时或调用 `get_swagger_ui_html()` 函数时传递 `swagger_ui_parameters` 参数。
+
+`swagger_ui_parameters` 接受一个直接传递给 Swagger UI的字典,包含配置参数键值对。
+
+FastAPI会将这些配置转换为 **JSON**,使其与 JavaScript 兼容,因为这是 Swagger UI 需要的。
+
+## 不使用语法高亮
+
+比如,你可以禁用 Swagger UI 中的语法高亮。
+
+当没有改变设置时,语法高亮默认启用:
+
+

+
+但是你可以通过设置 `syntaxHighlight` 为 `False` 来禁用 Swagger UI 中的语法高亮:
+
+{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
+
+...在此之后,Swagger UI 将不会高亮代码:
+
+

+
+## 改变主题
+
+同样地,你也可以通过设置键 `"syntaxHighlight.theme"` 来设置语法高亮主题(注意中间有一个点):
+
+{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
+
+这个配置会改变语法高亮主题:
+
+

+
+## 改变默认 Swagger UI 参数
+
+FastAPI 包含了一些默认配置参数,适用于大多数用例。
+
+其包括这些默认配置参数:
+
+{* ../../fastapi/openapi/docs.py ln[7:23] *}
+
+你可以通过在 `swagger_ui_parameters` 中设置不同的值来覆盖它们。
+
+比如,如果要禁用 `deepLinking`,你可以像这样传递设置到 `swagger_ui_parameters` 中:
+
+{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
+
+## 其他 Swagger UI 参数
+
+查看其他 Swagger UI 参数,请阅读
docs for Swagger UI parameters。
+
+## JavaScript-only 配置
+
+Swagger UI 同样允许使用 **JavaScript-only** 配置对象(例如,JavaScript 函数)。
+
+FastAPI 包含这些 JavaScript-only 的 `presets` 设置:
+
+```JavaScript
+presets: [
+ SwaggerUIBundle.presets.apis,
+ SwaggerUIBundle.SwaggerUIStandalonePreset
+]
+```
+
+这些是 **JavaScript** 对象,而不是字符串,所以你不能直接从 Python 代码中传递它们。
+
+如果你需要像这样使用 JavaScript-only 配置,你可以使用上述方法之一。覆盖所有 Swagger UI *path operation* 并手动编写任何你需要的 JavaScript。
diff --git a/docs/zh/docs/how-to/general.md b/docs/zh/docs/how-to/general.md
new file mode 100644
index 000000000..e8b6dd3b2
--- /dev/null
+++ b/docs/zh/docs/how-to/general.md
@@ -0,0 +1,39 @@
+# 通用 - 如何操作 - 诀窍
+
+这里是一些指向文档中其他部分的链接,用于解答一般性或常见问题。
+
+## 数据过滤 - 安全性
+
+为确保不返回超过需要的数据,请阅读 [教程 - 响应模型 - 返回类型](../tutorial/response-model.md){.internal-link target=_blank} 文档。
+
+## 文档的标签 - OpenAPI
+
+在文档界面中添加**路径操作**的标签和进行分组,请阅读 [教程 - 路径操作配置 - Tags 参数](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank} 文档。
+
+## 文档的概要和描述 - OpenAPI
+
+在文档界面中添加**路径操作**的概要和描述,请阅读 [教程 - 路径操作配置 - Summary 和 Description 参数](../tutorial/path-operation-configuration.md#summary-description){.internal-link target=_blank} 文档。
+
+## 文档的响应描述 - OpenAPI
+
+在文档界面中定义并显示响应描述,请阅读 [教程 - 路径操作配置 - 响应描述](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank} 文档。
+
+## 文档弃用**路径操作** - OpenAPI
+
+在文档界面中显示弃用的**路径操作**,请阅读 [教程 - 路径操作配置 - 弃用](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank} 文档。
+
+## 将任何数据转换为 JSON 兼容格式
+
+要将任何数据转换为 JSON 兼容格式,请阅读 [教程 - JSON 兼容编码器](../tutorial/encoder.md){.internal-link target=_blank} 文档。
+
+## OpenAPI 元数据 - 文档
+
+要添加 OpenAPI 的元数据,包括许可证、版本、联系方式等,请阅读 [教程 - 元数据和文档 URL](../tutorial/metadata.md){.internal-link target=_blank} 文档。
+
+## OpenAPI 自定义 URL
+
+要自定义 OpenAPI 的 URL(或删除它),请阅读 [教程 - 元数据和文档 URL](../tutorial/metadata.md#openapi-url){.internal-link target=_blank} 文档。
+
+## OpenAPI 文档 URL
+
+要更改用于自动生成文档的 URL,请阅读 [教程 - 元数据和文档 URL](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
diff --git a/docs/zh/docs/how-to/index.md b/docs/zh/docs/how-to/index.md
new file mode 100644
index 000000000..ac097618b
--- /dev/null
+++ b/docs/zh/docs/how-to/index.md
@@ -0,0 +1,13 @@
+# 如何操作 - 诀窍
+
+在这里,你将看到关于**多个主题**的不同诀窍或“如何操作”指南。
+
+这些方法多数是**相互独立**的,在大多数情况下,你只需在这些内容适用于**你的项目**时才需要学习它们。
+
+如果某些内容看起来对你的项目有用,请继续查阅,否则请直接跳过它们。
+
+/// tip | 小技巧
+
+如果你想以系统的方式**学习 FastAPI**(推荐),请阅读 [教程 - 用户指南](../tutorial/index.md){.internal-link target=_blank} 的每一章节。
+
+///
diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md
index 7901e9c2c..94cf8745c 100644
--- a/docs/zh/docs/index.md
+++ b/docs/zh/docs/index.md
@@ -1,3 +1,9 @@
+# FastAPI
+
+
+
@@ -5,30 +11,33 @@
FastAPI 框架,高性能,易于学习,高效编码,生产可用
-
-
+
+
-
-
+
+
+
+
+
---
**文档**:
https://fastapi.tiangolo.com
-**源码**:
https://github.com/tiangolo/fastapi
+**源码**:
https://github.com/fastapi/fastapi
---
-FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示。
+FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 并基于标准的 Python 类型提示。
关键特性:
-* **快速**:可与 **NodeJS** 和 **Go** 比肩的极高性能(归功于 Starlette 和 Pydantic)。[最快的 Python web 框架之一](#_11)。
+* **快速**:可与 **NodeJS** 和 **Go** 并肩的极高性能(归功于 Starlette 和 Pydantic)。[最快的 Python web 框架之一](#_11)。
* **高效编码**:提高功能开发速度约 200% 至 300%。*
* **更少 bug**:减少约 40% 的人为(开发者)导致错误。*
@@ -61,7 +70,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
「_[...] 最近我一直在使用 **FastAPI**。[...] 实际上我正在计划将其用于我所在的**微软**团队的所有**机器学习服务**。其中一些服务正被集成进核心 **Windows** 产品和一些 **Office** 产品。_」
-
+
---
@@ -85,7 +94,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
「_老实说,你的作品看起来非常可靠和优美。在很多方面,这就是我想让 **Hug** 成为的样子 - 看到有人实现了它真的很鼓舞人心。_」
-
+
---
@@ -107,12 +116,12 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
## 依赖
-Python 3.6 及更高版本
+Python 及更高版本
FastAPI 站在以下巨人的肩膀之上:
*
Starlette 负责 web 部分。
-*
Pydantic 负责数据部分。
+*
Pydantic 负责数据部分。
## 安装
@@ -126,7 +135,7 @@ $ pip install fastapi
-你还会需要一个 ASGI 服务器,生产环境可以使用
Uvicorn 或者
Hypercorn。
+你还会需要一个 ASGI 服务器,生产环境可以使用
Uvicorn 或者
Hypercorn。
@@ -187,7 +196,7 @@ async def read_item(item_id: int, q: Union[str, None] = None):
**Note**:
-如果你不知道是否会用到,可以查看文档的 _"In a hurry?"_ 章节中
关于 `async` 和 `await` 的部分。
+如果你不知道是否会用到,可以查看文档的 _"In a hurry?"_ 章节中
关于 `async` 和 `await` 的部分。
@@ -323,7 +332,7 @@ def update_item(item_id: int, item: Item):
你不需要去学习新的语法、了解特定库的方法或类,等等。
-只需要使用标准的 **Python 3.6 及更高版本**。
+只需要使用标准的 **Python 及更高版本**。
举个例子,比如声明 `int` 类型:
@@ -410,7 +419,7 @@ item: Item

-
教程 - 用户指南 中有包含更多特性的更完整示例。
+
教程 - 用户指南 中有包含更多特性的更完整示例。
**剧透警告**: 教程 - 用户指南中的内容有:
@@ -431,31 +440,30 @@ item: Item
独立机构 TechEmpower 所作的基准测试结果显示,基于 Uvicorn 运行的 **FastAPI** 程序是
最快的 Python web 框架之一,仅次于 Starlette 和 Uvicorn 本身(FastAPI 内部使用了它们)。(*)
-想了解更多,请查阅
基准测试 章节。
+想了解更多,请查阅
基准测试 章节。
## 可选依赖
用于 Pydantic:
-*
ujson
- 更快的 JSON
「解析」。
-*
email_validator
- 用于 email 校验。
+*
email-validator
- 用于 email 校验。
用于 Starlette:
*
httpx
- 使用 `TestClient` 时安装。
*
jinja2
- 使用默认模板配置时安装。
-*
python-multipart
- 需要通过 `request.form()` 对表单进行
「解析」时安装。
+*
python-multipart
- 需要通过 `request.form()` 对表单进行
「解析」时安装。
*
itsdangerous
- 需要 `SessionMiddleware` 支持时安装。
*
pyyaml
- 使用 Starlette 提供的 `SchemaGenerator` 时安装(有 FastAPI 你可能并不需要它)。
*
graphene
- 需要 `GraphQLApp` 支持时安装。
-*
ujson
- 使用 `UJSONResponse` 时安装。
用于 FastAPI / Starlette:
*
uvicorn
- 用于加载和运行你的应用程序的服务器。
*
orjson
- 使用 `ORJSONResponse` 时安装。
+*
ujson
- 使用 `UJSONResponse` 时安装。
-你可以通过 `pip install fastapi[all]` 命令来安装以上所有依赖。
+你可以通过 `pip install "fastapi[all]"` 命令来安装以上所有依赖。
## 许可协议
diff --git a/docs/zh/docs/learn/index.md b/docs/zh/docs/learn/index.md
new file mode 100644
index 000000000..38696f6fe
--- /dev/null
+++ b/docs/zh/docs/learn/index.md
@@ -0,0 +1,5 @@
+# 学习
+
+以下是学习 **FastAPI** 的介绍部分和教程。
+
+您可以认为这是一本 **书**,一门 **课程**,是 **官方** 且推荐的学习FastAPI的方法。😎
diff --git a/docs/zh/docs/project-generation.md b/docs/zh/docs/project-generation.md
new file mode 100644
index 000000000..48eb990df
--- /dev/null
+++ b/docs/zh/docs/project-generation.md
@@ -0,0 +1,28 @@
+# FastAPI全栈模板
+
+模板通常带有特定的设置,而且被设计为灵活和可定制的。这允许您根据项目的需求修改和调整它们,使它们成为一个很好的起点。🏁
+
+您可以使用此模板开始,因为它包含了许多已经为您完成的初始设置、安全性、数据库和一些API端点。
+
+代码仓:
Full Stack FastAPI Template
+
+## FastAPI全栈模板 - 技术栈和特性
+
+- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) 用于Python后端API.
+ - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) 用于Python和SQL数据库的集成(ORM)。
+ - 🔍 [Pydantic](https://docs.pydantic.dev) FastAPI的依赖项之一,用于数据验证和配置管理。
+ - 💾 [PostgreSQL](https://www.postgresql.org) 作为SQL数据库。
+- 🚀 [React](https://react.dev) 用于前端。
+ - 💃 使用了TypeScript、hooks、[Vite](https://vitejs.dev)和其他一些现代化的前端技术栈。
+ - 🎨 [Chakra UI](https://chakra-ui.com) 用于前端组件。
+ - 🤖 一个自动化生成的前端客户端。
+ - 🧪 [Playwright](https://playwright.dev)用于端到端测试。
+ - 🦇 支持暗黑主题(Dark mode)。
+- 🐋 [Docker Compose](https://www.docker.com) 用于开发环境和生产环境。
+- 🔒 默认使用密码哈希来保证安全。
+- 🔑 JWT令牌用于权限验证。
+- 📫 使用邮箱来进行密码恢复。
+- ✅ 单元测试用了[Pytest](https://pytest.org).
+- 📞 [Traefik](https://traefik.io) 用于反向代理和负载均衡。
+- 🚢 部署指南(Docker Compose)包含了如何起一个Traefik前端代理来自动化HTTPS认证。
+- 🏭 CI(持续集成)和 CD(持续部署)基于GitHub Actions。
diff --git a/docs/zh/docs/python-types.md b/docs/zh/docs/python-types.md
index 6cdb4b588..ba767da87 100644
--- a/docs/zh/docs/python-types.md
+++ b/docs/zh/docs/python-types.md
@@ -12,16 +12,18 @@
但即使你不会用到 **FastAPI**,了解一下类型提示也会让你从中受益。
-!!! note
- 如果你已经精通 Python,并且了解关于类型提示的一切知识,直接跳到下一章节吧。
+/// note
+
+如果你已经精通 Python,并且了解关于类型提示的一切知识,直接跳到下一章节吧。
+
+///
## 动机
让我们从一个简单的例子开始:
-```Python
-{!../../../docs_src/python_types/tutorial001.py!}
-```
+{* ../../docs_src/python_types/tutorial001.py *}
+
运行这段程序将输出:
@@ -35,9 +37,8 @@ John Doe
* 通过 `title()` 将每个参数的第一个字母转换为大写形式。
* 中间用一个空格来
拼接它们。
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
-```
+{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+
### 修改示例
@@ -79,9 +80,8 @@ John Doe
这些就是"类型提示":
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
-```
+{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+
这和声明默认值是不同的,例如:
@@ -109,9 +109,8 @@ John Doe
下面是一个已经有类型提示的函数:
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
-```
+{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+
因为编辑器已经知道了这些变量的类型,所以不仅能对代码进行补全,还能检查其中的错误:
@@ -119,9 +118,8 @@ John Doe
现在你知道了必须先修复这个问题,通过 `str(age)` 把 `age` 转换成字符串:
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
-```
+{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+
## 声明类型
@@ -140,9 +138,8 @@ John Doe
* `bool`
* `bytes`
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
-```
+{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+
### 嵌套类型
@@ -158,9 +155,8 @@ John Doe
从 `typing` 模块导入 `List`(注意是大写的 `L`):
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial006.py!}
-```
+{* ../../docs_src/python_types/tutorial006.py hl[1] *}
+
同样以冒号(`:`)来声明这个变量。
@@ -168,9 +164,8 @@ John Doe
由于列表是带有"子类型"的类型,所以我们把子类型放在方括号中:
-```Python hl_lines="4"
-{!../../../docs_src/python_types/tutorial006.py!}
-```
+{* ../../docs_src/python_types/tutorial006.py hl[4] *}
+
这表示:"变量 `items` 是一个 `list`,并且这个列表里的每一个元素都是 `str`"。
@@ -188,9 +183,8 @@ John Doe
声明 `tuple` 和 `set` 的方法也是一样的:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial007.py!}
-```
+{* ../../docs_src/python_types/tutorial007.py hl[1,4] *}
+
这表示:
@@ -205,9 +199,8 @@ John Doe
第二个子类型声明 `dict` 的所有值:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial008.py!}
-```
+{* ../../docs_src/python_types/tutorial008.py hl[1,4] *}
+
这表示:
@@ -221,15 +214,13 @@ John Doe
假设你有一个名为 `Person` 的类,拥有 name 属性:
-```Python hl_lines="1-3"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+
接下来,你可以将一个变量声明为 `Person` 类型:
-```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+
然后,你将再次获得所有的编辑器支持:
@@ -237,7 +228,7 @@ John Doe
## Pydantic 模型
-
Pydantic 是一个用来用来执行数据校验的 Python 库。
+
Pydantic 是一个用来执行数据校验的 Python 库。
你可以将数据的"结构"声明为具有属性的类。
@@ -249,12 +240,14 @@ John Doe
下面的例子来自 Pydantic 官方文档:
-```Python
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py *}
+
-!!! info
- 想进一步了解
Pydantic,请阅读其文档.
+/// info
+
+想进一步了解
Pydantic,请阅读其文档.
+
+///
整个 **FastAPI** 建立在 Pydantic 的基础之上。
@@ -282,5 +275,8 @@ John Doe
最重要的是,通过使用标准的 Python 类型,只需要在一个地方声明(而不是添加更多的类、装饰器等),**FastAPI** 会为你完成很多的工作。
-!!! info
- 如果你已经阅读了所有教程,回过头来想了解有关类型的更多信息,
来自 `mypy` 的"速查表"是不错的资源。
+/// info
+
+如果你已经阅读了所有教程,回过头来想了解有关类型的更多信息,
来自 `mypy` 的"速查表"是不错的资源。
+
+///
diff --git a/docs/zh/docs/tutorial/background-tasks.md b/docs/zh/docs/tutorial/background-tasks.md
new file mode 100644
index 000000000..40e61add7
--- /dev/null
+++ b/docs/zh/docs/tutorial/background-tasks.md
@@ -0,0 +1,124 @@
+# 后台任务
+
+你可以定义在返回响应后运行的后台任务。
+
+这对需要在请求之后执行的操作很有用,但客户端不必在接收响应之前等待操作完成。
+
+包括这些例子:
+
+* 执行操作后发送的电子邮件通知:
+ * 由于连接到电子邮件服务器并发送电子邮件往往很“慢”(几秒钟),您可以立即返回响应并在后台发送电子邮件通知。
+* 处理数据:
+ * 例如,假设您收到的文件必须经过一个缓慢的过程,您可以返回一个"Accepted"(HTTP 202)响应并在后台处理它。
+
+## 使用 `BackgroundTasks`
+
+首先导入 `BackgroundTasks` 并在 *路径操作函数* 中使用类型声明 `BackgroundTasks` 定义一个参数:
+
+{* ../../docs_src/background_tasks/tutorial001.py hl[1, 13] *}
+
+**FastAPI** 会创建一个 `BackgroundTasks` 类型的对象并作为该参数传入。
+
+## 创建一个任务函数
+
+创建要作为后台任务运行的函数。
+
+它只是一个可以接收参数的标准函数。
+
+它可以是 `async def` 或普通的 `def` 函数,**FastAPI** 知道如何正确处理。
+
+在这种情况下,任务函数将写入一个文件(模拟发送电子邮件)。
+
+由于写操作不使用 `async` 和 `await`,我们用普通的 `def` 定义函数:
+
+{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+
+## 添加后台任务
+
+在你的 *路径操作函数* 里,用 `.add_task()` 方法将任务函数传到 *后台任务* 对象中:
+
+{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+
+`.add_task()` 接收以下参数:
+
+* 在后台运行的任务函数(`write_notification`)。
+* 应按顺序传递给任务函数的任意参数序列(`email`)。
+* 应传递给任务函数的任意关键字参数(`message="some notification"`)。
+
+## 依赖注入
+
+使用 `BackgroundTasks` 也适用于依赖注入系统,你可以在多个级别声明 `BackgroundTasks` 类型的参数:在 *路径操作函数* 里,在依赖中(可依赖),在子依赖中,等等。
+
+**FastAPI** 知道在每种情况下该做什么以及如何复用同一对象,因此所有后台任务被合并在一起并且随后在后台运行:
+
+//// tab | Python 3.10+
+
+{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13, 15, 22, 25] *}
+
+////
+
+//// tab | Python 3.9+
+
+{* ../../docs_src/background_tasks/tutorial002_an_py39.py hl[13, 15, 22, 25] *}
+
+////
+
+//// tab | Python 3.8+
+
+{* ../../docs_src/background_tasks/tutorial002_an.py hl[14, 16, 23, 26] *}
+
+////
+
+//// tab | Python 3.10+ 没Annotated
+
+/// tip
+
+尽可能选择使用 `Annotated` 的版本。
+
+///
+
+{* ../../docs_src/background_tasks/tutorial002_py310.py hl[11, 13, 20, 23] *}
+
+////
+
+//// tab | Python 3.8+ 没Annotated
+
+/// tip
+
+尽可能选择使用 `Annotated` 的版本。
+
+///
+
+{* ../../docs_src/background_tasks/tutorial002.py hl[13, 15, 22, 25] *}
+
+////
+
+该示例中,信息会在响应发出 *之后* 被写到 `log.txt` 文件。
+
+如果请求中有查询,它将在后台任务中写入日志。
+
+然后另一个在 *路径操作函数* 生成的后台任务会使用路径参数 `email` 写入一条信息。
+
+## 技术细节
+
+`BackgroundTasks` 类直接来自
`starlette.background`。
+
+它被直接导入/包含到FastAPI以便你可以从 `fastapi` 导入,并避免意外从 `starlette.background` 导入备用的 `BackgroundTask` (后面没有 `s`)。
+
+通过仅使用 `BackgroundTasks` (而不是 `BackgroundTask`),使得能将它作为 *路径操作函数* 的参数 ,并让**FastAPI**为您处理其余部分, 就像直接使用 `Request` 对象。
+
+在FastAPI中仍然可以单独使用 `BackgroundTask`,但您必须在代码中创建对象,并返回包含它的Starlette `Response`。
+
+更多细节查看
Starlette's official docs for Background Tasks.
+
+## 告诫
+
+如果您需要执行繁重的后台计算,并且不一定需要由同一进程运行(例如,您不需要共享内存、变量等),那么使用其他更大的工具(如
Celery)可能更好。
+
+它们往往需要更复杂的配置,即消息/作业队列管理器,如RabbitMQ或Redis,但它们允许您在多个进程中运行后台任务,甚至是在多个服务器中。
+
+但是,如果您需要从同一个**FastAPI**应用程序访问变量和对象,或者您需要执行小型后台任务(如发送电子邮件通知),您只需使用 `BackgroundTasks` 即可。
+
+## 回顾
+
+导入并使用 `BackgroundTasks` 通过 *路径操作函数* 中的参数和依赖项来添加后台任务。
diff --git a/docs/zh/docs/tutorial/bigger-applications.md b/docs/zh/docs/tutorial/bigger-applications.md
index 9f0134f68..554bc654f 100644
--- a/docs/zh/docs/tutorial/bigger-applications.md
+++ b/docs/zh/docs/tutorial/bigger-applications.md
@@ -4,8 +4,11 @@
**FastAPI** 提供了一个方便的工具,可以在保持所有灵活性的同时构建你的应用程序。
-!!! info
- 如果你来自 Flask,那这将相当于 Flask 的 Blueprints。
+/// info
+
+如果你来自 Flask,那这将相当于 Flask 的 Blueprints。
+
+///
## 一个文件结构示例
@@ -26,16 +29,19 @@
│ └── admin.py
```
-!!! tip
- 上面有几个 `__init__.py` 文件:每个目录或子目录中都有一个。
+/// tip
+
+上面有几个 `__init__.py` 文件:每个目录或子目录中都有一个。
- 这就是能将代码从一个文件导入到另一个文件的原因。
+这就是能将代码从一个文件导入到另一个文件的原因。
- 例如,在 `app/main.py` 中,你可以有如下一行:
+例如,在 `app/main.py` 中,你可以有如下一行:
+
+```
+from app.routers import items
+```
- ```
- from app.routers import items
- ```
+///
* `app` 目录包含了所有内容。并且它有一个空文件 `app/__init__.py`,因此它是一个「Python 包」(「Python 模块」的集合):`app`。
* 它包含一个 `app/main.py` 文件。由于它位于一个 Python 包(一个包含 `__init__.py` 文件的目录)中,因此它是该包的一个「模块」:`app.main`。
@@ -46,7 +52,7 @@
* 还有一个子目录 `app/internal/` 包含另一个 `__init__.py` 文件,因此它是又一个「Python 子包」:`app.internal`。
* `app/internal/admin.py` 是另一个子模块:`app.internal.admin`。
-

+

带有注释的同一文件结构:
@@ -79,8 +85,8 @@
你可以导入它并通过与 `FastAPI` 类相同的方式创建一个「实例」:
-```Python hl_lines="1 3"
-{!../../../docs_src/bigger_applications/app/routers/users.py!}
+```Python hl_lines="1 3" title="app/routers/users.py"
+{!../../docs_src/bigger_applications/app/routers/users.py!}
```
### 使用 `APIRouter` 的*路径操作*
@@ -89,8 +95,8 @@
使用方式与 `FastAPI` 类相同:
-```Python hl_lines="6 11 16"
-{!../../../docs_src/bigger_applications/app/routers/users.py!}
+```Python hl_lines="6 11 16" title="app/routers/users.py"
+{!../../docs_src/bigger_applications/app/routers/users.py!}
```
你可以将 `APIRouter` 视为一个「迷你 `FastAPI`」类。
@@ -99,8 +105,11 @@
所有相同的 `parameters`、`responses`、`dependencies`、`tags` 等等。
-!!! tip
- 在此示例中,该变量被命名为 `router`,但你可以根据你的想法自由命名。
+/// tip
+
+在此示例中,该变量被命名为 `router`,但你可以根据你的想法自由命名。
+
+///
我们将在主 `FastAPI` 应用中包含该 `APIRouter`,但首先,让我们来看看依赖项和另一个 `APIRouter`。
@@ -112,14 +121,17 @@
现在我们将使用一个简单的依赖项来读取一个自定义的 `X-Token` 请求首部:
-```Python hl_lines="1 4-6"
-{!../../../docs_src/bigger_applications/app/dependencies.py!}
+```Python hl_lines="1 4-6" title="app/dependencies.py"
+{!../../docs_src/bigger_applications/app/dependencies.py!}
```
-!!! tip
- 我们正在使用虚构的请求首部来简化此示例。
+/// tip
+
+我们正在使用虚构的请求首部来简化此示例。
+
+但在实际情况下,使用集成的[安全性实用工具](security/index.md){.internal-link target=_blank}会得到更好的效果。
- 但在实际情况下,使用集成的[安全性实用工具](./security/index.md){.internal-link target=_blank}会得到更好的效果。
+///
## 其他使用 `APIRouter` 的模块
@@ -143,8 +155,8 @@
因此,我们可以将其添加到 `APIRouter` 中,而不是将其添加到每个路径操作中。
-```Python hl_lines="5-10 16 21"
-{!../../../docs_src/bigger_applications/app/routers/items.py!}
+```Python hl_lines="5-10 16 21" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
```
由于每个*路径操作*的路径都必须以 `/` 开头,例如:
@@ -163,8 +175,11 @@ async def read_item(item_id: str):
我们可以添加一个 `dependencies` 列表,这些依赖项将被添加到路由器中的所有*路径操作*中,并将针对向它们发起的每个请求执行/解决。
-!!! tip
- 请注意,和[*路径操作装饰器*中的依赖项](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}很类似,没有值会被传递给你的*路径操作函数*。
+/// tip
+
+请注意,和[*路径操作装饰器*中的依赖项](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}很类似,没有值会被传递给你的*路径操作函数*。
+
+///
最终结果是项目相关的路径现在为:
@@ -181,11 +196,17 @@ async def read_item(item_id: str):
* 路由器的依赖项最先执行,然后是[装饰器中的 `dependencies`](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank},再然后是普通的参数依赖项。
* 你还可以添加[具有 `scopes` 的 `Security` 依赖项](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}。
-!!! tip
- 在 `APIRouter`中具有 `dependencies` 可以用来,例如,对一整组的*路径操作*要求身份认证。即使这些依赖项并没有分别添加到每个路径操作中。
+/// tip
+
+在 `APIRouter`中具有 `dependencies` 可以用来,例如,对一整组的*路径操作*要求身份认证。即使这些依赖项并没有分别添加到每个路径操作中。
+
+///
+
+/// check
-!!! check
- `prefix`、`tags`、`responses` 以及 `dependencies` 参数只是(和其他很多情况一样)**FastAPI** 的一个用于帮助你避免代码重复的功能。
+`prefix`、`tags`、`responses` 以及 `dependencies` 参数只是(和其他很多情况一样)**FastAPI** 的一个用于帮助你避免代码重复的功能。
+
+///
### 导入依赖项
@@ -195,14 +216,17 @@ async def read_item(item_id: str):
因此,我们通过 `..` 对依赖项使用了相对导入:
-```Python hl_lines="3"
-{!../../../docs_src/bigger_applications/app/routers/items.py!}
+```Python hl_lines="3" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
```
#### 相对导入如何工作
-!!! tip
- 如果你完全了解导入的工作原理,请从下面的下一部分继续。
+/// tip
+
+如果你完全了解导入的工作原理,请从下面的下一部分继续。
+
+///
一个单点 `.`,例如:
@@ -220,7 +244,7 @@ from .dependencies import get_token_header
请记住我们的程序/文件结构是怎样的:
-

+

---
@@ -265,14 +289,17 @@ from ...dependencies import get_token_header
但是我们仍然可以添加*更多*将会应用于特定的*路径操作*的 `tags`,以及一些特定于该*路径操作*的额外 `responses`:
-```Python hl_lines="30-31"
-{!../../../docs_src/bigger_applications/app/routers/items.py!}
+```Python hl_lines="30-31" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
```
-!!! tip
- 最后的这个路径操作将包含标签的组合:`["items","custom"]`。
+/// tip
+
+最后的这个路径操作将包含标签的组合:`["items","custom"]`。
- 并且在文档中也会有两个响应,一个用于 `404`,一个用于 `403`。
+并且在文档中也会有两个响应,一个用于 `404`,一个用于 `403`。
+
+///
## `FastAPI` 主体
@@ -290,16 +317,16 @@ from ...dependencies import get_token_header
我们甚至可以声明[全局依赖项](dependencies/global-dependencies.md){.internal-link target=_blank},它会和每个 `APIRouter` 的依赖项组合在一起:
-```Python hl_lines="1 3 7"
-{!../../../docs_src/bigger_applications/app/main.py!}
+```Python hl_lines="1 3 7" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
```
### 导入 `APIRouter`
现在,我们导入具有 `APIRouter` 的其他子模块:
-```Python hl_lines="5"
-{!../../../docs_src/bigger_applications/app/main.py!}
+```Python hl_lines="5" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
```
由于文件 `app/routers/users.py` 和 `app/routers/items.py` 是同一 Python 包 `app` 一个部分的子模块,因此我们可以使用单个点 ` .` 通过「相对导入」来导入它们。
@@ -328,20 +355,23 @@ from .routers import items, users
from app.routers import items, users
```
-!!! info
- 第一个版本是「相对导入」:
+/// info
+
+第一个版本是「相对导入」:
- ```Python
- from .routers import items, users
- ```
+```Python
+from .routers import items, users
+```
- 第二个版本是「绝对导入」:
+第二个版本是「绝对导入」:
+
+```Python
+from app.routers import items, users
+```
- ```Python
- from app.routers import items, users
- ```
+要了解有关 Python 包和模块的更多信息,请查阅
关于 Modules 的 Python 官方文档。
- 要了解有关 Python 包和模块的更多信息,请查阅
关于 Modules 的 Python 官方文档。
+///
### 避免名称冲突
@@ -360,38 +390,47 @@ from .routers.users import router
因此,为了能够在同一个文件中使用它们,我们直接导入子模块:
-```Python hl_lines="4"
-{!../../../docs_src/bigger_applications/app/main.py!}
+```Python hl_lines="5" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
```
### 包含 `users` 和 `items` 的 `APIRouter`
现在,让我们来包含来自 `users` 和 `items` 子模块的 `router`。
-```Python hl_lines="10-11"
-{!../../../docs_src/bigger_applications/app/main.py!}
+```Python hl_lines="10-11" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
```
-!!! info
- `users.router` 包含了 `app/routers/users.py` 文件中的 `APIRouter`。
+/// info
- `items.router` 包含了 `app/routers/items.py` 文件中的 `APIRouter`。
+`users.router` 包含了 `app/routers/users.py` 文件中的 `APIRouter`。
+
+`items.router` 包含了 `app/routers/items.py` 文件中的 `APIRouter`。
+
+///
使用 `app.include_router()`,我们可以将每个 `APIRouter` 添加到主 `FastAPI` 应用程序中。
它将包含来自该路由器的所有路由作为其一部分。
-!!! note "技术细节"
- 实际上,它将在内部为声明在 `APIRouter` 中的每个*路径操作*创建一个*路径操作*。
+/// note | 技术细节
+
+实际上,它将在内部为声明在 `APIRouter` 中的每个*路径操作*创建一个*路径操作*。
+
+所以,在幕后,它实际上会像所有的东西都是同一个应用程序一样工作。
+
+///
- 所以,在幕后,它实际上会像所有的东西都是同一个应用程序一样工作。
+/// check
-!!! check
- 包含路由器时,你不必担心性能问题。
+包含路由器时,你不必担心性能问题。
- 这将花费几微秒时间,并且只会在启动时发生。
+这将花费几微秒时间,并且只会在启动时发生。
- 因此,它不会影响性能。⚡
+因此,它不会影响性能。⚡
+
+///
### 包含一个有自定义 `prefix`、`tags`、`responses` 和 `dependencies` 的 `APIRouter`
@@ -401,16 +440,16 @@ from .routers.users import router
对于此示例,它将非常简单。但是假设由于它是与组织中的其他项目所共享的,因此我们无法对其进行修改,以及直接在 `APIRouter` 中添加 `prefix`、`dependencies`、`tags` 等:
-```Python hl_lines="3"
-{!../../../docs_src/bigger_applications/app/internal/admin.py!}
+```Python hl_lines="3" title="app/internal/admin.py"
+{!../../docs_src/bigger_applications/app/internal/admin.py!}
```
但是我们仍然希望在包含 `APIRouter` 时设置一个自定义的 `prefix`,以便其所有*路径操作*以 `/admin` 开头,我们希望使用本项目已经有的 `dependencies` 保护它,并且我们希望它包含自定义的 `tags` 和 `responses`。
我们可以通过将这些参数传递给 `app.include_router()` 来完成所有的声明,而不必修改原始的 `APIRouter`:
-```Python hl_lines="14-17"
-{!../../../docs_src/bigger_applications/app/main.py!}
+```Python hl_lines="14-17" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
```
这样,原始的 `APIRouter` 将保持不变,因此我们仍然可以与组织中的其他项目共享相同的 `app/internal/admin.py` 文件。
@@ -432,22 +471,25 @@ from .routers.users import router
这里我们这样做了...只是为了表明我们可以做到🤷:
-```Python hl_lines="21-23"
-{!../../../docs_src/bigger_applications/app/main.py!}
+```Python hl_lines="21-23" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
```
它将与通过 `app.include_router()` 添加的所有其他*路径操作*一起正常运行。
-!!! info "特别的技术细节"
- **注意**:这是一个非常技术性的细节,你也许可以**直接跳过**。
+/// info | 特别的技术细节
+
+**注意**:这是一个非常技术性的细节,你也许可以**直接跳过**。
+
+---
- ---
+`APIRouter` 没有被「挂载」,它们与应用程序的其余部分没有隔离。
- `APIRouter` 没有被「挂载」,它们与应用程序的其余部分没有隔离。
+这是因为我们想要在 OpenAPI 模式和用户界面中包含它们的*路径操作*。
- 这是因为我们想要在 OpenAPI 模式和用户界面中包含它们的*路径操作*。
+由于我们不能仅仅隔离它们并独立于其余部分来「挂载」它们,因此*路径操作*是被「克隆的」(重新创建),而不是直接包含。
- 由于我们不能仅仅隔离它们并独立于其余部分来「挂载」它们,因此*路径操作*是被「克隆的」(重新创建),而不是直接包含。
+///
## 查看自动化的 API 文档
diff --git a/docs/zh/docs/tutorial/body-fields.md b/docs/zh/docs/tutorial/body-fields.md
index 053cae71c..4cff58bfc 100644
--- a/docs/zh/docs/tutorial/body-fields.md
+++ b/docs/zh/docs/tutorial/body-fields.md
@@ -1,48 +1,53 @@
# 请求体 - 字段
-与使用 `Query`、`Path` 和 `Body` 在*路径操作函数*中声明额外的校验和元数据的方式相同,你可以使用 Pydantic 的 `Field` 在 Pydantic 模型内部声明校验和元数据。
+与在*路径操作函数*中使用 `Query`、`Path` 、`Body` 声明校验与元数据的方式一样,可以使用 Pydantic 的 `Field` 在 Pydantic 模型内部声明校验和元数据。
## 导入 `Field`
-首先,你必须导入它:
+首先,从 Pydantic 中导入 `Field`:
-```Python hl_lines="2"
-{!../../../docs_src/body_fields/tutorial001.py!}
-```
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
-!!! warning
- 注意,`Field` 是直接从 `pydantic` 导入的,而不是像其他的(`Query`,`Path`,`Body` 等)都从 `fastapi` 导入。
+/// warning | 警告
+
+注意,与从 `fastapi` 导入 `Query`,`Path`、`Body` 不同,要直接从 `pydantic` 导入 `Field` 。
+
+///
## 声明模型属性
-然后,你可以对模型属性使用 `Field`:
+然后,使用 `Field` 定义模型的属性:
+
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[11:14] *}
+
+`Field` 的工作方式和 `Query`、`Path`、`Body` 相同,参数也相同。
+
+/// note | 技术细节
+
+实际上,`Query`、`Path` 都是 `Params` 的子类,而 `Params` 类又是 Pydantic 中 `FieldInfo` 的子类。
-```Python hl_lines="9-10"
-{!../../../docs_src/body_fields/tutorial001.py!}
-```
+Pydantic 的 `Field` 返回也是 `FieldInfo` 的类实例。
-`Field` 的工作方式和 `Query`、`Path` 和 `Body` 相同,包括它们的参数等等也完全相同。
+`Body` 直接返回的也是 `FieldInfo` 的子类的对象。后文还会介绍一些 `Body` 的子类。
-!!! note "技术细节"
- 实际上,`Query`、`Path` 和其他你将在之后看到的类,创建的是由一个共同的 `Params` 类派生的子类的对象,该共同类本身又是 Pydantic 的 `FieldInfo` 类的子类。
+注意,从 `fastapi` 导入的 `Query`、`Path` 等对象实际上都是返回特殊类的函数。
- Pydantic 的 `Field` 也会返回一个 `FieldInfo` 的实例。
+///
- `Body` 也直接返回 `FieldInfo` 的一个子类的对象。还有其他一些你之后会看到的类是 `Body` 类的子类。
+/// tip | 提示
- 请记住当你从 `fastapi` 导入 `Query`、`Path` 等对象时,他们实际上是返回特殊类的函数。
+注意,模型属性的类型、默认值及 `Field` 的代码结构与*路径操作函数*的参数相同,只不过是用 `Field` 替换了`Path`、`Query`、`Body`。
-!!! tip
- 注意每个模型属性如何使用类型、默认值和 `Field` 在代码结构上和*路径操作函数*的参数是相同的,区别是用 `Field` 替换`Path`、`Query` 和 `Body`。
+///
-## 添加额外信息
+## 添加更多信息
-你可以在 `Field`、`Query`、`Body` 中声明额外的信息。这些信息将包含在生成的 JSON Schema 中。
+`Field`、`Query`、`Body` 等对象里可以声明更多信息,并且 JSON Schema 中也会集成这些信息。
-你将在文档的后面部分学习声明示例时,了解到更多有关添加额外信息的知识。
+*声明示例*一章中将详细介绍添加更多信息的知识。
-## 总结
+## 小结
-你可以使用 Pydantic 的 `Field` 为模型属性声明额外的校验和元数据。
+Pydantic 的 `Field` 可以为模型属性声明更多校验和元数据。
-你还可以使用额外的关键字参数来传递额外的 JSON Schema 元数据。
+传递 JSON Schema 元数据还可以使用更多关键字参数。
diff --git a/docs/zh/docs/tutorial/body-multiple-params.md b/docs/zh/docs/tutorial/body-multiple-params.md
index 34fa5b638..b4356fdcb 100644
--- a/docs/zh/docs/tutorial/body-multiple-params.md
+++ b/docs/zh/docs/tutorial/body-multiple-params.md
@@ -8,12 +8,13 @@
你还可以通过将默认值设置为 `None` 来将请求体参数声明为可选参数:
-```Python hl_lines="17-19"
-{!../../../docs_src/body_multiple_params/tutorial001.py!}
-```
+{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
+
+/// note
+
+请注意,在这种情况下,将从请求体获取的 `item` 是可选的。因为它的默认值为 `None`。
-!!! note
- 请注意,在这种情况下,将从请求体获取的 `item` 是可选的。因为它的默认值为 `None`。
+///
## 多个请求体参数
@@ -30,9 +31,7 @@
但是你也可以声明多个请求体参数,例如 `item` 和 `user`:
-```Python hl_lines="20"
-{!../../../docs_src/body_multiple_params/tutorial002.py!}
-```
+{* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
在这种情况下,**FastAPI** 将注意到该函数中有多个请求体参数(两个 Pydantic 模型参数)。
@@ -53,9 +52,11 @@
}
```
-!!! note
- 请注意,即使 `item` 的声明方式与之前相同,但现在它被期望通过 `item` 键内嵌在请求体中。
+/// note
+
+请注意,即使 `item` 的声明方式与之前相同,但现在它被期望通过 `item` 键内嵌在请求体中。
+///
**FastAPI** 将自动对请求中的数据进行转换,因此 `item` 参数将接收指定的内容,`user` 参数也是如此。
@@ -72,9 +73,7 @@
但是你可以使用 `Body` 指示 **FastAPI** 将其作为请求体的另一个键进行处理。
-```Python hl_lines="22"
-{!../../../docs_src/body_multiple_params/tutorial003.py!}
-```
+{* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
在这种情况下,**FastAPI** 将期望像这样的请求体:
@@ -109,13 +108,13 @@ q: str = None
比如:
-```Python hl_lines="25"
-{!../../../docs_src/body_multiple_params/tutorial004.py!}
-```
+{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[27] *}
-!!! info
- `Body` 同样具有与 `Query`、`Path` 以及其他后面将看到的类完全相同的额外校验和元数据参数。
+/// info
+`Body` 同样具有与 `Query`、`Path` 以及其他后面将看到的类完全相同的额外校验和元数据参数。
+
+///
## 嵌入单个请求体参数
@@ -131,9 +130,7 @@ item: Item = Body(embed=True)
比如:
-```Python hl_lines="15"
-{!../../../docs_src/body_multiple_params/tutorial005.py!}
-```
+{* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
在这种情况下,**FastAPI** 将期望像这样的请求体:
diff --git a/docs/zh/docs/tutorial/body-nested-models.md b/docs/zh/docs/tutorial/body-nested-models.md
index 7649ee6fe..df96d96b4 100644
--- a/docs/zh/docs/tutorial/body-nested-models.md
+++ b/docs/zh/docs/tutorial/body-nested-models.md
@@ -6,9 +6,7 @@
你可以将一个属性定义为拥有子元素的类型。例如 Python `list`:
-```Python hl_lines="12"
-{!../../../docs_src/body_nested_models/tutorial001.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
这将使 `tags` 成为一个由元素组成的列表。不过它没有声明每个元素的类型。
@@ -20,9 +18,7 @@
首先,从 Python 的标准库 `typing` 模块中导入 `List`:
-```Python hl_lines="1"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
### 声明具有子类型的 List
@@ -43,9 +39,7 @@ my_list: List[str]
因此,在我们的示例中,我们可以将 `tags` 明确地指定为一个「字符串列表」:
-```Python hl_lines="14"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
## Set 类型
@@ -55,9 +49,7 @@ Python 具有一种特殊的数据类型来保存一组唯一的元素,即 `se
然后我们可以导入 `Set` 并将 `tag` 声明为一个由 `str` 组成的 `set`:
-```Python hl_lines="1 14"
-{!../../../docs_src/body_nested_models/tutorial003.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
这样,即使你收到带有重复数据的请求,这些数据也会被转换为一组唯一项。
@@ -79,17 +71,13 @@ Pydantic 模型的每个属性都具有类型。
例如,我们可以定义一个 `Image` 模型:
-```Python hl_lines="9 10 11"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
### 将子模型用作类型
然后我们可以将其用作一个属性的类型:
-```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
这意味着 **FastAPI** 将期望类似于以下内容的请求体:
@@ -118,13 +106,11 @@ Pydantic 模型的每个属性都具有类型。
除了普通的单一值类型(如 `str`、`int`、`float` 等)外,你还可以使用从 `str` 继承的更复杂的单一值类型。
-要了解所有的可用选项,请查看关于
来自 Pydantic 的外部类型 的文档。你将在下一章节中看到一些示例。
+要了解所有的可用选项,请查看关于
来自 Pydantic 的外部类型 的文档。你将在下一章节中看到一些示例。
例如,在 `Image` 模型中我们有一个 `url` 字段,我们可以把它声明为 Pydantic 的 `HttpUrl`,而不是 `str`:
-```Python hl_lines="4 10"
-{!../../../docs_src/body_nested_models/tutorial005.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
该字符串将被检查是否为有效的 URL,并在 JSON Schema / OpenAPI 文档中进行记录。
@@ -132,9 +118,7 @@ Pydantic 模型的每个属性都具有类型。
你还可以将 Pydantic 模型用作 `list`、`set` 等的子类型:
-```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial006.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
这将期望(转换,校验,记录文档等)下面这样的 JSON 请求体:
@@ -162,19 +146,23 @@ Pydantic 模型的每个属性都具有类型。
}
```
-!!! info
- 请注意 `images` 键现在具有一组 image 对象是如何发生的。
+/// info
+
+请注意 `images` 键现在具有一组 image 对象是如何发生的。
+
+///
## 深度嵌套模型
你可以定义任意深度的嵌套模型:
-```Python hl_lines="9 14 20 23 27"
-{!../../../docs_src/body_nested_models/tutorial007.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
+
+/// info
+
+请注意 `Offer` 拥有一组 `Item` 而反过来 `Item` 又是一个可选的 `Image` 列表是如何发生的。
-!!! info
- 请注意 `Offer` 拥有一组 `Item` 而反过来 `Item` 又是一个可选的 `Image` 列表是如何发生的。
+///
## 纯列表请求体
@@ -186,9 +174,7 @@ images: List[Image]
例如:
-```Python hl_lines="15"
-{!../../../docs_src/body_nested_models/tutorial008.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
## 无处不在的编辑器支持
@@ -218,18 +204,19 @@ images: List[Image]
在下面的例子中,你将接受任意键为 `int` 类型并且值为 `float` 类型的 `dict`:
-```Python hl_lines="15"
-{!../../../docs_src/body_nested_models/tutorial009.py!}
-```
+{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
+
+/// tip
+
+请记住 JSON 仅支持将 `str` 作为键。
-!!! tip
- 请记住 JSON 仅支持将 `str` 作为键。
+但是 Pydantic 具有自动转换数据的功能。
- 但是 Pydantic 具有自动转换数据的功能。
+这意味着,即使你的 API 客户端只能将字符串作为键发送,只要这些字符串内容仅包含整数,Pydantic 就会对其进行转换并校验。
- 这意味着,即使你的 API 客户端只能将字符串作为键发送,只要这些字符串内容仅包含整数,Pydantic 就会对其进行转换并校验。
+然后你接收的名为 `weights` 的 `dict` 实际上将具有 `int` 类型的键和 `float` 类型的值。
- 然后你接收的名为 `weights` 的 `dict` 实际上将具有 `int` 类型的键和 `float` 类型的值。
+///
## 总结
diff --git a/docs/zh/docs/tutorial/body-updates.md b/docs/zh/docs/tutorial/body-updates.md
index 43f20f8fc..87f88f255 100644
--- a/docs/zh/docs/tutorial/body-updates.md
+++ b/docs/zh/docs/tutorial/body-updates.md
@@ -6,9 +6,7 @@
把输入数据转换为以 JSON 格式存储的数据(比如,使用 NoSQL 数据库时),可以使用 `jsonable_encoder`。例如,把 `datetime` 转换为 `str`。
-```Python hl_lines="30-35"
-{!../../../docs_src/body_updates/tutorial001.py!}
-```
+{* ../../docs_src/body_updates/tutorial001.py hl[30:35] *}
`PUT` 用于接收替换现有数据的数据。
@@ -34,15 +32,17 @@
即,只发送要更新的数据,其余数据保持不变。
-!!! Note "笔记"
+/// note | 笔记
+
+`PATCH` 没有 `PUT` 知名,也怎么不常用。
- `PATCH` 没有 `PUT` 知名,也怎么不常用。
+很多人甚至只用 `PUT` 实现部分更新。
- 很多人甚至只用 `PUT` 实现部分更新。
+**FastAPI** 对此没有任何限制,可以**随意**互换使用这两种操作。
- **FastAPI** 对此没有任何限制,可以**随意**互换使用这两种操作。
+但本指南也会分别介绍这两种操作各自的用途。
- 但本指南也会分别介绍这两种操作各自的用途。
+///
### 使用 Pydantic 的 `exclude_unset` 参数
@@ -54,9 +54,7 @@
然后再用它生成一个只含已设置(在请求中所发送)数据,且省略了默认值的 `dict`:
-```Python hl_lines="34"
-{!../../../docs_src/body_updates/tutorial002.py!}
-```
+{* ../../docs_src/body_updates/tutorial002.py hl[34] *}
### 使用 Pydantic 的 `update` 参数
@@ -64,9 +62,7 @@
例如,`stored_item_model.copy(update=update_data)`:
-```Python hl_lines="35"
-{!../../../docs_src/body_updates/tutorial002.py!}
-```
+{* ../../docs_src/body_updates/tutorial002.py hl[35] *}
### 更新部分数据小结
@@ -83,19 +79,21 @@
* 把数据保存至数据库;
* 返回更新后的模型。
-```Python hl_lines="30-37"
-{!../../../docs_src/body_updates/tutorial002.py!}
-```
+{* ../../docs_src/body_updates/tutorial002.py hl[30:37] *}
+
+/// tip | 提示
+
+实际上,HTTP `PUT` 也可以完成相同的操作。
+但本节以 `PATCH` 为例的原因是,该操作就是为了这种用例创建的。
-!!! tip "提示"
+///
- 实际上,HTTP `PUT` 也可以完成相同的操作。
- 但本节以 `PATCH` 为例的原因是,该操作就是为了这种用例创建的。
+/// note | 笔记
-!!! note "笔记"
+注意,输入模型仍需验证。
- 注意,输入模型仍需验证。
+因此,如果希望接收的部分更新数据可以省略其他所有属性,则要把模型中所有的属性标记为可选(使用默认值或 `None`)。
- 因此,如果希望接收的部分更新数据可以省略其他所有属性,则要把模型中所有的属性标记为可选(使用默认值或 `None`)。
+为了区分用于**更新**所有可选值的模型与用于**创建**包含必选值的模型,请参照[更多模型](extra-models.md){.internal-link target=_blank} 一节中的思路。
- 为了区分用于**更新**所有可选值的模型与用于**创建**包含必选值的模型,请参照[更多模型](extra-models.md){.internal-link target=_blank} 一节中的思路。
+///
diff --git a/docs/zh/docs/tutorial/body.md b/docs/zh/docs/tutorial/body.md
index f80ab5bf5..3820fc747 100644
--- a/docs/zh/docs/tutorial/body.md
+++ b/docs/zh/docs/tutorial/body.md
@@ -1,39 +1,40 @@
# 请求体
-当你需要将数据从客户端(例如浏览器)发送给 API 时,你将其作为「请求体」发送。
+FastAPI 使用**请求体**从客户端(例如浏览器)向 API 发送数据。
-**请求**体是客户端发送给 API 的数据。**响应**体是 API 发送给客户端的数据。
+**请求体**是客户端发送给 API 的数据。**响应体**是 API 发送给客户端的数据。
-你的 API 几乎总是要发送**响应**体。但是客户端并不总是需要发送**请求**体。
+API 基本上肯定要发送**响应体**,但是客户端不一定发送**请求体**。
-我们使用
Pydantic 模型来声明**请求**体,并能够获得它们所具有的所有能力和优点。
+使用
Pydantic 模型声明**请求体**,能充分利用它的功能和优点。
-!!! info
- 你不能使用 `GET` 操作(HTTP 方法)发送请求体。
+/// info | 说明
- 要发送数据,你必须使用下列方法之一:`POST`(较常见)、`PUT`、`DELETE` 或 `PATCH`。
+发送数据使用 `POST`(最常用)、`PUT`、`DELETE`、`PATCH` 等操作。
+
+规范中没有定义使用 `GET` 发送请求体的操作,但不管怎样,FastAPI 也支持这种方式,只不过仅用于非常复杂或极端的用例。
+
+我们不建议使用 `GET`,因此,在 Swagger UI 交互文档中不会显示有关 `GET` 的内容,而且代理协议也不一定支持 `GET`。
+
+///
## 导入 Pydantic 的 `BaseModel`
-首先,你需要从 `pydantic` 中导入 `BaseModel`:
+从 `pydantic` 中导入 `BaseModel`:
-```Python hl_lines="2"
-{!../../../docs_src/body/tutorial001.py!}
-```
+{* ../../docs_src/body/tutorial001_py310.py hl[2] *}
## 创建数据模型
-然后,将你的数据模型声明为继承自 `BaseModel` 的类。
+把数据模型声明为继承 `BaseModel` 的类。
-使用标准的 Python 类型来声明所有属性:
+使用 Python 标准类型声明所有属性:
-```Python hl_lines="5-9"
-{!../../../docs_src/body/tutorial001.py!}
-```
+{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
-和声明查询参数时一样,当一个模型属性具有默认值时,它不是必需的。否则它是一个必需属性。将默认值设为 `None` 可使其成为可选属性。
+与声明查询参数一样,包含默认值的模型属性是可选的,否则就是必选的。默认值为 `None` 的模型属性也是可选的。
-例如,上面的模型声明了一个这样的 JSON「`object`」(或 Python `dict`):
+例如,上述模型声明如下 JSON **对象**(即 Python **字典**):
```JSON
{
@@ -44,7 +45,7 @@
}
```
-...由于 `description` 和 `tax` 是可选的(它们的默认值为 `None`),下面的 JSON「`object`」也将是有效的:
+……由于 `description` 和 `tax` 是可选的(默认值为 `None`),下面的 JSON **对象**也有效:
```JSON
{
@@ -53,95 +54,109 @@
}
```
-## 声明为参数
+## 声明请求体参数
-使用与声明路径和查询参数的相同方式声明请求体,即可将其添加到「路径操作」中:
+使用与声明路径和查询参数相同的方式声明请求体,把请求体添加至*路径操作*:
-```Python hl_lines="16"
-{!../../../docs_src/body/tutorial001.py!}
-```
+{* ../../docs_src/body/tutorial001_py310.py hl[16] *}
-...并且将它的类型声明为你创建的 `Item` 模型。
+……此处,请求体参数的类型为 `Item` 模型。
-## 结果
+## 结论
-仅仅使用了 Python 类型声明,**FastAPI** 将会:
+仅使用 Python 类型声明,**FastAPI** 就可以:
-* 将请求体作为 JSON 读取。
-* 转换为相应的类型(在需要时)。
-* 校验数据。
- * 如果数据无效,将返回一条清晰易读的错误信息,指出不正确数据的确切位置和内容。
-* 将接收的数据赋值到参数 `item` 中。
- * 由于你已经在函数中将它声明为 `Item` 类型,你还将获得对于所有属性及其类型的一切编辑器支持(代码补全等)。
-* 为你的模型生成
JSON 模式 定义,你还可以在其他任何对你的项目有意义的地方使用它们。
-* 这些模式将成为生成的 OpenAPI 模式的一部分,并且被自动化文档
UI 所使用。
+* 以 JSON 形式读取请求体
+* (在必要时)把请求体转换为对应的类型
+* 校验数据:
+ * 数据无效时返回错误信息,并指出错误数据的确切位置和内容
+* 把接收的数据赋值给参数 `item`
+ * 把函数中请求体参数的类型声明为 `Item`,还能获得代码补全等编辑器支持
+* 为模型生成
JSON Schema,在项目中所需的位置使用
+* 这些概图是 OpenAPI 概图的部件,用于 API 文档
UI
-## 自动化文档
+## API 文档
-你所定义模型的 JSON 模式将成为生成的 OpenAPI 模式的一部分,并且在交互式 API 文档中展示:
+Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文档中显示:
-

+

-而且还将在每一个需要它们的*路径操作*的 API 文档中使用:
+而且,还会用于 API 文档中使用了概图的*路径操作*:
-

+

## 编辑器支持
-在你的编辑器中,你会在函数内部的任意地方得到类型提示和代码补全(如果你接收的是一个 `dict` 而不是 Pydantic 模型,则不会发生这种情况):
+在编辑器中,函数内部均可使用类型提示、代码补全(如果接收的不是 Pydantic 模型,而是**字典**,就没有这样的支持):
+
+

+
+还支持检查错误的类型操作:
+
+

-

+这并非偶然,整个 **FastAPI** 框架都是围绕这种思路精心设计的。
-你还会获得对不正确的类型操作的错误检查:
+并且,在 FastAPI 的设计阶段,我们就已经进行了全面测试,以确保 FastAPI 可以获得所有编辑器的支持。
-

+我们还改进了 Pydantic,让它也支持这些功能。
-这并非偶然,整个框架都是围绕该设计而构建。
+虽然上面的截图取自
Visual Studio Code。
-并且在进行任何实现之前,已经在设计阶段经过了全面测试,以确保它可以在所有的编辑器中生效。
+但
PyCharm 和大多数 Python 编辑器也支持同样的功能:
-Pydantic 本身甚至也进行了一些更改以支持此功能。
+

-上面的截图取自
Visual Studio Code。
+/// tip | 提示
-但是在
PyCharm 和绝大多数其他 Python 编辑器中你也会获得同样的编辑器支持:
+使用
PyCharm 编辑器时,推荐安装
Pydantic PyCharm 插件。
-

+该插件用于完善 PyCharm 对 Pydantic 模型的支持,优化的功能如下:
+
+* 自动补全
+* 类型检查
+* 代码重构
+* 查找
+* 代码审查
+
+///
## 使用模型
-在函数内部,你可以直接访问模型对象的所有属性:
+在*路径操作*函数内部直接访问模型对象的属性:
-```Python hl_lines="19"
-{!../../../docs_src/body/tutorial002.py!}
-```
+{* ../../docs_src/body/tutorial002_py310.py hl[19] *}
## 请求体 + 路径参数
-你可以同时声明路径参数和请求体。
+**FastAPI** 支持同时声明路径参数和请求体。
-**FastAPI** 将识别出与路径参数匹配的函数参数应**从路径中获取**,而声明为 Pydantic 模型的函数参数应**从请求体中获取**。
+**FastAPI** 能识别与**路径参数**匹配的函数参数,还能识别从**请求体**中获取的类型为 Pydantic 模型的函数参数。
-```Python hl_lines="15-16"
-{!../../../docs_src/body/tutorial003.py!}
-```
+{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
## 请求体 + 路径参数 + 查询参数
-你还可以同时声明**请求体**、**路径参数**和**查询参数**。
+**FastAPI** 支持同时声明**请求体**、**路径参数**和**查询参数**。
-**FastAPI** 会识别它们中的每一个,并从正确的位置获取数据。
+**FastAPI** 能够正确识别这三种参数,并从正确的位置获取数据。
-```Python hl_lines="16"
-{!../../../docs_src/body/tutorial004.py!}
-```
+{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
+
+函数参数按如下规则进行识别:
+
+- **路径**中声明了相同参数的参数,是路径参数
+- 类型是(`int`、`float`、`str`、`bool` 等)**单类型**的参数,是**查询**参数
+- 类型是 **Pydantic 模型**的参数,是**请求体**
+
+/// note | 笔记
+
+因为默认值是 `None`, FastAPI 会把 `q` 当作可选参数。
-函数参数将依次按如下规则进行识别:
+FastAPI 不使用 `Optional[str]` 中的 `Optional`, 但 `Optional` 可以让编辑器提供更好的支持,并检测错误。
-* 如果在**路径**中也声明了该参数,它将被用作路径参数。
-* 如果参数属于**单一类型**(比如 `int`、`float`、`str`、`bool` 等)它将被解释为**查询**参数。
-* 如果参数的类型被声明为一个 **Pydantic 模型**,它将被解释为**请求体**。
+///
## 不使用 Pydantic
-如果你不想使用 Pydantic 模型,你还可以使用 **Body** 参数。请参阅文档 [请求体 - 多个参数:请求体中的单一值](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}。
+即便不使用 Pydantic 模型也能使用 **Body** 参数。详见[请求体 - 多参数:请求体中的单值](body-multiple-params.md#_2){.internal-link target=\_blank}。
diff --git a/docs/zh/docs/tutorial/cookie-param-models.md b/docs/zh/docs/tutorial/cookie-param-models.md
new file mode 100644
index 000000000..6a7b09e25
--- /dev/null
+++ b/docs/zh/docs/tutorial/cookie-param-models.md
@@ -0,0 +1,76 @@
+# Cookie 参数模型
+
+如果您有一组相关的 **cookie**,您可以创建一个 **Pydantic 模型**来声明它们。🍪
+
+这将允许您在**多个地方**能够**重用模型**,并且可以一次性声明所有参数的验证方式和元数据。😎
+
+/// note
+
+自 FastAPI 版本 `0.115.0` 起支持此功能。🤓
+
+///
+
+/// tip
+
+此技术同样适用于 `Query` 、 `Cookie` 和 `Header` 。😎
+
+///
+
+## 带有 Pydantic 模型的 Cookie
+
+在 **Pydantic** 模型中声明所需的 **cookie** 参数,然后将参数声明为 `Cookie` :
+
+{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
+
+**FastAPI** 将从请求中接收到的 **cookie** 中**提取**出**每个字段**的数据,并提供您定义的 Pydantic 模型。
+
+## 查看文档
+
+您可以在文档 UI 的 `/docs` 中查看定义的 cookie:
+
+
+

+
+
+/// info
+
+请记住,由于**浏览器**以特殊方式**处理 cookie**,并在后台进行操作,因此它们**不会**轻易允许 **JavaScript** 访问这些 cookie。
+
+如果您访问 `/docs` 的 **API 文档 UI**,您将能够查看您*路径操作*的 cookie **文档**。
+
+但是即使您**填写数据**并点击“执行”,由于文档界面使用 **JavaScript**,cookie 将不会被发送。而您会看到一条**错误**消息,就好像您没有输入任何值一样。
+
+///
+
+## 禁止额外的 Cookie
+
+在某些特殊使用情况下(可能并不常见),您可能希望**限制**您想要接收的 cookie。
+
+您的 API 现在可以控制自己的
cookie 同意。🤪🍪
+
+您可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段:
+
+{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
+
+如果客户尝试发送一些**额外的 cookie**,他们将收到**错误**响应。
+
+可怜的 cookie 通知条,费尽心思为了获得您的同意,却被
API 拒绝了。🍪
+
+例如,如果客户端尝试发送一个值为 `good-list-please` 的 `santa_tracker` cookie,客户端将收到一个**错误**响应,告知他们 `santa_tracker`
cookie 是不允许的:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["cookie", "santa_tracker"],
+ "msg": "Extra inputs are not permitted",
+ "input": "good-list-please",
+ }
+ ]
+}
+```
+
+## 总结
+
+您可以使用 **Pydantic 模型**在 **FastAPI** 中声明
**cookie**。😎
diff --git a/docs/zh/docs/tutorial/cookie-params.md b/docs/zh/docs/tutorial/cookie-params.md
index d67daf0f9..495600814 100644
--- a/docs/zh/docs/tutorial/cookie-params.md
+++ b/docs/zh/docs/tutorial/cookie-params.md
@@ -1,34 +1,36 @@
# Cookie 参数
-你可以像定义 `Query` 参数和 `Path` 参数一样来定义 `Cookie` 参数。
+ 定义 `Cookie` 参数与定义 `Query` 和 `Path` 参数一样。
## 导入 `Cookie`
-首先,导入 `Cookie`:
+首先,导入 `Cookie`:
-```Python hl_lines="3"
-{!../../../docs_src/cookie_params/tutorial001.py!}
-```
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
## 声明 `Cookie` 参数
-声明 `Cookie` 参数的结构与声明 `Query` 参数和 `Path` 参数时相同。
+声明 `Cookie` 参数的方式与声明 `Query` 和 `Path` 参数相同。
-第一个值是参数的默认值,同时也可以传递所有验证参数或注释参数,来校验参数:
+第一个值是默认值,还可以传递所有验证参数或注释参数:
-```Python hl_lines="9"
-{!../../../docs_src/cookie_params/tutorial001.py!}
-```
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
-!!! note "技术细节"
- `Cookie` 、`Path` 、`Query`是兄弟类,它们都继承自公共的 `Param` 类
+/// note | 技术细节
- 但请记住,当你从 `fastapi` 导入的 `Query`、`Path`、`Cookie` 或其他参数声明函数,这些实际上是返回特殊类的函数。
+`Cookie` 、`Path` 、`Query` 是**兄弟类**,都继承自共用的 `Param` 类。
-!!! info
- 你需要使用 `Cookie` 来声明 cookie 参数,否则参数将会被解释为查询参数。
+注意,从 `fastapi` 导入的 `Query`、`Path`、`Cookie` 等对象,实际上是返回特殊类的函数。
-## 总结
+///
-使用 `Cookie` 声明 cookie 参数,使用方式与 `Query` 和 `Path` 类似。
+/// info | 说明
+
+必须使用 `Cookie` 声明 cookie 参数,否则该参数会被解释为查询参数。
+
+///
+
+## 小结
+
+使用 `Cookie` 声明 cookie 参数的方式与 `Query` 和 `Path` 相同。
diff --git a/docs/zh/docs/tutorial/cors.md b/docs/zh/docs/tutorial/cors.md
index ddd4e7682..a4f15f647 100644
--- a/docs/zh/docs/tutorial/cors.md
+++ b/docs/zh/docs/tutorial/cors.md
@@ -46,9 +46,7 @@
* 特定的 HTTP 方法(`POST`,`PUT`)或者使用通配符 `"*"` 允许所有方法。
* 特定的 HTTP headers 或者使用通配符 `"*"` 允许所有 headers。
-```Python hl_lines="2 6-11 13-19"
-{!../../../docs_src/cors/tutorial001.py!}
-```
+{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
默认情况下,这个 `CORSMiddleware` 实现所使用的默认参数较为保守,所以你需要显式地启用特定的源、方法或者 headers,以便浏览器能够在跨域上下文中使用它们。
@@ -78,7 +76,10 @@
更多关于
CORS 的信息,请查看
Mozilla CORS 文档。
-!!! note "技术细节"
- 你也可以使用 `from starlette.middleware.cors import CORSMiddleware`。
+/// note | 技术细节
- 出于方便,**FastAPI** 在 `fastapi.middleware` 中为开发者提供了几个中间件。但是大多数可用的中间件都是直接来自 Starlette。
+你也可以使用 `from starlette.middleware.cors import CORSMiddleware`。
+
+出于方便,**FastAPI** 在 `fastapi.middleware` 中为开发者提供了几个中间件。但是大多数可用的中间件都是直接来自 Starlette。
+
+///
diff --git a/docs/zh/docs/tutorial/debugging.md b/docs/zh/docs/tutorial/debugging.md
index 51801d498..734b85565 100644
--- a/docs/zh/docs/tutorial/debugging.md
+++ b/docs/zh/docs/tutorial/debugging.md
@@ -6,9 +6,7 @@
在你的 FastAPI 应用中直接导入 `uvicorn` 并运行:
-```Python hl_lines="1 15"
-{!../../../docs_src/debugging/tutorial001.py!}
-```
+{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
### 关于 `__name__ == "__main__"`
@@ -70,8 +68,11 @@ from myapp import app
uvicorn.run(app, host="0.0.0.0", port=8000)
```
-!!! info
- 更多信息请检查
Python 官方文档.
+/// info
+
+更多信息请检查
Python 官方文档.
+
+///
## 使用你的调试器运行代码
diff --git a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
index 5813272ee..f07280790 100644
--- a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -6,17 +6,7 @@
在前面的例子中, 我们从依赖项 ("可依赖对象") 中返回了一个 `dict`:
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="9"
- {!> ../../../docs_src/dependencies/tutorial001.py!}
- ```
-
-=== "Python 3.10 以及以上"
-
- ```Python hl_lines="7"
- {!> ../../../docs_src/dependencies/tutorial001_py310.py!}
- ```
+{* ../../docs_src/dependencies/tutorial001_py310.py hl[7] *}
但是后面我们在路径操作函数的参数 `commons` 中得到了一个 `dict`。
@@ -79,45 +69,15 @@ fluffy = Cat(name="Mr Fluffy")
所以,我们可以将上面的依赖项 "可依赖对象" `common_parameters` 更改为类 `CommonQueryParams`:
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="11-15"
- {!> ../../../docs_src/dependencies/tutorial002.py!}
- ```
-
-=== "Python 3.10 以及 以上"
-
- ```Python hl_lines="9-13"
- {!> ../../../docs_src/dependencies/tutorial002_py310.py!}
- ```
+{* ../../docs_src/dependencies/tutorial002_py310.py hl[9:13] *}
注意用于创建类实例的 `__init__` 方法:
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="12"
- {!> ../../../docs_src/dependencies/tutorial002.py!}
- ```
-
-=== "Python 3.10 以及 以上"
-
- ```Python hl_lines="10"
- {!> ../../../docs_src/dependencies/tutorial002_py310.py!}
- ```
+{* ../../docs_src/dependencies/tutorial002_py310.py hl[10] *}
...它与我们以前的 `common_parameters` 具有相同的参数:
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="9"
- {!> ../../../docs_src/dependencies/tutorial001.py!}
- ```
-
-=== "Python 3.10 以及 以上"
-
- ```Python hl_lines="6"
- {!> ../../../docs_src/dependencies/tutorial001_py310.py!}
- ```
+{* ../../docs_src/dependencies/tutorial001_py310.py hl[6] *}
这些参数就是 **FastAPI** 用来 "处理" 依赖项的。
@@ -133,17 +93,7 @@ fluffy = Cat(name="Mr Fluffy")
现在,您可以使用这个类来声明你的依赖项了。
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="19"
- {!> ../../../docs_src/dependencies/tutorial002.py!}
- ```
-
-=== "Python 3.10 以及 以上"
-
- ```Python hl_lines="17"
- {!> ../../../docs_src/dependencies/tutorial002_py310.py!}
- ```
+{* ../../docs_src/dependencies/tutorial002_py310.py hl[17] *}
**FastAPI** 调用 `CommonQueryParams` 类。这将创建该类的一个 "实例",该实例将作为参数 `commons` 被传递给你的函数。
@@ -183,17 +133,7 @@ commons = Depends(CommonQueryParams)
..就像:
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="19"
- {!> ../../../docs_src/dependencies/tutorial003.py!}
- ```
-
-=== "Python 3.10 以及 以上"
-
- ```Python hl_lines="17"
- {!> ../../../docs_src/dependencies/tutorial003_py310.py!}
- ```
+{* ../../docs_src/dependencies/tutorial003_py310.py hl[17] *}
但是声明类型是被鼓励的,因为那样你的编辑器就会知道将传递什么作为参数 `commons` ,然后它可以帮助你完成代码,类型检查,等等:
@@ -227,21 +167,14 @@ commons: CommonQueryParams = Depends()
同样的例子看起来像这样:
-=== "Python 3.6 以及 以上"
-
- ```Python hl_lines="19"
- {!> ../../../docs_src/dependencies/tutorial004.py!}
- ```
+{* ../../docs_src/dependencies/tutorial004_py310.py hl[17] *}
-=== "Python 3.10 以及 以上"
+... **FastAPI** 会知道怎么处理。
- ```Python hl_lines="17"
- {!> ../../../docs_src/dependencies/tutorial004_py310.py!}
- ```
+/// tip
-... **FastAPI** 会知道怎么处理。
+如果这看起来更加混乱而不是更加有帮助,那么请忽略它,你不*需要*它。
-!!! tip
- 如果这看起来更加混乱而不是更加有帮助,那么请忽略它,你不*需要*它。
+这只是一个快捷方式。因为 **FastAPI** 关心的是帮助您减少代码重复。
- 这只是一个快捷方式。因为 **FastAPI** 关心的是帮助您减少代码重复。
+///
diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
index 61ea371e5..51b3e9fc3 100644
--- a/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
+++ b/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -14,25 +14,27 @@
该参数的值是由 `Depends()` 组成的 `list`:
-```Python hl_lines="17"
-{!../../../docs_src/dependencies/tutorial006.py!}
-```
+{* ../../docs_src/dependencies/tutorial006.py hl[17] *}
路径操作装饰器依赖项(以下简称为**“路径装饰器依赖项”**)的执行或解析方式和普通依赖项一样,但就算这些依赖项会返回值,它们的值也不会传递给*路径操作函数*。
-!!! tip "提示"
+/// tip | 提示
- 有些编辑器会检查代码中没使用过的函数参数,并显示错误提示。
+有些编辑器会检查代码中没使用过的函数参数,并显示错误提示。
- 在*路径操作装饰器*中使用 `dependencies` 参数,可以确保在执行依赖项的同时,避免编辑器显示错误提示。
+在*路径操作装饰器*中使用 `dependencies` 参数,可以确保在执行依赖项的同时,避免编辑器显示错误提示。
- 使用路径装饰器依赖项还可以避免开发新人误会代码中包含无用的未使用参数。
+使用路径装饰器依赖项还可以避免开发新人误会代码中包含无用的未使用参数。
-!!! info "说明"
+///
- 本例中,使用的是自定义响应头 `X-Key` 和 `X-Token`。
+/// info | 说明
- 但实际开发中,尤其是在实现安全措施时,最好使用 FastAPI 内置的[安全工具](../security/index.md){.internal-link target=_blank}(详见下一章)。
+本例中,使用的是自定义响应头 `X-Key` 和 `X-Token`。
+
+但实际开发中,尤其是在实现安全措施时,最好使用 FastAPI 内置的[安全工具](../security/index.md){.internal-link target=_blank}(详见下一章)。
+
+///
## 依赖项错误和返回值
@@ -42,17 +44,13 @@
路径装饰器依赖项可以声明请求的需求项(比如响应头)或其他子依赖项:
-```Python hl_lines="6 11"
-{!../../../docs_src/dependencies/tutorial006.py!}
-```
+{* ../../docs_src/dependencies/tutorial006.py hl[6,11] *}
### 触发异常
路径装饰器依赖项与正常的依赖项一样,可以 `raise` 异常:
-```Python hl_lines="8 13"
-{!../../../docs_src/dependencies/tutorial006.py!}
-```
+{* ../../docs_src/dependencies/tutorial006.py hl[8,13] *}
### 返回值
@@ -60,9 +58,7 @@
因此,可以复用在其他位置使用过的、(能返回值的)普通依赖项,即使没有使用这个值,也会执行该依赖项:
-```Python hl_lines="9 14"
-{!../../../docs_src/dependencies/tutorial006.py!}
-```
+{* ../../docs_src/dependencies/tutorial006.py hl[9,14] *}
## 为一组路径操作定义依赖项
diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md
new file mode 100644
index 000000000..a863bb861
--- /dev/null
+++ b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -0,0 +1,267 @@
+# 使用yield的依赖项
+
+FastAPI支持在完成后执行一些
额外步骤的依赖项.
+
+为此,你需要使用 `yield` 而不是 `return`,然后再编写这些额外的步骤(代码)。
+
+/// tip | 提示
+
+确保在每个依赖中只使用一次 `yield`。
+
+///
+
+/// note | 技术细节
+
+任何一个可以与以下内容一起使用的函数:
+
+*
`@contextlib.contextmanager` 或者
+*
`@contextlib.asynccontextmanager`
+
+都可以作为 **FastAPI** 的依赖项。
+
+实际上,FastAPI内部就使用了这两个装饰器。
+
+///
+
+## 使用 `yield` 的数据库依赖项
+
+例如,你可以使用这种方式创建一个数据库会话,并在完成后关闭它。
+
+在发送响应之前,只会执行 `yield` 语句及之前的代码:
+
+{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
+
+生成的值会注入到 *路由函数* 和其他依赖项中:
+
+{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+
+`yield` 语句后面的代码会在创建响应后,发送响应前执行:
+
+{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+
+/// tip | 提示
+
+你可以使用 `async` 或普通函数。
+
+**FastAPI** 会像处理普通依赖一样,对每个依赖做正确的处理。
+
+///
+
+## 包含 `yield` 和 `try` 的依赖项
+
+如果在包含 `yield` 的依赖中使用 `try` 代码块,你会捕获到使用依赖时抛出的任何异常。
+
+例如,如果某段代码在另一个依赖中或在 *路由函数* 中使数据库事务"回滚"或产生任何其他错误,你将会在依赖中捕获到异常。
+
+因此,你可以使用 `except SomeException` 在依赖中捕获特定的异常。
+
+同样,你也可以使用 `finally` 来确保退出步骤得到执行,无论是否存在异常。
+
+{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+## 使用 `yield` 的子依赖项
+
+你可以声明任意数量和层级的树状依赖,而且它们中的任何一个或所有的都可以使用 `yield`。
+
+**FastAPI** 会确保每个带有 `yield` 的依赖中的"退出代码"按正确顺序运行。
+
+例如,`dependency_c` 可以依赖于 `dependency_b`,而 `dependency_b` 则依赖于 `dependency_a`。
+
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
+
+所有这些依赖都可以使用 `yield`。
+
+在这种情况下,`dependency_c` 在执行其退出代码时需要 `dependency_b`(此处称为 `dep_b`)的值仍然可用。
+
+而 `dependency_b` 反过来则需要 `dependency_a`(此处称为 `dep_a` )的值在其退出代码中可用。
+
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
+
+同样,你可以混合使用带有 `yield` 或 `return` 的依赖。
+
+你也可以声明一个依赖于多个带有 `yield` 的依赖,等等。
+
+你可以拥有任何你想要的依赖组合。
+
+**FastAPI** 将确保按正确的顺序运行所有内容。
+
+/// note | 技术细节
+
+这是由 Python 的
上下文管理器完成的。
+
+**FastAPI** 在内部使用它们来实现这一点。
+
+///
+
+## 包含 `yield` 和 `HTTPException` 的依赖项
+
+你可以使用带有 `yield` 的依赖项,并且可以包含 `try` 代码块用于捕获异常。
+
+同样,你可以在 `yield` 之后的退出代码中抛出一个 `HTTPException` 或类似的异常。
+
+/// tip | 提示
+
+这是一种相对高级的技巧,在大多数情况下你并不需要使用它,因为你可以在其他代码中抛出异常(包括 `HTTPException` ),例如在 *路由函数* 中。
+
+但是如果你需要,你也可以在依赖项中做到这一点。🤓
+
+///
+
+{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
+
+你还可以创建一个 [自定义异常处理器](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} 用于捕获异常(同时也可以抛出另一个 `HTTPException`)。
+
+## 包含 `yield` 和 `except` 的依赖项
+
+如果你在包含 `yield` 的依赖项中使用 `except` 捕获了一个异常,然后你没有重新抛出该异常(或抛出一个新异常),与在普通的Python代码中相同,FastAPI不会注意到发生了异常。
+
+{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
+
+在示例代码的情况下,客户端将会收到 *HTTP 500 Internal Server Error* 的响应,因为我们没有抛出 `HTTPException` 或者类似的异常,并且服务器也 **不会有任何日志** 或者其他提示来告诉我们错误是什么。😱
+
+### 在包含 `yield` 和 `except` 的依赖项中一定要 `raise`
+
+如果你在使用 `yield` 的依赖项中捕获到了一个异常,你应该再次抛出捕获到的异常,除非你抛出 `HTTPException` 或类似的其他异常,
+
+你可以使用 `raise` 再次抛出捕获到的异常。
+
+{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
+
+现在客户端同样会得到 *HTTP 500 Internal Server Error* 响应,但是服务器日志会记录下我们自定义的 `InternalError`。
+
+## 使用 `yield` 的依赖项的执行
+
+执行顺序大致如下时序图所示。时间轴从上到下,每一列都代表交互或者代码执行的一部分。
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant handler as Exception handler
+participant dep as Dep with yield
+participant operation as Path Operation
+participant tasks as Background tasks
+
+ Note over client,operation: Can raise exceptions, including HTTPException
+ client ->> dep: Start request
+ Note over dep: Run code up to yield
+ opt raise Exception
+ dep -->> handler: Raise Exception
+ handler -->> client: HTTP error response
+ end
+ dep ->> operation: Run dependency, e.g. DB session
+ opt raise
+ operation -->> dep: Raise Exception (e.g. HTTPException)
+ opt handle
+ dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
+ end
+ handler -->> client: HTTP error response
+ end
+
+ operation ->> client: Return response to client
+ Note over client,operation: Response is already sent, can't change it anymore
+ opt Tasks
+ operation -->> tasks: Send background tasks
+ end
+ opt Raise other exception
+ tasks -->> tasks: Handle exceptions in the background task code
+ end
+```
+
+/// info | 说明
+
+只会向客户端发送 **一次响应** ,可能是一个错误响应,也可能是来自 *路由函数* 的响应。
+
+在发送了其中一个响应之后,就无法再发送其他响应了。
+
+///
+
+/// tip | 提示
+
+这个时序图展示了 `HTTPException`,除此之外你也可以抛出任何你在使用 `yield` 的依赖项中或者[自定义异常处理器](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}中捕获的异常。
+
+如果你引发任何异常,它将传递给使用 `yield` 的依赖项,包括 `HTTPException`。在大多数情况下你应当从使用 `yield` 的依赖项中重新抛出捕获的异常或者一个新的异常来确保它会被正确的处理。
+
+///
+
+## 包含 `yield`, `HTTPException`, `except` 的依赖项和后台任务
+
+/// warning | 注意
+
+你大概率不需要了解这些技术细节,可以跳过这一章节继续阅读后续的内容。
+
+如果你使用的FastAPI的版本早于0.106.0,并且在使用后台任务中使用了包含 `yield` 的依赖项中的资源,那么这些细节会对你有一些用处。
+
+///
+
+### 包含 `yield` 和 `except` 的依赖项的技术细节
+
+在FastAPI 0.110.0版本之前,如果使用了一个包含 `yield` 的依赖项,你在依赖项中使用 `except` 捕获了一个异常,但是你没有再次抛出该异常,这个异常会被自动抛出/转发到异常处理器或者内部服务错误处理器。
+
+### 后台任务和使用 `yield` 的依赖项的技术细节
+
+在FastAPI 0.106.0版本之前,在 `yield` 后面抛出异常是不可行的,因为 `yield` 之后的退出代码是在响应被发送之后再执行,这个时候异常处理器已经执行过了。
+
+这样设计的目的主要是为了允许在后台任务中使用被依赖项`yield`的对象,因为退出代码会在后台任务结束后再执行。
+
+然而这也意味着在等待响应通过网络传输的同时,非必要的持有一个 `yield` 依赖项中的资源(例如数据库连接),这一行为在FastAPI 0.106.0被改变了。
+
+/// tip | 提示
+
+除此之外,后台任务通常是一组独立的逻辑,应该被单独处理,并且使用它自己的资源(例如它自己的数据库连接)。
+
+这样也会让你的代码更加简洁。
+
+///
+
+如果你之前依赖于这一行为,那么现在你应该在后台任务中创建并使用它自己的资源,不要在内部使用属于 `yield` 依赖项的资源。
+
+例如,你应该在后台任务中创建一个新的数据库会话用于查询数据,而不是使用相同的会话。你应该将对象的ID作为参数传递给后台任务函数,然后在该函数中重新获取该对象,而不是直接将数据库对象作为参数。
+
+## 上下文管理器
+
+### 什么是"上下文管理器"
+
+"上下文管理器"是你可以在 `with` 语句中使用的任何Python对象。
+
+例如,
你可以使用`with`读取文件:
+
+```Python
+with open("./somefile.txt") as f:
+ contents = f.read()
+ print(contents)
+```
+
+在底层,`open("./somefile.txt")`创建了一个被称为"上下文管理器"的对象。
+
+当 `with` 代码块结束时,它会确保关闭文件,即使发生了异常也是如此。
+
+当你使用 `yield` 创建一个依赖项时,**FastAPI** 会在内部将其转换为上下文管理器,并与其他相关工具结合使用。
+
+### 在使用 `yield` 的依赖项中使用上下文管理器
+
+/// warning | 注意
+
+这是一个更为"高级"的想法。
+
+如果你刚开始使用 **FastAPI** ,你可以暂时可以跳过它。
+
+///
+
+在Python中,你可以通过
创建一个带有`__enter__()`和`__exit__()`方法的类来创建上下文管理器。
+
+你也可以在 **FastAPI** 的 `yield` 依赖项中通过 `with` 或者 `async with` 语句来使用它们:
+
+{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
+
+/// tip | 提示
+
+另一种创建上下文管理器的方法是:
+
+*
`@contextlib.contextmanager`或者
+*
`@contextlib.asynccontextmanager`
+
+使用它们装饰一个只有单个 `yield` 的函数。这就是 **FastAPI** 内部对于 `yield` 依赖项的处理方式。
+
+但是你不需要为FastAPI的依赖项使用这些装饰器(而且也不应该)。FastAPI会在内部为你处理这些。
+
+///
diff --git a/docs/zh/docs/tutorial/dependencies/global-dependencies.md b/docs/zh/docs/tutorial/dependencies/global-dependencies.md
index 3f7afa32c..797fd76b7 100644
--- a/docs/zh/docs/tutorial/dependencies/global-dependencies.md
+++ b/docs/zh/docs/tutorial/dependencies/global-dependencies.md
@@ -6,9 +6,7 @@
这样一来,就可以为所有*路径操作*应用该依赖项:
-```Python hl_lines="15"
-{!../../../docs_src/dependencies/tutorial012.py!}
-```
+{* ../../docs_src/dependencies/tutorial012.py hl[15] *}
[*路径装饰器依赖项*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 一章的思路均适用于全局依赖项, 在本例中,这些依赖项可以用于应用中的所有*路径操作*。
diff --git a/docs/zh/docs/tutorial/dependencies/index.md b/docs/zh/docs/tutorial/dependencies/index.md
index c717da0f6..9eec69ed5 100644
--- a/docs/zh/docs/tutorial/dependencies/index.md
+++ b/docs/zh/docs/tutorial/dependencies/index.md
@@ -1,4 +1,4 @@
-# 依赖项 - 第一步
+# 依赖项
FastAPI 提供了简单易用,但功能强大的**
依赖注入**系统。
@@ -31,9 +31,7 @@ FastAPI 提供了简单易用,但功能强大的**
read_users
这样,只编写一次代码,**FastAPI** 就可以为多个*路径操作*共享这段代码 。
-!!! check "检查"
+/// check | 检查
+
+注意,无需创建专门的类,并将之传递给 **FastAPI** 以进行「注册」或执行类似的操作。
- 注意,无需创建专门的类,并将之传递给 **FastAPI** 以进行「注册」或执行类似的操作。
+只要把它传递给 `Depends`,**FastAPI** 就知道该如何执行后续操作。
- 只要把它传递给 `Depends`,**FastAPI** 就知道该如何执行后续操作。
+///
## 要不要使用 `async`?
@@ -114,9 +112,11 @@ common_parameters --> read_users
上述这些操作都是可行的,**FastAPI** 知道该怎么处理。
-!!! note "笔记"
+/// note | 笔记
+
+如里不了解异步,请参阅[异步:*“着急了?”*](../../async.md){.internal-link target=_blank} 一章中 `async` 和 `await` 的内容。
- 如里不了解异步,请参阅[异步:*“着急了?”*](../../async.md){.internal-link target=_blank} 一章中 `async` 和 `await` 的内容。
+///
## 与 OpenAPI 集成
diff --git a/docs/zh/docs/tutorial/dependencies/sub-dependencies.md b/docs/zh/docs/tutorial/dependencies/sub-dependencies.md
index 58377bbfe..2e7746433 100644
--- a/docs/zh/docs/tutorial/dependencies/sub-dependencies.md
+++ b/docs/zh/docs/tutorial/dependencies/sub-dependencies.md
@@ -10,9 +10,7 @@ FastAPI 支持创建含**子依赖项**的依赖项。
下列代码创建了第一层依赖项:
-```Python hl_lines="8-9"
-{!../../../docs_src/dependencies/tutorial005.py!}
-```
+{* ../../docs_src/dependencies/tutorial005.py hl[8:9] *}
这段代码声明了类型为 `str` 的可选查询参数 `q`,然后返回这个查询参数。
@@ -22,9 +20,7 @@ FastAPI 支持创建含**子依赖项**的依赖项。
接下来,创建另一个依赖项函数,并同时用该依赖项自身再声明一个依赖项(所以这也是一个「依赖项」):
-```Python hl_lines="13"
-{!../../../docs_src/dependencies/tutorial005.py!}
-```
+{* ../../docs_src/dependencies/tutorial005.py hl[13] *}
这里重点说明一下声明的参数:
@@ -37,15 +33,15 @@ FastAPI 支持创建含**子依赖项**的依赖项。
接下来,就可以使用依赖项:
-```Python hl_lines="22"
-{!../../../docs_src/dependencies/tutorial005.py!}
-```
+{* ../../docs_src/dependencies/tutorial005.py hl[22] *}
-!!! info "信息"
+/// info | 信息
- 注意,这里在*路径操作函数*中只声明了一个依赖项,即 `query_or_cookie_extractor` 。
+注意,这里在*路径操作函数*中只声明了一个依赖项,即 `query_or_cookie_extractor` 。
- 但 **FastAPI** 必须先处理 `query_extractor`,以便在调用 `query_or_cookie_extractor` 时使用 `query_extractor` 返回的结果。
+但 **FastAPI** 必须先处理 `query_extractor`,以便在调用 `query_or_cookie_extractor` 时使用 `query_extractor` 返回的结果。
+
+///
```mermaid
graph TB
@@ -79,10 +75,12 @@ async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False
但它依然非常强大,能够声明任意嵌套深度的「图」或树状的依赖结构。
-!!! tip "提示"
+/// tip | 提示
+
+这些简单的例子现在看上去虽然没有什么实用价值,
- 这些简单的例子现在看上去虽然没有什么实用价值,
+但在**安全**一章中,您会了解到这些例子的用途,
- 但在**安全**一章中,您会了解到这些例子的用途,
+以及这些例子所能节省的代码量。
- 以及这些例子所能节省的代码量。
+///
diff --git a/docs/zh/docs/tutorial/encoder.md b/docs/zh/docs/tutorial/encoder.md
index cb813940c..e52aaa2ed 100644
--- a/docs/zh/docs/tutorial/encoder.md
+++ b/docs/zh/docs/tutorial/encoder.md
@@ -20,17 +20,7 @@
它接收一个对象,比如Pydantic模型,并会返回一个JSON兼容的版本:
-=== "Python 3.6 and above"
-
- ```Python hl_lines="5 22"
- {!> ../../../docs_src/encoder/tutorial001.py!}
- ```
-
-=== "Python 3.10 and above"
-
- ```Python hl_lines="4 21"
- {!> ../../../docs_src/encoder/tutorial001_py310.py!}
- ```
+{* ../../docs_src/encoder/tutorial001_py310.py hl[4,21] *}
在这个例子中,它将Pydantic模型转换为`dict`,并将`datetime`转换为`str`。
@@ -38,5 +28,8 @@
这个操作不会返回一个包含JSON格式(作为字符串)数据的庞大的`str`。它将返回一个Python标准数据结构(例如`dict`),其值和子值都与JSON兼容。
-!!! note
- `jsonable_encoder`实际上是FastAPI内部用来转换数据的。但是它在许多其他场景中也很有用。
+/// note
+
+`jsonable_encoder`实际上是FastAPI内部用来转换数据的。但是它在许多其他场景中也很有用。
+
+///
diff --git a/docs/zh/docs/tutorial/extra-data-types.md b/docs/zh/docs/tutorial/extra-data-types.md
index ac3e07654..b064ee551 100644
--- a/docs/zh/docs/tutorial/extra-data-types.md
+++ b/docs/zh/docs/tutorial/extra-data-types.md
@@ -36,7 +36,7 @@
* `datetime.timedelta`:
* 一个 Python `datetime.timedelta`.
* 在请求和响应中将表示为 `float` 代表总秒数。
- * Pydantic 也允许将其表示为 "ISO 8601 时间差异编码", 查看文档了解更多信息。
+ * Pydantic 也允许将其表示为 "ISO 8601 时间差异编码", 查看文档了解更多信息。
* `frozenset`:
* 在请求和响应中,作为 `set` 对待:
* 在请求中,列表将被读取,消除重复,并将其转换为一个 `set`。
@@ -44,23 +44,19 @@
* 产生的模式将指定那些 `set` 的值是唯一的 (使用 JSON 模式的 `uniqueItems`)。
* `bytes`:
* 标准的 Python `bytes`。
- * 在请求和相应中被当作 `str` 处理。
+ * 在请求和响应中被当作 `str` 处理。
* 生成的模式将指定这个 `str` 是 `binary` "格式"。
* `Decimal`:
* 标准的 Python `Decimal`。
- * 在请求和相应中被当做 `float` 一样处理。
-* 您可以在这里检查所有有效的pydantic数据类型: Pydantic data types.
+ * 在请求和响应中被当做 `float` 一样处理。
+* 您可以在这里检查所有有效的pydantic数据类型: Pydantic data types.
## 例子
下面是一个*路径操作*的示例,其中的参数使用了上面的一些类型。
-```Python hl_lines="1 3 12-16"
-{!../../../docs_src/extra_data_types/tutorial001.py!}
-```
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[1,3,12:16] *}
注意,函数内的参数有原生的数据类型,你可以,例如,执行正常的日期操作,如:
-```Python hl_lines="18-19"
-{!../../../docs_src/extra_data_types/tutorial001.py!}
-```
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[18:19] *}
diff --git a/docs/zh/docs/tutorial/extra-models.md b/docs/zh/docs/tutorial/extra-models.md
index 1fbe77be8..ccfb3aa5a 100644
--- a/docs/zh/docs/tutorial/extra-models.md
+++ b/docs/zh/docs/tutorial/extra-models.md
@@ -1,55 +1,56 @@
-# 额外的模型
+# 更多模型
-我们从前面的示例继续,拥有多个相关的模型是很常见的。
+书接上文,多个关联模型这种情况很常见。
-对用户模型来说尤其如此,因为:
+特别是用户模型,因为:
-* **输入模型**需要拥有密码属性。
-* **输出模型**不应该包含密码。
-* **数据库模型**很可能需要保存密码的哈希值。
+* **输入模型**应该含密码
+* **输出模型**不应含密码
+* **数据库模型**需要加密的密码
-!!! danger
- 永远不要存储用户的明文密码。始终存储一个可以用于验证的「安全哈希值」。
+/// danger | 危险
- 如果你尚未了解该知识,你可以在[安全章节](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}中学习何为「密码哈希值」。
+千万不要存储用户的明文密码。始终存储可以进行验证的**安全哈希值**。
+
+如果不了解这方面的知识,请参阅[安全性中的章节](security/simple-oauth2.md#password-hashing){.internal-link target=_blank},了解什么是**密码哈希**。
+
+///
## 多个模型
-下面是应该如何根据它们的密码字段以及使用位置去定义模型的大概思路:
+下面的代码展示了不同模型处理密码字段的方式,及使用位置的大致思路:
-```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
-{!../../../docs_src/extra_models/tutorial001.py!}
-```
+{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
-### 关于 `**user_in.dict()`
+### `**user_in.dict()` 简介
#### Pydantic 的 `.dict()`
-`user_in` 是一个 `UserIn` 类的 Pydantic 模型.
+`user_in` 是类 `UserIn` 的 Pydantic 模型。
-Pydantic 模型具有 `.dict()` 方法,该方法返回一个拥有模型数据的 `dict`。
+Pydantic 模型支持 `.dict()` 方法,能返回包含模型数据的**字典**。
-因此,如果我们像下面这样创建一个 Pydantic 对象 `user_in`:
+因此,如果使用如下方式创建 Pydantic 对象 `user_in`:
```Python
user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
```
-然后我们调用:
+就能以如下方式调用:
```Python
user_dict = user_in.dict()
```
-现在我们有了一个数据位于变量 `user_dict` 中的 `dict`(它是一个 `dict` 而不是 Pydantic 模型对象)。
+现在,变量 `user_dict`中的就是包含数据的**字典**(变量 `user_dict` 是字典,不是 Pydantic 模型对象)。
-如果我们调用:
+以如下方式调用:
```Python
print(user_dict)
```
-我们将获得一个这样的 Python `dict`:
+输出的就是 Python **字典**:
```Python
{
@@ -62,15 +63,15 @@ print(user_dict)
#### 解包 `dict`
-如果我们将 `user_dict` 这样的 `dict` 以 `**user_dict` 形式传递给一个函数(或类),Python将对其进行「解包」。它会将 `user_dict` 的键和值作为关键字参数直接传递。
+把**字典** `user_dict` 以 `**user_dict` 形式传递给函数(或类),Python 会执行**解包**操作。它会把 `user_dict` 的键和值作为关键字参数直接传递。
-因此,从上面的 `user_dict` 继续,编写:
+因此,接着上面的 `user_dict` 继续编写如下代码:
```Python
UserInDB(**user_dict)
```
-会产生类似于以下的结果:
+就会生成如下结果:
```Python
UserInDB(
@@ -81,7 +82,7 @@ UserInDB(
)
```
-或者更确切地,直接使用 `user_dict` 来表示将来可能包含的任何内容:
+或更精准,直接把可能会用到的内容与 `user_dict` 一起使用:
```Python
UserInDB(
@@ -92,34 +93,34 @@ UserInDB(
)
```
-#### 来自于其他模型内容的 Pydantic 模型
+#### 用其它模型中的内容生成 Pydantic 模型
-如上例所示,我们从 `user_in.dict()` 中获得了 `user_dict`,此代码:
+上例中 ,从 `user_in.dict()` 中得到了 `user_dict`,下面的代码:
```Python
user_dict = user_in.dict()
UserInDB(**user_dict)
```
-等同于:
+等效于:
```Python
UserInDB(**user_in.dict())
```
-...因为 `user_in.dict()` 是一个 `dict`,然后我们通过以`**`开头传递给 `UserInDB` 来使 Python「解包」它。
+……因为 `user_in.dict()` 是字典,在传递给 `UserInDB` 时,把 `**` 加在 `user_in.dict()` 前,可以让 Python 进行**解包**。
-这样,我们获得了一个来自于其他 Pydantic 模型中的数据的 Pydantic 模型。
+这样,就可以用其它 Pydantic 模型中的数据生成 Pydantic 模型。
-#### 解包 `dict` 和额外关键字
+#### 解包 `dict` 和更多关键字
-然后添加额外的关键字参数 `hashed_password=hashed_password`,例如:
+接下来,继续添加关键字参数 `hashed_password=hashed_password`,例如:
```Python
UserInDB(**user_in.dict(), hashed_password=hashed_password)
```
-...最终的结果如下:
+……输出结果如下:
```Python
UserInDB(
@@ -131,69 +132,68 @@ UserInDB(
)
```
-!!! warning
- 辅助性的额外函数只是为了演示可能的数据流,但它们显然不能提供任何真正的安全性。
+/// warning | 警告
+
+辅助的附加函数只是为了演示可能的数据流,但它们显然不能提供任何真正的安全机制。
+
+///
## 减少重复
-减少代码重复是 **FastAPI** 的核心思想之一。
+**FastAPI** 的核心思想就是减少代码重复。
-因为代码重复会增加出现 bug、安全性问题、代码失步问题(当你在一个位置更新了代码但没有在其他位置更新)等的可能性。
+代码重复会导致 bug、安全问题、代码失步等问题(更新了某个位置的代码,但没有同步更新其它位置的代码)。
-上面的这些模型都共享了大量数据,并拥有重复的属性名称和类型。
+上面的这些模型共享了大量数据,拥有重复的属性名和类型。
-我们可以做得更好。
+FastAPI 可以做得更好。
-我们可以声明一个 `UserBase` 模型作为其他模型的基类。然后我们可以创建继承该模型属性(类型声明,校验等)的子类。
+声明 `UserBase` 模型作为其它模型的基类。然后,用该类衍生出继承其属性(类型声明、验证等)的子类。
-所有的数据转换、校验、文档生成等仍将正常运行。
+所有数据转换、校验、文档等功能仍将正常运行。
-这样,我们可以仅声明模型之间的差异部分(具有明文的 `password`、具有 `hashed_password` 以及不包括密码)。
+这样,就可以仅声明模型之间的差异部分(具有明文的 `password`、具有 `hashed_password` 以及不包括密码)。
-```Python hl_lines="9 15-16 19-20 23-24"
-{!../../../docs_src/extra_models/tutorial002.py!}
-```
+通过这种方式,可以只声明模型之间的区别(分别包含明文密码、哈希密码,以及无密码的模型)。
+
+{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
## `Union` 或者 `anyOf`
-你可以将一个响应声明为两种类型的 `Union`,这意味着该响应将是两种类型中的任何一种。
+响应可以声明为两种类型的 `Union` 类型,即该响应可以是两种类型中的任意类型。
-这将在 OpenAPI 中使用 `anyOf` 进行定义。
+在 OpenAPI 中可以使用 `anyOf` 定义。
-为此,请使用标准的 Python 类型提示 `typing.Union`:
+为此,请使用 Python 标准类型提示 `typing.Union`:
+/// note | 笔记
-!!! note
- 定义一个 `Union` 类型时,首先包括最详细的类型,然后是不太详细的类型。在下面的示例中,更详细的 `PlaneItem` 位于 `Union[PlaneItem,CarItem]` 中的 `CarItem` 之前。
+定义 `Union` 类型时,要把详细的类型写在前面,然后是不太详细的类型。下例中,更详细的 `PlaneItem` 位于 `Union[PlaneItem,CarItem]` 中的 `CarItem` 之前。
-```Python hl_lines="1 14-15 18-20 33"
-{!../../../docs_src/extra_models/tutorial003.py!}
-```
+///
+
+{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
## 模型列表
-你可以用同样的方式声明由对象列表构成的响应。
+使用同样的方式也可以声明由对象列表构成的响应。
为此,请使用标准的 Python `typing.List`:
-```Python hl_lines="1 20"
-{!../../../docs_src/extra_models/tutorial004.py!}
-```
+{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
## 任意 `dict` 构成的响应
-你还可以使用一个任意的普通 `dict` 声明响应,仅声明键和值的类型,而不使用 Pydantic 模型。
+任意的 `dict` 都能用于声明响应,只要声明键和值的类型,无需使用 Pydantic 模型。
-如果你事先不知道有效的字段/属性名称(对于 Pydantic 模型是必需的),这将很有用。
+事先不知道可用的字段 / 属性名时(Pydantic 模型必须知道字段是什么),这种方式特别有用。
-在这种情况下,你可以使用 `typing.Dict`:
+此时,可以使用 `typing.Dict`:
-```Python hl_lines="1 8"
-{!../../../docs_src/extra_models/tutorial005.py!}
-```
+{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
-## 总结
+## 小结
-使用多个 Pydantic 模型,并针对不同场景自由地继承。
+针对不同场景,可以随意使用不同的 Pydantic 模型继承定义的基类。
-如果一个实体必须能够具有不同的「状态」,你无需为每个状态的实体定义单独的数据模型。以用户「实体」为例,其状态有包含 `password`、包含 `password_hash` 以及不含密码。
+实体必须具有不同的**状态**时,不必为不同状态的实体单独定义数据模型。例如,用户**实体**就有包含 `password`、包含 `password_hash` 以及不含密码等多种状态。
diff --git a/docs/zh/docs/tutorial/first-steps.md b/docs/zh/docs/tutorial/first-steps.md
index 30fae99cf..80a34116a 100644
--- a/docs/zh/docs/tutorial/first-steps.md
+++ b/docs/zh/docs/tutorial/first-steps.md
@@ -2,9 +2,7 @@
最简单的 FastAPI 文件可能像下面这样:
-```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py *}
将其复制到 `main.py` 文件中。
@@ -13,24 +11,42 @@
```console
-$ uvicorn main:app --reload
+$ fastapi dev main.py
-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.
-```
+ FastAPI Starting development server 🚀
-
+ Searching for package file structure from directories
+ with __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with
+ the following code:
+
+ from main import app
+
+ app Using import string: main:app
-!!! note
- `uvicorn main:app` 命令含义如下:
+ server Server started at http://127.0.0.1:8000
+ server Documentation at http://127.0.0.1:8000/docs
- * `main`:`main.py` 文件(一个 Python「模块」)。
- * `app`:在 `main.py` 文件中通过 `app = FastAPI()` 创建的对象。
- * `--reload`:让服务器在更新代码后重新启动。仅在开发时使用该选项。
+ tip Running in development mode, for production use:
+ fastapi run
+ Logs:
+
+ INFO Will watch for changes in these directories:
+ ['/home/user/code/awesomeapp']
+ INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C
+ to quit)
+ INFO Started reloader process [383138] using WatchFiles
+ INFO Started server process [383153]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+```
+
+
在输出中,会有一行信息像下面这样:
@@ -38,7 +54,6 @@ $ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
-
该行显示了你的应用在本机所提供服务的 URL 地址。
### 查看
@@ -63,7 +78,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
前往
http://127.0.0.1:8000/redoc。
-你将会看到可选的自动生成文档 (由
ReDoc 提供):
+你将会看到可选的自动生成文档 (由
ReDoc 提供):

@@ -77,9 +92,9 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
#### API「模式」
-在这种场景下,OpenAPI 是一种规定如何定义 API 模式的规范。
+在这种场景下,
OpenAPI 是一种规定如何定义 API 模式的规范。
-定义的 OpenAPI 模式将包括你的 API 路径,以及它们可能使用的参数等等。
+「模式」的定义包括你的 API 路径,以及它们可能使用的参数等等。
#### 数据「模式」
@@ -93,7 +108,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
#### 查看 `openapi.json`
-如果你对原始的 OpenAPI 模式长什么样子感到好奇,其实它只是一个自动生成的包含了所有 API 描述的 JSON。
+如果你对原始的 OpenAPI 模式长什么样子感到好奇,FastAPI 自动生成了包含所有 API 描述的 JSON(模式)。
你可以直接在:
http://127.0.0.1:8000/openapi.json 看到它。
@@ -101,7 +116,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
```JSON
{
- "openapi": "3.0.2",
+ "openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
@@ -132,57 +147,26 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
### 步骤 1:导入 `FastAPI`
-```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
`FastAPI` 是一个为你的 API 提供了所有功能的 Python 类。
-!!! note "技术细节"
- `FastAPI` 是直接从 `Starlette` 继承的类。
+/// note | 技术细节
- 你可以通过 `FastAPI` 使用所有的 Starlette 的功能。
+`FastAPI` 是直接从 `Starlette` 继承的类。
+
+你可以通过 `FastAPI` 使用所有的
Starlette 的功能。
+
+///
### 步骤 2:创建一个 `FastAPI`「实例」
-```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
这里的变量 `app` 会是 `FastAPI` 类的一个「实例」。
这个实例将是创建你所有 API 的主要交互对象。
-这个 `app` 同样在如下命令中被 `uvicorn` 所引用:
-
-
-
-```console
-$ uvicorn main:app --reload
-
-INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
-
-
-
-如果你像下面这样创建应用:
-
-```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial002.py!}
-```
-
-将代码放入 `main.py` 文件中,然后你可以像下面这样运行 `uvicorn`:
-
-
-
-```console
-$ uvicorn main:my_awesome_api --reload
-
-INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
-
-
-
### 步骤 3:创建一个*路径操作*
#### 路径
@@ -201,8 +185,11 @@ https://example.com/items/foo
/items/foo
```
-!!! info
- 「路径」也通常被称为「端点」或「路由」。
+/// info
+
+「路径」也通常被称为「端点」或「路由」。
+
+///
开发 API 时,「路径」是用来分离「关注点」和「资源」的主要手段。
@@ -243,25 +230,26 @@ https://example.com/items/foo
#### 定义一个*路径操作装饰器*
-```Python hl_lines="6"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
`@app.get("/")` 告诉 **FastAPI** 在它下方的函数负责处理如下访问请求:
* 请求路径为 `/`
* 使用
get
操作
-!!! info "`@decorator` Info"
- `@something` 语法在 Python 中被称为「装饰器」。
+/// info | `@decorator` Info
- 像一顶漂亮的装饰帽一样,将它放在一个函数的上方(我猜测这个术语的命名就是这么来的)。
+`@something` 语法在 Python 中被称为「装饰器」。
- 装饰器接收位于其下方的函数并且用它完成一些工作。
+像一顶漂亮的装饰帽一样,将它放在一个函数的上方(我猜测这个术语的命名就是这么来的)。
- 在我们的例子中,这个装饰器告诉 **FastAPI** 位于其下方的函数对应着**路径** `/` 加上 `get` **操作**。
+装饰器接收位于其下方的函数并且用它完成一些工作。
- 它是一个「**路径操作装饰器**」。
+在我们的例子中,这个装饰器告诉 **FastAPI** 位于其下方的函数对应着**路径** `/` 加上 `get` **操作**。
+
+它是一个「**路径操作装饰器**」。
+
+///
你也可以使用其他的操作:
@@ -276,14 +264,17 @@ https://example.com/items/foo
* `@app.patch()`
* `@app.trace()`
-!!! tip
- 您可以随意使用任何一个操作(HTTP方法)。
+/// tip
+
+你可以随意使用任何一个操作(HTTP方法)。
- **FastAPI** 没有强制要求操作有任何特定的含义。
+**FastAPI** 没有强制要求操作有任何特定的含义。
- 此处提供的信息仅作为指导,而不是要求。
+此处提供的信息仅作为指导,而不是要求。
- 比如,当使用 GraphQL 时通常你所有的动作都通过 `post` 一种方法执行。
+比如,当使用 GraphQL 时通常你所有的动作都通过 `POST` 一种方法执行。
+
+///
### 步骤 4:定义**路径操作函数**
@@ -293,9 +284,7 @@ https://example.com/items/foo
* **操作**:是 `get`。
* **函数**:是位于「装饰器」下方的函数(位于 `@app.get("/")` 下方)。
-```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
这是一个 Python 函数。
@@ -307,18 +296,17 @@ https://example.com/items/foo
你也可以将其定义为常规函数而不使用 `async def`:
-```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
-```
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
-!!! note
- 如果你不知道两者的区别,请查阅 [Async: *"In a hurry?"*](https://fastapi.tiangolo.com/async/#in-a-hurry){.internal-link target=_blank}。
+/// note
+
+如果你不知道两者的区别,请查阅 [并发: *赶时间吗?*](../async.md#_1){.internal-link target=_blank}。
+
+///
### 步骤 5:返回内容
-```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
你可以返回一个 `dict`、`list`,像 `str`、`int` 一样的单个值,等等。
@@ -330,6 +318,6 @@ https://example.com/items/foo
* 导入 `FastAPI`。
* 创建一个 `app` 实例。
-* 编写一个**路径操作装饰器**(如 `@app.get("/")`)。
-* 编写一个**路径操作函数**(如上面的 `def root(): ...`)。
-* 运行开发服务器(如 `uvicorn main:app --reload`)。
+* 编写一个**路径操作装饰器**,如 `@app.get("/")`。
+* 定义一个**路径操作函数**,如 `def root(): ...`。
+* 使用命令 `fastapi dev` 运行开发服务器。
diff --git a/docs/zh/docs/tutorial/handling-errors.md b/docs/zh/docs/tutorial/handling-errors.md
index 9b066bc2c..0b887c292 100644
--- a/docs/zh/docs/tutorial/handling-errors.md
+++ b/docs/zh/docs/tutorial/handling-errors.md
@@ -25,10 +25,7 @@
### 导入 `HTTPException`
-```Python hl_lines="1"
-{!../../../docs_src/handling_errors/tutorial001.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
### 触发 `HTTPException`
@@ -42,10 +39,7 @@
本例中,客户端用 `ID` 请求的 `item` 不存在时,触发状态码为 `404` 的异常:
-```Python hl_lines="11"
-{!../../../docs_src/handling_errors/tutorial001.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
### 响应结果
@@ -67,14 +61,15 @@
```
-!!! tip "提示"
+/// tip | 提示
- 触发 `HTTPException` 时,可以用参数 `detail` 传递任何能转换为 JSON 的值,不仅限于 `str`。
+触发 `HTTPException` 时,可以用参数 `detail` 传递任何能转换为 JSON 的值,不仅限于 `str`。
- 还支持传递 `dict`、`list` 等数据结构。
+还支持传递 `dict`、`list` 等数据结构。
- **FastAPI** 能自动处理这些数据,并将之转换为 JSON。
+**FastAPI** 能自动处理这些数据,并将之转换为 JSON。
+///
## 添加自定义响应头
@@ -84,10 +79,7 @@
但对于某些高级应用场景,还是需要添加自定义响应头:
-```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial002.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
## 安装自定义异常处理器
@@ -99,10 +91,7 @@
此时,可以用 `@app.exception_handler()` 添加自定义异常控制器:
-```Python hl_lines="5-7 13-18 24"
-{!../../../docs_src/handling_errors/tutorial003.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
请求 `/unicorns/yolo` 时,路径操作会触发 `UnicornException`。
@@ -115,12 +104,13 @@
```
-!!! note "技术细节"
+/// note | 技术细节
- `from starlette.requests import Request` 和 `from starlette.responses import JSONResponse` 也可以用于导入 `Request` 和 `JSONResponse`。
+`from starlette.requests import Request` 和 `from starlette.responses import JSONResponse` 也可以用于导入 `Request` 和 `JSONResponse`。
- **FastAPI** 提供了与 `starlette.responses` 相同的 `fastapi.responses` 作为快捷方式,但大部分响应操作都可以直接从 Starlette 导入。同理,`Request` 也是如此。
+**FastAPI** 提供了与 `starlette.responses` 相同的 `fastapi.responses` 作为快捷方式,但大部分响应操作都可以直接从 Starlette 导入。同理,`Request` 也是如此。
+///
## 覆盖默认异常处理器
@@ -140,12 +130,9 @@
这样,异常处理器就可以接收 `Request` 与异常。
-```Python hl_lines="2 14-16"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
-```
-
-访问 `/items/foo`,可以看到以下内容替换了默认 JSON 错误信息:
+访问 `/items/foo`,可以看到默认的 JSON 错误信息:
```JSON
{
@@ -163,7 +150,7 @@
```
-以下是文本格式的错误信息:
+被替换为了以下文本格式的错误信息:
```
1 validation error
@@ -174,12 +161,13 @@ path -> item_id
### `RequestValidationError` vs `ValidationError`
-!!! warning "警告"
+/// warning | 警告
- 如果您觉得现在还用不到以下技术细节,可以先跳过下面的内容。
+如果您觉得现在还用不到以下技术细节,可以先跳过下面的内容。
+///
-`RequestValidationError` 是 Pydantic 的
`ValidationError` 的子类。
+`RequestValidationError` 是 Pydantic 的
`ValidationError` 的子类。
**FastAPI** 调用的就是 `RequestValidationError` 类,因此,如果在 `response_model` 中使用 Pydantic 模型,且数据有错误时,在日志中就会看到这个错误。
@@ -195,17 +183,15 @@ path -> item_id
例如,只为错误返回纯文本响应,而不是返回 JSON 格式的内容:
-```Python hl_lines="3-4 9-11 22"
-{!../../../docs_src/handling_errors/tutorial004.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
-!!! note "技术细节"
+/// note | 技术细节
- 还可以使用 `from starlette.responses import PlainTextResponse`。
+还可以使用 `from starlette.responses import PlainTextResponse`。
- **FastAPI** 提供了与 `starlette.responses` 相同的 `fastapi.responses` 作为快捷方式,但大部分响应都可以直接从 Starlette 导入。
+**FastAPI** 提供了与 `starlette.responses` 相同的 `fastapi.responses` 作为快捷方式,但大部分响应都可以直接从 Starlette 导入。
+///
### 使用 `RequestValidationError` 的请求体
@@ -213,10 +199,7 @@ path -> item_id
开发时,可以用这个请求体生成日志、调试错误,并返回给用户。
-```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial005.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
现在试着发送一个无效的 `item`,例如:
@@ -279,10 +262,7 @@ FastAPI 支持先对异常进行某些处理,然后再使用 **FastAPI** 中
从 `fastapi.exception_handlers` 中导入要复用的默认异常处理器:
-```Python hl_lines="2-5 15 21"
-{!../../../docs_src/handling_errors/tutorial006.py!}
-
-```
+{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
虽然,本例只是输出了夸大其词的错误信息。
diff --git a/docs/zh/docs/tutorial/header-param-models.md b/docs/zh/docs/tutorial/header-param-models.md
new file mode 100644
index 000000000..13366aebc
--- /dev/null
+++ b/docs/zh/docs/tutorial/header-param-models.md
@@ -0,0 +1,56 @@
+# Header 参数模型
+
+如果您有一组相关的 **header 参数**,您可以创建一个 **Pydantic 模型**来声明它们。
+
+这将允许您在**多个地方**能够**重用模型**,并且可以一次性声明所有参数的验证和元数据。😎
+
+/// note
+
+自 FastAPI 版本 `0.115.0` 起支持此功能。🤓
+
+///
+
+## 使用 Pydantic 模型的 Header 参数
+
+在 **Pydantic 模型**中声明所需的 **header 参数**,然后将参数声明为 `Header` :
+
+{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
+
+**FastAPI** 将从请求中接收到的 **headers** 中**提取**出**每个字段**的数据,并提供您定义的 Pydantic 模型。
+
+## 查看文档
+
+您可以在文档 UI 的 `/docs` 中查看所需的 headers:
+
+
+

+
+
+## 禁止额外的 Headers
+
+在某些特殊使用情况下(可能并不常见),您可能希望**限制**您想要接收的 headers。
+
+您可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段:
+
+{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
+
+如果客户尝试发送一些**额外的 headers**,他们将收到**错误**响应。
+
+例如,如果客户端尝试发送一个值为 `plumbus` 的 `tool` header,客户端将收到一个**错误**响应,告知他们 header 参数 `tool` 是不允许的:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["header", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ ]
+}
+```
+
+## 总结
+
+您可以使用 **Pydantic 模型**在 **FastAPI** 中声明 **headers**。😎
diff --git a/docs/zh/docs/tutorial/header-params.md b/docs/zh/docs/tutorial/header-params.md
index c4b1c38ce..19bb455cf 100644
--- a/docs/zh/docs/tutorial/header-params.md
+++ b/docs/zh/docs/tutorial/header-params.md
@@ -1,79 +1,79 @@
# Header 参数
-你可以使用定义 `Query`, `Path` 和 `Cookie` 参数一样的方法定义 Header 参数。
+定义 `Header` 参数的方式与定义 `Query`、`Path`、`Cookie` 参数相同。
## 导入 `Header`
-首先导入 `Header`:
+首先,导入 `Header`:
-```Python hl_lines="3"
-{!../../../docs_src/header_params/tutorial001.py!}
-```
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
## 声明 `Header` 参数
-然后使用和`Path`, `Query` and `Cookie` 一样的结构定义 header 参数
+然后,使用和 `Path`、`Query`、`Cookie` 一样的结构定义 header 参数。
-第一个值是默认值,你可以传递所有的额外验证或注释参数:
+第一个值是默认值,还可以传递所有验证参数或注释参数:
-```Python hl_lines="9"
-{!../../../docs_src/header_params/tutorial001.py!}
-```
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | 技术细节
+
+`Header` 是 `Path`、`Query`、`Cookie` 的**兄弟类**,都继承自共用的 `Param` 类。
+
+注意,从 `fastapi` 导入的 `Query`、`Path`、`Header` 等对象,实际上是返回特殊类的函数。
-!!! note "技术细节"
- `Header` 是 `Path`, `Query` 和 `Cookie` 的兄弟类型。它也继承自通用的 `Param` 类.
+///
- 但是请记得,当你从`fastapi`导入 `Query`, `Path`, `Header`, 或其他时,实际上导入的是返回特定类型的函数。
+/// info | 说明
-!!! info
- 为了声明headers, 你需要使用`Header`, 因为否则参数将被解释为查询参数。
+必须使用 `Header` 声明 header 参数,否则该参数会被解释为查询参数。
+
+///
## 自动转换
-`Header` 在 `Path`, `Query` 和 `Cookie` 提供的功能之上有一点额外的功能。
+`Header` 比 `Path`、`Query` 和 `Cookie` 提供了更多功能。
-大多数标准的headers用 "连字符" 分隔,也称为 "减号" (`-`)。
+大部分标准请求头用**连字符**分隔,即**减号**(`-`)。
-但是像 `user-agent` 这样的变量在Python中是无效的。
+但是 `user-agent` 这样的变量在 Python 中是无效的。
-因此, 默认情况下, `Header` 将把参数名称的字符从下划线 (`_`) 转换为连字符 (`-`) 来提取并记录 headers.
+因此,默认情况下,`Header` 把参数名中的字符由下划线(`_`)改为连字符(`-`)来提取并存档请求头 。
-同时,HTTP headers 是大小写不敏感的,因此,因此可以使用标准Python样式(也称为 "snake_case")声明它们。
+同时,HTTP 的请求头不区分大小写,可以使用 Python 标准样式(即 **snake_case**)进行声明。
-因此,您可以像通常在Python代码中那样使用 `user_agent` ,而不需要将首字母大写为 `User_Agent` 或类似的东西。
+因此,可以像在 Python 代码中一样使用 `user_agent` ,无需把首字母大写为 `User_Agent` 等形式。
-如果出于某些原因,你需要禁用下划线到连字符的自动转换,设置`Header`的参数 `convert_underscores` 为 `False`:
+如需禁用下划线自动转换为连字符,可以把 `Header` 的 `convert_underscores` 参数设置为 `False`:
-```Python hl_lines="10"
-{!../../../docs_src/header_params/tutorial002.py!}
-```
+{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
-!!! warning
- 在设置 `convert_underscores` 为 `False` 之前,请记住,一些HTTP代理和服务器不允许使用带有下划线的headers。
+/// warning | 警告
+注意,使用 `convert_underscores = False` 要慎重,有些 HTTP 代理和服务器不支持使用带有下划线的请求头。
-## 重复的 headers
+///
-有可能收到重复的headers。这意味着,相同的header具有多个值。
+## 重复的请求头
-您可以在类型声明中使用一个list来定义这些情况。
+有时,可能需要接收重复的请求头。即同一个请求头有多个值。
-你可以通过一个Python `list` 的形式获得重复header的所有值。
+类型声明中可以使用 `list` 定义多个请求头。
-比如, 为了声明一个 `X-Token` header 可以出现多次,你可以这样写:
+使用 Python `list` 可以接收重复请求头所有的值。
-```Python hl_lines="9"
-{!../../../docs_src/header_params/tutorial003.py!}
-```
+例如,声明 `X-Token` 多次出现的请求头,可以写成这样:
+
+{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
-如果你与*路径操作*通信时发送两个HTTP headers,就像:
+与*路径操作*通信时,以下面的方式发送两个 HTTP 请求头:
```
X-Token: foo
X-Token: bar
```
-响应会是:
+响应结果是:
```JSON
{
@@ -84,8 +84,8 @@ X-Token: bar
}
```
-## 回顾
+## 小结
-使用 `Header` 来声明 header , 使用和 `Query`, `Path` 与 `Cookie` 相同的模式。
+使用 `Header` 声明请求头的方式与 `Query`、`Path` 、`Cookie` 相同。
-不用担心变量中的下划线,**FastAPI** 会负责转换它们。
+不用担心变量中的下划线,**FastAPI** 可以自动转换。
diff --git a/docs/zh/docs/tutorial/index.md b/docs/zh/docs/tutorial/index.md
index 6093caeb6..3ca927337 100644
--- a/docs/zh/docs/tutorial/index.md
+++ b/docs/zh/docs/tutorial/index.md
@@ -1,34 +1,58 @@
-# 教程 - 用户指南 - 简介
+# 教程 - 用户指南
-本教程将一步步向你展示如何使用 **FastAPI** 的绝大部分特性。
+本教程将一步步向您展示如何使用 **FastAPI** 的绝大部分特性。
-各个章节的内容循序渐进,但是又围绕着单独的主题,所以你可以直接跳转到某个章节以解决你的特定需求。
+各个章节的内容循序渐进,但是又围绕着单独的主题,所以您可以直接跳转到某个章节以解决您的特定需求。
-本教程同样可以作为将来的参考手册。
-
-你可以随时回到本教程并查阅你需要的内容。
+本教程同样可以作为将来的参考手册,所以您可以随时回到本教程并查阅您需要的内容。
## 运行代码
所有代码片段都可以复制后直接使用(它们实际上是经过测试的 Python 文件)。
-要运行任何示例,请将代码复制到 `main.py` 文件中,然后使用以下命令启动 `uvicorn`:
+要运行任何示例,请将代码复制到 `main.py` 文件中,然后使用以下命令启动 `fastapi dev`:
```console
-$ uvicorn main:app --reload
+$ fastapi dev main.py
+
+ FastAPI Starting development server 🚀
+
+ Searching for package file structure from directories
+ with __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with
+ the following code:
+
+ from main import app
+
+ app Using import string: main:app
-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.
+ server Server started at http://127.0.0.1:8000
+ server Documentation at http://127.0.0.1:8000/docs
+
+ tip Running in development mode, for production use:
+ fastapi run
+
+ Logs:
+
+ INFO Will watch for changes in these directories:
+ ['/home/user/code/awesomeapp']
+ INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C
+ to quit)
+ INFO Started reloader process [383138] using WatchFiles
+ INFO Started server process [383153]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
```
-强烈建议你在本地编写或复制代码,对其进行编辑并运行。
+**强烈建议**您在本地编写或复制代码,对其进行编辑并运行。
在编辑器中使用 FastAPI 会真正地展现出它的优势:只需要编写很少的代码,所有的类型检查,代码补全等等。
@@ -36,45 +60,34 @@ $ uvicorn main:app --reload
## 安装 FastAPI
-第一个步骤是安装 FastAPI。
+第一个步骤是安装 FastAPI.
-为了使用本教程,你可能需要安装所有的可选依赖及对应功能:
+请确保您创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后**安装 FastAPI**:
```console
-$ pip install "fastapi[all]"
+$ pip install "fastapi[standard]"
---> 100%
```
-......以上安装还包括了 `uvicorn`,你可以将其用作运行代码的服务器。
-
-!!! note
- 你也可以分开来安装。
-
- 假如你想将应用程序部署到生产环境,你可能要执行以下操作:
-
- ```
- pip install fastapi
- ```
+/// note
- 并且安装`uvicorn`来作为服务器:
+当您使用 `pip install "fastapi[standard]"` 进行安装时,它会附带一些默认的可选标准依赖项。
- ```
- pip install "uvicorn[standard]"
- ```
+如果您不想安装这些可选依赖,可以选择安装 `pip install fastapi`。
- 然后对你想使用的每个可选依赖项也执行相同的操作。
+///
## 进阶用户指南
-在本**教程-用户指南**之后,你可以阅读**进阶用户指南**。
+在本**教程-用户指南**之后,您可以阅读**进阶用户指南**。
**进阶用户指南**以本教程为基础,使用相同的概念,并教授一些额外的特性。
-但是你应该先阅读**教程-用户指南**(即你现在正在阅读的内容)。
+但是您应该先阅读**教程-用户指南**(即您现在正在阅读的内容)。
-教程经过精心设计,使你可以仅通过**教程-用户指南**来开发一个完整的应用程序,然后根据你的需要,使用**进阶用户指南**中的一些其他概念,以不同的方式来扩展它。
+教程经过精心设计,使您可以仅通过**教程-用户指南**来开发一个完整的应用程序,然后根据您的需要,使用**进阶用户指南**中的一些其他概念,以不同的方式来扩展它。
diff --git a/docs/zh/docs/tutorial/metadata.md b/docs/zh/docs/tutorial/metadata.md
index 3e669bc72..d29a1e6d0 100644
--- a/docs/zh/docs/tutorial/metadata.md
+++ b/docs/zh/docs/tutorial/metadata.md
@@ -1,105 +1,100 @@
-# 元数据和文档 URL
-
-你可以在 **FastAPI** 应用中自定义几个元数据配置。
-
-## 标题、描述和版本
-
-你可以设定:
-
-* **Title**:在 OpenAPI 和自动 API 文档用户界面中作为 API 的标题/名称使用。
-* **Description**:在 OpenAPI 和自动 API 文档用户界面中用作 API 的描述。
-* **Version**:API 版本,例如 `v2` 或者 `2.5.0`。
- * 如果你之前的应用程序版本也使用 OpenAPI 会很有用。
-
-使用 `title`、`description` 和 `version` 来设置它们:
-
-```Python hl_lines="4-6"
-{!../../../docs_src/metadata/tutorial001.py!}
-```
-
-通过这样设置,自动 API 文档看起来会像:
-
-

-
-## 标签元数据
-
-你也可以使用参数 `openapi_tags`,为用于分组路径操作的不同标签添加额外的元数据。
-
-它接受一个列表,这个列表包含每个标签对应的一个字典。
-
-每个字典可以包含:
-
-* `name`(**必要**):一个 `str`,它与*路径操作*和 `APIRouter` 中使用的 `tags` 参数有相同的标签名。
-* `description`:一个用于简短描述标签的 `str`。它支持 Markdown 并且会在文档用户界面中显示。
-* `externalDocs`:一个描述外部文档的 `dict`:
- * `description`:用于简短描述外部文档的 `str`。
- * `url`(**必要**):外部文档的 URL `str`。
-
-### 创建标签元数据
-
-让我们在带有标签的示例中为 `users` 和 `items` 试一下。
-
-创建标签元数据并把它传递给 `openapi_tags` 参数:
-
-```Python hl_lines="3-16 18"
-{!../../../docs_src/metadata/tutorial004.py!}
-```
-
-注意你可以在描述内使用 Markdown,例如「login」会显示为粗体(**login**)以及「fancy」会显示为斜体(_fancy_)。
-
-!!! 提示
- 不必为你使用的所有标签都添加元数据。
-
-### 使用你的标签
-
-将 `tags` 参数和*路径操作*(以及 `APIRouter`)一起使用,将其分配给不同的标签:
-
-```Python hl_lines="21 26"
-{!../../../docs_src/metadata/tutorial004.py!}
-```
-
-!!! 信息
- 阅读更多关于标签的信息[路径操作配置](../path-operation-configuration/#tags){.internal-link target=_blank}。
-
-### 查看文档
-
-如果你现在查看文档,它们会显示所有附加的元数据:
-
-

-
-### 标签顺序
-
-每个标签元数据字典的顺序也定义了在文档用户界面显示的顺序。
-
-例如按照字母顺序,即使 `users` 排在 `items` 之后,它也会显示在前面,因为我们将它的元数据添加为列表内的第一个字典。
-
-## OpenAPI URL
-
-默认情况下,OpenAPI 模式服务于 `/openapi.json`。
-
-但是你可以通过参数 `openapi_url` 对其进行配置。
-
-例如,将其设置为服务于 `/api/v1/openapi.json`:
-
-```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial002.py!}
-```
-
-如果你想完全禁用 OpenAPI 模式,可以将其设置为 `openapi_url=None`,这样也会禁用使用它的文档用户界面。
-
-## 文档 URLs
-
-你可以配置两个文档用户界面,包括:
-
-* **Swagger UI**:服务于 `/docs`。
- * 可以使用参数 `docs_url` 设置它的 URL。
- * 可以通过设置 `docs_url=None` 禁用它。
-* ReDoc:服务于 `/redoc`。
- * 可以使用参数 `redoc_url` 设置它的 URL。
- * 可以通过设置 `redoc_url=None` 禁用它。
-
-例如,设置 Swagger UI 服务于 `/documentation` 并禁用 ReDoc:
-
-```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial003.py!}
-```
+# 元数据和文档 URL
+
+你可以在 FastAPI 应用程序中自定义多个元数据配置。
+
+## API 元数据
+
+你可以在设置 OpenAPI 规范和自动 API 文档 UI 中使用的以下字段:
+
+| 参数 | 类型 | 描述 |
+|------------|------|-------------|
+| `title` | `str` | API 的标题。 |
+| `summary` | `str` | API 的简短摘要。
自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。. |
+| `description` | `str` | API 的简短描述。可以使用Markdown。 |
+| `version` | `string` | API 的版本。这是您自己的应用程序的版本,而不是 OpenAPI 的版本。例如 `2.5.0` 。 |
+| `terms_of_service` | `str` | API 服务条款的 URL。如果提供,则必须是 URL。 |
+| `contact` | `dict` | 公开的 API 的联系信息。它可以包含多个字段。
contact
字段
参数 | Type | 描述 |
---|
name | str | 联系人/组织的识别名称。 |
url | str | 指向联系信息的 URL。必须采用 URL 格式。 |
email | str | 联系人/组织的电子邮件地址。必须采用电子邮件地址的格式。 |
|
+| `license_info` | `dict` | 公开的 API 的许可证信息。它可以包含多个字段。
license_info
字段
参数 | 类型 | 描述 |
---|
name | str | 必须的 (如果设置了license_info ). 用于 API 的许可证名称。 |
identifier | str | 一个API的SPDX许可证表达。 The identifier field is mutually exclusive of the url field. 自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。 |
url | str | 用于 API 的许可证的 URL。必须采用 URL 格式。 |
|
+
+你可以按如下方式设置它们:
+
+{* ../../docs_src/metadata/tutorial001.py hl[4:6] *}
+
+/// tip
+
+您可以在 `description` 字段中编写 Markdown,它将在输出中呈现。
+
+///
+
+通过这样设置,自动 API 文档看起来会像:
+
+

+
+## 标签元数据
+
+### 创建标签元数据
+
+让我们在带有标签的示例中为 `users` 和 `items` 试一下。
+
+创建标签元数据并把它传递给 `openapi_tags` 参数:
+
+{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+
+注意你可以在描述内使用 Markdown,例如「login」会显示为粗体(**login**)以及「fancy」会显示为斜体(_fancy_)。
+
+/// tip | 提示
+
+不必为你使用的所有标签都添加元数据。
+
+///
+
+### 使用你的标签
+
+将 `tags` 参数和*路径操作*(以及 `APIRouter`)一起使用,将其分配给不同的标签:
+
+{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+
+/// info | 信息
+
+阅读更多关于标签的信息[路径操作配置](path-operation-configuration.md#tags){.internal-link target=_blank}。
+
+///
+
+### 查看文档
+
+如果你现在查看文档,它们会显示所有附加的元数据:
+
+

+
+### 标签顺序
+
+每个标签元数据字典的顺序也定义了在文档用户界面显示的顺序。
+
+例如按照字母顺序,即使 `users` 排在 `items` 之后,它也会显示在前面,因为我们将它的元数据添加为列表内的第一个字典。
+
+## OpenAPI URL
+
+默认情况下,OpenAPI 模式服务于 `/openapi.json`。
+
+但是你可以通过参数 `openapi_url` 对其进行配置。
+
+例如,将其设置为服务于 `/api/v1/openapi.json`:
+
+{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+
+如果你想完全禁用 OpenAPI 模式,可以将其设置为 `openapi_url=None`,这样也会禁用使用它的文档用户界面。
+
+## 文档 URLs
+
+你可以配置两个文档用户界面,包括:
+
+* **Swagger UI**:服务于 `/docs`。
+ * 可以使用参数 `docs_url` 设置它的 URL。
+ * 可以通过设置 `docs_url=None` 禁用它。
+* ReDoc:服务于 `/redoc`。
+ * 可以使用参数 `redoc_url` 设置它的 URL。
+ * 可以通过设置 `redoc_url=None` 禁用它。
+
+例如,设置 Swagger UI 服务于 `/documentation` 并禁用 ReDoc:
+
+{* ../../docs_src/metadata/tutorial003.py hl[3] *}
diff --git a/docs/zh/docs/tutorial/middleware.md b/docs/zh/docs/tutorial/middleware.md
index c9a7e7725..258ca7482 100644
--- a/docs/zh/docs/tutorial/middleware.md
+++ b/docs/zh/docs/tutorial/middleware.md
@@ -11,10 +11,13 @@
* 它可以对该**响应**做些什么或者执行任何需要的代码.
* 然后它返回这个 **响应**.
-!!! note "技术细节"
- 如果你使用了 `yield` 关键字依赖, 依赖中的退出代码将在执行中间件*后*执行.
+/// note | 技术细节
- 如果有任何后台任务(稍后记录), 它们将在执行中间件*后*运行.
+如果你使用了 `yield` 关键字依赖, 依赖中的退出代码将在执行中间件*后*执行.
+
+如果有任何后台任务(稍后记录), 它们将在执行中间件*后*运行.
+
+///
## 创建中间件
@@ -28,19 +31,23 @@
* 然后它将返回由相应的*路径操作*生成的 `response`.
* 然后你可以在返回 `response` 前进一步修改它.
-```Python hl_lines="8-9 11 14"
-{!../../../docs_src/middleware/tutorial001.py!}
-```
+{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+
+/// tip
+
+请记住可以
用'X-' 前缀添加专有自定义请求头.
+
+但是如果你想让浏览器中的客户端看到你的自定义请求头, 你需要把它们加到 CORS 配置 ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) 的 `expose_headers` 参数中,在
Starlette's CORS docs文档中.
+
+///
-!!! tip
- 请记住可以
用'X-' 前缀添加专有自定义请求头.
+/// note | 技术细节
- 但是如果你想让浏览器中的客户端看到你的自定义请求头, 你需要把它们加到 CORS 配置 ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) 的 `expose_headers` 参数中,在
Starlette's CORS docs文档中.
+你也可以使用 `from starlette.requests import Request`.
-!!! note "技术细节"
- 你也可以使用 `from starlette.requests import Request`.
+**FastAPI** 为了开发者方便提供了该对象. 但其实它直接来自于 Starlette.
- **FastAPI** 为了开发者方便提供了该对象. 但其实它直接来自于 Starlette.
+///
### 在 `response` 的前和后
@@ -50,9 +57,7 @@
例如你可以添加自定义请求头 `X-Process-Time` 包含以秒为单位的接收请求和生成响应的时间:
-```Python hl_lines="10 12-13"
-{!../../../docs_src/middleware/tutorial001.py!}
-```
+{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
## 其他中间件
diff --git a/docs/zh/docs/tutorial/path-operation-configuration.md b/docs/zh/docs/tutorial/path-operation-configuration.md
index f79b0e692..adeca2d3f 100644
--- a/docs/zh/docs/tutorial/path-operation-configuration.md
+++ b/docs/zh/docs/tutorial/path-operation-configuration.md
@@ -2,9 +2,11 @@
*路径操作装饰器*支持多种配置参数。
-!!! warning "警告"
+/// warning | 警告
- 注意:以下参数应直接传递给**路径操作装饰器**,不能传递给*路径操作函数*。
+注意:以下参数应直接传递给**路径操作装饰器**,不能传递给*路径操作函数*。
+
+///
## `status_code` 状态码
@@ -14,25 +16,23 @@
如果记不住数字码的涵义,也可以用 `status` 的快捷常量:
-```Python hl_lines="3 17"
-{!../../../docs_src/path_operation_configuration/tutorial001.py!}
-```
+{* ../../docs_src/path_operation_configuration/tutorial001.py hl[3,17] *}
状态码在响应中使用,并会被添加到 OpenAPI 概图。
-!!! note "技术细节"
+/// note | 技术细节
+
+也可以使用 `from starlette import status` 导入状态码。
- 也可以使用 `from starlette import status` 导入状态码。
+**FastAPI** 的`fastapi.status` 和 `starlette.status` 一样,只是快捷方式。实际上,`fastapi.status` 直接继承自 Starlette。
- **FastAPI** 的`fastapi.status` 和 `starlette.status` 一样,只是快捷方式。实际上,`fastapi.status` 直接继承自 Starlette。
+///
## `tags` 参数
`tags` 参数的值是由 `str` 组成的 `list` (一般只有一个 `str` ),`tags` 用于为*路径操作*添加标签:
-```Python hl_lines="17 22 27"
-{!../../../docs_src/path_operation_configuration/tutorial002.py!}
-```
+{* ../../docs_src/path_operation_configuration/tutorial002.py hl[17,22,27] *}
OpenAPI 概图会自动添加标签,供 API 文档接口使用:
@@ -42,9 +42,7 @@ OpenAPI 概图会自动添加标签,供 API 文档接口使用:
路径装饰器还支持 `summary` 和 `description` 这两个参数:
-```Python hl_lines="20-21"
-{!../../../docs_src/path_operation_configuration/tutorial003.py!}
-```
+{* ../../docs_src/path_operation_configuration/tutorial003.py hl[20:21] *}
## 文档字符串(`docstring`)
@@ -52,9 +50,7 @@ OpenAPI 概图会自动添加标签,供 API 文档接口使用:
文档字符串支持
Markdown,能正确解析和显示 Markdown 的内容,但要注意文档字符串的缩进。
-```Python hl_lines="19-27"
-{!../../../docs_src/path_operation_configuration/tutorial004.py!}
-```
+{* ../../docs_src/path_operation_configuration/tutorial004.py hl[19:27] *}
下图为 Markdown 文本在 API 文档中的显示效果:
@@ -64,19 +60,21 @@ OpenAPI 概图会自动添加标签,供 API 文档接口使用:
`response_description` 参数用于定义响应的描述说明:
-```Python hl_lines="21"
-{!../../../docs_src/path_operation_configuration/tutorial005.py!}
-```
+{* ../../docs_src/path_operation_configuration/tutorial005.py hl[21] *}
+
+/// info | 说明
+
+注意,`response_description` 只用于描述响应,`description` 一般则用于描述*路径操作*。
-!!! info "说明"
+///
- 注意,`response_description` 只用于描述响应,`description` 一般则用于描述*路径操作*。
+/// check | 检查
-!!! check "检查"
+OpenAPI 规定每个*路径操作*都要有响应描述。
- OpenAPI 规定每个*路径操作*都要有响应描述。
+如果没有定义响应描述,**FastAPI** 则自动生成内容为 "Successful response" 的响应描述。
- 如果没有定义响应描述,**FastAPI** 则自动生成内容为 "Successful response" 的响应描述。
+///

@@ -84,9 +82,7 @@ OpenAPI 概图会自动添加标签,供 API 文档接口使用:
`deprecated` 参数可以把*路径操作*标记为
弃用,无需直接删除:
-```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
-```
+{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
API 文档会把该路径操作标记为弃用:
diff --git a/docs/zh/docs/tutorial/path-params-numeric-validations.md b/docs/zh/docs/tutorial/path-params-numeric-validations.md
index 13512a08e..ff6242835 100644
--- a/docs/zh/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/zh/docs/tutorial/path-params-numeric-validations.md
@@ -6,9 +6,7 @@
首先,从 `fastapi` 导入 `Path`:
-```Python hl_lines="1"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
## 声明元数据
@@ -16,16 +14,17 @@
例如,要声明路径参数 `item_id`的 `title` 元数据值,你可以输入:
-```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
-!!! note
- 路径参数总是必需的,因为它必须是路径的一部分。
+/// note
- 所以,你应该在声明时使用 `...` 将其标记为必需参数。
+路径参数总是必需的,因为它必须是路径的一部分。
- 然而,即使你使用 `None` 声明路径参数或设置一个其他默认值也不会有任何影响,它依然会是必需参数。
+所以,你应该在声明时使用 `...` 将其标记为必需参数。
+
+然而,即使你使用 `None` 声明路径参数或设置一个其他默认值也不会有任何影响,它依然会是必需参数。
+
+///
## 按需对参数排序
@@ -43,9 +42,7 @@
因此,你可以将函数声明为:
-```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
## 按需对参数排序的技巧
@@ -55,9 +52,7 @@
Python 不会对该 `*` 做任何事情,但是它将知道之后的所有参数都应作为关键字参数(键值对),也被称为
kwargs
,来调用。即使它们没有默认值。
-```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
## 数值校验:大于等于
@@ -65,9 +60,7 @@ Python 不会对该 `*` 做任何事情,但是它将知道之后的所有参
像下面这样,添加 `ge=1` 后,`item_id` 将必须是一个大于(`g`reater than)或等于(`e`qual)`1` 的整数。
-```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial004.py hl[8] *}
## 数值校验:大于和小于等于
@@ -76,9 +69,7 @@ Python 不会对该 `*` 做任何事情,但是它将知道之后的所有参
* `gt`:大于(`g`reater `t`han)
* `le`:小于等于(`l`ess than or `e`qual)
-```Python hl_lines="9"
-{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial005.py hl[9] *}
## 数值校验:浮点数、大于和小于
@@ -90,9 +81,7 @@ Python 不会对该 `*` 做任何事情,但是它将知道之后的所有参
对于
lt
也是一样的。
-```Python hl_lines="11"
-{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial006.py hl[11] *}
## 总结
@@ -105,18 +94,24 @@ Python 不会对该 `*` 做任何事情,但是它将知道之后的所有参
* `lt`:小于(`l`ess `t`han)
* `le`:小于等于(`l`ess than or `e`qual)
-!!! info
- `Query`、`Path` 以及你后面会看到的其他类继承自一个共同的 `Param` 类(不需要直接使用它)。
+/// info
+
+`Query`、`Path` 以及你后面会看到的其他类继承自一个共同的 `Param` 类(不需要直接使用它)。
+
+而且它们都共享相同的所有你已看到并用于添加额外校验和元数据的参数。
+
+///
+
+/// note | 技术细节
- 而且它们都共享相同的所有你已看到并用于添加额外校验和元数据的参数。
+当你从 `fastapi` 导入 `Query`、`Path` 和其他同类对象时,它们实际上是函数。
-!!! note "技术细节"
- 当你从 `fastapi` 导入 `Query`、`Path` 和其他同类对象时,它们实际上是函数。
+当被调用时,它们返回同名类的实例。
- 当被调用时,它们返回同名类的实例。
+如此,你导入 `Query` 这个函数。当你调用它时,它将返回一个同样命名为 `Query` 的类的实例。
- 如此,你导入 `Query` 这个函数。当你调用它时,它将返回一个同样命名为 `Query` 的类的实例。
+因为使用了这些函数(而不是直接使用类),所以你的编辑器不会标记有关其类型的错误。
- 因为使用了这些函数(而不是直接使用类),所以你的编辑器不会标记有关其类型的错误。
+这样,你可以使用常规的编辑器和编码工具,而不必添加自定义配置来忽略这些错误。
- 这样,你可以使用常规的编辑器和编码工具,而不必添加自定义配置来忽略这些错误。
+///
diff --git a/docs/zh/docs/tutorial/path-params.md b/docs/zh/docs/tutorial/path-params.md
index 1b428d662..ac9df0831 100644
--- a/docs/zh/docs/tutorial/path-params.md
+++ b/docs/zh/docs/tutorial/path-params.md
@@ -1,48 +1,50 @@
# 路径参数
-你可以使用与 Python 格式化字符串相同的语法来声明路径"参数"或"变量":
+FastAPI 支持使用 Python 字符串格式化语法声明**路径参数**(**变量**):
-```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
-```
+{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
-路径参数 `item_id` 的值将作为参数 `item_id` 传递给你的函数。
+这段代码把路径参数 `item_id` 的值传递给路径函数的参数 `item_id`。
-所以,如果你运行示例并访问
http://127.0.0.1:8000/items/foo,将会看到如下响应:
+运行示例并访问
http://127.0.0.1:8000/items/foo,可获得如下响应:
```JSON
{"item_id":"foo"}
```
-## 有类型的路径参数
+## 声明路径参数的类型
-你可以使用标准的 Python 类型标注为函数中的路径参数声明类型。
+使用 Python 标准类型注解,声明路径操作函数中路径参数的类型。
-```Python hl_lines="7"
-{!../../../docs_src/path_params/tutorial002.py!}
-```
+{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+
+本例把 `item_id` 的类型声明为 `int`。
+
+/// check | 检查
-在这个例子中,`item_id` 被声明为 `int` 类型。
+类型声明将为函数提供错误检查、代码补全等编辑器支持。
-!!! check
- 这将为你的函数提供编辑器支持,包括错误检查、代码补全等等。
+///
-## 数据
转换
+## 数据
转换
-如果你运行示例并打开浏览器访问
http://127.0.0.1:8000/items/3,将得到如下响应:
+运行示例并访问
http://127.0.0.1:8000/items/3,返回的响应如下:
```JSON
{"item_id":3}
```
-!!! check
- 注意函数接收(并返回)的值为 3,是一个 Python `int` 值,而不是字符串 `"3"`。
+/// check | 检查
- 所以,**FastAPI** 通过上面的类型声明提供了对请求的自动
"解析"。
+注意,函数接收并返回的值是 `3`( `int`),不是 `"3"`(`str`)。
+
+**FastAPI** 通过类型声明自动
**解析**请求中的数据。
+
+///
## 数据校验
-但如果你通过浏览器访问
http://127.0.0.1:8000/items/foo,你会看到一个清晰可读的 HTTP 错误:
+通过浏览器访问
http://127.0.0.1:8000/items/foo,接收如下 HTTP 错误信息:
```JSON
{
@@ -59,176 +61,190 @@
}
```
-因为路径参数 `item_id` 传入的值为 `"foo"`,它不是一个 `int`。
+这是因为路径参数 `item_id` 的值 (`"foo"`)的类型不是 `int`。
+
+值的类型不是 `int ` 而是浮点数(`float`)时也会显示同样的错误,比如:
http://127.0.0.1:8000/items/4.2。
+
+/// check | 检查
-如果你提供的是 `float` 而非整数也会出现同样的错误,比如:
http://127.0.0.1:8000/items/4.2
+**FastAPI** 使用 Python 类型声明实现了数据校验。
-!!! check
- 所以,通过同样的 Python 类型声明,**FastAPI** 提供了数据校验功能。
+注意,上面的错误清晰地指出了未通过校验的具体原因。
- 注意上面的错误同样清楚地指出了校验未通过的具体原因。
+这在开发调试与 API 交互的代码时非常有用。
- 在开发和调试与你的 API 进行交互的代码时,这非常有用。
+///
-## 文档
+## 查看文档
-当你打开浏览器访问
http://127.0.0.1:8000/docs,你将看到自动生成的交互式 API 文档:
+访问
http://127.0.0.1:8000/docs,查看自动生成的 API 文档:
-

+

-!!! check
- 再一次,还是通过相同的 Python 类型声明,**FastAPI** 为你提供了自动生成的交互式文档(集成 Swagger UI)。
+/// check | 检查
- 注意这里的路径参数被声明为一个整数。
+还是使用 Python 类型声明,**FastAPI** 提供了(集成 Swagger UI 的)API 文档。
-## 基于标准的好处:可选文档
+注意,路径参数的类型是整数。
-由于生成的 API 模式来自于
OpenAPI 标准,所以有很多工具与其兼容。
+///
-正因如此,**FastAPI** 内置了一个可选的 API 文档(使用 Redoc):
+## 基于标准的好处,备选文档
-

+**FastAPI** 使用
OpenAPI 生成概图,所以能兼容很多工具。
-同样的,还有很多其他兼容的工具,包括适用于多种语言的代码生成工具。
+因此,**FastAPI** 还内置了 ReDoc 生成的备选 API 文档,可在此查看
http://127.0.0.1:8000/redoc:
+
+

+
+同样,还有很多兼容工具,包括多种语言的代码生成工具。
## Pydantic
-所有的数据校验都由
Pydantic 在幕后完成,所以你可以从它所有的优点中受益。并且你知道它在这方面非常胜任。
+FastAPI 充分地利用了
Pydantic 的优势,用它在后台校验数据。众所周知,Pydantic 擅长的就是数据校验。
-你可以使用同样的类型声明来声明 `str`、`float`、`bool` 以及许多其他的复合数据类型。
+同样,`str`、`float`、`bool` 以及很多复合数据类型都可以使用类型声明。
-本教程的下一章节将探讨其中的一些内容。
+下一章介绍详细内容。
## 顺序很重要
-在创建*路径操作*时,你会发现有些情况下路径是固定的。
+有时,*路径操作*中的路径是写死的。
-比如 `/users/me`,我们假设它用来获取关于当前用户的数据.
+比如要使用 `/users/me` 获取当前用户的数据。
-然后,你还可以使用路径 `/users/{user_id}` 来通过用户 ID 获取关于特定用户的数据。
+然后还要使用 `/users/{user_id}`,通过用户 ID 获取指定用户的数据。
-由于*路径操作*是按顺序依次运行的,你需要确保路径 `/users/me` 声明在路径 `/users/{user_id}`之前:
-```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
-```
+由于*路径操作*是按顺序依次运行的,因此,一定要在 `/users/{user_id}` 之前声明 `/users/me` :
+
+{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
-否则,`/users/{user_id}` 的路径还将与 `/users/me` 相匹配,"认为"自己正在接收一个值为 `"me"` 的 `user_id` 参数。
+否则,`/users/{user_id}` 将匹配 `/users/me`,FastAPI 会**认为**正在接收值为 `"me"` 的 `user_id` 参数。
## 预设值
-如果你有一个接收路径参数的路径操作,但你希望预先设定可能的有效参数值,则可以使用标准的 Python
`Enum` 类型。
+路径操作使用 Python 的
`Enum` 类型接收预设的*路径参数*。
-### 创建一个 `Enum` 类
+### 创建 `Enum` 类
-导入 `Enum` 并创建一个继承自 `str` 和 `Enum` 的子类。
+导入 `Enum` 并创建继承自 `str` 和 `Enum` 的子类。
-通过从 `str` 继承,API 文档将能够知道这些值必须为 `string` 类型并且能够正确地展示出来。
+通过从 `str` 继承,API 文档就能把值的类型定义为**字符串**,并且能正确渲染。
-然后创建具有固定值的类属性,这些固定值将是可用的有效值:
+然后,创建包含固定值的类属性,这些固定值是可用的有效值:
-```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
+
+/// info | 说明
+
+Python 3.4 及之后版本支持
枚举(即 enums)。
-!!! info
-
枚举(或 enums)从 3.4 版本起在 Python 中可用。
+///
-!!! tip
- 如果你想知道,"AlexNet"、"ResNet" 和 "LeNet" 只是机器学习中的
模型名称。
+/// tip | 提示
+
+**AlexNet**、**ResNet**、**LeNet** 是机器学习
模型。
+
+///
### 声明*路径参数*
-然后使用你定义的枚举类(`ModelName`)创建一个带有类型标注的*路径参数*:
+使用 Enum 类(`ModelName`)创建使用类型注解的*路径参数*:
-```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[16] *}
### 查看文档
-因为已经指定了*路径参数*的可用值,所以交互式文档可以恰当地展示它们:
+ API 文档会显示预定义*路径参数*的可用值:
-

+

-### 使用 Python *枚举类型*
+### 使用 Python _枚举类型_
-*路径参数*的值将是一个*枚举成员*。
+*路径参数*的值是枚举的元素。
-#### 比较*枚举成员*
+#### 比较*枚举元素*
-你可以将它与你创建的枚举类 `ModelName` 中的*枚举成员*进行比较:
+枚举类 `ModelName` 中的*枚举元素*支持比较操作:
-```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[17] *}
#### 获取*枚举值*
-你可以使用 `model_name.value` 或通常来说 `your_enum_member.value` 来获取实际的值(在这个例子中为 `str`):
+使用 `model_name.value` 或 `your_enum_member.value` 获取实际的值(本例中为**字符串**):
-```Python hl_lines="19"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+
+/// tip | 提示
+
+使用 `ModelName.lenet.value` 也能获取值 `"lenet"`。
+
+///
-!!! tip
- 你也可以通过 `ModelName.lenet.value` 来获取值 `"lenet"`。
+#### 返回*枚举元素*
-#### 返回*枚举成员*
+即使嵌套在 JSON 请求体里(例如, `dict`),也可以从*路径操作*返回*枚举元素*。
-你可以从*路径操作*中返回*枚举成员*,即使嵌套在 JSON 结构中(例如一个 `dict` 中)。
+返回给客户端之前,要把枚举元素转换为对应的值(本例中为字符串):
-在返回给客户端之前,它们将被转换为对应的值:
+{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
-```Python hl_lines="18-21"
-{!../../../docs_src/path_params/tutorial005.py!}
+客户端中的 JSON 响应如下:
+
+```JSON
+{
+ "model_name": "alexnet",
+ "message": "Deep Learning FTW!"
+}
```
## 包含路径的路径参数
-假设你有一个*路径操作*,它的路径为 `/files/{file_path}`。
+假设*路径操作*的路径为 `/files/{file_path}`。
-但是你需要 `file_path` 自身也包含*路径*,比如 `home/johndoe/myfile.txt`。
+但需要 `file_path` 中也包含*路径*,比如,`home/johndoe/myfile.txt`。
-因此,该文件的URL将类似于这样:`/files/home/johndoe/myfile.txt`。
+此时,该文件的 URL 是这样的:`/files/home/johndoe/myfile.txt`。
### OpenAPI 支持
-OpenAPI 不支持任何方式去声明*路径参数*以在其内部包含*路径*,因为这可能会导致难以测试和定义的情况出现。
+OpenAPI 不支持声明包含路径的*路径参数*,因为这会导致测试和定义更加困难。
-不过,你仍然可以通过 Starlette 的一个内部工具在 **FastAPI** 中实现它。
+不过,仍可使用 Starlette 内置工具在 **FastAPI** 中实现这一功能。
-而且文档依旧可以使用,但是不会添加任何该参数应包含路径的说明。
+而且不影响文档正常运行,但是不会添加该参数包含路径的说明。
### 路径转换器
-你可以使用直接来自 Starlette 的选项来声明一个包含*路径*的*路径参数*:
+直接使用 Starlette 的选项声明包含*路径*的*路径参数*:
```
/files/{file_path:path}
```
-在这种情况下,参数的名称为 `file_path`,结尾部分的 `:path` 说明该参数应匹配任意的*路径*。
+本例中,参数名为 `file_path`,结尾部分的 `:path` 说明该参数应匹配*路径*。
-因此,你可以这样使用它:
+用法如下:
-```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
-```
+{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+
+/// tip | 提示
+
+注意,包含 `/home/johndoe/myfile.txt` 的路径参数要以斜杠(`/`)开头。
-!!! tip
- 你可能会需要参数包含 `/home/johndoe/myfile.txt`,以斜杠(`/`)开头。
+本例中的 URL 是 `/files//home/johndoe/myfile.txt`。注意,`files` 和 `home` 之间要使用**双斜杠**(`//`)。
- 在这种情况下,URL 将会是 `/files//home/johndoe/myfile.txt`,在`files` 和 `home` 之间有一个双斜杠(`//`)。
+///
-## 总结
+## 小结
-使用 **FastAPI**,通过简短、直观和标准的 Python 类型声明,你将获得:
+通过简短、直观的 Python 标准类型声明,**FastAPI** 可以获得:
-* 编辑器支持:错误检查,代码补全等
-* 数据 "
解析"
-* 数据校验
-* API 标注和自动生成的文档
+- 编辑器支持:错误检查,代码自动补全等
+- 数据**
解析**
+- 数据校验
+- API 注解和 API 文档
-而且你只需要声明一次即可。
+只需要声明一次即可。
-这可能是 **FastAPI** 与其他框架相比主要的明显优势(除了原始性能以外)。
+这可能是除了性能以外,**FastAPI** 与其它框架相比的主要优势。
diff --git a/docs/zh/docs/tutorial/query-param-models.md b/docs/zh/docs/tutorial/query-param-models.md
new file mode 100644
index 000000000..c6a79a71a
--- /dev/null
+++ b/docs/zh/docs/tutorial/query-param-models.md
@@ -0,0 +1,68 @@
+# 查询参数模型
+
+如果你有一组具有相关性的**查询参数**,你可以创建一个 **Pydantic 模型**来声明它们。
+
+这将允许你在**多个地方**去**复用模型**,并且一次性为所有参数声明验证和元数据。😎
+
+/// note
+
+FastAPI 从 `0.115.0` 版本开始支持这个特性。🤓
+
+///
+
+## 使用 Pydantic 模型的查询参数
+
+在一个 **Pydantic 模型**中声明你需要的**查询参数**,然后将参数声明为 `Query`:
+
+{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
+
+**FastAPI** 将会从请求的**查询参数**中**提取**出**每个字段**的数据,并将其提供给你定义的 Pydantic 模型。
+
+## 查看文档
+
+你可以在 `/docs` 页面的 UI 中查看查询参数:
+
+
+

+
+
+## 禁止额外的查询参数
+
+在一些特殊的使用场景中(可能不是很常见),你可能希望**限制**你要接收的查询参数。
+
+你可以使用 Pydantic 的模型配置来 `forbid`(意为禁止 —— 译者注)任何 `extra`(意为额外的 —— 译者注)字段:
+
+{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
+
+假设有一个客户端尝试在**查询参数**中发送一些**额外的**数据,它将会收到一个**错误**响应。
+
+例如,如果客户端尝试发送一个值为 `plumbus` 的 `tool` 查询参数,如:
+
+```http
+https://example.com/items/?limit=10&tool=plumbus
+```
+
+他们将收到一个**错误**响应,告诉他们查询参数 `tool` 是不允许的:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["query", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus"
+ }
+ ]
+}
+```
+
+## 总结
+
+你可以使用 **Pydantic 模型**在 **FastAPI** 中声明**查询参数**。😎
+
+/// tip
+
+剧透警告:你也可以使用 Pydantic 模型来声明 cookie 和 headers,但你将在本教程的后面部分阅读到这部分内容。🤫
+
+///
diff --git a/docs/zh/docs/tutorial/query-params-str-validations.md b/docs/zh/docs/tutorial/query-params-str-validations.md
index 070074839..c2f9a7e9f 100644
--- a/docs/zh/docs/tutorial/query-params-str-validations.md
+++ b/docs/zh/docs/tutorial/query-params-str-validations.md
@@ -4,9 +4,7 @@
让我们以下面的应用程序为例:
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial001.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
查询参数 `q` 的类型为 `str`,默认值为 `None`,因此它是可选的。
@@ -18,17 +16,13 @@
为此,首先从 `fastapi` 导入 `Query`:
-```Python hl_lines="1"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial002.py hl[1] *}
## 使用 `Query` 作为默认值
现在,将 `Query` 用作查询参数的默认值,并将它的 `max_length` 参数设置为 50:
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial002.py hl[9] *}
由于我们必须用 `Query(default=None)` 替换默认值 `None`,`Query` 的第一个参数同样也是用于定义默认值。
@@ -58,17 +52,13 @@ q: Union[str, None] = Query(default=None, max_length=50)
你还可以添加 `min_length` 参数:
-```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial003.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial003.py hl[10] *}
## 添加正则表达式
你可以定义一个参数值必须匹配的
正则表达式:
-```Python hl_lines="11"
-{!../../../docs_src/query_params_str_validations/tutorial004.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial004.py hl[11] *}
这个指定的正则表达式通过以下规则检查接收到的参数值:
@@ -86,12 +76,13 @@ q: Union[str, None] = Query(default=None, max_length=50)
假设你想要声明查询参数 `q`,使其 `min_length` 为 `3`,并且默认值为 `fixedquery`:
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial005.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial005.py hl[7] *}
+
+/// note
-!!! note
- 具有默认值还会使该参数成为可选参数。
+具有默认值还会使该参数成为可选参数。
+
+///
## 声明为必需参数
@@ -115,23 +106,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
因此,当你在使用 `Query` 且需要声明一个值是必需的时,只需不声明默认参数:
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006.py!}
-```
-
-### 使用省略号(`...`)声明必需参数
-
-有另一种方法可以显式的声明一个值是必需的,即将默认参数的默认值设为 `...` :
-
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006b.py!}
-```
-
-!!! info
- 如果你之前没见过 `...` 这种用法:它是一个特殊的单独值,它是
Python 的一部分并且被称为「省略号」。
- Pydantic 和 FastAPI 使用它来显式的声明需要一个值。
-
-这将使 **FastAPI** 知道此查询参数是必需的。
+{* ../../docs_src/query_params_str_validations/tutorial006.py hl[7] *}
### 使用`None`声明必需参数
@@ -139,24 +114,13 @@ q: Union[str, None] = Query(default=None, min_length=3)
为此,你可以声明`None`是一个有效的类型,并仍然使用`default=...`:
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial006c.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial006c.py hl[9] *}
-!!! tip
- Pydantic 是 FastAPI 中所有数据验证和序列化的核心,当你在没有设默认值的情况下使用 `Optional` 或 `Union[Something, None]` 时,它具有特殊行为,你可以在 Pydantic 文档中阅读有关
必需可选字段的更多信息。
+/// tip
-### 使用Pydantic中的`Required`代替省略号(`...`)
-
-如果你觉得使用 `...` 不舒服,你也可以从 Pydantic 导入并使用 `Required`:
-
-```Python hl_lines="2 8"
-{!../../../docs_src/query_params_str_validations/tutorial006d.py!}
-```
-
-!!! tip
- 请记住,在大多数情况下,当你需要某些东西时,可以简单地省略 `default` 参数,因此你通常不必使用 `...` 或 `Required`
+Pydantic 是 FastAPI 中所有数据验证和序列化的核心,当你在没有设默认值的情况下使用 `Optional` 或 `Union[Something, None]` 时,它具有特殊行为,你可以在 Pydantic 文档中阅读有关
必需可选字段的更多信息。
+///
## 查询参数列表 / 多个值
@@ -164,9 +128,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
例如,要声明一个可在 URL 中出现多次的查询参数 `q`,你可以这样写:
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial011.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial011.py hl[9] *}
然后,输入如下网址:
@@ -187,8 +149,11 @@ http://localhost:8000/items/?q=foo&q=bar
}
```
-!!! tip
- 要声明类型为 `list` 的查询参数,如上例所示,你需要显式地使用 `Query`,否则该参数将被解释为请求体。
+/// tip
+
+要声明类型为 `list` 的查询参数,如上例所示,你需要显式地使用 `Query`,否则该参数将被解释为请求体。
+
+///
交互式 API 文档将会相应地进行更新,以允许使用多个值:
@@ -198,9 +163,7 @@ http://localhost:8000/items/?q=foo&q=bar
你还可以定义在没有任何给定值时的默认 `list` 值:
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial012.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial012.py hl[9] *}
如果你访问:
@@ -223,14 +186,15 @@ http://localhost:8000/items/
你也可以直接使用 `list` 代替 `List [str]`:
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial013.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial013.py hl[7] *}
-!!! note
- 请记住,在这种情况下 FastAPI 将不会检查列表的内容。
+/// note
- 例如,`List[int]` 将检查(并记录到文档)列表的内容必须是整数。但是单独的 `list` 不会。
+请记住,在这种情况下 FastAPI 将不会检查列表的内容。
+
+例如,`List[int]` 将检查(并记录到文档)列表的内容必须是整数。但是单独的 `list` 不会。
+
+///
## 声明更多元数据
@@ -238,22 +202,21 @@ http://localhost:8000/items/
这些信息将包含在生成的 OpenAPI 模式中,并由文档用户界面和外部工具所使用。
-!!! note
- 请记住,不同的工具对 OpenAPI 的支持程度可能不同。
+/// note
+
+请记住,不同的工具对 OpenAPI 的支持程度可能不同。
+
+其中一些可能不会展示所有已声明的额外信息,尽管在大多数情况下,缺少的这部分功能已经计划进行开发。
- 其中一些可能不会展示所有已声明的额外信息,尽管在大多数情况下,缺少的这部分功能已经计划进行开发。
+///
你可以添加 `title`:
-```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial007.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial007.py hl[10] *}
以及 `description`:
-```Python hl_lines="13"
-{!../../../docs_src/query_params_str_validations/tutorial008.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial008.py hl[13] *}
## 别名参数
@@ -273,9 +236,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
这时你可以用 `alias` 参数声明一个别名,该别名将用于在 URL 中查找查询参数值:
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial009.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial009.py hl[9] *}
## 弃用参数
@@ -285,9 +246,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
那么将参数 `deprecated=True` 传入 `Query`:
-```Python hl_lines="18"
-{!../../../docs_src/query_params_str_validations/tutorial010.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial010.py hl[18] *}
文档将会像下面这样展示它:
diff --git a/docs/zh/docs/tutorial/query-params.md b/docs/zh/docs/tutorial/query-params.md
index b1668a2d2..cc2e74b9e 100644
--- a/docs/zh/docs/tutorial/query-params.md
+++ b/docs/zh/docs/tutorial/query-params.md
@@ -1,86 +1,92 @@
# 查询参数
-声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数
+声明的参数不是路径参数时,路径操作函数会把该参数自动解释为**查询**参数。
-```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
-```
+{* ../../docs_src/query_params/tutorial001.py hl[9] *}
-查询字符串是键值对的集合,这些键值对位于 URL 的 `?` 之后,并以 `&` 符号分隔。
+查询字符串是键值对的集合,这些键值对位于 URL 的 `?` 之后,以 `&` 分隔。
-例如,在以下 url 中:
+例如,以下 URL 中:
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
-...查询参数为:
+……查询参数为:
-* `skip`:对应的值为 `0`
-* `limit`:对应的值为 `10`
+* `skip`:值为 `0`
+* `limit`:值为 `10`
-由于它们是 URL 的一部分,因此它们的"原始值"是字符串。
+这些值都是 URL 的组成部分,因此,它们的类型**本应**是字符串。
-但是,当你为它们声明了 Python 类型(在上面的示例中为 `int`)时,它们将转换为该类型并针对该类型进行校验。
+但声明 Python 类型(上例中为 `int`)之后,这些值就会转换为声明的类型,并进行类型校验。
-应用于路径参数的所有相同过程也适用于查询参数:
+所有应用于路径参数的流程也适用于查询参数:
-* (很明显的)编辑器支持
-* 数据
"解析"
+* (显而易见的)编辑器支持
+* 数据
**解析**
* 数据校验
-* 自动生成文档
+* API 文档
## 默认值
-由于查询参数不是路径的固定部分,因此它们可以是可选的,并且可以有默认值。
+查询参数不是路径的固定内容,它是可选的,还支持默认值。
-在上面的示例中,它们具有 `skip=0` 和 `limit=10` 的默认值。
+上例用 `skip=0` 和 `limit=10` 设定默认值。
-因此,访问 URL:
+访问 URL:
```
http://127.0.0.1:8000/items/
```
-将与访问以下地址相同:
+与访问以下地址相同:
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
-但是,如果你访问的是:
+但如果访问:
```
http://127.0.0.1:8000/items/?skip=20
```
-函数中的参数值将会是:
+查询参数的值就是:
* `skip=20`:在 URL 中设定的值
* `limit=10`:使用默认值
## 可选参数
-通过同样的方式,你可以将它们的默认值设置为 `None` 来声明可选查询参数:
+同理,把默认值设为 `None` 即可声明**可选的**查询参数:
-```Python hl_lines="7"
-{!../../../docs_src/query_params/tutorial002.py!}
-```
+{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
+
+本例中,查询参数 `q` 是可选的,默认值为 `None`。
+
+/// check | 检查
+
+注意,**FastAPI** 可以识别出 `item_id` 是路径参数,`q` 不是路径参数,而是查询参数。
+
+///
+
+/// note | 笔记
+
+因为默认值为 `= None`,FastAPI 把 `q` 识别为可选参数。
-在这个例子中,函数参数 `q` 将是可选的,并且默认值为 `None`。
+FastAPI 不使用 `Optional[str]` 中的 `Optional`(只使用 `str`),但 `Optional[str]` 可以帮助编辑器发现代码中的错误。
-!!! check
- 还要注意的是,**FastAPI** 足够聪明,能够分辨出参数 `item_id` 是路径参数而 `q` 不是,因此 `q` 是一个查询参数。
+///
## 查询参数类型转换
-你还可以声明 `bool` 类型,它们将被自动转换:
+参数还可以声明为 `bool` 类型,FastAPI 会自动转换参数类型:
-```Python hl_lines="7"
-{!../../../docs_src/query_params/tutorial003.py!}
-```
-这个例子中,如果你访问:
+{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
+
+本例中,访问:
```
http://127.0.0.1:8000/items/foo?short=1
@@ -110,42 +116,38 @@ http://127.0.0.1:8000/items/foo?short=on
http://127.0.0.1:8000/items/foo?short=yes
```
-或任何其他的变体形式(大写,首字母大写等等),你的函数接收的 `short` 参数都会是布尔值 `True`。对于值为 `False` 的情况也是一样的。
+或其它任意大小写形式(大写、首字母大写等),函数接收的 `short` 参数都是布尔值 `True`。值为 `False` 时也一样。
## 多个路径和查询参数
-你可以同时声明多个路径参数和查询参数,**FastAPI** 能够识别它们。
+**FastAPI** 可以识别同时声明的多个路径参数和查询参数。
-而且你不需要以任何特定的顺序来声明。
+而且声明查询参数的顺序并不重要。
-它们将通过名称被检测到:
+FastAPI 通过参数名进行检测:
-```Python hl_lines="6 8"
-{!../../../docs_src/query_params/tutorial004.py!}
-```
+{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
-## 必需查询参数
+## 必选查询参数
-当你为非路径参数声明了默认值时(目前而言,我们所知道的仅有查询参数),则该参数不是必需的。
+为不是路径参数的参数声明默认值(至此,仅有查询参数),该参数就**不是必选**的了。
-如果你不想添加一个特定的值,而只是想使该参数成为可选的,则将默认值设置为 `None`。
+如果只想把参数设为**可选**,但又不想指定参数的值,则要把默认值设为 `None`。
-但当你想让一个查询参数成为必需的,不声明任何默认值就可以:
+如果要把查询参数设置为**必选**,就不要声明默认值:
-```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
-```
+{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
-这里的查询参数 `needy` 是类型为 `str` 的必需查询参数。
+这里的查询参数 `needy` 是类型为 `str` 的必选查询参数。
-如果你在浏览器中打开一个像下面的 URL:
+在浏览器中打开如下 URL:
```
http://127.0.0.1:8000/items/foo-item
```
-...因为没有添加必需的参数 `needy`,你将看到类似以下的错误:
+……因为路径中没有必选参数 `needy`,返回的响应中会显示如下错误信息:
```JSON
{
@@ -162,13 +164,13 @@ http://127.0.0.1:8000/items/foo-item
}
```
-由于 `needy` 是必需参数,因此你需要在 URL 中设置它的值:
+`needy` 是必选参数,因此要在 URL 中设置值:
```
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
```
-...这样就正常了:
+……这样就正常了:
```JSON
{
@@ -177,17 +179,18 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
}
```
-当然,你也可以定义一些参数为必需的,一些具有默认值,而某些则完全是可选的:
+当然,把一些参数定义为必选,为另一些参数设置默认值,再把其它参数定义为可选,这些操作都是可以的:
-```Python hl_lines="7"
-{!../../../docs_src/query_params/tutorial006.py!}
-```
+{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
+
+本例中有 3 个查询参数:
+
+* `needy`,必选的 `str` 类型参数
+* `skip`,默认值为 `0` 的 `int` 类型参数
+* `limit`,可选的 `int` 类型参数
-在这个例子中,有3个查询参数:
+/// tip | 提示
-* `needy`,一个必需的 `str` 类型参数。
-* `skip`,一个默认值为 `0` 的 `int` 类型参数。
-* `limit`,一个可选的 `int` 类型参数。
+还可以像在[路径参数](path-params.md#_8){.internal-link target=_blank} 中那样使用 `Enum`。
-!!! tip
- 你还可以像在 [路径参数](path-params.md#predefined-values){.internal-link target=_blank} 中那样使用 `Enum`。
+///
diff --git a/docs/zh/docs/tutorial/request-files.md b/docs/zh/docs/tutorial/request-files.md
index e18d6fc9f..81ddc7238 100644
--- a/docs/zh/docs/tutorial/request-files.md
+++ b/docs/zh/docs/tutorial/request-files.md
@@ -2,39 +2,41 @@
`File` 用于定义客户端的上传文件。
-!!! info "说明"
+/// info | 说明
- 因为上传文件以「表单数据」形式发送。
+因为上传文件以「表单数据」形式发送。
- 所以接收上传文件,要预先安装
`python-multipart`。
+所以接收上传文件,要预先安装
`python-multipart`。
- 例如: `pip install python-multipart`。
+例如: `pip install python-multipart`。
+
+///
## 导入 `File`
从 `fastapi` 导入 `File` 和 `UploadFile`:
-```Python hl_lines="1"
-{!../../../docs_src/request_files/tutorial001.py!}
-```
+{* ../../docs_src/request_files/tutorial001.py hl[1] *}
## 定义 `File` 参数
创建文件(`File`)参数的方式与 `Body` 和 `Form` 一样:
-```Python hl_lines="7"
-{!../../../docs_src/request_files/tutorial001.py!}
-```
+{* ../../docs_src/request_files/tutorial001.py hl[7] *}
-!!! info "说明"
+/// info | 说明
- `File` 是直接继承自 `Form` 的类。
+`File` 是直接继承自 `Form` 的类。
- 注意,从 `fastapi` 导入的 `Query`、`Path`、`File` 等项,实际上是返回特定类的函数。
+注意,从 `fastapi` 导入的 `Query`、`Path`、`File` 等项,实际上是返回特定类的函数。
-!!! tip "提示"
+///
- 声明文件体必须使用 `File`,否则,FastAPI 会把该参数当作查询参数或请求体(JSON)参数。
+/// tip | 提示
+
+声明文件体必须使用 `File`,否则,FastAPI 会把该参数当作查询参数或请求体(JSON)参数。
+
+///
文件作为「表单数据」上传。
@@ -48,9 +50,7 @@
定义文件参数时使用 `UploadFile`:
-```Python hl_lines="12"
-{!../../../docs_src/request_files/tutorial001.py!}
-```
+{* ../../docs_src/request_files/tutorial001.py hl[12] *}
`UploadFile` 与 `bytes` 相比有更多优势:
@@ -92,13 +92,17 @@ contents = await myfile.read()
contents = myfile.file.read()
```
-!!! note "`async` 技术细节"
+/// note | `async` 技术细节
- 使用 `async` 方法时,**FastAPI** 在线程池中执行文件方法,并 `await` 操作完成。
+使用 `async` 方法时,**FastAPI** 在线程池中执行文件方法,并 `await` 操作完成。
-!!! note "Starlette 技术细节"
+///
- **FastAPI** 的 `UploadFile` 直接继承自 **Starlette** 的 `UploadFile`,但添加了一些必要功能,使之与 **Pydantic** 及 FastAPI 的其它部件兼容。
+/// note | Starlette 技术细节
+
+**FastAPI** 的 `UploadFile` 直接继承自 **Starlette** 的 `UploadFile`,但添加了一些必要功能,使之与 **Pydantic** 及 FastAPI 的其它部件兼容。
+
+///
## 什么是 「表单数据」
@@ -106,43 +110,35 @@ contents = myfile.file.read()
**FastAPI** 要确保从正确的位置读取数据,而不是读取 JSON。
-!!! note "技术细节"
+/// note | 技术细节
- 不包含文件时,表单数据一般用 `application/x-www-form-urlencoded`「媒体类型」编码。
+不包含文件时,表单数据一般用 `application/x-www-form-urlencoded`「媒体类型」编码。
- 但表单包含文件时,编码为 `multipart/form-data`。使用了 `File`,**FastAPI** 就知道要从请求体的正确位置获取文件。
+但表单包含文件时,编码为 `multipart/form-data`。使用了 `File`,**FastAPI** 就知道要从请求体的正确位置获取文件。
- 编码和表单字段详见
MDN Web 文档的 POST
小节。
+编码和表单字段详见
MDN Web 文档的 POST
小节。
-!!! warning "警告"
+///
- 可在一个*路径操作*中声明多个 `File` 和 `Form` 参数,但不能同时声明要接收 JSON 的 `Body` 字段。因为此时请求体的编码是 `multipart/form-data`,不是 `application/json`。
+/// warning | 警告
- 这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
+可在一个*路径操作*中声明多个 `File` 和 `Form` 参数,但不能同时声明要接收 JSON 的 `Body` 字段。因为此时请求体的编码是 `multipart/form-data`,不是 `application/json`。
-## 可选文件上传
-
-您可以通过使用标准类型注解并将 None 作为默认值的方式将一个文件参数设为可选:
+这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
-=== "Python 3.6 及以上版本"
+///
- ```Python hl_lines="9 17"
- {!> ../../../docs_src/request_files/tutorial001_02.py!}
- ```
+## 可选文件上传
-=== "Python 3.9 及以上版本"
+您可以通过使用标准类型注解并将 None 作为默认值的方式将一个文件参数设为可选:
- ```Python hl_lines="7 14"
- {!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
- ```
+{* ../../docs_src/request_files/tutorial001_02_py310.py hl[7,14] *}
## 带有额外元数据的 `UploadFile`
您也可以将 `File()` 与 `UploadFile` 一起使用,例如,设置额外的元数据:
-```Python hl_lines="13"
-{!../../../docs_src/request_files/tutorial001_03.py!}
-```
+{* ../../docs_src/request_files/tutorial001_03.py hl[13] *}
## 多文件上传
@@ -152,42 +148,24 @@ FastAPI 支持同时上传多个文件。
上传多个文件时,要声明含 `bytes` 或 `UploadFile` 的列表(`List`):
-=== "Python 3.6 及以上版本"
-
- ```Python hl_lines="10 15"
- {!> ../../../docs_src/request_files/tutorial002.py!}
- ```
-
-=== "Python 3.9 及以上版本"
-
- ```Python hl_lines="8 13"
- {!> ../../../docs_src/request_files/tutorial002_py39.py!}
- ```
+{* ../../docs_src/request_files/tutorial002_py39.py hl[8,13] *}
接收的也是含 `bytes` 或 `UploadFile` 的列表(`list`)。
-!!! note "技术细节"
+/// note | 技术细节
+
+也可以使用 `from starlette.responses import HTMLResponse`。
- 也可以使用 `from starlette.responses import HTMLResponse`。
+`fastapi.responses` 其实与 `starlette.responses` 相同,只是为了方便开发者调用。实际上,大多数 **FastAPI** 的响应都直接从 Starlette 调用。
- `fastapi.responses` 其实与 `starlette.responses` 相同,只是为了方便开发者调用。实际上,大多数 **FastAPI** 的响应都直接从 Starlette 调用。
+///
### 带有额外元数据的多文件上传
和之前的方式一样, 您可以为 `File()` 设置额外参数, 即使是 `UploadFile`:
-=== "Python 3.6 及以上版本"
-
- ```Python hl_lines="18"
- {!> ../../../docs_src/request_files/tutorial003.py!}
- ```
-
-=== "Python 3.9 及以上版本"
-
- ```Python hl_lines="16"
- {!> ../../../docs_src/request_files/tutorial003_py39.py!}
- ```
+{* ../../docs_src/request_files/tutorial003_py39.py hl[16] *}
## 小结
diff --git a/docs/zh/docs/tutorial/request-form-models.md b/docs/zh/docs/tutorial/request-form-models.md
new file mode 100644
index 000000000..e639e4b9f
--- /dev/null
+++ b/docs/zh/docs/tutorial/request-form-models.md
@@ -0,0 +1,78 @@
+# 表单模型
+
+您可以使用 **Pydantic 模型**在 FastAPI 中声明**表单字段**。
+
+/// info
+
+要使用表单,需预先安装
`python-multipart` 。
+
+确保您创建、激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank}后再安装。
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+/// note
+
+自 FastAPI 版本 `0.113.0` 起支持此功能。🤓
+
+///
+
+## 表单的 Pydantic 模型
+
+您只需声明一个 **Pydantic 模型**,其中包含您希望接收的**表单字段**,然后将参数声明为 `Form` :
+
+{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
+
+**FastAPI** 将从请求中的**表单数据**中**提取**出**每个字段**的数据,并提供您定义的 Pydantic 模型。
+
+## 检查文档
+
+您可以在文档 UI 中验证它,地址为 `/docs` :
+
+
+

+
+
+## 禁止额外的表单字段
+
+在某些特殊使用情况下(可能并不常见),您可能希望将表单字段**限制**为仅在 Pydantic 模型中声明过的字段,并**禁止**任何**额外**的字段。
+
+/// note
+
+自 FastAPI 版本 `0.114.0` 起支持此功能。🤓
+
+///
+
+您可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段:
+
+{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
+
+如果客户端尝试发送一些额外的数据,他们将收到**错误**响应。
+
+例如,如果客户端尝试发送这样的表单字段:
+
+* `username`: `Rick`
+* `password`: `Portal Gun`
+* `extra`: `Mr. Poopybutthole`
+
+他们将收到一条错误响应,表明字段 `extra` 是不被允许的:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "Mr. Poopybutthole"
+ }
+ ]
+}
+```
+
+## 总结
+
+您可以使用 Pydantic 模型在 FastAPI 中声明表单字段。😎
diff --git a/docs/zh/docs/tutorial/request-forms-and-files.md b/docs/zh/docs/tutorial/request-forms-and-files.md
index 70cd70f98..f72e5047a 100644
--- a/docs/zh/docs/tutorial/request-forms-and-files.md
+++ b/docs/zh/docs/tutorial/request-forms-and-files.md
@@ -2,35 +2,35 @@
FastAPI 支持同时使用 `File` 和 `Form` 定义文件和表单字段。
-!!! info "说明"
+/// info | 说明
- 接收上传文件或表单数据,要预先安装
`python-multipart`。
+接收上传文件或表单数据,要预先安装
`python-multipart`。
- 例如,`pip install python-multipart`。
+例如,`pip install python-multipart`。
+
+///
## 导入 `File` 与 `Form`
-```Python hl_lines="1"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
-```
+{* ../../docs_src/request_forms_and_files/tutorial001.py hl[1] *}
## 定义 `File` 与 `Form` 参数
创建文件和表单参数的方式与 `Body` 和 `Query` 一样:
-```Python hl_lines="8"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
-```
+{* ../../docs_src/request_forms_and_files/tutorial001.py hl[8] *}
文件和表单字段作为表单数据上传与接收。
声明文件可以使用 `bytes` 或 `UploadFile` 。
-!!! warning "警告"
+/// warning | 警告
+
+可在一个*路径操作*中声明多个 `File` 与 `Form` 参数,但不能同时声明要接收 JSON 的 `Body` 字段。因为此时请求体的编码为 `multipart/form-data`,不是 `application/json`。
- 可在一个*路径操作*中声明多个 `File` 与 `Form` 参数,但不能同时声明要接收 JSON 的 `Body` 字段。因为此时请求体的编码为 `multipart/form-data`,不是 `application/json`。
+这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
- 这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
+///
## 小结
diff --git a/docs/zh/docs/tutorial/request-forms.md b/docs/zh/docs/tutorial/request-forms.md
index 6436ffbcd..ee03e82a7 100644
--- a/docs/zh/docs/tutorial/request-forms.md
+++ b/docs/zh/docs/tutorial/request-forms.md
@@ -2,27 +2,25 @@
接收的不是 JSON,而是表单字段时,要使用 `Form`。
-!!! info "说明"
+/// info | 说明
- 要使用表单,需预先安装
`python-multipart`。
+要使用表单,需预先安装
`python-multipart`。
- 例如,`pip install python-multipart`。
+例如,`pip install python-multipart`。
+
+///
## 导入 `Form`
从 `fastapi` 导入 `Form`:
-```Python hl_lines="1"
-{!../../../docs_src/request_forms/tutorial001.py!}
-```
+{* ../../docs_src/request_forms/tutorial001.py hl[1] *}
## 定义 `Form` 参数
创建表单(`Form`)参数的方式与 `Body` 和 `Query` 一样:
-```Python hl_lines="7"
-{!../../../docs_src/request_forms/tutorial001.py!}
-```
+{* ../../docs_src/request_forms/tutorial001.py hl[7] *}
例如,OAuth2 规范的 "密码流" 模式规定要通过表单字段发送 `username` 和 `password`。
@@ -30,13 +28,17 @@
使用 `Form` 可以声明与 `Body` (及 `Query`、`Path`、`Cookie`)相同的元数据和验证。
-!!! info "说明"
+/// info | 说明
+
+`Form` 是直接继承自 `Body` 的类。
+
+///
- `Form` 是直接继承自 `Body` 的类。
+/// tip | 提示
-!!! tip "提示"
+声明表单体要显式使用 `Form` ,否则,FastAPI 会把该参数当作查询参数或请求体(JSON)参数。
- 声明表单体要显式使用 `Form` ,否则,FastAPI 会把该参数当作查询参数或请求体(JSON)参数。
+///
## 关于 "表单字段"
@@ -44,19 +46,23 @@
**FastAPI** 要确保从正确的位置读取数据,而不是读取 JSON。
-!!! note "技术细节"
+/// note | 技术细节
+
+表单数据的「媒体类型」编码一般为 `application/x-www-form-urlencoded`。
+
+但包含文件的表单编码为 `multipart/form-data`。文件处理详见下节。
- 表单数据的「媒体类型」编码一般为 `application/x-www-form-urlencoded`。
+编码和表单字段详见
MDN Web 文档的 POST
小节。
- 但包含文件的表单编码为 `multipart/form-data`。文件处理详见下节。
+///
- 编码和表单字段详见
MDN Web 文档的 POST
小节。
+/// warning | 警告
-!!! warning "警告"
+可在一个*路径操作*中声明多个 `Form` 参数,但不能同时声明要接收 JSON 的 `Body` 字段。因为此时请求体的编码是 `application/x-www-form-urlencoded`,不是 `application/json`。
- 可在一个*路径操作*中声明多个 `Form` 参数,但不能同时声明要接收 JSON 的 `Body` 字段。因为此时请求体的编码是 `application/x-www-form-urlencoded`,不是 `application/json`。
+这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
- 这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
+///
## 小结
diff --git a/docs/zh/docs/tutorial/response-model.md b/docs/zh/docs/tutorial/response-model.md
index ea3d0666d..049cd1223 100644
--- a/docs/zh/docs/tutorial/response-model.md
+++ b/docs/zh/docs/tutorial/response-model.md
@@ -8,12 +8,13 @@
* `@app.delete()`
* 等等。
-```Python hl_lines="17"
-{!../../../docs_src/response_model/tutorial001.py!}
-```
+{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
+
+/// note
-!!! note
- 注意,`response_model`是「装饰器」方法(`get`,`post` 等)的一个参数。不像之前的所有参数和请求体,它不属于*路径操作函数*。
+注意,`response_model`是「装饰器」方法(`get`,`post` 等)的一个参数。不像之前的所有参数和请求体,它不属于*路径操作函数*。
+
+///
它接收的类型与你将为 Pydantic 模型属性所声明的类型相同,因此它可以是一个 Pydantic 模型,但也可以是一个由 Pydantic 模型组成的 `list`,例如 `List[Item]`。
@@ -28,22 +29,21 @@ FastAPI 将使用此 `response_model` 来:
* 会将输出数据限制在该模型定义内。下面我们会看到这一点有多重要。
-!!! note "技术细节"
- 响应模型在参数中被声明,而不是作为函数返回类型的注解,这是因为路径函数可能不会真正返回该响应模型,而是返回一个 `dict`、数据库对象或其他模型,然后再使用 `response_model` 来执行字段约束和序列化。
+/// note | 技术细节
+
+响应模型在参数中被声明,而不是作为函数返回类型的注解,这是因为路径函数可能不会真正返回该响应模型,而是返回一个 `dict`、数据库对象或其他模型,然后再使用 `response_model` 来执行字段约束和序列化。
+
+///
## 返回与输入相同的数据
现在我们声明一个 `UserIn` 模型,它将包含一个明文密码属性。
-```Python hl_lines="9 11"
-{!../../../docs_src/response_model/tutorial002.py!}
-```
+{* ../../docs_src/response_model/tutorial002.py hl[9,11] *}
我们正在使用此模型声明输入数据,并使用同一模型声明输出数据:
-```Python hl_lines="17-18"
-{!../../../docs_src/response_model/tutorial002.py!}
-```
+{* ../../docs_src/response_model/tutorial002.py hl[17:18] *}
现在,每当浏览器使用一个密码创建用户时,API 都会在响应中返回相同的密码。
@@ -51,28 +51,25 @@ FastAPI 将使用此 `response_model` 来:
但是,如果我们在其他的*路径操作*中使用相同的模型,则可能会将用户的密码发送给每个客户端。
-!!! danger
- 永远不要存储用户的明文密码,也不要在响应中发送密码。
+/// danger
+
+永远不要存储用户的明文密码,也不要在响应中发送密码。
+
+///
## 添加输出模型
相反,我们可以创建一个有明文密码的输入模型和一个没有明文密码的输出模型:
-```Python hl_lines="9 11 16"
-{!../../../docs_src/response_model/tutorial003.py!}
-```
+{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
这样,即便我们的*路径操作函数*将会返回包含密码的相同输入用户:
-```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial003.py!}
-```
+{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
...我们已经将 `response_model` 声明为了不包含密码的 `UserOut` 模型:
-```Python hl_lines="22"
-{!../../../docs_src/response_model/tutorial003.py!}
-```
+{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
因此,**FastAPI** 将会负责过滤掉未在输出模型中声明的所有数据(使用 Pydantic)。
@@ -90,9 +87,7 @@ FastAPI 将使用此 `response_model` 来:
你的响应模型可以具有默认值,例如:
-```Python hl_lines="11 13-14"
-{!../../../docs_src/response_model/tutorial004.py!}
-```
+{* ../../docs_src/response_model/tutorial004.py hl[11,13:14] *}
* `description: Union[str, None] = None` 具有默认值 `None`。
* `tax: float = 10.5` 具有默认值 `10.5`.
@@ -106,9 +101,7 @@ FastAPI 将使用此 `response_model` 来:
你可以设置*路径操作装饰器*的 `response_model_exclude_unset=True` 参数:
-```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial004.py!}
-```
+{* ../../docs_src/response_model/tutorial004.py hl[24] *}
然后响应中将不会包含那些默认值,而是仅有实际设置的值。
@@ -121,16 +114,22 @@ FastAPI 将使用此 `response_model` 来:
}
```
-!!! info
- FastAPI 通过 Pydantic 模型的 `.dict()` 配合
该方法的 `exclude_unset` 参数 来实现此功能。
+/// info
+
+FastAPI 通过 Pydantic 模型的 `.dict()` 配合
该方法的 `exclude_unset` 参数 来实现此功能。
+
+///
+
+/// info
-!!! info
- 你还可以使用:
+你还可以使用:
- * `response_model_exclude_defaults=True`
- * `response_model_exclude_none=True`
+* `response_model_exclude_defaults=True`
+* `response_model_exclude_none=True`
- 参考
Pydantic 文档 中对 `exclude_defaults` 和 `exclude_none` 的描述。
+参考
Pydantic 文档 中对 `exclude_defaults` 和 `exclude_none` 的描述。
+
+///
#### 默认值字段有实际值的数据
@@ -165,10 +164,13 @@ FastAPI 将使用此 `response_model` 来:
因此,它们将包含在 JSON 响应中。
-!!! tip
- 请注意默认值可以是任何值,而不仅是`None`。
+/// tip
+
+请注意默认值可以是任何值,而不仅是`None`。
+
+它们可以是一个列表(`[]`),一个值为 `10.5`的 `float`,等等。
- 它们可以是一个列表(`[]`),一个值为 `10.5`的 `float`,等等。
+///
### `response_model_include` 和 `response_model_exclude`
@@ -178,29 +180,31 @@ FastAPI 将使用此 `response_model` 来:
如果你只有一个 Pydantic 模型,并且想要从输出中移除一些数据,则可以使用这种快捷方法。
-!!! tip
- 但是依然建议你使用上面提到的主意,使用多个类而不是这些参数。
+/// tip
- 这是因为即使使用 `response_model_include` 或 `response_model_exclude` 来省略某些属性,在应用程序的 OpenAPI 定义(和文档)中生成的 JSON Schema 仍将是完整的模型。
+但是依然建议你使用上面提到的主意,使用多个类而不是这些参数。
- 这也适用于作用类似的 `response_model_by_alias`。
+这是因为即使使用 `response_model_include` 或 `response_model_exclude` 来省略某些属性,在应用程序的 OpenAPI 定义(和文档)中生成的 JSON Schema 仍将是完整的模型。
-```Python hl_lines="31 37"
-{!../../../docs_src/response_model/tutorial005.py!}
-```
+这也适用于作用类似的 `response_model_by_alias`。
+
+///
+
+{* ../../docs_src/response_model/tutorial005.py hl[31,37] *}
-!!! tip
- `{"name", "description"}` 语法创建一个具有这两个值的 `set`。
+/// tip
- 等同于 `set(["name", "description"])`。
+`{"name", "description"}` 语法创建一个具有这两个值的 `set`。
+
+等同于 `set(["name", "description"])`。
+
+///
#### 使用 `list` 而不是 `set`
如果你忘记使用 `set` 而是使用 `list` 或 `tuple`,FastAPI 仍会将其转换为 `set` 并且正常工作:
-```Python hl_lines="31 37"
-{!../../../docs_src/response_model/tutorial006.py!}
-```
+{* ../../docs_src/response_model/tutorial006.py hl[31,37] *}
## 总结
diff --git a/docs/zh/docs/tutorial/response-status-code.md b/docs/zh/docs/tutorial/response-status-code.md
index 357831942..aa8032ada 100644
--- a/docs/zh/docs/tutorial/response-status-code.md
+++ b/docs/zh/docs/tutorial/response-status-code.md
@@ -1,89 +1,101 @@
# 响应状态码
-与指定响应模型的方式相同,你也可以在以下任意的*路径操作*中使用 `status_code` 参数来声明用于响应的 HTTP 状态码:
+与指定响应模型的方式相同,在以下任意*路径操作*中,可以使用 `status_code` 参数声明用于响应的 HTTP 状态码:
* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
-* 等等。
+* 等……
-```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
-```
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
-!!! note
- 注意,`status_code` 是「装饰器」方法(`get`,`post` 等)的一个参数。不像之前的所有参数和请求体,它不属于*路径操作函数*。
+/// note | 笔记
-`status_code` 参数接收一个表示 HTTP 状态码的数字。
+注意,`status_code` 是(`get`、`post` 等)**装饰器**方法中的参数。与之前的参数和请求体不同,不是*路径操作函数*的参数。
-!!! info
- `status_code` 也能够接收一个 `IntEnum` 类型,比如 Python 的
`http.HTTPStatus`。
+///
-它将会:
+`status_code` 参数接收表示 HTTP 状态码的数字。
-* 在响应中返回该状态码。
-* 在 OpenAPI 模式中(以及在用户界面中)将其记录为:
+/// info | 说明
-

+`status_code` 还能接收 `IntEnum` 类型,比如 Python 的
`http.HTTPStatus`。
-!!! note
- 一些响应状态码(请参阅下一部分)表示响应没有响应体。
+///
- FastAPI 知道这一点,并将生成表明没有响应体的 OpenAPI 文档。
+它可以:
+
+* 在响应中返回状态码
+* 在 OpenAPI 概图(及用户界面)中存档:
+
+

+
+/// note | 笔记
+
+某些响应状态码表示响应没有响应体(参阅下一章)。
+
+FastAPI 可以进行识别,并生成表明无响应体的 OpenAPI 文档。
+
+///
## 关于 HTTP 状态码
-!!! note
- 如果你已经了解什么是 HTTP 状态码,请跳到下一部分。
+/// note | 笔记
+
+如果已经了解 HTTP 状态码,请跳到下一章。
+
+///
+
+在 HTTP 协议中,发送 3 位数的数字状态码是响应的一部分。
+
+这些状态码都具有便于识别的关联名称,但是重要的还是数字。
+
+简言之:
+
+* `100` 及以上的状态码用于返回**信息**。这类状态码很少直接使用。具有这些状态码的响应不能包含响应体
+* **`200`** 及以上的状态码用于表示**成功**。这些状态码是最常用的
+ * `200` 是默认状态代码,表示一切**正常**
+ * `201` 表示**已创建**,通常在数据库中创建新记录后使用
+ * `204` 是一种特殊的例子,表示**无内容**。该响应在没有为客户端返回内容时使用,因此,该响应不能包含响应体
+* **`300`** 及以上的状态码用于**重定向**。具有这些状态码的响应不一定包含响应体,但 `304`**未修改**是个例外,该响应不得包含响应体
+* **`400`** 及以上的状态码用于表示**客户端错误**。这些可能是第二常用的类型
+ * `404`,用于**未找到**响应
+ * 对于来自客户端的一般错误,可以只使用 `400`
+* `500` 及以上的状态码用于表示服务器端错误。几乎永远不会直接使用这些状态码。应用代码或服务器出现问题时,会自动返回这些状态代码
-在 HTTP 协议中,你将发送 3 位数的数字状态码作为响应的一部分。
+/// tip | 提示
-这些状态码有一个识别它们的关联名称,但是重要的还是数字。
+状态码及适用场景的详情,请参阅
MDN 的 HTTP 状态码文档。
-简而言之:
+///
-* `100` 及以上状态码用于「消息」响应。你很少直接使用它们。具有这些状态代码的响应不能带有响应体。
-* **`200`** 及以上状态码用于「成功」响应。这些是你最常使用的。
- * `200` 是默认状态代码,它表示一切「正常」。
- * 另一个例子会是 `201`,「已创建」。它通常在数据库中创建了一条新记录后使用。
- * 一个特殊的例子是 `204`,「无内容」。此响应在没有内容返回给客户端时使用,因此该响应不能包含响应体。
-* **`300`** 及以上状态码用于「重定向」。具有这些状态码的响应可能有或者可能没有响应体,但 `304`「未修改」是个例外,该响应不得含有响应体。
-* **`400`** 及以上状态码用于「客户端错误」响应。这些可能是你第二常使用的类型。
- * 一个例子是 `404`,用于「未找到」响应。
- * 对于来自客户端的一般错误,你可以只使用 `400`。
-* `500` 及以上状态码用于服务器端错误。你几乎永远不会直接使用它们。当你的应用程序代码或服务器中的某些部分出现问题时,它将自动返回这些状态代码之一。
+## 状态码名称快捷方式
-!!! tip
- 要了解有关每个状态代码以及适用场景的更多信息,请查看
MDN 关于 HTTP 状态码的文档。
+再看下之前的例子:
-## 记住名称的捷径
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
-让我们再次看看之前的例子:
+`201` 表示**已创建**的状态码。
-```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
-```
+但我们没有必要记住所有代码的含义。
-`201` 是表示「已创建」的状态码。
+可以使用 `fastapi.status` 中的快捷变量。
-但是你不必去记住每个代码的含义。
+{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
-你可以使用来自 `fastapi.status` 的便捷变量。
+这只是一种快捷方式,具有相同的数字代码,但它可以使用编辑器的自动补全功能:
-```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
-```
+

-它们只是一种便捷方式,它们具有同样的数字代码,但是这样使用你就可以使用编辑器的自动补全功能来查找它们:
+/// note | 技术细节
-

+也可以使用 `from starlette import status`。
-!!! note "技术细节"
- 你也可以使用 `from starlette import status`。
+为了让开发者更方便,**FastAPI** 提供了与 `starlette.status` 完全相同的 `fastapi.status`。但它直接来自于 Starlette。
- 为了给你(即开发者)提供方便,**FastAPI** 提供了与 `starlette.status` 完全相同的 `fastapi.status`。但它直接来自于 Starlette。
+///
## 更改默认状态码
-稍后,在[高级用户指南](../advanced/response-change-status-code.md){.internal-link target=_blank}中你将了解如何返回与在此声明的默认状态码不同的状态码。
+[高级用户指南](../advanced/response-change-status-code.md){.internal-link target=_blank}中,将介绍如何返回与在此声明的默认状态码不同的状态码。
diff --git a/docs/zh/docs/tutorial/schema-extra-example.md b/docs/zh/docs/tutorial/schema-extra-example.md
index 8f5fbfe70..6c132eed3 100644
--- a/docs/zh/docs/tutorial/schema-extra-example.md
+++ b/docs/zh/docs/tutorial/schema-extra-example.md
@@ -8,11 +8,9 @@
## Pydantic `schema_extra`
-您可以使用 `Config` 和 `schema_extra` 为Pydantic模型声明一个示例,如
Pydantic 文档:定制 Schema 中所述:
+您可以使用 `Config` 和 `schema_extra` 为Pydantic模型声明一个示例,如
Pydantic 文档:定制 Schema 中所述:
-```Python hl_lines="15-23"
-{!../../../docs_src/schema_extra_example/tutorial001.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:21] *}
这些额外的信息将按原样添加到输出的JSON模式中。
@@ -20,12 +18,13 @@
在 `Field`, `Path`, `Query`, `Body` 和其他你之后将会看到的工厂函数,你可以为JSON 模式声明额外信息,你也可以通过给工厂函数传递其他的任意参数来给JSON 模式声明额外信息,比如增加 `example`:
-```Python hl_lines="4 10-13"
-{!../../../docs_src/schema_extra_example/tutorial002.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
-!!! warning
- 请记住,传递的那些额外参数不会添加任何验证,只会添加注释,用于文档的目的。
+/// warning
+
+请记住,传递的那些额外参数不会添加任何验证,只会添加注释,用于文档的目的。
+
+///
## `Body` 额外参数
@@ -33,9 +32,7 @@
比如,你可以将请求体的一个 `example` 传递给 `Body`:
-```Python hl_lines="20-25"
-{!../../../docs_src/schema_extra_example/tutorial003.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:27] *}
## 文档 UI 中的例子
diff --git a/docs/zh/docs/tutorial/security/first-steps.md b/docs/zh/docs/tutorial/security/first-steps.md
index 86c3320ce..225eb2695 100644
--- a/docs/zh/docs/tutorial/security/first-steps.md
+++ b/docs/zh/docs/tutorial/security/first-steps.md
@@ -20,19 +20,19 @@
把下面的示例代码复制到 `main.py`:
-```Python
-{!../../../docs_src/security/tutorial001.py!}
-```
+{* ../../docs_src/security/tutorial001_an_py39.py *}
## 运行
-!!! info "说明"
+/// info | 说明
+
+先安装
`python-multipart`。
- 先安装
`python-multipart`。
+安装命令: `pip install python-multipart`。
- 安装命令: `pip install python-multipart`。
+这是因为 **OAuth2** 使用**表单数据**发送 `username` 与 `password`。
- 这是因为 **OAuth2** 使用**表单数据**发送 `username` 与 `password`。
+///
用下面的命令运行该示例:
@@ -54,19 +54,23 @@ $ uvicorn main:app --reload

-!!! check "Authorize 按钮!"
+/// check | Authorize 按钮!
- 页面右上角出现了一个「**Authorize**」按钮。
+页面右上角出现了一个「**Authorize**」按钮。
- *路径操作*的右上角也出现了一个可以点击的小锁图标。
+*路径操作*的右上角也出现了一个可以点击的小锁图标。
+
+///
点击 **Authorize** 按钮,弹出授权表单,输入 `username` 与 `password` 及其它可选字段:

-!!! note "笔记"
+/// note | 笔记
+
+目前,在表单中输入内容不会有任何反应,后文会介绍相关内容。
- 目前,在表单中输入内容不会有任何反应,后文会介绍相关内容。
+///
虽然此文档不是给前端最终用户使用的,但这个自动工具非常实用,可在文档中与所有 API 交互。
@@ -108,39 +112,43 @@ OAuth2 的设计目标是为了让后端或 API 独立于服务器验证用户
本例使用 **OAuth2** 的 **Password** 流以及 **Bearer** 令牌(`Token`)。为此要使用 `OAuth2PasswordBearer` 类。
-!!! info "说明"
+/// info | 说明
+
+`Bearer` 令牌不是唯一的选择。
- `Bearer` 令牌不是唯一的选择。
+但它是最适合这个用例的方案。
- 但它是最适合这个用例的方案。
+甚至可以说,它是适用于绝大多数用例的最佳方案,除非您是 OAuth2 的专家,知道为什么其它方案更合适。
- 甚至可以说,它是适用于绝大多数用例的最佳方案,除非您是 OAuth2 的专家,知道为什么其它方案更合适。
+本例中,**FastAPI** 还提供了构建工具。
- 本例中,**FastAPI** 还提供了构建工具。
+///
创建 `OAuth2PasswordBearer` 的类实例时,要传递 `tokenUrl` 参数。该参数包含客户端(用户浏览器中运行的前端) 的 URL,用于发送 `username` 与 `password`,并获取令牌。
-```Python hl_lines="6"
-{!../../../docs_src/security/tutorial001.py!}
-```
+{* ../../docs_src/security/tutorial001.py hl[6] *}
+
+/// tip | 提示
-!!! tip "提示"
+在此,`tokenUrl="token"` 指向的是暂未创建的相对 URL `token`。这个相对 URL 相当于 `./token`。
- 在此,`tokenUrl="token"` 指向的是暂未创建的相对 URL `token`。这个相对 URL 相当于 `./token`。
+因为使用的是相对 URL,如果 API 位于 `https://example.com/`,则指向 `https://example.com/token`。但如果 API 位于 `https://example.com/api/v1/`,它指向的就是`https://example.com/api/v1/token`。
- 因为使用的是相对 URL,如果 API 位于 `https://example.com/`,则指向 `https://example.com/token`。但如果 API 位于 `https://example.com/api/v1/`,它指向的就是`https://example.com/api/v1/token`。
+使用相对 URL 非常重要,可以确保应用在遇到[使用代理](../../advanced/behind-a-proxy.md){.internal-link target=_blank}这样的高级用例时,也能正常运行。
- 使用相对 URL 非常重要,可以确保应用在遇到[使用代理](../../advanced/behind-a-proxy.md){.internal-link target=_blank}这样的高级用例时,也能正常运行。
+///
该参数不会创建端点或*路径操作*,但会声明客户端用来获取令牌的 URL `/token` 。此信息用于 OpenAPI 及 API 文档。
接下来,学习如何创建实际的路径操作。
-!!! info "说明"
+/// info | 说明
+
+严苛的 **Pythonista** 可能不喜欢用 `tokenUrl` 这种命名风格代替 `token_url`。
- 严苛的 **Pythonista** 可能不喜欢用 `tokenUrl` 这种命名风格代替 `token_url`。
+这种命名方式是因为要使用与 OpenAPI 规范中相同的名字。以便在深入校验安全方案时,能通过复制粘贴查找更多相关信息。
- 这种命名方式是因为要使用与 OpenAPI 规范中相同的名字。以便在深入校验安全方案时,能通过复制粘贴查找更多相关信息。
+///
`oauth2_scheme` 变量是 `OAuth2PasswordBearer` 的实例,也是**可调用项**。
@@ -156,19 +164,19 @@ oauth2_scheme(some, parameters)
接下来,使用 `Depends` 把 `oauth2_scheme` 传入依赖项。
-```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
-```
+{* ../../docs_src/security/tutorial001.py hl[10] *}
该依赖项使用字符串(`str`)接收*路径操作函数*的参数 `token` 。
**FastAPI** 使用依赖项在 OpenAPI 概图(及 API 文档)中定义**安全方案**。
-!!! info "技术细节"
+/// info | 技术细节
+
+**FastAPI** 使用(在依赖项中声明的)类 `OAuth2PasswordBearer` 在 OpenAPI 中定义安全方案,这是因为它继承自 `fastapi.security.oauth2.OAuth2`,而该类又是继承自`fastapi.security.base.SecurityBase`。
- **FastAPI** 使用(在依赖项中声明的)类 `OAuth2PasswordBearer` 在 OpenAPI 中定义安全方案,这是因为它继承自 `fastapi.security.oauth2.OAuth2`,而该类又是继承自`fastapi.security.base.SecurityBase`。
+所有与 OpenAPI(及 API 文档)集成的安全工具都继承自 `SecurityBase`, 这就是为什么 **FastAPI** 能把它们集成至 OpenAPI 的原因。
- 所有与 OpenAPI(及 API 文档)集成的安全工具都继承自 `SecurityBase`, 这就是为什么 **FastAPI** 能把它们集成至 OpenAPI 的原因。
+///
## 实现的操作
diff --git a/docs/zh/docs/tutorial/security/get-current-user.md b/docs/zh/docs/tutorial/security/get-current-user.md
index 477baec3a..1f254a103 100644
--- a/docs/zh/docs/tutorial/security/get-current-user.md
+++ b/docs/zh/docs/tutorial/security/get-current-user.md
@@ -1,114 +1,107 @@
# 获取当前用户
-在上一章节中,(基于依赖项注入系统的)安全系统向*路径操作函数*提供了一个 `str` 类型的 `token`:
+上一章中,(基于依赖注入系统的)安全系统向*路径操作函数*传递了 `str` 类型的 `token`:
-```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
-```
+{* ../../docs_src/security/tutorial001.py hl[10] *}
-但这还不是很实用。
+但这并不实用。
-让我们来使它返回当前用户给我们。
+接下来,我们学习如何返回当前用户。
-## 创建一个用户模型
+## 创建用户模型
-首先,让我们来创建一个用户 Pydantic 模型。
+首先,创建 Pydantic 用户模型。
-与使用 Pydantic 声明请求体的方式相同,我们可以在其他任何地方使用它:
+与使用 Pydantic 声明请求体相同,并且可在任何位置使用:
-```Python hl_lines="5 12-16"
-{!../../../docs_src/security/tutorial002.py!}
-```
+{* ../../docs_src/security/tutorial002.py hl[5,12:16] *}
-## 创建一个 `get_current_user` 依赖项
+## 创建 `get_current_user` 依赖项
-让我们来创建一个 `get_current_user` 依赖项。
+创建 `get_current_user` 依赖项。
-还记得依赖项可以有子依赖项吗?
+还记得依赖项支持子依赖项吗?
-`get_current_user` 将具有一个我们之前所创建的同一个 `oauth2_scheme` 作为依赖项。
+`get_current_user` 使用 `oauth2_scheme` 作为依赖项。
-与我们之前直接在路径操作中所做的相同,我们新的依赖项 `get_current_user` 将从子依赖项 `oauth2_scheme` 中接收一个 `str` 类型的 `token`:
+与之前直接在路径操作中的做法相同,新的 `get_current_user` 依赖项从子依赖项 `oauth2_scheme` 中接收 `str` 类型的 `token`:
-```Python hl_lines="25"
-{!../../../docs_src/security/tutorial002.py!}
-```
+{* ../../docs_src/security/tutorial002.py hl[25] *}
## 获取用户
-`get_current_user` 将使用我们创建的(伪)工具函数,该函数接收 `str` 类型的令牌并返回我们的 Pydantic `User` 模型:
+`get_current_user` 使用创建的(伪)工具函数,该函数接收 `str` 类型的令牌,并返回 Pydantic 的 `User` 模型:
-```Python hl_lines="19-22 26-27"
-{!../../../docs_src/security/tutorial002.py!}
-```
+{* ../../docs_src/security/tutorial002.py hl[19:22,26:27] *}
## 注入当前用户
-因此现在我们可以在*路径操作*中使用 `get_current_user` 作为 `Depends` 了:
+在*路径操作* 的 `Depends` 中使用 `get_current_user`:
-```Python hl_lines="31"
-{!../../../docs_src/security/tutorial002.py!}
-```
+{* ../../docs_src/security/tutorial002.py hl[31] *}
-注意我们将 `current_user` 的类型声明为 Pydantic 模型 `User`。
+注意,此处把 `current_user` 的类型声明为 Pydantic 的 `User` 模型。
-这将帮助我们在函数内部使用所有的代码补全和类型检查。
+这有助于在函数内部使用代码补全和类型检查。
-!!! tip
- 你可能还记得请求体也是使用 Pydantic 模型来声明的。
+/// tip | 提示
- 在这里 **FastAPI** 不会搞混,因为你正在使用的是 `Depends`。
+还记得请求体也是使用 Pydantic 模型声明的吧。
-!!! check
- 这种依赖系统的设计方式使我们可以拥有不同的依赖项(不同的「可依赖类型」),并且它们都返回一个 `User` 模型。
+放心,因为使用了 `Depends`,**FastAPI** 不会搞混。
- 我们并未被局限于只能有一个返回该类型数据的依赖项。
+///
+/// check | 检查
-## 其他模型
+依赖系统的这种设计方式可以支持不同的依赖项返回同一个 `User` 模型。
-现在你可以直接在*路径操作函数*中获取当前用户,并使用 `Depends` 在**依赖注入**级别处理安全性机制。
+而不是局限于只能有一个返回该类型数据的依赖项。
-你可以使用任何模型或数据来满足安全性要求(在这个示例中,使用的是 Pydantic 模型 `User`)。
+///
-但是你并未被限制只能使用某些特定的数据模型,类或类型。
+## 其它模型
-你想要在模型中使用 `id` 和 `email` 而不使用任何的 `username`?当然可以。你可以同样地使用这些工具。
+接下来,直接在*路径操作函数*中获取当前用户,并用 `Depends` 在**依赖注入**系统中处理安全机制。
-你只想要一个 `str`?或者仅仅一个 `dict`?还是直接一个数据库模型类的实例?它们的工作方式都是一样的。
+开发者可以使用任何模型或数据满足安全需求(本例中是 Pydantic 的 `User` 模型)。
-实际上你没有用户登录到你的应用程序,而是只拥有访问令牌的机器人,程序或其他系统?再一次,它们的工作方式也是一样的。
+而且,不局限于只能使用特定的数据模型、类或类型。
-尽管去使用你的应用程序所需要的任何模型,任何类,任何数据库。**FastAPI** 通过依赖项注入系统都帮你搞定。
+不想在模型中使用 `username`,而是使用 `id` 和 `email`?当然可以。这些工具也支持。
+只想使用字符串?或字典?甚至是数据库类模型的实例?工作方式都一样。
-## 代码体积
+实际上,就算登录应用的不是用户,而是只拥有访问令牌的机器人、程序或其它系统?工作方式也一样。
-这个示例似乎看起来很冗长。考虑到我们在同一文件中混合了安全性,数据模型工具函数和路径操作等代码。
+尽管使用应用所需的任何模型、类、数据库。**FastAPI** 通过依赖注入系统都能帮您搞定。
-但关键的是。
-安全性和依赖项注入内容只需要编写一次。
+## 代码大小
-你可以根据需要使其变得很复杂。而且只需要在一个地方写一次。但仍然具备所有的灵活性。
+这个示例看起来有些冗长。毕竟这个文件同时包含了安全、数据模型的工具函数,以及路径操作等代码。
-但是,你可以有无数个使用同一安全系统的端点(*路径操作*)。
+但,关键是:
-所有(或所需的任何部分)的端点,都可以利用对这些或你创建的其他依赖项进行复用所带来的优势。
+**安全和依赖注入的代码只需要写一次。**
-所有的这无数个*路径操作*甚至可以小到只需 3 行代码:
+就算写得再复杂,也只是在一个位置写一次就够了。所以,要多复杂就可以写多复杂。
-```Python hl_lines="30-32"
-{!../../../docs_src/security/tutorial002.py!}
-```
+但是,就算有数千个端点(*路径操作*),它们都可以使用同一个安全系统。
-## 总结
+而且,所有端点(或它们的任何部件)都可以利用这些依赖项或任何其它依赖项。
-现在你可以直接在*路径操作函数*中获取当前用户。
+所有*路径操作*只需 3 行代码就可以了:
-我们已经进行到一半了。
+{* ../../docs_src/security/tutorial002.py hl[30:32] *}
-我们只需要再为用户/客户端添加一个真正发送 `username` 和 `password` 的*路径操作*。
+## 小结
-这些内容在下一章节。
+现在,我们可以直接在*路径操作函数*中获取当前用户。
+
+至此,安全的内容已经讲了一半。
+
+只要再为用户或客户端的*路径操作*添加真正发送 `username` 和 `password` 的功能就可以了。
+
+下一章见。
diff --git a/docs/zh/docs/tutorial/security/index.md b/docs/zh/docs/tutorial/security/index.md
index 8f302a16c..e888a4fe9 100644
--- a/docs/zh/docs/tutorial/security/index.md
+++ b/docs/zh/docs/tutorial/security/index.md
@@ -1,4 +1,4 @@
-# 安全性简介
+# 安全性
有许多方法可以处理安全性、身份认证和授权等问题。
@@ -32,9 +32,11 @@ OAuth2是一个规范,它定义了几种处理身份认证和授权的方法
OAuth2 没有指定如何加密通信,它期望你为应用程序使用 HTTPS 进行通信。
-!!! tip
- 在有关**部署**的章节中,你将了解如何使用 Traefik 和 Let's Encrypt 免费设置 HTTPS。
+/// tip
+在有关**部署**的章节中,你将了解如何使用 Traefik 和 Let's Encrypt 免费设置 HTTPS。
+
+///
## OpenID Connect
@@ -87,10 +89,13 @@ OpenAPI 定义了以下安全方案:
* 此自动发现机制是 OpenID Connect 规范中定义的内容。
-!!! tip
- 集成其他身份认证/授权提供者(例如Google,Facebook,Twitter,GitHub等)也是可能的,而且较为容易。
+/// tip
+
+集成其他身份认证/授权提供者(例如Google,Facebook,Twitter,GitHub等)也是可能的,而且较为容易。
+
+最复杂的问题是创建一个像这样的身份认证/授权提供程序,但是 **FastAPI** 为你提供了轻松完成任务的工具,同时为你解决了重活。
- 最复杂的问题是创建一个像这样的身份认证/授权提供程序,但是 **FastAPI** 为你提供了轻松完成任务的工具,同时为你解决了重活。
+///
## **FastAPI** 实用工具
diff --git a/docs/zh/docs/tutorial/security/oauth2-jwt.md b/docs/zh/docs/tutorial/security/oauth2-jwt.md
index 054198545..7d338419b 100644
--- a/docs/zh/docs/tutorial/security/oauth2-jwt.md
+++ b/docs/zh/docs/tutorial/security/oauth2-jwt.md
@@ -26,29 +26,27 @@ JWT 字符串没有加密,任何人都能用它恢复原始信息。
如需深入了解 JWT 令牌,了解它的工作方式,请参阅
https://jwt.io。
-## 安装 `python-jose`
+## 安装 `PyJWT`
-安装 `python-jose`,在 Python 中生成和校验 JWT 令牌:
+安装 `PyJWT`,在 Python 中生成和校验 JWT 令牌:
```console
-$ pip install python-jose[cryptography]
+$ pip install pyjwt
---> 100%
```
-
Python-jose 需要安装配套的加密后端。
+/// info | 说明
-本教程推荐的后端是:
pyca/cryptography。
+如果您打算使用类似 RSA 或 ECDSA 的数字签名算法,您应该安装加密库依赖项 `pyjwt[crypto]`。
-!!! tip "提示"
+您可以在
PyJWT Installation docs 获得更多信息。
- 本教程以前使用
PyJWT。
-
- 但后来换成了 Python-jose,因为 Python-jose 支持 PyJWT 的所有功能,还支持与其它工具集成时可能会用到的一些其它功能。
+///
## 密码哈希
@@ -62,7 +60,7 @@ $ pip install python-jose[cryptography]
原因很简单,假如数据库被盗,窃贼无法获取用户的明文密码,得到的只是哈希值。
-这样一来,窃贼就无法在其它应用中使用窃取的密码,要知道,很多用户在所有系统中都使用相同的密码,风险超大)。
+这样一来,窃贼就无法在其它应用中使用窃取的密码(要知道,很多用户在所有系统中都使用相同的密码,风险超大)。
## 安装 `passlib`
@@ -84,13 +82,15 @@ $ pip install passlib[bcrypt]
-!!! tip "提示"
+/// tip | 提示
+
+`passlib` 甚至可以读取 Django、Flask 的安全插件等工具创建的密码。
- `passlib` 甚至可以读取 Django、Flask 的安全插件等工具创建的密码。
+例如,把 Django 应用的数据共享给 FastAPI 应用的数据库。或利用同一个数据库,可以逐步把应用从 Django 迁移到 FastAPI。
- 例如,把 Django 应用的数据共享给 FastAPI 应用的数据库。或利用同一个数据库,可以逐步把应用从 Django 迁移到 FastAPI。
+并且,用户可以同时从 Django 应用或 FastAPI 应用登录。
- 并且,用户可以同时从 Django 应用或 FastAPI 应用登录。
+///
## 密码哈希与校验
@@ -98,13 +98,15 @@ $ pip install passlib[bcrypt]
创建用于密码哈希和身份校验的 PassLib **上下文**。
-!!! tip "提示"
+/// tip | 提示
+
+PassLib 上下文还支持使用不同哈希算法的功能,包括只能校验的已弃用旧算法等。
- PassLib 上下文还支持使用不同哈希算法的功能,包括只能校验的已弃用旧算法等。
+例如,用它读取和校验其它系统(如 Django)生成的密码,但要使用其它算法,如 Bcrypt,生成新的哈希密码。
- 例如,用它读取和校验其它系统(如 Django)生成的密码,但要使用其它算法,如 Bcrypt,生成新的哈希密码。
+同时,这些功能都是兼容的。
- 同时,这些功能都是兼容的。
+///
接下来,创建三个工具函数,其中一个函数用于哈希用户的密码。
@@ -112,13 +114,13 @@ $ pip install passlib[bcrypt]
第三个函数用于身份验证,并返回用户。
-```Python hl_lines="7 48 55-56 59-60 69-75"
-{!../../../docs_src/security/tutorial004.py!}
-```
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
+
+/// note | 笔记
-!!! note "笔记"
+查看新的(伪)数据库 `fake_users_db`,就能看到哈希后的密码:`"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`。
- 查看新的(伪)数据库 `fake_users_db`,就能看到哈希后的密码:`"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`。
+///
## 处理 JWT 令牌
@@ -148,9 +150,7 @@ $ openssl rand -hex 32
创建生成新的访问令牌的工具函数。
-```Python hl_lines="6 12-14 28-30 78-86"
-{!../../../docs_src/security/tutorial004.py!}
-```
+{* ../../docs_src/security/tutorial004.py hl[6,12:14,28:30,78:86] *}
## 更新依赖项
@@ -160,9 +160,7 @@ $ openssl rand -hex 32
如果令牌无效,则直接返回 HTTP 错误。
-```Python hl_lines="89-106"
-{!../../../docs_src/security/tutorial004.py!}
-```
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
## 更新 `/token` *路径操作*
@@ -170,9 +168,7 @@ $ openssl rand -hex 32
创建并返回真正的 JWT 访问令牌。
-```Python hl_lines="115-128"
-{!../../../docs_src/security/tutorial004.py!}
-```
+{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
### JWT `sub` 的技术细节
@@ -210,9 +206,11 @@ JWT 规范还包括 `sub` 键,值是令牌的主题。
用户名: `johndoe` 密码: `secret`
-!!! check "检查"
+/// check | 检查
- 注意,代码中没有明文密码**`secret`**,只保存了它的哈希值。
+注意,代码中没有明文密码**`secret`**,只保存了它的哈希值。
+
+///
-```Python
-name: str
+```console
+$ pip install sqlmodel
+---> 100%
```
-请牢记这一点,这样您在使用`:`还是`=`时就不会感到困惑。
-
-### 创建用于读取/返回的Pydantic*模型/模式*
-
-现在创建当从 API 返回数据时、将在读取数据时使用的Pydantic*模型(schemas)。*
-
-例如,在创建一个项目之前,我们不知道分配给它的 ID 是什么,但是在读取它时(从 API 返回时)我们已经知道它的 ID。
+
-同样,当读取用户时,我们现在可以声明`items`,将包含属于该用户的项目。
+## 创建含有单一模型的应用程序
-不仅是这些项目的 ID,还有我们在 Pydantic*模型*中定义的用于读取项目的所有数据:`Item`.
+我们首先创建应用程序的最简单的第一个版本,只有一个 **SQLModel** 模型。
-=== "Python 3.6 及以上版本"
+稍后我们将通过下面的**多个模型**提高其安全性和多功能性。🤓
- ```Python hl_lines="15-17 31-34"
- {!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
- ```
+### 创建模型
-=== "Python 3.9 及以上版本"
+导入 `SQLModel` 并创建一个数据库模型:
- ```Python hl_lines="15-17 31-34"
- {!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
- ```
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
-=== "Python 3.10 及以上版本"
+`Hero` 类与 Pydantic 模型非常相似(实际上,从底层来看,它确实*就是一个 Pydantic 模型*)。
- ```Python hl_lines="13-15 29-32"
- {!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
- ```
+有一些区别:
-!!! tip
- 请注意,读取用户(从 API 返回)时将使用不包括`password`的`User` Pydantic*模型*。
+* `table=True` 会告诉 SQLModel 这是一个*表模型*,它应该表示 SQL 数据库中的一个*表*,而不仅仅是一个*数据模型*(就像其他常规的 Pydantic 类一样)。
-### 使用 Pydantic 的`orm_mode`
+* `Field(primary_key=True)` 会告诉 SQLModel `id` 是 SQL 数据库中的**主键**(您可以在 SQLModel 文档中了解更多关于 SQL 主键的信息)。
-现在,在用于查询的 Pydantic*模型*`Item`中`User`,添加一个内部`Config`类。
+ 把类型设置为 `int | None` ,SQLModel 就能知道该列在 SQL 数据库中应该是 `INTEGER` 类型,并且应该是 `NULLABLE` 。
-此类[`Config`](https://pydantic-docs.helpmanual.io/usage/model_config/)用于为 Pydantic 提供配置。
+* `Field(index=True)` 会告诉 SQLModel 应该为此列创建一个 **SQL 索引**,这样在读取按此列过滤的数据时,程序能在数据库中进行更快的查找。
-在`Config`类中,设置属性`orm_mode = True`。
+ SQLModel 会知道声明为 `str` 的内容将是类型为 `TEXT` (或 `VARCHAR` ,具体取决于数据库)的 SQL 列。
-=== "Python 3.6 及以上版本"
+### 创建引擎(Engine)
- ```Python hl_lines="15 19-20 31 36-37"
- {!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
- ```
+SQLModel 的引擎 `engine`(实际上它是一个 SQLAlchemy `engine` )是用来与数据库**保持连接**的。
-=== "Python 3.9 及以上版本"
+您只需构建**一个 `engine`**,来让您的所有代码连接到同一个数据库。
- ```Python hl_lines="15 19-20 31 36-37"
- {!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
- ```
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *}
-=== "Python 3.10 及以上版本"
+使用 `check_same_thread=False` 可以让 FastAPI 在不同线程中使用同一个 SQLite 数据库。这很有必要,因为**单个请求**可能会使用**多个线程**(例如在依赖项中)。
- ```Python hl_lines="13 17-18 29 34-35"
- {!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
- ```
+不用担心,我们会按照代码结构确保**每个请求使用一个单独的 SQLModel *会话***,这实际上就是 `check_same_thread` 想要实现的。
-!!! tip
- 请注意,它使用`=`分配一个值,例如:
+### 创建表
- `orm_mode = True`
+然后,我们来添加一个函数,使用 `SQLModel.metadata.create_all(engine)` 为所有*表模型***创建表**。
- 它不使用之前的`:`来类型声明。
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *}
- 这是设置配置值,而不是声明类型。
+### 创建会话(Session)依赖项
-Pydantic`orm_mode`将告诉 Pydantic*模型*读取数据,即它不是一个`dict`,而是一个 ORM 模型(或任何其他具有属性的任意对象)。
+**`Session`** 会存储**内存中的对象**并跟踪数据中所需更改的内容,然后它**使用 `engine`** 与数据库进行通信。
-这样,而不是仅仅试图从`dict`上 `id` 中获取值,如下所示:
+我们会使用 `yield` 创建一个 FastAPI **依赖项**,为每个请求提供一个新的 `Session` 。这确保我们每个请求使用一个单独的会话。🤓
-```Python
-id = data["id"]
-```
+然后我们创建一个 `Annotated` 的依赖项 `SessionDep` 来简化其他也会用到此依赖的代码。
-尝试从属性中获取它,如:
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *}
-```Python
-id = data.id
-```
+### 在启动时创建数据库表
-有了这个,Pydantic*模型*与 ORM 兼容,您只需在*路径操作*`response_model`的参数中声明它即可。
+我们会在应用程序启动时创建数据库表。
-您将能够返回一个数据库模型,它将从中读取数据。
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *}
-#### ORM 模式的技术细节
+此处,在应用程序启动事件中,我们创建了表。
-SQLAlchemy 和许多其他默认情况下是“延迟加载”。
+而对于生产环境,您可能会用一个能够在启动应用程序之前运行的迁移脚本。🤓
-这意味着,例如,除非您尝试访问包含该数据的属性,否则它们不会从数据库中获取关系数据。
+/// tip
-例如,访问属性`items`:
+SQLModel 将会拥有封装 Alembic 的迁移工具,但目前您可以直接使用
+
+```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/zh/docs/virtual-environments.md b/docs/zh/docs/virtual-environments.md
new file mode 100644
index 000000000..9b3c0340a
--- /dev/null
+++ b/docs/zh/docs/virtual-environments.md
@@ -0,0 +1,844 @@
+# 虚拟环境
+
+当你在 Python 工程中工作时,你可能会有必要用到一个**虚拟环境**(或类似的机制)来隔离你为每个工程安装的包。
+
+/// info
+
+如果你已经了解虚拟环境,知道如何创建和使用它们,你可以考虑跳过这一部分。🤓
+
+///
+
+/// tip
+
+**虚拟环境**和**环境变量**是不同的。
+
+**环境变量**是系统中的一个变量,可以被程序使用。
+
+**虚拟环境**是一个包含一些文件的目录。
+
+///
+
+/// info
+
+这个页面将教你如何使用**虚拟环境**以及了解它们的工作原理。
+
+如果你计划使用一个**可以为你管理一切的工具**(包括安装 Python),试试
+
+```console
+// 进入主目录
+$ cd
+// 创建一个用于存放所有代码工程的目录
+$ mkdir code
+// 进入 code 目录
+$ cd code
+// 创建一个用于存放这个工程的目录
+$ mkdir awesome-project
+// 进入这个工程的目录
+$ cd awesome-project
+```
+
+
+
+## 创建一个虚拟环境
+
+在开始一个 Python 工程的**第一时间**,**
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+如果它显示了在你工程 (在这个例子中是 `awesome-project`) 的 `.venv/bin/python` 中的 `python` 二进制文件,那么它就生效了。🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+如果它显示了在你工程 (在这个例子中是 `awesome-project`) 的 `.venv\Scripts\python` 中的 `python` 二进制文件,那么它就生效了。🎉
+
+////
+
+## 升级 `pip`
+
+/// tip
+
+如果你使用
+
+```console
+// 先别去运行这个命令,这只是一个示例 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+这将会从
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+这意味着将使用的 `python` 程序是**在虚拟环境中**的那个。
+
+在 Linux 和 macOS 中使用 `which`,在 Windows PowerShell 中使用 `Get-Command`。
+
+这个命令的工作方式是,它会在 `PATH` 环境变量中查找,按顺序**逐个路径**查找名为 `python` 的程序。一旦找到,它会**显示该程序的路径**。
+
+最重要的部分是,当你调用 `python` 时,将执行的就是这个确切的 "`python`"。
+
+因此,你可以确认你是否在正确的虚拟环境中。
+
+/// tip
+
+激活一个虚拟环境,获取一个 Python,然后**转到另一个工程**是一件很容易的事情;
+
+但如果第二个工程**无法工作**,那是因为你使用了来自另一个工程的虚拟环境的、**不正确的 Python**。
+
+因此,会检查正在使用的 `python` 是很有用的。🤓
+
+///
+
+## 为什么要停用虚拟环境
+
+例如,你可能正在一个工程 `philosophers-stone` 上工作,**激活了该虚拟环境**,安装了包并使用了该环境,
+
+然后你想要在**另一个工程** `prisoner-of-azkaban` 上工作,
+
+你进入那个工程:
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+$ python main.py
+
+// 导入 sirius 报错,它没有安装 😱
+Traceback (most recent call last):
+ File "main.py", line 1, in
+ import sirius
+```
+
+
+
+但是如果你停用虚拟环境并激活 `prisoner-of-askaban` 的新虚拟环境,那么当你运行 `python` 时,它会使用 `prisoner-of-askaban` 中的虚拟环境中的 Python。
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// 你不需要在旧目录中操作停用,你可以在任何地方操作停用,甚至在转到另一个工程之后 😎
+$ deactivate
+
+// 激活 prisoner-of-azkaban/.venv 中的虚拟环境 🚀
+$ source .venv/bin/activate
+
+// 现在当你运行 python 时,它会在这个虚拟环境中找到安装的 sirius 包 ✨
+$ python main.py
+
+I solemnly swear 🐺
+```
+
+
+
+## 替代方案
+
+这是一个简单的指南,可以帮助你入门并教会你如何理解一切**底层**的东西。
+
+有许多**替代方案**来管理虚拟环境、包依赖(requirements)、工程。
+
+一旦你准备好并想要使用一个工具来**管理整个工程**、包依赖、虚拟环境等,建议你尝试