Browse Source

Merge branch 'master' into multipleAPIKeyHeaders

pull/4791/head
bilal alpaslan 2 years ago
committed by GitHub
parent
commit
bd78cead88
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      .github/DISCUSSION_TEMPLATE/questions.yml
  2. 12
      .github/ISSUE_TEMPLATE/config.yml
  3. 181
      .github/ISSUE_TEMPLATE/feature-request.yml
  4. 22
      .github/ISSUE_TEMPLATE/privileged.yml
  5. 419
      .github/actions/notify-translations/app/main.py
  6. 21
      .github/actions/notify-translations/app/translations.yml
  7. 214
      .github/actions/people/app/main.py
  8. 4
      .github/workflows/build-docs.yml
  9. 1
      .github/workflows/notify-translations.yml
  10. 3
      .github/workflows/people.yml
  11. 2
      .github/workflows/preview-docs.yml
  12. 2
      .github/workflows/publish.yml
  13. 2
      .github/workflows/smokeshow.yml
  14. 16
      .github/workflows/test.yml
  15. 12
      .pre-commit-config.yaml
  16. 10
      README.md
  17. 8
      docs/az/mkdocs.yml
  18. 8
      docs/de/mkdocs.yml
  19. 13
      docs/en/data/external_links.yml
  20. 247
      docs/en/data/github_sponsors.yml
  21. 374
      docs/en/data/people.yml
  22. 12
      docs/en/data/sponsors.yml
  23. 3
      docs/en/data/sponsors_badge.yml
  24. 129
      docs/en/docs/advanced/events.md
  25. 2
      docs/en/docs/advanced/middleware.md
  26. 2
      docs/en/docs/async.md
  27. 2
      docs/en/docs/deployment/concepts.md
  28. 9
      docs/en/docs/external-links.md
  29. 12
      docs/en/docs/fastapi-people.md
  30. 38
      docs/en/docs/help-fastapi.md
  31. BIN
      docs/en/docs/img/sponsors/powens.png
  32. 178
      docs/en/docs/img/sponsors/svix.svg
  33. 6
      docs/en/docs/index.md
  34. 2
      docs/en/docs/project-generation.md
  35. 254
      docs/en/docs/release-notes.md
  36. 2
      docs/en/docs/tutorial/bigger-applications.md
  37. 2
      docs/en/docs/tutorial/metadata.md
  38. 212
      docs/en/docs/tutorial/response-model.md
  39. 8
      docs/en/mkdocs.yml
  40. 6
      docs/en/overrides/main.html
  41. 8
      docs/es/mkdocs.yml
  42. 8
      docs/fa/mkdocs.yml
  43. 168
      docs/fr/docs/advanced/path-operation-advanced-configuration.md
  44. 153
      docs/fr/docs/deployment/manually.md
  45. 112
      docs/fr/docs/tutorial/debugging.md
  46. 11
      docs/fr/mkdocs.yml
  47. 8
      docs/he/mkdocs.yml
  48. 467
      docs/hy/docs/index.md
  49. 148
      docs/hy/mkdocs.yml
  50. 0
      docs/hy/overrides/.gitignore
  51. 8
      docs/id/mkdocs.yml
  52. 8
      docs/it/mkdocs.yml
  53. 8
      docs/ja/mkdocs.yml
  54. 84
      docs/ko/docs/tutorial/cors.md
  55. 9
      docs/ko/mkdocs.yml
  56. 8
      docs/nl/mkdocs.yml
  57. 8
      docs/pl/mkdocs.yml
  58. 42
      docs/pt/docs/tutorial/encoder.md
  59. 39
      docs/pt/docs/tutorial/static-files.md
  60. 10
      docs/pt/mkdocs.yml
  61. 469
      docs/ru/docs/contributing.md
  62. 180
      docs/ru/docs/fastapi-people.md
  63. 257
      docs/ru/docs/help-fastapi.md
  64. 77
      docs/ru/docs/history-design-future.md
  65. 69
      docs/ru/docs/tutorial/body-fields.md
  66. 49
      docs/ru/docs/tutorial/cookie-params.md
  67. 12
      docs/ru/mkdocs.yml
  68. 8
      docs/sq/mkdocs.yml
  69. 8
      docs/sv/mkdocs.yml
  70. 148
      docs/ta/mkdocs.yml
  71. 0
      docs/ta/overrides/.gitignore
  72. 336
      docs/tr/docs/tutorial/first_steps.md
  73. 10
      docs/tr/mkdocs.yml
  74. 8
      docs/uk/mkdocs.yml
  75. 2
      docs/zh/docs/benchmarks.md
  76. 2
      docs/zh/docs/index.md
  77. 8
      docs/zh/mkdocs.yml
  78. 2
      docs_src/app_testing/tutorial002.py
  79. 2
      docs_src/body_multiple_params/tutorial004.py
  80. 2
      docs_src/body_multiple_params/tutorial004_py310.py
  81. 28
      docs_src/events/tutorial003.py
  82. 2
      docs_src/path_params_numeric_validations/tutorial006.py
  83. 12
      docs_src/response_model/tutorial001.py
  84. 27
      docs_src/response_model/tutorial001_01.py
  85. 25
      docs_src/response_model/tutorial001_01_py310.py
  86. 27
      docs_src/response_model/tutorial001_01_py39.py
  87. 12
      docs_src/response_model/tutorial001_py310.py
  88. 12
      docs_src/response_model/tutorial001_py39.py
  89. 4
      docs_src/response_model/tutorial002.py
  90. 4
      docs_src/response_model/tutorial002_py310.py
  91. 4
      docs_src/response_model/tutorial003.py
  92. 21
      docs_src/response_model/tutorial003_01.py
  93. 19
      docs_src/response_model/tutorial003_01_py310.py
  94. 11
      docs_src/response_model/tutorial003_02.py
  95. 9
      docs_src/response_model/tutorial003_03.py
  96. 13
      docs_src/response_model/tutorial003_04.py
  97. 11
      docs_src/response_model/tutorial003_04_py310.py
  98. 13
      docs_src/response_model/tutorial003_05.py
  99. 11
      docs_src/response_model/tutorial003_05_py310.py
  100. 4
      docs_src/response_model/tutorial003_py310.py

18
.github/ISSUE_TEMPLATE/question.yml → .github/DISCUSSION_TEMPLATE/questions.yml

@ -1,5 +1,3 @@
name: Question or Problem
description: Ask a question or ask about a problem
labels: [question] labels: [question]
body: body:
- type: markdown - type: markdown
@ -9,9 +7,9 @@ body:
Please follow these instructions, fill every question, and do every step. 🙏 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'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 issues. 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. 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.
@ -21,16 +19,16 @@ body:
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. 😎 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. 🤓 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 - type: checkboxes
id: checks id: checks
attributes: attributes:
label: First Check label: First Check
description: Please confirm and check all the following options. description: Please confirm and check all the following options.
options: options:
- label: I added a very descriptive title to this issue. - label: I added a very descriptive title here.
required: true required: true
- label: I used the GitHub search to find a similar issue and didn't find it. - label: I used the GitHub search to find a similar question and didn't find it.
required: true required: true
- label: I searched the FastAPI documentation, with the integrated search. - label: I searched the FastAPI documentation, with the integrated search.
required: true required: true
@ -38,7 +36,7 @@ body:
required: true required: true
- label: I already read and followed all the tutorial in the docs and didn't find an answer. - label: I already read and followed all the tutorial in the docs and didn't find an answer.
required: true required: true
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic). - label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/pydantic/pydantic).
required: true required: true
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui). - label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
required: true required: true
@ -51,9 +49,9 @@ body:
description: | description: |
After submitting this, I commit to one of: 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. * 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. * 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. * Review one Pull Request by downloading the code and following [all the review process](https://fastapi.tiangolo.com/help-fastapi/#review-pull-requests).
options: options:
- label: I commit to help with one of those options 👆 - label: I commit to help with one of those options 👆

12
.github/ISSUE_TEMPLATE/config.yml

@ -2,3 +2,15 @@ blank_issues_enabled: false
contact_links: contact_links:
- name: Security Contact - name: Security Contact
about: Please report security vulnerabilities to [email protected] about: Please report security vulnerabilities to [email protected]
- name: Question or Problem
about: Ask a question or ask about a problem in GitHub Discussions.
url: https://github.com/tiangolo/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/tiangolo/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/tiangolo/fastapi/discussions/categories/show-and-tell
- name: Translations
about: Coordinate translations in GitHub Discussions.
url: https://github.com/tiangolo/fastapi/discussions/categories/translations

181
.github/ISSUE_TEMPLATE/feature-request.yml

@ -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.

22
.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/tiangolo/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.

419
.github/actions/notify-translations/app/main.py

@ -1,10 +1,11 @@
import logging import logging
import random import random
import sys
import time import time
from pathlib import Path from pathlib import Path
from typing import Dict, Union from typing import Any, Dict, List, Union, cast
import yaml import httpx
from github import Github from github import Github
from pydantic import BaseModel, BaseSettings, SecretStr from pydantic import BaseModel, BaseSettings, SecretStr
@ -13,12 +14,172 @@ lang_all_label = "lang-all"
approved_label = "approved-2" approved_label = "approved-2"
translations_path = Path(__file__).parent / "translations.yml" translations_path = Path(__file__).parent / "translations.yml"
github_graphql_url = "https://api.github.com/graphql"
questions_translations_category_id = "DIC_kwDOCZduT84CT5P9"
all_discussions_query = """
query Q($category_id: ID) {
repository(name: "fastapi", owner: "tiangolo") {
discussions(categoryId: $category_id, first: 100) {
nodes {
title
id
number
labels(first: 10) {
edges {
node {
id
name
}
}
}
}
}
}
}
"""
translation_discussion_query = """
query Q($after: String, $discussion_number: Int!) {
repository(name: "fastapi", owner: "tiangolo") {
discussion(number: $discussion_number) {
comments(first: 100, after: $after) {
edges {
cursor
node {
id
url
body
}
}
}
}
}
}
"""
add_comment_mutation = """
mutation Q($discussion_id: ID!, $body: String!) {
addDiscussionComment(input: {discussionId: $discussion_id, body: $body}) {
comment {
id
url
body
}
}
}
"""
update_comment_mutation = """
mutation Q($comment_id: ID!, $body: String!) {
updateDiscussionComment(input: {commentId: $comment_id, body: $body}) {
comment {
id
url
body
}
}
}
"""
class Comment(BaseModel):
id: str
url: str
body: str
class UpdateDiscussionComment(BaseModel):
comment: Comment
class UpdateCommentData(BaseModel):
updateDiscussionComment: UpdateDiscussionComment
class UpdateCommentResponse(BaseModel):
data: UpdateCommentData
class AddDiscussionComment(BaseModel):
comment: Comment
class AddCommentData(BaseModel):
addDiscussionComment: AddDiscussionComment
class AddCommentResponse(BaseModel):
data: AddCommentData
class CommentsEdge(BaseModel):
node: Comment
cursor: str
class Comments(BaseModel):
edges: List[CommentsEdge]
class CommentsDiscussion(BaseModel):
comments: Comments
class CommentsRepository(BaseModel):
discussion: CommentsDiscussion
class CommentsData(BaseModel):
repository: CommentsRepository
class CommentsResponse(BaseModel):
data: CommentsData
class AllDiscussionsLabelNode(BaseModel):
id: str
name: str
class AllDiscussionsLabelsEdge(BaseModel):
node: AllDiscussionsLabelNode
class AllDiscussionsDiscussionLabels(BaseModel):
edges: List[AllDiscussionsLabelsEdge]
class AllDiscussionsDiscussionNode(BaseModel):
title: str
id: str
number: int
labels: AllDiscussionsDiscussionLabels
class AllDiscussionsDiscussions(BaseModel):
nodes: List[AllDiscussionsDiscussionNode]
class AllDiscussionsRepository(BaseModel):
discussions: AllDiscussionsDiscussions
class AllDiscussionsData(BaseModel):
repository: AllDiscussionsRepository
class AllDiscussionsResponse(BaseModel):
data: AllDiscussionsData
class Settings(BaseSettings): class Settings(BaseSettings):
github_repository: str github_repository: str
input_token: SecretStr input_token: SecretStr
github_event_path: Path github_event_path: Path
github_event_name: Union[str, None] = None github_event_name: Union[str, None] = None
httpx_timeout: int = 30
input_debug: Union[bool, None] = False input_debug: Union[bool, None] = False
@ -30,6 +191,113 @@ class PartialGitHubEvent(BaseModel):
pull_request: PartialGitHubEventIssue pull_request: PartialGitHubEventIssue
def get_graphql_response(
*,
settings: Settings,
query: str,
after: Union[str, None] = None,
category_id: Union[str, None] = None,
discussion_number: Union[int, None] = None,
discussion_id: Union[str, None] = None,
comment_id: Union[str, None] = None,
body: Union[str, None] = None,
) -> Dict[str, Any]:
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
# some fields are only used by one query, but GraphQL allows unused variables, so
# keep them here for simplicity
variables = {
"after": after,
"category_id": category_id,
"discussion_number": discussion_number,
"discussion_id": discussion_id,
"comment_id": comment_id,
"body": body,
}
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}, category_id: {category_id}"
)
logging.error(response.text)
raise RuntimeError(response.text)
data = response.json()
if "errors" in data:
logging.error(f"Errors in response, after: {after}, category_id: {category_id}")
logging.error(response.text)
raise RuntimeError(response.text)
return cast(Dict[str, Any], data)
def get_graphql_translation_discussions(*, settings: Settings):
data = get_graphql_response(
settings=settings,
query=all_discussions_query,
category_id=questions_translations_category_id,
)
graphql_response = AllDiscussionsResponse.parse_obj(data)
return graphql_response.data.repository.discussions.nodes
def get_graphql_translation_discussion_comments_edges(
*, settings: Settings, discussion_number: int, after: Union[str, None] = None
):
data = get_graphql_response(
settings=settings,
query=translation_discussion_query,
discussion_number=discussion_number,
after=after,
)
graphql_response = CommentsResponse.parse_obj(data)
return graphql_response.data.repository.discussion.comments.edges
def get_graphql_translation_discussion_comments(
*, settings: Settings, discussion_number: int
):
comment_nodes: List[Comment] = []
discussion_edges = get_graphql_translation_discussion_comments_edges(
settings=settings, discussion_number=discussion_number
)
while discussion_edges:
for discussion_edge in discussion_edges:
comment_nodes.append(discussion_edge.node)
last_edge = discussion_edges[-1]
discussion_edges = get_graphql_translation_discussion_comments_edges(
settings=settings,
discussion_number=discussion_number,
after=last_edge.cursor,
)
return comment_nodes
def create_comment(*, settings: Settings, discussion_id: str, body: str):
data = get_graphql_response(
settings=settings,
query=add_comment_mutation,
discussion_id=discussion_id,
body=body,
)
response = AddCommentResponse.parse_obj(data)
return response.data.addDiscussionComment.comment
def update_comment(*, settings: Settings, comment_id: str, body: str):
data = get_graphql_response(
settings=settings,
query=update_comment_mutation,
comment_id=comment_id,
body=body,
)
response = UpdateCommentResponse.parse_obj(data)
return response.data.updateDiscussionComment.comment
if __name__ == "__main__": if __name__ == "__main__":
settings = Settings() settings = Settings()
if settings.input_debug: if settings.input_debug:
@ -45,60 +313,105 @@ if __name__ == "__main__":
) )
contents = settings.github_event_path.read_text() contents = settings.github_event_path.read_text()
github_event = PartialGitHubEvent.parse_raw(contents) 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}") # Avoid race conditions with multiple labels
sleep_time = random.random() * 10 # random number between 0 and 10 seconds sleep_time = random.random() * 10 # random number between 0 and 10 seconds
pr = repo.get_pull(github_event.pull_request.number) logging.info(
logging.debug( f"Sleeping for {sleep_time} seconds to avoid "
f"Processing PR: {pr.number}, with anti-race condition sleep time: {sleep_time}" "race conditions and multiple comments"
) )
if pr.state == "open": time.sleep(sleep_time)
logging.debug(f"PR is open: {pr.number}")
label_strs = {label.name for label in pr.get_labels()} # Get PR
if lang_all_label in label_strs and awaiting_label in label_strs: logging.debug(f"Processing PR: #{github_event.pull_request.number}")
pr = repo.get_pull(github_event.pull_request.number)
label_strs = {label.name for label in pr.get_labels()}
langs = []
for label in label_strs:
if label.startswith("lang-") and not label == lang_all_label:
langs.append(label[5:])
logging.info(f"PR #{pr.number} has labels: {label_strs}")
if not langs or lang_all_label not in label_strs:
logging.info(f"PR #{pr.number} doesn't seem to be a translation PR, skipping")
sys.exit(0)
# Generate translation map, lang ID to discussion
discussions = get_graphql_translation_discussions(settings=settings)
lang_to_discussion_map: Dict[str, AllDiscussionsDiscussionNode] = {}
for discussion in discussions:
for edge in discussion.labels.edges:
label = edge.node.name
if label.startswith("lang-") and not label == lang_all_label:
lang = label[5:]
lang_to_discussion_map[lang] = discussion
logging.debug(f"Using translations map: {lang_to_discussion_map}")
# Messages to create or check
new_translation_message = f"Good news everyone! 😉 There's a new translation PR to be reviewed: #{pr.number} by @{pr.user.login}. 🎉 This requires 2 approvals from native speakers to be merged. 🤓"
done_translation_message = f"~There's a new translation PR to be reviewed: #{pr.number} by @{pr.user.login}~ Good job! This is done. 🍰☕"
# Normally only one language, but still
for lang in langs:
if lang not in lang_to_discussion_map:
log_message = f"Could not find discussion for language: {lang}"
logging.error(log_message)
raise RuntimeError(log_message)
discussion = lang_to_discussion_map[lang]
logging.info(
f"Found a translation discussion for language: {lang} in discussion: #{discussion.number}"
)
already_notified_comment: Union[Comment, None] = None
already_done_comment: Union[Comment, None] = None
logging.info(
f"Checking current comments in discussion: #{discussion.number} to see if already notified about this PR: #{pr.number}"
)
comments = get_graphql_translation_discussion_comments(
settings=settings, discussion_number=discussion.number
)
for comment in comments:
if new_translation_message in comment.body:
already_notified_comment = comment
elif done_translation_message in comment.body:
already_done_comment = comment
logging.info(
f"Already notified comment: {already_notified_comment}, already done comment: {already_done_comment}"
)
if pr.state == "open" and awaiting_label in label_strs:
logging.info( logging.info(
f"This PR seems to be a language translation and awaiting reviews: {pr.number}" f"This PR seems to be a language translation and awaiting reviews: #{pr.number}"
) )
if approved_label in label_strs: if already_notified_comment:
message = ( logging.info(
f"It seems this PR already has the approved label: {pr.number}" f"This PR #{pr.number} was already notified in comment: {already_notified_comment.url}"
) )
logging.error(message) else:
raise RuntimeError(message) logging.info(
langs = [] f"Writing notification comment about PR #{pr.number} in Discussion: #{discussion.number}"
for label in label_strs: )
if label.startswith("lang-") and not label == lang_all_label: comment = create_comment(
langs.append(label[5:]) settings=settings,
for lang in langs: discussion_id=discussion.id,
if lang in translations_map: body=new_translation_message,
num = translations_map[lang] )
logging.info( logging.info(f"Notified in comment: {comment.url}")
f"Found a translation issue for language: {lang} in issue: {num}" elif pr.state == "closed" or approved_label in label_strs:
) logging.info(f"Already approved or closed PR #{pr.number}")
issue = repo.get_issue(num) if already_done_comment:
message = f"Good news everyone! 😉 There's a new translation PR to be reviewed: #{pr.number} 🎉" logging.info(
already_notified = False f"This PR #{pr.number} was already marked as done in comment: {already_done_comment.url}"
time.sleep(sleep_time) )
logging.info( elif already_notified_comment:
f"Sleeping for {sleep_time} seconds to avoid race conditions and multiple comments" updated_comment = update_comment(
) settings=settings,
logging.info( comment_id=already_notified_comment.id,
f"Checking current comments in issue: {num} to see if already notified about this PR: {pr.number}" body=done_translation_message,
) )
for comment in issue.get_comments(): logging.info(f"Marked as done in comment: {updated_comment.url}")
if message in comment.body: else:
already_notified = True logging.info(
if not already_notified: f"There doesn't seem to be anything to be done about PR #{pr.number}"
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") logging.info("Finished")

21
.github/actions/notify-translations/app/translations.yml

@ -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

214
.github/actions/people/app/main.py

@ -4,7 +4,7 @@ import sys
from collections import Counter, defaultdict from collections import Counter, defaultdict
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from pathlib import Path from pathlib import Path
from typing import Container, DefaultDict, Dict, List, Set, Union from typing import Any, Container, DefaultDict, Dict, List, Set, Union
import httpx import httpx
import yaml import yaml
@ -12,6 +12,50 @@ from github import Github
from pydantic import BaseModel, BaseSettings, SecretStr from pydantic import BaseModel, BaseSettings, SecretStr
github_graphql_url = "https://api.github.com/graphql" github_graphql_url = "https://api.github.com/graphql"
questions_category_id = "MDE4OkRpc2N1c3Npb25DYXRlZ29yeTMyMDAxNDM0"
discussions_query = """
query Q($after: String, $category_id: ID) {
repository(name: "fastapi", owner: "tiangolo") {
discussions(first: 100, after: $after, categoryId: $category_id) {
edges {
cursor
node {
number
author {
login
avatarUrl
url
}
title
createdAt
comments(first: 100) {
nodes {
createdAt
author {
login
avatarUrl
url
}
isAnswer
replies(first: 10) {
nodes {
createdAt
author {
login
avatarUrl
url
}
}
}
}
}
}
}
}
}
}
"""
issues_query = """ issues_query = """
query Q($after: String) { query Q($after: String) {
@ -131,15 +175,30 @@ class Author(BaseModel):
url: str url: str
# Issues and Discussions
class CommentsNode(BaseModel): class CommentsNode(BaseModel):
createdAt: datetime createdAt: datetime
author: Union[Author, None] = None author: Union[Author, None] = None
class Replies(BaseModel):
nodes: List[CommentsNode]
class DiscussionsCommentsNode(CommentsNode):
replies: Replies
class Comments(BaseModel): class Comments(BaseModel):
nodes: List[CommentsNode] nodes: List[CommentsNode]
class DiscussionsComments(BaseModel):
nodes: List[DiscussionsCommentsNode]
class IssuesNode(BaseModel): class IssuesNode(BaseModel):
number: int number: int
author: Union[Author, None] = None author: Union[Author, None] = None
@ -149,27 +208,59 @@ class IssuesNode(BaseModel):
comments: Comments comments: Comments
class DiscussionsNode(BaseModel):
number: int
author: Union[Author, None] = None
title: str
createdAt: datetime
comments: DiscussionsComments
class IssuesEdge(BaseModel): class IssuesEdge(BaseModel):
cursor: str cursor: str
node: IssuesNode node: IssuesNode
class DiscussionsEdge(BaseModel):
cursor: str
node: DiscussionsNode
class Issues(BaseModel): class Issues(BaseModel):
edges: List[IssuesEdge] edges: List[IssuesEdge]
class Discussions(BaseModel):
edges: List[DiscussionsEdge]
class IssuesRepository(BaseModel): class IssuesRepository(BaseModel):
issues: Issues issues: Issues
class DiscussionsRepository(BaseModel):
discussions: Discussions
class IssuesResponseData(BaseModel): class IssuesResponseData(BaseModel):
repository: IssuesRepository repository: IssuesRepository
class DiscussionsResponseData(BaseModel):
repository: DiscussionsRepository
class IssuesResponse(BaseModel): class IssuesResponse(BaseModel):
data: IssuesResponseData data: IssuesResponseData
class DiscussionsResponse(BaseModel):
data: DiscussionsResponseData
# PRs
class LabelNode(BaseModel): class LabelNode(BaseModel):
name: str name: str
@ -219,6 +310,9 @@ class PRsResponse(BaseModel):
data: PRsResponseData data: PRsResponseData
# Sponsors
class SponsorEntity(BaseModel): class SponsorEntity(BaseModel):
login: str login: str
avatarUrl: str avatarUrl: str
@ -264,10 +358,16 @@ class Settings(BaseSettings):
def get_graphql_response( def get_graphql_response(
*, settings: Settings, query: str, after: Union[str, None] = None *,
): settings: Settings,
query: str,
after: Union[str, None] = None,
category_id: Union[str, None] = None,
) -> Dict[str, Any]:
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"} headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
variables = {"after": after} # category_id is only used by one query, but GraphQL allows unused variables, so
# keep it here for simplicity
variables = {"after": after, "category_id": category_id}
response = httpx.post( response = httpx.post(
github_graphql_url, github_graphql_url,
headers=headers, headers=headers,
@ -275,10 +375,16 @@ def get_graphql_response(
json={"query": query, "variables": variables, "operationName": "Q"}, json={"query": query, "variables": variables, "operationName": "Q"},
) )
if response.status_code != 200: if response.status_code != 200:
logging.error(f"Response was not 200, after: {after}") logging.error(
f"Response was not 200, after: {after}, category_id: {category_id}"
)
logging.error(response.text) logging.error(response.text)
raise RuntimeError(response.text) raise RuntimeError(response.text)
data = response.json() data = response.json()
if "errors" in data:
logging.error(f"Errors in response, after: {after}, category_id: {category_id}")
logging.error(response.text)
raise RuntimeError(response.text)
return data return data
@ -288,6 +394,21 @@ def get_graphql_issue_edges(*, settings: Settings, after: Union[str, None] = Non
return graphql_response.data.repository.issues.edges return graphql_response.data.repository.issues.edges
def get_graphql_question_discussion_edges(
*,
settings: Settings,
after: Union[str, None] = None,
):
data = get_graphql_response(
settings=settings,
query=discussions_query,
after=after,
category_id=questions_category_id,
)
graphql_response = DiscussionsResponse.parse_obj(data)
return graphql_response.data.repository.discussions.edges
def get_graphql_pr_edges(*, settings: Settings, after: Union[str, None] = None): def get_graphql_pr_edges(*, settings: Settings, after: Union[str, None] = None):
data = get_graphql_response(settings=settings, query=prs_query, after=after) data = get_graphql_response(settings=settings, query=prs_query, after=after)
graphql_response = PRsResponse.parse_obj(data) graphql_response = PRsResponse.parse_obj(data)
@ -300,7 +421,7 @@ def get_graphql_sponsor_edges(*, settings: Settings, after: Union[str, None] = N
return graphql_response.data.user.sponsorshipsAsMaintainer.edges return graphql_response.data.user.sponsorshipsAsMaintainer.edges
def get_experts(settings: Settings): def get_issues_experts(settings: Settings):
issue_nodes: List[IssuesNode] = [] issue_nodes: List[IssuesNode] = []
issue_edges = get_graphql_issue_edges(settings=settings) issue_edges = get_graphql_issue_edges(settings=settings)
@ -326,13 +447,78 @@ def get_experts(settings: Settings):
for comment in issue.comments.nodes: for comment in issue.comments.nodes:
if comment.author: if comment.author:
authors[comment.author.login] = comment.author authors[comment.author.login] = comment.author
if comment.author.login == issue_author_name: if comment.author.login != issue_author_name:
continue issue_commentors.add(comment.author.login)
issue_commentors.add(comment.author.login)
for author_name in issue_commentors: for author_name in issue_commentors:
commentors[author_name] += 1 commentors[author_name] += 1
if issue.createdAt > one_month_ago: if issue.createdAt > one_month_ago:
last_month_commentors[author_name] += 1 last_month_commentors[author_name] += 1
return commentors, last_month_commentors, authors
def get_discussions_experts(settings: Settings):
discussion_nodes: List[DiscussionsNode] = []
discussion_edges = get_graphql_question_discussion_edges(settings=settings)
while discussion_edges:
for discussion_edge in discussion_edges:
discussion_nodes.append(discussion_edge.node)
last_edge = discussion_edges[-1]
discussion_edges = get_graphql_question_discussion_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 discussion in discussion_nodes:
discussion_author_name = None
if discussion.author:
authors[discussion.author.login] = discussion.author
discussion_author_name = discussion.author.login
discussion_commentors = set()
for comment in discussion.comments.nodes:
if comment.author:
authors[comment.author.login] = comment.author
if comment.author.login != discussion_author_name:
discussion_commentors.add(comment.author.login)
for reply in comment.replies.nodes:
if reply.author:
authors[reply.author.login] = reply.author
if reply.author.login != discussion_author_name:
discussion_commentors.add(reply.author.login)
for author_name in discussion_commentors:
commentors[author_name] += 1
if discussion.createdAt > one_month_ago:
last_month_commentors[author_name] += 1
return commentors, last_month_commentors, authors
def get_experts(settings: Settings):
# Migrated to only use GitHub Discussions
# (
# issues_commentors,
# issues_last_month_commentors,
# issues_authors,
# ) = get_issues_experts(settings=settings)
(
discussions_commentors,
discussions_last_month_commentors,
discussions_authors,
) = get_discussions_experts(settings=settings)
# commentors = issues_commentors + discussions_commentors
commentors = discussions_commentors
# last_month_commentors = (
# issues_last_month_commentors + discussions_last_month_commentors
# )
last_month_commentors = discussions_last_month_commentors
# authors = {**issues_authors, **discussions_authors}
authors = {**discussions_authors}
return commentors, last_month_commentors, authors return commentors, last_month_commentors, authors
@ -425,13 +611,13 @@ if __name__ == "__main__":
logging.info(f"Using config: {settings.json()}") logging.info(f"Using config: {settings.json()}")
g = Github(settings.input_standard_token.get_secret_value()) g = Github(settings.input_standard_token.get_secret_value())
repo = g.get_repo(settings.github_repository) repo = g.get_repo(settings.github_repository)
issue_commentors, issue_last_month_commentors, issue_authors = get_experts( question_commentors, question_last_month_commentors, question_authors = get_experts(
settings=settings settings=settings
) )
contributors, pr_commentors, reviewers, pr_authors = get_contributors( contributors, pr_commentors, reviewers, pr_authors = get_contributors(
settings=settings settings=settings
) )
authors = {**issue_authors, **pr_authors} authors = {**question_authors, **pr_authors}
maintainers_logins = {"tiangolo"} maintainers_logins = {"tiangolo"}
bot_names = {"codecov", "github-actions", "pre-commit-ci", "dependabot"} bot_names = {"codecov", "github-actions", "pre-commit-ci", "dependabot"}
maintainers = [] maintainers = []
@ -440,7 +626,7 @@ if __name__ == "__main__":
maintainers.append( maintainers.append(
{ {
"login": login, "login": login,
"answers": issue_commentors[login], "answers": question_commentors[login],
"prs": contributors[login], "prs": contributors[login],
"avatarUrl": user.avatarUrl, "avatarUrl": user.avatarUrl,
"url": user.url, "url": user.url,
@ -453,13 +639,13 @@ if __name__ == "__main__":
min_count_reviewer = 4 min_count_reviewer = 4
skip_users = maintainers_logins | bot_names skip_users = maintainers_logins | bot_names
experts = get_top_users( experts = get_top_users(
counter=issue_commentors, counter=question_commentors,
min_count=min_count_expert, min_count=min_count_expert,
authors=authors, authors=authors,
skip_users=skip_users, skip_users=skip_users,
) )
last_month_active = get_top_users( last_month_active = get_top_users(
counter=issue_last_month_commentors, counter=question_last_month_commentors,
min_count=min_count_last_month, min_count=min_count_last_month,
authors=authors, authors=authors,
skip_users=skip_users, skip_users=skip_users,

4
.github/workflows/build-docs.yml

@ -7,7 +7,7 @@ on:
types: [opened, synchronize] types: [opened, synchronize]
jobs: jobs:
build-docs: build-docs:
runs-on: ubuntu-18.04 runs-on: ubuntu-latest
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@ -17,7 +17,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: "3.7" python-version: "3.11"
- uses: actions/cache@v3 - uses: actions/cache@v3
id: cache id: cache
with: with:

1
.github/workflows/notify-translations.yml

@ -4,6 +4,7 @@ on:
pull_request_target: pull_request_target:
types: types:
- labeled - labeled
- closed
jobs: jobs:
notify-translations: notify-translations:

3
.github/workflows/people.yml

@ -15,6 +15,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
# Ref: https://github.com/actions/runner/issues/2033
- name: Fix git safe.directory in container
run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
# Allow debugging with tmate # Allow debugging with tmate
- name: Setup tmate session - name: Setup tmate session
uses: mxschmitt/action-tmate@v3 uses: mxschmitt/action-tmate@v3

2
.github/workflows/preview-docs.yml

@ -16,7 +16,7 @@ jobs:
rm -rf ./site rm -rf ./site
mkdir ./site mkdir ./site
- name: Download Artifact Docs - name: Download Artifact Docs
uses: dawidd6/[email protected]4.2 uses: dawidd6/[email protected]6.0
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: build-docs.yml workflow: build-docs.yml

2
.github/workflows/publish.yml

@ -31,7 +31,7 @@ jobs:
- name: Build distribution - name: Build distribution
run: python -m build run: python -m build
- name: Publish - name: Publish
uses: pypa/gh-action-pypi-publish@v1.5.2 uses: pypa/gh-action-pypi-publish@v1.6.4
with: with:
password: ${{ secrets.PYPI_API_TOKEN }} password: ${{ secrets.PYPI_API_TOKEN }}
- name: Dump GitHub context - name: Dump GitHub context

2
.github/workflows/smokeshow.yml

@ -20,7 +20,7 @@ jobs:
- run: pip install smokeshow - run: pip install smokeshow
- uses: dawidd6/[email protected]4.2 - uses: dawidd6/[email protected]6.0
with: with:
workflow: test.yml workflow: test.yml
commit: ${{ github.event.workflow_run.head_sha }} commit: ${{ github.event.workflow_run.head_sha }}

16
.github/workflows/test.yml

@ -75,3 +75,19 @@ jobs:
with: with:
name: coverage-html name: coverage-html
path: htmlcov path: htmlcov
# 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: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}

12
.pre-commit-config.yaml

@ -1,8 +1,10 @@
# See https://pre-commit.com for more information # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
default_language_version:
python: python3.10
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0 rev: v4.4.0
hooks: hooks:
- id: check-added-large-files - id: check-added-large-files
- id: check-toml - id: check-toml
@ -12,20 +14,20 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v3.2.2 rev: v3.3.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: args:
- --py3-plus - --py3-plus
- --keep-runtime-typing - --keep-runtime-typing
- repo: https://github.com/charliermarsh/ruff-pre-commit - repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.138 rev: v0.0.254
hooks: hooks:
- id: ruff - id: ruff
args: args:
- --fix - --fix
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.10.1 rev: 5.12.0
hooks: hooks:
- id: isort - id: isort
name: isort (python) name: isort (python)
@ -36,7 +38,7 @@ repos:
name: isort (pyi) name: isort (pyi)
types: [pyi] types: [pyi]
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 22.10.0 rev: 23.1.0
hooks: hooks:
- id: black - id: black
ci: ci:

10
README.md

@ -49,14 +49,14 @@ The key features are:
<a href="https://bit.ly/3dmXC5S" target="_blank" title="The data structure for unstructured multimodal data"><img src="https://fastapi.tiangolo.com/img/sponsors/docarray.svg"></a> <a href="https://bit.ly/3dmXC5S" target="_blank" title="The data structure for unstructured multimodal data"><img src="https://fastapi.tiangolo.com/img/sponsors/docarray.svg"></a>
<a href="https://bit.ly/3JJ7y5C" target="_blank" title="Build cross-modal and multimodal applications on the cloud"><img src="https://fastapi.tiangolo.com/img/sponsors/jina2.svg"></a> <a href="https://bit.ly/3JJ7y5C" target="_blank" title="Build cross-modal and multimodal applications on the cloud"><img src="https://fastapi.tiangolo.com/img/sponsors/jina2.svg"></a>
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a> <a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
<a href="https://doist.com/careers/9B437B1615-wa-senior-backend-engineer-python" target="_blank" title="Help us migrate doist to FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/doist.svg"></a>
<a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a> <a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a>
<a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a> <a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a>
<a href="https://training.talkpython.fm/fastapi-courses" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython.png"></a> <a href="https://training.talkpython.fm/fastapi-courses" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython.png"></a>
<a href="https://testdriven.io/courses/tdd-fastapi/" target="_blank" title="Learn to build high-quality web apps with best practices"><img src="https://fastapi.tiangolo.com/img/sponsors/testdriven.svg"></a> <a href="https://testdriven.io/courses/tdd-fastapi/" target="_blank" title="Learn to build high-quality web apps with best practices"><img src="https://fastapi.tiangolo.com/img/sponsors/testdriven.svg"></a>
<a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a> <a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
<a href="https://www.udemy.com/course/fastapi-rest/" target="_blank" title="Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails."><img src="https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg"></a> <a href="https://www.udemy.com/course/fastapi-rest/" target="_blank" title="Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails."><img src="https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg"></a>
<a href="https://careers.budget-insight.com/" target="_blank" title="Budget Insight is hiring!"><img src="https://fastapi.tiangolo.com/img/sponsors/budget-insight.svg"></a> <a href="https://careers.powens.com/" target="_blank" title="Powens is hiring!"><img src="https://fastapi.tiangolo.com/img/sponsors/powens.png"></a>
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
<!-- /sponsors --> <!-- /sponsors -->
@ -102,6 +102,12 @@ The key features are:
--- ---
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs ## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a> <a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>

8
docs/az/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/de/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -81,7 +83,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -112,6 +114,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -132,6 +136,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

13
docs/en/data/external_links.yml

@ -1,5 +1,13 @@
articles: articles:
english: english:
- 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: WayScript - author: WayScript
author_link: https://www.wayscript.com author_link: https://www.wayscript.com
link: https://blog.wayscript.com/fast-api-quickstart/ link: https://blog.wayscript.com/fast-api-quickstart/
@ -300,6 +308,11 @@ articles:
author_link: https://fullstackstation.com/author/figonking/ author_link: https://fullstackstation.com/author/figonking/
link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/ link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
title: 'FASTAPI: TRIỂN KHAI BẰNG DOCKER' title: 'FASTAPI: TRIỂN KHAI BẰNG DOCKER'
taiwanese:
- author: Leon
author_link: http://editor.leonh.space/
link: https://editor.leonh.space/2022/tortoise/
title: 'Tortoise ORM / FastAPI 整合快速筆記'
podcasts: podcasts:
english: english:
- author: Podcast.`__init__` - author: Podcast.`__init__`

247
docs/en/data/github_sponsors.yml

@ -2,15 +2,12 @@ sponsors:
- - login: jina-ai - - login: jina-ai
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4 avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
url: https://github.com/jina-ai url: https://github.com/jina-ai
- - login: Doist - - login: armand-sauzay
avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4 avatarUrl: https://avatars.githubusercontent.com/u/35524799?u=56e3e944bfe62770d1709c09552d2efc6d285ca6&v=4
url: https://github.com/Doist url: https://github.com/armand-sauzay
- login: cryptapi - - login: cryptapi
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4 avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
url: https://github.com/cryptapi 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 - - login: nihpo
avatarUrl: https://avatars.githubusercontent.com/u/1841030?u=0264956d7580f7e46687a762a7baa629f84cf97c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1841030?u=0264956d7580f7e46687a762a7baa629f84cf97c&v=4
url: https://github.com/nihpo url: https://github.com/nihpo
@ -32,6 +29,9 @@ sponsors:
- login: investsuite - login: investsuite
avatarUrl: https://avatars.githubusercontent.com/u/73833632?v=4 avatarUrl: https://avatars.githubusercontent.com/u/73833632?v=4
url: https://github.com/investsuite url: https://github.com/investsuite
- login: svix
avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
url: https://github.com/svix
- login: VincentParedes - login: VincentParedes
avatarUrl: https://avatars.githubusercontent.com/u/103889729?v=4 avatarUrl: https://avatars.githubusercontent.com/u/103889729?v=4
url: https://github.com/VincentParedes url: https://github.com/VincentParedes
@ -44,36 +44,24 @@ sponsors:
- - login: vyos - - login: vyos
avatarUrl: https://avatars.githubusercontent.com/u/5647000?v=4 avatarUrl: https://avatars.githubusercontent.com/u/5647000?v=4
url: https://github.com/vyos 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 - login: takashi-yoneya
avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4 avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4
url: https://github.com/takashi-yoneya url: https://github.com/takashi-yoneya
- login: mercedes-benz
avatarUrl: https://avatars.githubusercontent.com/u/34240465?v=4
url: https://github.com/mercedes-benz
- login: xoflare - login: xoflare
avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4 avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
url: https://github.com/xoflare url: https://github.com/xoflare
- login: Striveworks
avatarUrl: https://avatars.githubusercontent.com/u/45523576?v=4
url: https://github.com/Striveworks
- login: BoostryJP - login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4 avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP url: https://github.com/BoostryJP
- - login: johnadjei - - login: johnadjei
avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4 avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
url: https://github.com/johnadjei 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 - login: HiredScore
avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4 avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4
url: https://github.com/HiredScore url: https://github.com/HiredScore
- login: ianshan0915
avatarUrl: https://avatars.githubusercontent.com/u/5893101?u=a178d247d882578b1d1ef214b2494e52eb28634c&v=4
url: https://github.com/ianshan0915
- login: Trivie - login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4 avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie url: https://github.com/Trivie
@ -83,6 +71,9 @@ sponsors:
- - login: moellenbeck - - login: moellenbeck
avatarUrl: https://avatars.githubusercontent.com/u/169372?v=4 avatarUrl: https://avatars.githubusercontent.com/u/169372?v=4
url: https://github.com/moellenbeck url: https://github.com/moellenbeck
- login: birkjernstrom
avatarUrl: https://avatars.githubusercontent.com/u/281715?u=4be14b43f76b4bd497b1941309bb390250b405e6&v=4
url: https://github.com/birkjernstrom
- login: AccentDesign - login: AccentDesign
avatarUrl: https://avatars.githubusercontent.com/u/2429332?v=4 avatarUrl: https://avatars.githubusercontent.com/u/2429332?v=4
url: https://github.com/AccentDesign url: https://github.com/AccentDesign
@ -110,9 +101,6 @@ sponsors:
- - login: indeedeng - - login: indeedeng
avatarUrl: https://avatars.githubusercontent.com/u/2905043?v=4 avatarUrl: https://avatars.githubusercontent.com/u/2905043?v=4
url: https://github.com/indeedeng 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 - - login: Kludex
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex url: https://github.com/Kludex
@ -134,9 +122,6 @@ sponsors:
- login: pamelafox - login: pamelafox
avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4 avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
url: https://github.com/pamelafox url: https://github.com/pamelafox
- login: deserat
avatarUrl: https://avatars.githubusercontent.com/u/299332?v=4
url: https://github.com/deserat
- login: ericof - login: ericof
avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4
url: https://github.com/ericof url: https://github.com/ericof
@ -152,30 +137,24 @@ sponsors:
- login: jqueguiner - login: jqueguiner
avatarUrl: https://avatars.githubusercontent.com/u/690878?u=bd65cc1f228ce6455e56dfaca3ef47c33bc7c3b0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/690878?u=bd65cc1f228ce6455e56dfaca3ef47c33bc7c3b0&v=4
url: https://github.com/jqueguiner url: https://github.com/jqueguiner
- login: alexsantos - login: iobruno
avatarUrl: https://avatars.githubusercontent.com/u/932219?v=4 avatarUrl: https://avatars.githubusercontent.com/u/901651?u=460bc34ac298dca9870aafe3a1560a2ae789bc4a&v=4
url: https://github.com/alexsantos url: https://github.com/iobruno
- login: tcsmith - login: tcsmith
avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4
url: https://github.com/tcsmith 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 - login: mrkmcknz
avatarUrl: https://avatars.githubusercontent.com/u/1089376?u=2b9b8a8c25c33a4f6c220095638bd821cdfd13a3&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1089376?u=2b9b8a8c25c33a4f6c220095638bd821cdfd13a3&v=4
url: https://github.com/mrkmcknz url: https://github.com/mrkmcknz
- login: coffeewasmyidea - login: coffeewasmyidea
avatarUrl: https://avatars.githubusercontent.com/u/1636488?u=8e32a4f200eff54dd79cd79d55d254bfce5e946d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1636488?u=8e32a4f200eff54dd79cd79d55d254bfce5e946d&v=4
url: https://github.com/coffeewasmyidea url: https://github.com/coffeewasmyidea
- login: jonakoudijs
avatarUrl: https://avatars.githubusercontent.com/u/1906344?u=5ca0c9a1a89b6a2ba31abe35c66bdc07af60a632&v=4
url: https://github.com/jonakoudijs
- login: corleyma - login: corleyma
avatarUrl: https://avatars.githubusercontent.com/u/2080732?u=aed2ff652294a87d666b1c3f6dbe98104db76d26&v=4 avatarUrl: https://avatars.githubusercontent.com/u/2080732?u=c61f9a4bbc45a45f5d855f93e5f6e0fc8b32c468&v=4
url: https://github.com/corleyma 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 - login: andre1sk
avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4 avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
url: https://github.com/andre1sk url: https://github.com/andre1sk
@ -185,51 +164,36 @@ sponsors:
- login: ColliotL - login: ColliotL
avatarUrl: https://avatars.githubusercontent.com/u/3412402?u=ca64b07ecbef2f9da1cc2cac3f37522aa4814902&v=4 avatarUrl: https://avatars.githubusercontent.com/u/3412402?u=ca64b07ecbef2f9da1cc2cac3f37522aa4814902&v=4
url: https://github.com/ColliotL url: https://github.com/ColliotL
- login: grillazz
avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=453cd1725c8d7fe3e258016bc19cff861d4fcb53&v=4
url: https://github.com/grillazz
- login: dblackrun - login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4 avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun url: https://github.com/dblackrun
- login: zsinx6 - login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4 avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6 url: https://github.com/zsinx6
- login: MarekBleschke
avatarUrl: https://avatars.githubusercontent.com/u/3616870?v=4
url: https://github.com/MarekBleschke
- login: aacayaco - login: aacayaco
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4 avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
url: https://github.com/aacayaco url: https://github.com/aacayaco
- login: anomaly - login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4 avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly 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 - login: jgreys
avatarUrl: https://avatars.githubusercontent.com/u/4136890?u=c66ae617d614f6c886f1f1c1799d22100b3c848d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4136890?u=c66ae617d614f6c886f1f1c1799d22100b3c848d&v=4
url: https://github.com/jgreys url: https://github.com/jgreys
- login: gorhack
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
url: https://github.com/gorhack
- login: jaredtrog - login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4 avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog url: https://github.com/jaredtrog
- login: oliverxchen - login: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen 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 - login: ennui93
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
url: https://github.com/ennui93 url: https://github.com/ennui93
- login: ternaus - login: ternaus
avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=fabc8d75c921b3380126adb5a931c5da6e7db04f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=fabc8d75c921b3380126adb5a931c5da6e7db04f&v=4
url: https://github.com/ternaus url: https://github.com/ternaus
- login: eseglem
avatarUrl: https://avatars.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
url: https://github.com/eseglem
- login: Yaleesa - login: Yaleesa
avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4 avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4
url: https://github.com/Yaleesa url: https://github.com/Yaleesa
@ -248,6 +212,9 @@ sponsors:
- login: Rehket - login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket url: https://github.com/Rehket
- login: ValentinCalomme
avatarUrl: https://avatars.githubusercontent.com/u/7288672?u=e09758c7a36c49f0fb3574abe919cbd344fdc2d6&v=4
url: https://github.com/ValentinCalomme
- login: hiancdtrsnm - login: hiancdtrsnm
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4 avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
url: https://github.com/hiancdtrsnm url: https://github.com/hiancdtrsnm
@ -257,15 +224,9 @@ sponsors:
- login: wdwinslow - login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4 avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow 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 - login: svats2k
avatarUrl: https://avatars.githubusercontent.com/u/12378398?u=ecf28c19f61052e664bdfeb2391f8107d137915c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/12378398?u=ecf28c19f61052e664bdfeb2391f8107d137915c&v=4
url: https://github.com/svats2k 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 - login: dannywade
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
url: https://github.com/dannywade url: https://github.com/dannywade
@ -273,20 +234,26 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4 avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
url: https://github.com/khadrawy url: https://github.com/khadrawy
- login: pablonnaoji - login: pablonnaoji
avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=afc15bd5a4ba9c5c7206bbb1bcaeef606a0932e0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=7480e0eaf959e9c5dfe3a05286f2ea4588c0a3c6&v=4
url: https://github.com/pablonnaoji url: https://github.com/pablonnaoji
- login: mjohnsey
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
url: https://github.com/mjohnsey
- login: abdalla19977
avatarUrl: https://avatars.githubusercontent.com/u/17257234?v=4
url: https://github.com/abdalla19977
- login: wedwardbeck - login: wedwardbeck
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
url: https://github.com/wedwardbeck 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 - login: Filimoa
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=0be845711495bbd7b756e13fcaeb8efc1ebd78ba&v=4
url: https://github.com/Filimoa url: https://github.com/Filimoa
- login: shuheng-liu - login: shuheng-liu
avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4 avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
url: https://github.com/shuheng-liu url: https://github.com/shuheng-liu
- login: Pablongo24
avatarUrl: https://avatars.githubusercontent.com/u/24843427?u=78a6798469889d7a0690449fc667c39e13d5c6a9&v=4
url: https://github.com/Pablongo24
- login: Joeriksson - login: Joeriksson
avatarUrl: https://avatars.githubusercontent.com/u/25037079?v=4 avatarUrl: https://avatars.githubusercontent.com/u/25037079?v=4
url: https://github.com/Joeriksson url: https://github.com/Joeriksson
@ -317,9 +284,12 @@ sponsors:
- login: ProteinQure - login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4 avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure url: https://github.com/ProteinQure
- login: faviasono - login: askurihin
avatarUrl: https://avatars.githubusercontent.com/u/37707874?u=f0b75ca4248987c08ed8fb8ed682e7e74d5d7091&v=4 avatarUrl: https://avatars.githubusercontent.com/u/37978981?v=4
url: https://github.com/faviasono url: https://github.com/askurihin
- login: arleybri18
avatarUrl: https://avatars.githubusercontent.com/u/39681546?u=5c028f81324b0e8c73b3c15bc4e7b0218d2ba0c3&v=4
url: https://github.com/arleybri18
- login: ybressler - login: ybressler
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=41e2c00f1eebe3c402635f0325e41b4e6511462c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=41e2c00f1eebe3c402635f0325e41b4e6511462c&v=4
url: https://github.com/ybressler url: https://github.com/ybressler
@ -329,18 +299,21 @@ sponsors:
- login: VictorCalderon - login: VictorCalderon
avatarUrl: https://avatars.githubusercontent.com/u/44529243?u=cea69884f826a29aff1415493405209e0706d07a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/44529243?u=cea69884f826a29aff1415493405209e0706d07a&v=4
url: https://github.com/VictorCalderon 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 - login: rafsaf
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4 avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
url: https://github.com/rafsaf url: https://github.com/rafsaf
- login: dudikbender - login: dudikbender
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4 avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4
url: https://github.com/dudikbender url: https://github.com/dudikbender
- login: dazeddd - login: thisistheplace
avatarUrl: https://avatars.githubusercontent.com/u/59472056?u=7a1b668449bf8b448db13e4c575576d24d7d658b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/57633545?u=a3f3a7f8ace8511c6c067753f6eb6aee0db11ac6&v=4
url: https://github.com/dazeddd url: https://github.com/thisistheplace
- login: kyjoconn
avatarUrl: https://avatars.githubusercontent.com/u/58443406?u=a3e9c2acfb7ba62edda9334aba61cf027f41f789&v=4
url: https://github.com/kyjoconn
- login: A-Edge
avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
url: https://github.com/A-Edge
- login: yakkonaut - login: yakkonaut
avatarUrl: https://avatars.githubusercontent.com/u/60633704?u=90a71fd631aa998ba4a96480788f017c9904e07b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/60633704?u=90a71fd631aa998ba4a96480788f017c9904e07b&v=4
url: https://github.com/yakkonaut url: https://github.com/yakkonaut
@ -350,31 +323,28 @@ sponsors:
- login: predictionmachine - login: predictionmachine
avatarUrl: https://avatars.githubusercontent.com/u/63719559?v=4 avatarUrl: https://avatars.githubusercontent.com/u/63719559?v=4
url: https://github.com/predictionmachine 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 - login: daverin
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
url: https://github.com/daverin url: https://github.com/daverin
- login: anthonycepeda - login: anthonycepeda
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=4252c6b6dc5024af502a823a3ac5e7a03a69963f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=4252c6b6dc5024af502a823a3ac5e7a03a69963f&v=4
url: https://github.com/anthonycepeda 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 - login: DelfinaCare
avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4 avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
url: https://github.com/DelfinaCare url: https://github.com/DelfinaCare
- login: programvx - login: osawa-koki
avatarUrl: https://avatars.githubusercontent.com/u/96057906?v=4 avatarUrl: https://avatars.githubusercontent.com/u/94336223?u=59c6fe6945bcbbaff87b2a794238671b060620d2&v=4
url: https://github.com/programvx url: https://github.com/osawa-koki
- login: pyt3h - login: pyt3h
avatarUrl: https://avatars.githubusercontent.com/u/99658549?v=4 avatarUrl: https://avatars.githubusercontent.com/u/99658549?v=4
url: https://github.com/pyt3h url: https://github.com/pyt3h
- login: Dagmaara - login: Dagmaara
avatarUrl: https://avatars.githubusercontent.com/u/115501964?v=4 avatarUrl: https://avatars.githubusercontent.com/u/115501964?v=4
url: https://github.com/Dagmaara url: https://github.com/Dagmaara
- - login: linux-china - - login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
- login: linux-china
avatarUrl: https://avatars.githubusercontent.com/u/46711?u=cd77c65338b158750eb84dc7ff1acf3209ccfc4f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/46711?u=cd77c65338b158750eb84dc7ff1acf3209ccfc4f&v=4
url: https://github.com/linux-china url: https://github.com/linux-china
- login: ddanier - login: ddanier
@ -389,12 +359,6 @@ sponsors:
- login: bryanculbertson - login: bryanculbertson
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
url: https://github.com/bryanculbertson 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 - login: adamghill
avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4 avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
url: https://github.com/adamghill url: https://github.com/adamghill
@ -404,9 +368,6 @@ sponsors:
- login: dmig - login: dmig
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4 avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
url: https://github.com/dmig 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 - login: securancy
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4 avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
url: https://github.com/securancy url: https://github.com/securancy
@ -419,39 +380,27 @@ sponsors:
- login: janfilips - login: janfilips
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=50de77b93d3a0b06887e672d4e8c7b9d643085aa&v=4 avatarUrl: https://avatars.githubusercontent.com/u/870699?u=50de77b93d3a0b06887e672d4e8c7b9d643085aa&v=4
url: https://github.com/janfilips 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 - login: allen0125
avatarUrl: https://avatars.githubusercontent.com/u/1448456?u=dc2ad819497eef494b88688a1796e0adb87e7cae&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1448456?u=dc2ad819497eef494b88688a1796e0adb87e7cae&v=4
url: https://github.com/allen0125 url: https://github.com/allen0125
- login: WillHogan - login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
url: https://github.com/WillHogan url: https://github.com/WillHogan
- login: my3
avatarUrl: https://avatars.githubusercontent.com/u/1825270?v=4
url: https://github.com/my3
- login: cbonoz - login: cbonoz
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
url: https://github.com/cbonoz 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 - login: paul121
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4 avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
url: https://github.com/paul121 url: https://github.com/paul121
- login: igorcorrea - login: larsvik
avatarUrl: https://avatars.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4 avatarUrl: https://avatars.githubusercontent.com/u/3442226?v=4
url: https://github.com/igorcorrea url: https://github.com/larsvik
- login: anthonycorletti - login: anthonycorletti
avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4 avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
url: https://github.com/anthonycorletti 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 - login: nikeee
avatarUrl: https://avatars.githubusercontent.com/u/4068864?u=63f8eee593f25138e0f1032ef442e9ad24907d4c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4068864?u=63f8eee593f25138e0f1032ef442e9ad24907d4c&v=4
url: https://github.com/nikeee url: https://github.com/nikeee
@ -467,11 +416,14 @@ sponsors:
- login: Baghdady92 - login: Baghdady92
avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4 avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
url: https://github.com/Baghdady92 url: https://github.com/Baghdady92
- login: KentShikama
avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
url: https://github.com/KentShikama
- login: holec - login: holec
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4 avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
url: https://github.com/holec url: https://github.com/holec
- login: mattwelke - login: mattwelke
avatarUrl: https://avatars.githubusercontent.com/u/7719209?u=5d963ead289969257190b133250653bd99df06ba&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7719209?v=4
url: https://github.com/mattwelke url: https://github.com/mattwelke
- login: hcristea - login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
@ -479,9 +431,6 @@ sponsors:
- login: moonape1226 - login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226 url: https://github.com/moonape1226
- login: yenchenLiu
avatarUrl: https://avatars.githubusercontent.com/u/9199638?u=8cdf5ae507448430d90f6f3518d1665a23afe99b&v=4
url: https://github.com/yenchenLiu
- login: xncbf - login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=866a1311e4bd3ec5ae84185c4fcc99f397c883d7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=866a1311e4bd3ec5ae84185c4fcc99f397c883d7&v=4
url: https://github.com/xncbf url: https://github.com/xncbf
@ -506,9 +455,9 @@ sponsors:
- login: giuliano-oliveira - login: giuliano-oliveira
avatarUrl: https://avatars.githubusercontent.com/u/13181797?u=0ef2dfbf7fc9a9726d45c21d32b5d1038a174870&v=4 avatarUrl: https://avatars.githubusercontent.com/u/13181797?u=0ef2dfbf7fc9a9726d45c21d32b5d1038a174870&v=4
url: https://github.com/giuliano-oliveira url: https://github.com/giuliano-oliveira
- login: logan-connolly - login: TheR1D
avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4 avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b2923ac17fe6e2a7c9ea14800351ddb92f79b100&v=4
url: https://github.com/logan-connolly url: https://github.com/TheR1D
- login: cdsre - login: cdsre
avatarUrl: https://avatars.githubusercontent.com/u/16945936?v=4 avatarUrl: https://avatars.githubusercontent.com/u/16945936?v=4
url: https://github.com/cdsre url: https://github.com/cdsre
@ -518,21 +467,18 @@ sponsors:
- login: paulowiz - login: paulowiz
avatarUrl: https://avatars.githubusercontent.com/u/18649504?u=d8a6ac40321f2bded0eba78b637751c7f86c6823&v=4 avatarUrl: https://avatars.githubusercontent.com/u/18649504?u=d8a6ac40321f2bded0eba78b637751c7f86c6823&v=4
url: https://github.com/paulowiz 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 - login: ghandic
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4 avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic 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 - login: pers0n4
avatarUrl: https://avatars.githubusercontent.com/u/24864600?u=444441027bc2c9f9db68e8047d65ff23d25699cf&v=4 avatarUrl: https://avatars.githubusercontent.com/u/24864600?u=f211a13a7b572cbbd7779b9c8d8cb428cc7ba07e&v=4
url: https://github.com/pers0n4 url: https://github.com/pers0n4
- login: SebTota - login: SebTota
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4 avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
url: https://github.com/SebTota url: https://github.com/SebTota
- login: hoenie-ams
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
url: https://github.com/hoenie-ams
- login: joerambo - login: joerambo
avatarUrl: https://avatars.githubusercontent.com/u/26282974?v=4 avatarUrl: https://avatars.githubusercontent.com/u/26282974?v=4
url: https://github.com/joerambo url: https://github.com/joerambo
@ -549,7 +495,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4 avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440 url: https://github.com/engineerjoe440
- login: bnkc - login: bnkc
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=20f362505e2a994805233f42e69f9f14b4a9dd0c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=76cdc0a8b4e88c7d3e58dccb4b2670839e1247b4&v=4
url: https://github.com/bnkc url: https://github.com/bnkc
- login: declon - login: declon
avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4 avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
@ -564,26 +510,14 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/38921751?u=ae14bc1e40f2dd5a9c5741fc0b0dffbd416a5fa9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/38921751?u=ae14bc1e40f2dd5a9c5741fc0b0dffbd416a5fa9&v=4
url: https://github.com/ww-daniel-mora url: https://github.com/ww-daniel-mora
- login: rwxd - 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 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 - login: arrrrrmin
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=2a812c1a2ec58227ed01778837f255143de9df97&v=4 avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=5265858add14a6822bd145f7547323cf078563e6&v=4
url: https://github.com/arrrrrmin 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 - login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=f4888c2c54929bd86eed0d3971d09fcb306e5088&v=4 avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=f4888c2c54929bd86eed0d3971d09fcb306e5088&v=4
url: https://github.com/hgalytoby 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 - login: data-djinn
avatarUrl: https://avatars.githubusercontent.com/u/56449985?u=42146e140806908d49bd59ccc96f222abf587886&v=4 avatarUrl: https://avatars.githubusercontent.com/u/56449985?u=42146e140806908d49bd59ccc96f222abf587886&v=4
url: https://github.com/data-djinn url: https://github.com/data-djinn
@ -602,21 +536,12 @@ sponsors:
- login: realabja - login: realabja
avatarUrl: https://avatars.githubusercontent.com/u/66185192?u=001e2dd9297784f4218997981b4e6fa8357bb70b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/66185192?u=001e2dd9297784f4218997981b4e6fa8357bb70b&v=4
url: https://github.com/realabja url: https://github.com/realabja
- login: alessio-proietti - login: garydsong
avatarUrl: https://avatars.githubusercontent.com/u/67370599?u=8ac73db1e18e946a7681f173abdb640516f88515&v=4 avatarUrl: https://avatars.githubusercontent.com/u/105745865?u=03cc1aa9c978be0020e5a1ce1ecca323dd6c8d65&v=4
url: https://github.com/alessio-proietti url: https://github.com/garydsong
- login: pondDevThai - - login: Leon0824
avatarUrl: https://avatars.githubusercontent.com/u/71592181?u=08af9a59bccfd8f6b101de1005aa9822007d0a44&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1922026?v=4
url: https://github.com/pondDevThai url: https://github.com/Leon0824
- - 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 - login: danburonline
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
url: https://github.com/danburonline url: https://github.com/danburonline
- login: Moises6669
avatarUrl: https://avatars.githubusercontent.com/u/66188523?u=96af25b8d5be9f983cb96e9dd7c605c716caf1f5&v=4
url: https://github.com/Moises6669

374
docs/en/data/people.yml

@ -1,158 +1,158 @@
maintainers: maintainers:
- login: tiangolo - login: tiangolo
answers: 1837 answers: 1827
prs: 360 prs: 384
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4
url: https://github.com/tiangolo url: https://github.com/tiangolo
experts: experts:
- login: Kludex - login: Kludex
count: 374 count: 376
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex url: https://github.com/Kludex
- login: dmontagu - login: dmontagu
count: 262 count: 237
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4 avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu 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 - login: Mause
count: 207 count: 220
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4 avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause url: https://github.com/Mause
- login: ycd
count: 217
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
url: https://github.com/ycd
- login: JarroVGIT - login: JarroVGIT
count: 192 count: 192
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4 avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT url: https://github.com/JarroVGIT
- login: euri10 - login: euri10
count: 166 count: 151
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10 url: https://github.com/euri10
- login: phy25 - login: phy25
count: 130 count: 126
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4 avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25 url: https://github.com/phy25
- login: iudeen - login: iudeen
count: 87 count: 116
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen url: https://github.com/iudeen
- login: jgould22
count: 101
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: raphaelauv - login: raphaelauv
count: 77 count: 83
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv url: https://github.com/raphaelauv
- login: ArcLightSlavik - login: ArcLightSlavik
count: 71 count: 71
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
url: https://github.com/ArcLightSlavik url: https://github.com/ArcLightSlavik
- login: ghandic
count: 71
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic
- login: falkben - login: falkben
count: 59 count: 57
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4 avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben 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: sm-Fifteen
count: 50 count: 49
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4 avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen url: https://github.com/sm-Fifteen
- login: insomnes
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: Dustyposa - login: Dustyposa
count: 45 count: 45
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4 avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa url: https://github.com/Dustyposa
- login: insomnes
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: frankie567
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
url: https://github.com/frankie567
- login: acidjunk
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: odiseo0
count: 42
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4
url: https://github.com/odiseo0
- login: adriangb - login: adriangb
count: 40 count: 40
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=75087f0cf0e9f725f3cd18a899218b6c63ae60d3&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=1e2c2c9b39f5c9b780fb933d8995cf08ec235a47&v=4
url: https://github.com/adriangb url: https://github.com/adriangb
- login: includeamin - login: includeamin
count: 39 count: 40
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4 avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin url: https://github.com/includeamin
- login: STeveShary - login: STeveShary
count: 37 count: 37
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary 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 - login: krishnardt
count: 31 count: 35
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt url: https://github.com/krishnardt
- login: wshayes - login: yinziyan1206
count: 29 count: 34
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
url: https://github.com/wshayes url: https://github.com/yinziyan1206
- login: chbndrhnns
count: 34
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
- login: panla - login: panla
count: 29 count: 32
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4 avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla url: https://github.com/panla
- login: ghandic - login: prostomarkeloff
count: 25 count: 28
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4 avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
url: https://github.com/ghandic url: https://github.com/prostomarkeloff
- login: dbanty - login: dbanty
count: 25 count: 26
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4 avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
url: https://github.com/dbanty url: https://github.com/dbanty
- login: yinziyan1206 - login: wshayes
count: 25 count: 25
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4 avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/yinziyan1206 url: https://github.com/wshayes
- login: SirTelemak - login: SirTelemak
count: 24 count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak url: https://github.com/SirTelemak
- login: odiseo0 - login: caeser1996
count: 24 count: 21
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4 avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
url: https://github.com/odiseo0 url: https://github.com/caeser1996
- login: acnebs - login: rafsaf
count: 22 count: 21
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
url: https://github.com/acnebs url: https://github.com/rafsaf
- login: nsidnev - login: nsidnev
count: 22 count: 20
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
url: https://github.com/nsidnev url: https://github.com/nsidnev
- login: acnebs
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
url: https://github.com/acnebs
- login: chris-allnutt - login: chris-allnutt
count: 21 count: 20
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4 avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt url: https://github.com/chris-allnutt
- login: retnikt - login: retnikt
count: 19 count: 18
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4 avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
url: https://github.com/retnikt url: https://github.com/retnikt
- login: rafsaf - login: zoliknemet
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
url: https://github.com/rafsaf
- login: Hultner
count: 18 count: 18
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4 avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
url: https://github.com/Hultner url: https://github.com/zoliknemet
- login: jorgerpo
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
url: https://github.com/jorgerpo
- login: nkhitrov - login: nkhitrov
count: 17 count: 17
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4 avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
@ -161,75 +161,79 @@ experts:
count: 17 count: 17
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
url: https://github.com/harunyasar url: https://github.com/harunyasar
- login: waynerv - login: Hultner
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
url: https://github.com/Hultner
- login: jonatasoli
count: 16 count: 16
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
url: https://github.com/waynerv url: https://github.com/jonatasoli
- login: dstlny - login: dstlny
count: 16 count: 16
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny url: https://github.com/dstlny
- login: jonatasoli - login: jorgerpo
count: 15 count: 15
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4 avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
url: https://github.com/jonatasoli url: https://github.com/jorgerpo
- login: mbroton - login: ghost
count: 15 count: 15
avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10137?u=b1951d34a583cf12ec0d3b0781ba19be97726318&v=4
url: https://github.com/mbroton url: https://github.com/ghost
- login: simondale00
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/33907262?v=4
url: https://github.com/simondale00
- login: hellocoldworld - login: hellocoldworld
count: 14 count: 14
avatarUrl: https://avatars.githubusercontent.com/u/47581948?u=3d2186796434c507a6cb6de35189ab0ad27c356f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/47581948?u=3d2186796434c507a6cb6de35189ab0ad27c356f&v=4
url: https://github.com/hellocoldworld url: https://github.com/hellocoldworld
- login: haizaar - login: waynerv
count: 13 count: 14
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=dd40d99a3e1935d0b768f122bfe2258d6ea53b2b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/haizaar url: https://github.com/waynerv
- login: valentin994 - login: mbroton
count: 13 count: 13
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4 avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4
url: https://github.com/valentin994 url: https://github.com/mbroton
- 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: last_month_active:
- login: mr-st0rm
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/48455163?u=6b83550e4e70bea57cd2fdb41e717aeab7f64a91&v=4
url: https://github.com/mr-st0rm
- login: caeser1996
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
url: https://github.com/caeser1996
- login: ebottos94
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
url: https://github.com/ebottos94
- login: jgould22 - login: jgould22
count: 9 count: 6
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22 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 - login: Kludex
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex url: https://github.com/Kludex
- login: JarroVGIT - login: clemens-tolboom
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: TheJumpyWizard
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/90986815?u=67e9c13c9f063dd4313db7beb64eaa2f3a37f1fe&v=4 avatarUrl: https://avatars.githubusercontent.com/u/371014?v=4
url: https://github.com/TheJumpyWizard url: https://github.com/clemens-tolboom
- login: mbroton - login: williamjamir
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/5083518?u=b76ca8e08b906a86fa195fb817dd94e8d9d3d8f6&v=4
url: https://github.com/williamjamir
- login: nymous
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
url: https://github.com/mbroton url: https://github.com/nymous
- login: mateoradman - login: frankie567
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/48420316?u=066f36b8e8e263b0d90798113b0f291d3266db7c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
url: https://github.com/mateoradman url: https://github.com/frankie567
top_contributors: top_contributors:
- login: waynerv - login: waynerv
count: 25 count: 25
@ -239,6 +243,10 @@ top_contributors:
count: 22 count: 22
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4 avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi url: https://github.com/tokusumi
- login: Kludex
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: jaystone776 - login: jaystone776
count: 17 count: 17
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4 avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
@ -247,10 +255,6 @@ top_contributors:
count: 16 count: 16
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4 avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu url: https://github.com/dmontagu
- login: Kludex
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: euri10 - login: euri10
count: 13 count: 13
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
@ -269,7 +273,7 @@ top_contributors:
url: https://github.com/Serrones url: https://github.com/Serrones
- login: RunningIkkyu - login: RunningIkkyu
count: 7 count: 7
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=efb5b45b55584450507834f279ce48d4d64dea2f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
url: https://github.com/RunningIkkyu url: https://github.com/RunningIkkyu
- login: hard-coders - login: hard-coders
count: 7 count: 7
@ -279,6 +283,10 @@ top_contributors:
count: 7 count: 7
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
url: https://github.com/rjNemo url: https://github.com/rjNemo
- login: batlopes
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4
url: https://github.com/batlopes
- login: wshayes - login: wshayes
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
@ -295,10 +303,14 @@ top_contributors:
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4 avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4
url: https://github.com/ComicShrimp url: https://github.com/ComicShrimp
- login: batlopes - login: NinaHwang
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=eee6bfe9224c71193025ab7477f4f96ceaa05c62&v=4
url: https://github.com/batlopes url: https://github.com/NinaHwang
- login: Xewus
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
- login: jekirl - login: jekirl
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
@ -327,25 +339,21 @@ top_contributors:
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4 avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
url: https://github.com/lsglucas url: https://github.com/lsglucas
- login: NinaHwang
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
url: https://github.com/NinaHwang
top_reviewers: top_reviewers:
- login: Kludex - login: Kludex
count: 109 count: 111
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4 avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex url: https://github.com/Kludex
- login: BilalAlpaslan - login: BilalAlpaslan
count: 70 count: 75
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
url: https://github.com/BilalAlpaslan url: https://github.com/BilalAlpaslan
- login: yezz123 - login: yezz123
count: 59 count: 71
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4 avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
url: https://github.com/yezz123 url: https://github.com/yezz123
- login: tokusumi - login: tokusumi
count: 50 count: 51
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4 avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi url: https://github.com/tokusumi
- login: waynerv - login: waynerv
@ -360,6 +368,10 @@ top_reviewers:
count: 45 count: 45
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
url: https://github.com/ycd url: https://github.com/ycd
- login: iudeen
count: 44
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: cikay - login: cikay
count: 41 count: 41
avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4 avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4
@ -372,22 +384,18 @@ top_reviewers:
count: 33 count: 33
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=b2ea249c6b41ddf98679c8d110d0f67d4a3ebf93&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=b2ea249c6b41ddf98679c8d110d0f67d4a3ebf93&v=4
url: https://github.com/AdrianDeAnda url: https://github.com/AdrianDeAnda
- login: iudeen
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: ArcLightSlavik - login: ArcLightSlavik
count: 31 count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
url: https://github.com/ArcLightSlavik url: https://github.com/ArcLightSlavik
- login: cassiobotaro
count: 28
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
- login: komtaki - login: komtaki
count: 27 count: 27
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4 avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
url: https://github.com/komtaki 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 - login: lsglucas
count: 26 count: 26
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4 avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
@ -396,6 +404,14 @@ top_reviewers:
count: 23 count: 23
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4 avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu url: https://github.com/dmontagu
- login: LorhanSohaky
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
url: https://github.com/LorhanSohaky
- login: rjNemo
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
url: https://github.com/rjNemo
- login: hard-coders - login: hard-coders
count: 20 count: 20
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
@ -404,10 +420,10 @@ top_reviewers:
count: 19 count: 19
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4 avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
url: https://github.com/0417taehyun url: https://github.com/0417taehyun
- login: rjNemo - login: odiseo0
count: 17 count: 19
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4
url: https://github.com/rjNemo url: https://github.com/odiseo0
- login: Smlep - login: Smlep
count: 17 count: 17
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4 avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
@ -436,22 +452,26 @@ top_reviewers:
count: 15 count: 15
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
url: https://github.com/delhi09 url: https://github.com/delhi09
- login: odiseo0 - login: Ryandaydev
count: 15 count: 15
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=809f3d1074d04bbc28012a7f17f06ea56f5bd71a&v=4
url: https://github.com/odiseo0 url: https://github.com/Ryandaydev
- login: Xewus
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
- login: sh0nk - login: sh0nk
count: 13 count: 13
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
url: https://github.com/sh0nk url: https://github.com/sh0nk
- login: peidrao
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=5401640e0b961cc199dee39ec79e162c7833cd6b&v=4
url: https://github.com/peidrao
- login: RunningIkkyu - login: RunningIkkyu
count: 12 count: 12
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=efb5b45b55584450507834f279ce48d4d64dea2f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
url: https://github.com/RunningIkkyu url: https://github.com/RunningIkkyu
- login: LorhanSohaky
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
url: https://github.com/LorhanSohaky
- login: solomein-sv - login: solomein-sv
count: 11 count: 11
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
@ -472,10 +492,10 @@ top_reviewers:
count: 10 count: 10
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4 avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4
url: https://github.com/ComicShrimp url: https://github.com/ComicShrimp
- login: peidrao - login: r0b2g1t
count: 10 count: 10
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=88c2cb42a99e0f50cdeae3606992568184783ee5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/5357541?u=6428442d875d5d71aaa1bb38bb11c4be1a526bc2&v=4
url: https://github.com/peidrao url: https://github.com/r0b2g1t
- login: izaguerreiro - login: izaguerreiro
count: 9 count: 9
avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4 avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
@ -496,10 +516,18 @@ top_reviewers:
count: 9 count: 9
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4 avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
url: https://github.com/bezaca url: https://github.com/bezaca
- login: dimaqq
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/662249?v=4
url: https://github.com/dimaqq
- login: raphaelauv - login: raphaelauv
count: 8 count: 8
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv url: https://github.com/raphaelauv
- login: axel584
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/1334088?v=4
url: https://github.com/axel584
- login: blt232018 - login: blt232018
count: 8 count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4 avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
@ -508,23 +536,3 @@ top_reviewers:
count: 8 count: 8
avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4 avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
url: https://github.com/rogerbrinkmann 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
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
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
url: https://github.com/jovicon

12
docs/en/data/sponsors.yml

@ -8,9 +8,6 @@ gold:
- url: https://cryptapi.io/ - url: https://cryptapi.io/
title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway." title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg 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
silver: silver:
- url: https://www.deta.sh/?ref=fastapi - url: https://www.deta.sh/?ref=fastapi
title: The launchpad for all your (team's) ideas title: The launchpad for all your (team's) ideas
@ -30,9 +27,12 @@ silver:
- url: https://www.udemy.com/course/fastapi-rest/ - 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. 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 img: https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg
- url: https://careers.budget-insight.com/ - url: https://careers.powens.com/
title: Budget Insight is hiring! title: Powens is hiring!
img: https://fastapi.tiangolo.com/img/sponsors/budget-insight.svg img: https://fastapi.tiangolo.com/img/sponsors/powens.png
- url: https://www.svix.com/
title: Svix - Webhooks as a service
img: https://fastapi.tiangolo.com/img/sponsors/svix.svg
bronze: bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source - url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy. title: Biosecurity risk assessments made easy.

3
docs/en/data/sponsors_badge.yml

@ -13,3 +13,6 @@ logins:
- BLUE-DEVIL1134 - BLUE-DEVIL1134
- ObliviousAI - ObliviousAI
- Doist - Doist
- nihpo
- svix
- armand-sauzay

129
docs/en/docs/advanced/events.md

@ -1,13 +1,108 @@
# Events: startup - shutdown # Lifespan Events
You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down. You can define logic (code) that should be executed before the application **starts up**. This means that this code will be executed **once**, **before** the application **starts receiving requests**.
These functions can be declared with `async def` or normal `def`. The same way, you can define logic (code) that should be executed when the application is **shutting down**. In this case, this code will be executed **once**, **after** having handled possibly **many requests**.
Because this code is executed before the application **starts** taking requests, and right after it **finishes** handling requests, it covers the whole application **lifespan** (the word "lifespan" will be important in a second 😉).
This can be very useful for setting up **resources** that you need to use for the whole app, and that are **shared** among requests, and/or that you need to **clean up** afterwards. For example, a database connection pool, or loading a shared machine learning model.
## Use Case
Let's start with an example **use case** and then see how to solve it with this.
Let's imagine that you have some **machine learning models** that you want to use to handle requests. 🤖
The same models are shared among requests, so, it's not one model per request, or one per user or something similar.
Let's imagine that loading the model can **take quite some time**, because it has to read a lot of **data from disk**. So you don't want to do it for every request.
You could load it at the top level of the module/file, but that would also mean that it would **load the model** even if you are just running a simple automated test, then that test would be **slow** because it would have to wait for the model to load before being able to run an independent part of the code.
That's what we'll solve, let's load the model before the requests are handled, but only right before the application starts receiving requests, not while the code is being loaded.
## Lifespan
You can define this *startup* and *shutdown* logic using the `lifespan` parameter of the `FastAPI` app, and a "context manager" (I'll show you what that is in a second).
Let's start with an example and then see it in detail.
We create an async function `lifespan()` with `yield` like this:
```Python hl_lines="16 19"
{!../../../docs_src/events/tutorial003.py!}
```
Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.
And then, right after the `yield`, we unload the model. This code will be executed **after** the application **finishes handling requests**, right before the *shutdown*. This could, for example, release resources like memory or a GPU.
!!! tip
The `shutdown` would happen when you are **stopping** the application.
Maybe you need to start a new version, or you just got tired of running it. 🤷
### Lifespan function
The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
```Python hl_lines="14-19"
{!../../../docs_src/events/tutorial003.py!}
```
The first part of the function, before the `yield`, will be executed **before** the application starts.
And the part after the `yield` will be executed **after** the application has finished.
### Async Context Manager
If you check, the function is decorated with an `@asynccontextmanager`.
That converts the function into something called an "**async context manager**".
```Python hl_lines="1 13"
{!../../../docs_src/events/tutorial003.py!}
```
A **context manager** in Python is something that you can use in a `with` statement, for example, `open()` can be used as a context manager:
```Python
with open("file.txt") as file:
file.read()
```
In recent versions of Python, there's also an **async context manager**. You would use it with `async with`:
```Python
async with lifespan(app):
await do_stuff()
```
When you create a context manager or an async context manager like above, what it does is that, before entering the `with` block, it will execute the code before the `yield`, and after exiting the `with` block, it will execute the code after the `yield`.
In our code example above, we don't use it directly, but we pass it to FastAPI for it to use it.
The `lifespan` parameter of the `FastAPI` app takes an **async context manager**, so we can pass our new `lifespan` async context manager to it.
```Python hl_lines="22"
{!../../../docs_src/events/tutorial003.py!}
```
## Alternative Events (deprecated)
!!! warning !!! warning
Only event handlers for the main application will be executed, not for [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}. The recommended way to handle the *startup* and *shutdown* is using the `lifespan` parameter of the `FastAPI` app as described above.
You can probably skip this part.
## `startup` event There's an alternative way to define this logic to be executed during *startup* and during *shutdown*.
You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down.
These functions can be declared with `async def` or normal `def`.
### `startup` event
To add a function that should be run before the application starts, declare it with the event `"startup"`: To add a function that should be run before the application starts, declare it with the event `"startup"`:
@ -21,7 +116,7 @@ You can add more than one event handler function.
And your application won't start receiving requests until all the `startup` event handlers have completed. And your application won't start receiving requests until all the `startup` event handlers have completed.
## `shutdown` event ### `shutdown` event
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`: To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
@ -43,5 +138,25 @@ Here, the `shutdown` event handler function will write a text line `"Application
So, we declare the event handler function with standard `def` instead of `async def`. So, we declare the event handler function with standard `def` instead of `async def`.
### `startup` and `shutdown` together
There's a high chance that the logic for your *startup* and *shutdown* is connected, you might want to start something and then finish it, acquire a resource and then release it, etc.
Doing that in separated functions that don't share logic or variables together is more difficult as you would need to store values in global variables or similar tricks.
Because of that, it's now recommended to instead use the `lifespan` as explained above.
## Technical Details
Just a technical detail for the curious nerds. 🤓
Underneath, in the ASGI technical specification, this is part of the <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan Protocol</a>, and it defines events called `startup` and `shutdown`.
!!! info !!! info
You can read more about these event handlers in <a href="https://www.starlette.io/events/" class="external-link" target="_blank">Starlette's Events' docs</a>. You can read more about the Starlette `lifespan` handlers in <a href="https://www.starlette.io/lifespan/" class="external-link" target="_blank">Starlette's Lifespan' docs</a>.
Including how to handle lifespan state that can be used in other areas of your code.
## Sub Applications
🚨 Have in mind that these lifespan events (startup and shutdown) will only be executed for the main application, not for [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}.

2
docs/en/docs/advanced/middleware.md

@ -92,7 +92,7 @@ There are many other ASGI middlewares.
For example: For example:
* <a href="https://docs.sentry.io/platforms/python/asgi/" class="external-link" target="_blank">Sentry</a> * <a href="https://docs.sentry.io/platforms/python/guides/fastapi/" class="external-link" target="_blank">Sentry</a>
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn's `ProxyHeadersMiddleware`</a> * <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn's `ProxyHeadersMiddleware`</a>
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a> * <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>

2
docs/en/docs/async.md

@ -283,7 +283,7 @@ For example:
### Concurrency + Parallelism: Web + Machine Learning ### Concurrency + Parallelism: Web + Machine Learning
With **FastAPI** you can take the advantage of concurrency that is very common for web development (the same main attractive of NodeJS). With **FastAPI** you can take the advantage of concurrency that is very common for web development (the same main attraction of NodeJS).
But you can also exploit the benefits of parallelism and multiprocessing (having multiple processes running in parallel) for **CPU bound** workloads like those in Machine Learning systems. But you can also exploit the benefits of parallelism and multiprocessing (having multiple processes running in parallel) for **CPU bound** workloads like those in Machine Learning systems.

2
docs/en/docs/deployment/concepts.md

@ -235,7 +235,7 @@ Here are some possible combinations and strategies:
* One Uvicorn **process manager** would listen on the **IP** and **port**, and it would start **multiple Uvicorn worker processes** * One Uvicorn **process manager** would listen on the **IP** and **port**, and it would start **multiple Uvicorn worker processes**
* **Kubernetes** and other distributed **container systems** * **Kubernetes** and other distributed **container systems**
* Something in the **Kubernetes** layer would listen on the **IP** and **port**. The replication would be by having **multiple containers**, each with **one Uvicorn process** running * Something in the **Kubernetes** layer would listen on the **IP** and **port**. The replication would be by having **multiple containers**, each with **one Uvicorn process** running
* **Cloud services** that handle this for your * **Cloud services** that handle this for you
* The cloud service will probably **handle replication for you**. It would possibly let you define **a process to run**, or a **container image** to use, in any case, it would most probably be **a single Uvicorn process**, and the cloud service would be in charge of replicating it. * The cloud service will probably **handle replication for you**. It would possibly let you define **a process to run**, or a **container image** to use, in any case, it would most probably be **a single Uvicorn process**, and the cloud service would be in charge of replicating it.
!!! tip !!! tip

9
docs/en/docs/external-links.md

@ -56,6 +56,15 @@ Here's an incomplete list of some of them.
{% endfor %} {% endfor %}
{% endif %} {% endif %}
### Taiwanese
{% if external_links %}
{% for article in external_links.articles.taiwanese %}
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
## Podcasts ## Podcasts
{% if external_links %} {% if external_links %}

12
docs/en/docs/fastapi-people.md

@ -28,7 +28,7 @@ I'm the creator and maintainer of **FastAPI**. You can read more about that in [
These are the people that: These are the people that:
* [Help others with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}. * [Help others with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank}.
* [Create Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}. * [Create Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
* Review Pull Requests, [especially important for translations](contributing.md#translations){.internal-link target=_blank}. * Review Pull Requests, [especially important for translations](contributing.md#translations){.internal-link target=_blank}.
@ -36,13 +36,13 @@ A round of applause to them. 👏 🙇
## Most active users last month ## Most active users last month
These are the users that have been [helping others the most with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} during the last month. ☕ These are the users that have been [helping others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank} during the last month. ☕
{% if people %} {% if people %}
<div class="user-list user-list-center"> <div class="user-list user-list-center">
{% for user in people.last_month_active %} {% for user in people.last_month_active %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Issues replied: {{ user.count }}</div></div> <div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
{% endfor %} {% endfor %}
</div> </div>
@ -52,7 +52,7 @@ These are the users that have been [helping others the most with issues (questio
Here are the **FastAPI Experts**. 🤓 Here are the **FastAPI Experts**. 🤓
These are the users that have [helped others the most with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} through *all time*. These are the users that have [helped others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank} through *all time*.
They have proven to be experts by helping many others. ✨ They have proven to be experts by helping many others. ✨
@ -60,7 +60,7 @@ They have proven to be experts by helping many others. ✨
<div class="user-list user-list-center"> <div class="user-list user-list-center">
{% for user in people.experts %} {% for user in people.experts %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Issues replied: {{ user.count }}</div></div> <div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
{% endfor %} {% endfor %}
</div> </div>
@ -169,7 +169,7 @@ They are supporting my work with **FastAPI** (and others), mainly through <a hre
The main intention of this page is to highlight the effort of the community to help others. The main intention of this page is to highlight the effort of the community to help others.
Especially including efforts that are normally less visible, and in many cases more arduous, like helping others with issues and reviewing Pull Requests with translations. Especially including efforts that are normally less visible, and in many cases more arduous, like helping others with questions and reviewing Pull Requests with translations.
The data is calculated each month, you can read the <a href="https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/app/main.py" class="external-link" target="_blank">source code here</a>. The data is calculated each month, you can read the <a href="https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/app/main.py" class="external-link" target="_blank">source code here</a>.

38
docs/en/docs/help-fastapi.md

@ -69,11 +69,16 @@ I love to hear about how **FastAPI** is being used, what you have liked in it, i
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">Vote for **FastAPI** in AlternativeTo</a>. * <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">Vote for **FastAPI** in AlternativeTo</a>.
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">Say you use **FastAPI** on StackShare</a>. * <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">Say you use **FastAPI** on StackShare</a>.
## Help others with issues in GitHub ## Help others with questions in GitHub
You can see <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">existing issues</a> and try and help others, most of the times those issues are questions that you might already know the answer for. 🤓 You can try and help others with their questions in:
If you are helping a lot of people with issues, you might become an official [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}. 🎉 * <a href="https://github.com/tiangolo/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
* <a href="https://github.com/tiangolo/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
In many cases you might already know the answer for those questions. 🤓
If you are helping a lot of people with their questions, you will become an official [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}. 🎉
Just remember, the most important point is: try to be kind. People come with their frustrations and in many cases don't ask in the best way, but try as best as you can to be kind. 🤗 Just remember, the most important point is: try to be kind. People come with their frustrations and in many cases don't ask in the best way, but try as best as you can to be kind. 🤗
@ -81,7 +86,7 @@ The idea is for the **FastAPI** community to be kind and welcoming. At the same
--- ---
Here's how to help others with issues: Here's how to help others with questions (in discussions or issues):
### Understand the question ### Understand the question
@ -113,24 +118,27 @@ In many cases they will only copy a fragment of the code, but that's not enough
If they reply, there's a high chance you would have solved their problem, congrats, **you're a hero**! 🦸 If they reply, there's a high chance you would have solved their problem, congrats, **you're a hero**! 🦸
* Now you can ask them, if that solved their problem, to **close the issue**. * Now, if that solved their problem, you can ask them to:
* In GitHub Discussions: mark the comment as the **answer**.
* In GitHub Issues: **close** the issue**.
## Watch the GitHub repository ## Watch the GitHub repository
You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀 You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
If you select "Watching" instead of "Releases only" you will receive notifications when someone creates a new issue. If you select "Watching" instead of "Releases only" you will receive notifications when someone creates a new issue or question. You can also specify that you only want to be notified about new issues, or discussions, or PRs, etc.
Then you can try and help them solve those issues. Then you can try and help them solve those questions.
## Create issues ## Ask Questions
You can <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">create a new issue</a> in the GitHub repository, for example to: You can <a href="https://github.com/tiangolo/fastapi/discussions/new?category=questions" class="external-link" target="_blank">create a new question</a> in the GitHub repository, for example to:
* Ask a **question** or ask about a **problem**. * Ask a **question** or ask about a **problem**.
* Suggest a new **feature**. * Suggest a new **feature**.
**Note**: if you create an issue, then I'm going to ask you to also help others. 😉 **Note**: if you do it, then I'm going to ask you to also help others. 😉
## Review Pull Requests ## Review Pull Requests
@ -144,7 +152,7 @@ Here's what to have in mind and how to review a pull request:
### Understand the problem ### Understand the problem
* First, make sure you **understand the problem** that the pull request is trying to solve. It might have a longer discussion in an issue. * First, make sure you **understand the problem** that the pull request is trying to solve. It might have a longer discussion in a GitHub Discussion or issue.
* There's also a good chance that the pull request is not actually needed because the problem can be solved in a **different way**. Then you can suggest or ask about that. * There's also a good chance that the pull request is not actually needed because the problem can be solved in a **different way**. Then you can suggest or ask about that.
@ -207,7 +215,7 @@ There's a lot of work to do, and for most of it, **YOU** can do it.
The main tasks that you can do right now are: The main tasks that you can do right now are:
* [Help others with issues in GitHub](#help-others-with-issues-in-github){.internal-link target=_blank} (see the section above). * [Help others with questions in GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (see the section above).
* [Review Pull Requests](#review-pull-requests){.internal-link target=_blank} (see the section above). * [Review Pull Requests](#review-pull-requests){.internal-link target=_blank} (see the section above).
Those two tasks are what **consume time the most**. That's the main work of maintaining FastAPI. Those two tasks are what **consume time the most**. That's the main work of maintaining FastAPI.
@ -219,7 +227,7 @@ If you can help me with that, **you are helping me maintain FastAPI** and making
Join the 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord chat server</a> 👥 and hang out with others in the FastAPI community. Join the 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord chat server</a> 👥 and hang out with others in the FastAPI community.
!!! tip !!! tip
For questions, ask them in <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">GitHub issues</a>, there's a much better chance you will receive help by the [FastAPI Experts](fastapi-people.md#experts){.internal-link target=_blank}. For questions, ask them in <a href="https://github.com/tiangolo/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a>, there's a much better chance you will receive help by the [FastAPI Experts](fastapi-people.md#experts){.internal-link target=_blank}.
Use the chat only for other general conversations. Use the chat only for other general conversations.
@ -229,9 +237,9 @@ There is also the previous <a href="https://gitter.im/tiangolo/fastapi" class="e
Have in mind that as chats allow more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers. Have in mind that as chats allow more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers.
In GitHub issues the template will guide you to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking. And in GitHub I can make sure I always answer everything, even if it takes some time. I can't personally do that with the chat systems. 😅 In GitHub, the template will guide you to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking. And in GitHub I can make sure I always answer everything, even if it takes some time. I can't personally do that with the chat systems. 😅
Conversations in the chat systems are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation. And only the ones in GitHub issues count to become a [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}, so you will most probably receive more attention in GitHub issues. Conversations in the chat systems are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation. And only the ones in GitHub count to become a [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}, so you will most probably receive more attention in GitHub.
On the other side, there are thousands of users in the chat systems, so there's a high chance you'll find someone to talk to there, almost all the time. 😄 On the other side, there are thousands of users in the chat systems, so there's a high chance you'll find someone to talk to there, almost all the time. 😄

BIN
docs/en/docs/img/sponsors/powens.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

178
docs/en/docs/img/sponsors/svix.svg

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
width="240"
height="100"
viewBox="0 0 240 100"
sodipodi:docname="svix-vector.svg"
inkscape:version="1.0.2 (1.0.2+r75+1)"
inkscape:export-filename="../../../../../tmp/banner.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<metadata
id="metadata15">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="2.364373"
inkscape:cx="9.516265"
inkscape:cy="64.499129"
inkscape:window-width="1920"
inkscape:window-height="1025"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="text1936"
inkscape:document-rotation="0" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.986808;stroke-opacity:1;paint-order:fill markers stroke"
id="rect3346"
width="240"
height="100"
x="-240"
y="0"
rx="0"
transform="scale(-1,1)" />
<g
id="g6454"
transform="matrix(0.87971356,0,0,0.87971356,13.956407,4.3914173)">
<g
id="g8-7"
transform="matrix(0.10637635,0,0,0.10637635,14.16696,-68.565829)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
fill="#ffffff"
d="m 356.996,807.521 c -24.779,24.776 -40.104,59.008 -40.104,96.812 0,37.809 15.325,72.034 40.104,96.808 55.364,55.372 104.225,24.98 135.285,56.04 9.84,9.842 15.933,23.447 15.933,38.474 0,15.023 -6.093,28.632 -15.933,38.473 -9.843,9.845 -23.45,15.936 -38.475,15.936 -10.021,0 -19.375,-2.686 -27.377,-7.354 -25.975,-15.161 -30.519,-48.084 -70.353,-71.339 -20.285,-11.842 -43.846,-18.637 -68.954,-18.637 -35.289,0 -67.459,13.355 -91.735,35.282 9.772,28.697 24.19,55.246 42.359,78.749 2.707,-5.83 6.413,-11.102 10.901,-15.589 9.841,-9.842 23.45,-15.936 38.475,-15.936 10.021,0 19.375,2.686 27.376,7.354 8.556,4.994 15.55,11.989 20.191,20.202 12.059,21.337 29.423,39.029 50.162,51.137 20.285,11.842 43.846,18.637 68.955,18.637 37.804,0 72.036,-15.326 96.812,-40.105 24.775,-24.775 40.104,-59.001 40.104,-96.81 0,-37.802 -15.328,-72.034 -40.104,-96.81 -55.367,-55.367 -104.229,-24.983 -135.285,-56.038 -9.843,-9.845 -15.935,-23.448 -15.935,-38.473 0,-15.025 6.092,-28.632 15.935,-38.475 9.839,-9.839 23.448,-15.933 38.473,-15.933 10.021,0 19.376,2.682 27.378,7.354 25.973,15.162 30.517,48.083 70.351,71.339 20.284,11.842 43.846,18.635 68.956,18.635 35.284,0 67.459,-13.352 91.733,-35.28 -9.772,-28.7 -24.19,-55.247 -42.359,-78.751 -2.705,5.831 -6.413,11.102 -10.901,15.589 -9.843,9.843 -23.448,15.935 -38.473,15.935 -10.021,0 -19.375,-2.684 -27.378,-7.354 -8.556,-4.995 -15.548,-11.99 -20.19,-20.202 -12.059,-21.336 -29.422,-39.029 -50.16,-51.138 -20.285,-11.841 -43.847,-18.634 -68.956,-18.634 -37.81,-10e-4 -72.037,15.327 -96.811,40.102 z"
id="path2-0" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
fill="#018ffa"
d="m 453.806,727.069 c -150.731,0 -272.922,122.192 -272.922,272.924 0,30.797 5.1,60.402 14.503,88.021 24.276,-21.927 56.446,-35.282 91.735,-35.282 25.108,0 48.669,6.795 68.954,18.637 39.833,23.255 44.377,56.178 70.353,71.339 8.002,4.669 17.356,7.354 27.377,7.354 15.025,0 28.632,-6.091 38.475,-15.936 9.84,-9.841 15.933,-23.449 15.933,-38.473 0,-15.026 -6.093,-28.632 -15.933,-38.474 -31.06,-31.06 -79.921,-0.668 -135.285,-56.04 -24.779,-24.773 -40.104,-58.999 -40.104,-96.808 0,-37.804 15.325,-72.036 40.104,-96.812 24.774,-24.776 59.001,-40.104 96.81,-40.104 25.109,0 48.671,6.793 68.956,18.634 20.738,12.108 38.101,29.802 50.16,51.138 4.643,8.212 11.634,15.208 20.19,20.202 8.004,4.67 17.358,7.354 27.378,7.354 15.025,0 28.63,-6.092 38.473,-15.935 4.488,-4.488 8.196,-9.759 10.901,-15.589 C 619.951,768.65 541.735,727.069 453.806,727.069 Z"
id="path4-9" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
fill="#018ffa"
d="m 550.617,998.844 c 24.775,24.776 40.104,59.008 40.104,96.81 0,37.809 -15.328,72.034 -40.104,96.81 -24.776,24.779 -59.008,40.105 -96.812,40.105 -25.108,0 -48.67,-6.795 -68.955,-18.637 -20.738,-12.107 -38.103,-29.8 -50.162,-51.137 -4.641,-8.213 -11.635,-15.208 -20.191,-20.202 -8.002,-4.669 -17.356,-7.354 -27.376,-7.354 -15.025,0 -28.634,6.094 -38.475,15.936 -4.488,4.487 -8.194,9.759 -10.901,15.589 49.916,64.571 128.132,106.15 216.06,106.15 150.732,0 272.923,-122.19 272.923,-272.921 0,-30.797 -5.102,-60.403 -14.505,-88.02 -24.274,21.928 -56.449,35.28 -91.733,35.28 -25.109,0 -48.671,-6.793 -68.956,-18.635 -39.834,-23.257 -44.378,-56.178 -70.351,-71.339 -8.002,-4.672 -17.358,-7.354 -27.378,-7.354 -15.025,0 -28.634,6.094 -38.473,15.933 -9.843,9.843 -15.935,23.45 -15.935,38.475 0,15.025 6.092,28.628 15.935,38.473 31.056,31.055 79.918,0.672 135.285,56.038 z"
id="path6-3" />
</g>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fill="#1a283f"
d="m 130.33984,26.880256 c -3.16236,-2.773976 -6.38003,-3.606158 -10.65199,-3.606158 -4.9932,0 -11.53972,2.219223 -11.53972,8.543723 0,6.213868 6.15824,8.100027 11.31771,8.488514 3.88359,0.221902 5.43699,0.998661 5.43699,2.884821 0,1.997109 -2.3857,3.328942 -4.93756,3.273306 -3.0514,-0.05542 -7.48974,-1.664365 -9.43143,-3.828059 l -3.32873,4.826615 c 3.99444,4.16091 8.32193,4.882248 12.64922,4.882248 7.8227,0 11.7616,-4.160911 11.7616,-8.987525 0,-7.267846 -6.5465,-8.432879 -11.70619,-8.765837 -3.49509,-0.221902 -5.10415,-1.220563 -5.10415,-2.995878 0,-1.719787 1.77542,-2.71834 4.9932,-2.71834 2.60739,0 4.82683,0.61028 6.7683,2.441125 z m 26.57462,-2.884929 -3.77274,9.154112 -4.16091,11.428864 -4.21655,-11.539709 -3.77243,-9.043159 h -7.37879 l 11.70597,27.517648 h 7.32359 l 11.65045,-27.517648 h -7.37859 z m 17.4203,-0.05552 v 27.462122 h -6.76852 V 23.939802 Z m -7.37847,-7.600591 c 0,5.270417 7.98896,5.270417 7.98896,0 -10e-5,-5.270523 -7.98896,-5.270523 -7.98896,0 z m 26.68514,16.976603 -5.38137,-9.26485 h -8.09992 v 0.22169 l 8.98753,13.259494 -9.54228,13.703403 v 0.166266 h 8.09993 l 5.93611,-9.154112 5.93655,9.154111 h 8.09992 v -0.166266 l -9.54218,-13.703403 8.98743,-13.259494 v -0.22169 h -8.09992 z"
id="path10-6"
style="stroke-width:0.106376" />
</g>
<g
aria-label="Webhooks as a Service"
id="text1936"
style="font-style:normal;font-weight:normal;font-size:16px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none">
<path
d="M 43.474213,86.844101 H 40.739838 L 39.24765,80.476913 q -0.273437,-1.125 -0.460937,-2.351562 -0.1875,1.023437 -0.304688,1.5625 -0.117187,0.53125 -1.664062,7.15625 H 34.083588 L 31.24765,75.836288 h 2.335938 l 1.59375,7.109375 0.359375,1.71875 q 0.21875,-1.085937 0.421875,-2.070312 0.210937,-0.992188 1.5625,-6.757813 h 2.578125 l 1.390625,5.859375 q 0.164062,0.65625 0.554687,2.96875 l 0.195313,-0.90625 0.414062,-1.796875 1.328125,-6.125 h 2.335938 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path840" />
<path
d="m 50.62265,87.000351 q -1.90625,0 -2.929687,-1.125 -1.023438,-1.132813 -1.023438,-3.296875 0,-2.09375 1.039063,-3.21875 1.039062,-1.125 2.945312,-1.125 1.820313,0 2.78125,1.210937 0.960938,1.203125 0.960938,3.53125 v 0.0625 h -5.421875 q 0,1.234375 0.453125,1.867188 0.460937,0.625 1.304687,0.625 1.164063,0 1.46875,-1.007813 l 2.070313,0.179688 q -0.898438,2.296875 -3.648438,2.296875 z m 0,-7.382813 q -0.773437,0 -1.195312,0.539063 -0.414063,0.539062 -0.4375,1.507812 h 3.28125 q -0.0625,-1.023437 -0.492188,-1.53125 -0.429687,-0.515625 -1.15625,-0.515625 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path842" />
<path
d="m 64.067963,82.586288 q 0,2.09375 -0.84375,3.257813 -0.835938,1.15625 -2.398438,1.15625 -0.898437,0 -1.554687,-0.390625 -0.65625,-0.390625 -1.007813,-1.125 h -0.01563 q 0,0.273437 -0.03906,0.75 -0.03125,0.476562 -0.07031,0.609375 h -2.132812 q 0.0625,-0.726563 0.0625,-1.929688 v -9.664062 h 2.195312 v 3.234375 l -0.03125,1.375 h 0.03125 q 0.742188,-1.625 2.703125,-1.625 1.5,0 2.296875,1.140625 0.804688,1.132812 0.804688,3.210937 z m -2.289063,0 q 0,-1.4375 -0.421875,-2.132812 -0.421875,-0.695313 -1.304687,-0.695313 -0.890625,0 -1.359375,0.75 -0.460938,0.742188 -0.460938,2.148438 0,1.34375 0.453125,2.09375 0.460938,0.75 1.351563,0.75 1.742187,0 1.742187,-2.914063 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path844" />
<path
d="m 68.013275,80.078476 q 0.445313,-0.96875 1.117188,-1.40625 0.671875,-0.4375 1.601562,-0.4375 1.34375,0 2.0625,0.828125 0.71875,0.828125 0.71875,2.421875 v 5.359375 h -2.1875 v -4.734375 q 0,-2.226563 -1.507812,-2.226563 -0.796875,0 -1.289063,0.6875 -0.484375,0.679688 -0.484375,1.75 v 4.523438 h -2.195312 v -11.59375 h 2.195312 v 3.164062 q 0,0.851563 -0.0625,1.664063 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path846" />
<path
d="m 83.661713,82.609726 q 0,2.054687 -1.140625,3.226562 -1.140625,1.164063 -3.15625,1.164063 -1.976563,0 -3.101563,-1.171875 -1.125,-1.171875 -1.125,-3.21875 0,-2.039063 1.125,-3.203125 1.125,-1.171875 3.148438,-1.171875 2.070312,0 3.15625,1.132812 1.09375,1.125 1.09375,3.242188 z m -2.296875,0 q 0,-1.507813 -0.492188,-2.1875 -0.492187,-0.679688 -1.429687,-0.679688 -2,0 -2,2.867188 0,1.414062 0.484375,2.15625 0.492187,0.734375 1.414062,0.734375 2.023438,0 2.023438,-2.890625 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path848" />
<path
d="m 93.442963,82.609726 q 0,2.054687 -1.140625,3.226562 -1.140625,1.164063 -3.15625,1.164063 -1.976563,0 -3.101563,-1.171875 -1.125,-1.171875 -1.125,-3.21875 0,-2.039063 1.125,-3.203125 1.125,-1.171875 3.148438,-1.171875 2.070312,0 3.15625,1.132812 1.09375,1.125 1.09375,3.242188 z m -2.296875,0 q 0,-1.507813 -0.492188,-2.1875 -0.492187,-0.679688 -1.429687,-0.679688 -2,0 -2,2.867188 0,1.414062 0.484375,2.15625 0.492187,0.734375 1.414062,0.734375 2.023438,0 2.023438,-2.890625 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path850" />
<path
d="m 100.5914,86.844101 -2.257812,-3.828125 -0.945313,0.65625 v 3.171875 h -2.195312 v -11.59375 h 2.195312 v 6.640625 l 3.015625,-3.5 h 2.35938 l -2.968755,3.296875 3.195315,5.15625 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path852" />
<path
d="m 111.22421,84.375351 q 0,1.226562 -1.00781,1.929687 -1,0.695313 -2.77344,0.695313 -1.74218,0 -2.67187,-0.546875 -0.92188,-0.554688 -1.22656,-1.71875 l 1.92968,-0.289063 q 0.16407,0.601563 0.5625,0.851563 0.40625,0.25 1.40625,0.25 0.92188,0 1.34375,-0.234375 0.42188,-0.234375 0.42188,-0.734375 0,-0.40625 -0.34375,-0.640625 -0.33594,-0.242188 -1.14844,-0.40625 -1.85937,-0.367188 -2.50781,-0.679688 -0.64844,-0.320312 -0.99219,-0.820312 -0.33594,-0.507813 -0.33594,-1.242188 0,-1.210937 0.92969,-1.882812 0.9375,-0.679688 2.64844,-0.679688 1.50781,0 2.42187,0.585938 0.92188,0.585937 1.14844,1.695312 l -1.94531,0.203125 q -0.0937,-0.515625 -0.46094,-0.765625 -0.36719,-0.257812 -1.16406,-0.257812 -0.78125,0 -1.17188,0.203125 -0.39062,0.195312 -0.39062,0.664062 0,0.367188 0.29687,0.585938 0.30469,0.210937 1.01563,0.351562 0.99219,0.203125 1.75781,0.421875 0.77344,0.210938 1.23438,0.507813 0.46875,0.296875 0.74218,0.765625 0.28125,0.460937 0.28125,1.1875 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path854" />
<path
d="m 119.39609,87.000351 q -1.22656,0 -1.91406,-0.664063 -0.6875,-0.671875 -0.6875,-1.882812 0,-1.3125 0.85156,-2 0.85937,-0.6875 2.48437,-0.703125 l 1.82032,-0.03125 v -0.429688 q 0,-0.828125 -0.28907,-1.226562 -0.28906,-0.40625 -0.94531,-0.40625 -0.60937,0 -0.89844,0.28125 -0.28125,0.273437 -0.35156,0.914062 l -2.28906,-0.109375 q 0.21094,-1.234375 1.125,-1.867187 0.92187,-0.640625 2.50781,-0.640625 1.60156,0 2.46875,0.789062 0.86719,0.789063 0.86719,2.242188 v 3.078125 q 0,0.710937 0.15625,0.984375 0.16406,0.265625 0.53906,0.265625 0.25,0 0.48438,-0.04687 v 1.1875 q -0.19532,0.04687 -0.35157,0.08594 -0.15625,0.03906 -0.3125,0.0625 -0.15625,0.02344 -0.33593,0.03906 -0.17188,0.01563 -0.40625,0.01563 -0.82813,0 -1.22657,-0.40625 -0.39062,-0.40625 -0.46875,-1.195313 h -0.0469 q -0.92188,1.664063 -2.78125,1.664063 z m 2.55469,-4.070313 -1.125,0.01563 q -0.76563,0.03125 -1.08594,0.171875 -0.32031,0.132813 -0.49219,0.414063 -0.16406,0.28125 -0.16406,0.75 0,0.601562 0.27344,0.898437 0.28125,0.289063 0.74218,0.289063 0.51563,0 0.9375,-0.28125 0.42969,-0.28125 0.67188,-0.773438 0.24219,-0.5 0.24219,-1.054687 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path856" />
<path
d="m 133.47421,84.375351 q 0,1.226562 -1.00781,1.929687 -1,0.695313 -2.77344,0.695313 -1.74218,0 -2.67187,-0.546875 -0.92188,-0.554688 -1.22656,-1.71875 l 1.92968,-0.289063 q 0.16407,0.601563 0.5625,0.851563 0.40625,0.25 1.40625,0.25 0.92188,0 1.34375,-0.234375 0.42188,-0.234375 0.42188,-0.734375 0,-0.40625 -0.34375,-0.640625 -0.33594,-0.242188 -1.14844,-0.40625 -1.85937,-0.367188 -2.50781,-0.679688 -0.64844,-0.320312 -0.99219,-0.820312 -0.33594,-0.507813 -0.33594,-1.242188 0,-1.210937 0.92969,-1.882812 0.9375,-0.679688 2.64844,-0.679688 1.50781,0 2.42187,0.585938 0.92188,0.585937 1.14844,1.695312 l -1.94531,0.203125 q -0.0937,-0.515625 -0.46094,-0.765625 -0.36719,-0.257812 -1.16406,-0.257812 -0.78125,0 -1.17188,0.203125 -0.39062,0.195312 -0.39062,0.664062 0,0.367188 0.29687,0.585938 0.30469,0.210937 1.01563,0.351562 0.99219,0.203125 1.75781,0.421875 0.77344,0.210938 1.23438,0.507813 0.46875,0.296875 0.74218,0.765625 0.28125,0.460937 0.28125,1.1875 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path858" />
<path
d="m 141.64609,87.000351 q -1.22656,0 -1.91406,-0.664063 -0.6875,-0.671875 -0.6875,-1.882812 0,-1.3125 0.85156,-2 0.85937,-0.6875 2.48437,-0.703125 l 1.82032,-0.03125 v -0.429688 q 0,-0.828125 -0.28907,-1.226562 -0.28906,-0.40625 -0.94531,-0.40625 -0.60937,0 -0.89844,0.28125 -0.28125,0.273437 -0.35156,0.914062 l -2.28906,-0.109375 q 0.21094,-1.234375 1.125,-1.867187 0.92187,-0.640625 2.50781,-0.640625 1.60156,0 2.46875,0.789062 0.86719,0.789063 0.86719,2.242188 v 3.078125 q 0,0.710937 0.15625,0.984375 0.16406,0.265625 0.53906,0.265625 0.25,0 0.48438,-0.04687 v 1.1875 q -0.19532,0.04687 -0.35157,0.08594 -0.15625,0.03906 -0.3125,0.0625 -0.15625,0.02344 -0.33593,0.03906 -0.17188,0.01563 -0.40625,0.01563 -0.82813,0 -1.22657,-0.40625 -0.39062,-0.40625 -0.46875,-1.195313 h -0.0469 q -0.92188,1.664063 -2.78125,1.664063 z m 2.55469,-4.070313 -1.125,0.01563 q -0.76563,0.03125 -1.08594,0.171875 -0.32031,0.132813 -0.49219,0.414063 -0.16406,0.28125 -0.16406,0.75 0,0.601562 0.27344,0.898437 0.28125,0.289063 0.74218,0.289063 0.51563,0 0.9375,-0.28125 0.42969,-0.28125 0.67188,-0.773438 0.24219,-0.5 0.24219,-1.054687 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path860" />
<path
d="m 161.9664,83.672226 q 0,1.617187 -1.20312,2.476562 -1.19532,0.851563 -3.51563,0.851563 -2.11719,0 -3.32031,-0.75 -1.20313,-0.75 -1.54688,-2.273438 l 2.22657,-0.367187 q 0.22656,0.875 0.88281,1.273437 0.65625,0.390625 1.82031,0.390625 2.41406,0 2.41406,-1.46875 0,-0.46875 -0.28125,-0.773437 -0.27343,-0.304688 -0.78125,-0.507813 -0.5,-0.203125 -1.92968,-0.492187 -1.23438,-0.289063 -1.71875,-0.460938 -0.48438,-0.179687 -0.875,-0.414062 -0.39063,-0.242188 -0.66407,-0.578125 -0.27343,-0.335938 -0.42968,-0.789063 -0.14844,-0.453125 -0.14844,-1.039062 0,-1.492188 1.11719,-2.28125 1.125,-0.796875 3.26562,-0.796875 2.04688,0 3.07031,0.640625 1.03125,0.640625 1.32813,2.117187 l -2.23438,0.304688 q -0.17187,-0.710938 -0.70312,-1.070313 -0.52344,-0.359375 -1.50781,-0.359375 -2.09375,0 -2.09375,1.3125 0,0.429688 0.21875,0.703125 0.22656,0.273438 0.66406,0.46875 0.4375,0.1875 1.77344,0.476563 1.58593,0.335937 2.26562,0.625 0.6875,0.28125 1.08594,0.664062 0.39844,0.375 0.60937,0.90625 0.21094,0.523438 0.21094,1.210938 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path862" />
<path
d="m 167.18515,87.000351 q -1.90625,0 -2.92969,-1.125 -1.02343,-1.132813 -1.02343,-3.296875 0,-2.09375 1.03906,-3.21875 1.03906,-1.125 2.94531,-1.125 1.82031,0 2.78125,1.210937 0.96094,1.203125 0.96094,3.53125 v 0.0625 h -5.42188 q 0,1.234375 0.45313,1.867188 0.46094,0.625 1.30469,0.625 1.16406,0 1.46875,-1.007813 l 2.07031,0.179688 q -0.89844,2.296875 -3.64844,2.296875 z m 0,-7.382813 q -0.77344,0 -1.19531,0.539063 -0.41406,0.539062 -0.4375,1.507812 h 3.28125 q -0.0625,-1.023437 -0.49219,-1.53125 -0.42969,-0.515625 -1.15625,-0.515625 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path864" />
<path
d="m 172.63046,86.844101 v -6.46875 q 0,-0.695313 -0.0234,-1.15625 -0.0156,-0.46875 -0.0391,-0.828125 h 2.09375 q 0.0234,0.140625 0.0625,0.859375 0.0391,0.710937 0.0391,0.945312 h 0.0312 q 0.32031,-0.890625 0.57031,-1.25 0.25,-0.367187 0.59375,-0.539062 0.34375,-0.179688 0.85937,-0.179688 0.42188,0 0.67969,0.117188 v 1.835937 q -0.53125,-0.117187 -0.9375,-0.117187 -0.82031,0 -1.28125,0.664062 -0.45312,0.664063 -0.45312,1.96875 v 4.148438 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path866" />
<path
d="m 183.44296,86.844101 h -2.625 l -3.02343,-8.453125 h 2.32031 l 1.47656,4.726562 q 0.11719,0.390625 0.55469,1.953125 0.0781,-0.320312 0.32031,-1.125 0.24219,-0.804687 1.79688,-5.554687 h 2.29687 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path868" />
<path
d="m 187.75546,76.867538 v -1.617187 h 2.19532 v 1.617187 z m 0,9.976563 v -8.453125 h 2.19532 v 8.453125 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path870" />
<path
d="m 195.7164,87.000351 q -1.92187,0 -2.96875,-1.140625 -1.04687,-1.148438 -1.04687,-3.195313 0,-2.09375 1.05468,-3.257812 1.05469,-1.171875 2.99219,-1.171875 1.49219,0 2.46875,0.75 0.97656,0.75 1.22656,2.070312 l -2.21093,0.109375 q -0.0937,-0.648437 -0.46875,-1.03125 -0.375,-0.390625 -1.0625,-0.390625 -1.69532,0 -1.69532,2.835938 0,2.921875 1.72657,2.921875 0.625,0 1.04687,-0.390625 0.42188,-0.398438 0.52344,-1.179688 l 2.20312,0.101563 q -0.11718,0.867187 -0.625,1.546875 -0.5,0.679687 -1.32031,1.054687 -0.82031,0.367188 -1.84375,0.367188 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path872" />
<path
d="m 204.56015,87.000351 q -1.90625,0 -2.92969,-1.125 -1.02343,-1.132813 -1.02343,-3.296875 0,-2.09375 1.03906,-3.21875 1.03906,-1.125 2.94531,-1.125 1.82031,0 2.78125,1.210937 0.96094,1.203125 0.96094,3.53125 v 0.0625 h -5.42188 q 0,1.234375 0.45313,1.867188 0.46094,0.625 1.30469,0.625 1.16406,0 1.46875,-1.007813 l 2.07031,0.179688 q -0.89844,2.296875 -3.64844,2.296875 z m 0,-7.382813 q -0.77344,0 -1.19531,0.539063 -0.41406,0.539062 -0.4375,1.507812 h 3.28125 q -0.0625,-1.023437 -0.49219,-1.53125 -0.42969,-0.515625 -1.15625,-0.515625 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans Bold'"
id="path874" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

6
docs/en/docs/index.md

@ -99,6 +99,12 @@ The key features are:
--- ---
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs ## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a> <a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>

2
docs/en/docs/project-generation.md

@ -1,6 +1,6 @@
# Project Generation - Template # Project Generation - Template
You can use a project generator to get started, as it includes a lot of the initial set up, security, database and first API endpoints already done for you. You can use a project generator to get started, as it includes a lot of the initial set up, security, database and some API endpoints already done for you.
A project generator will always have a very opinionated setup that you should update and adapt for your own needs, but it might be a good starting point for your project. A project generator will always have a very opinionated setup that you should update and adapt for your own needs, but it might be a good starting point for your project.

254
docs/en/docs/release-notes.md

@ -2,6 +2,254 @@
## Latest Changes ## Latest Changes
## 0.94.1
### Fixes
* 🎨 Fix types for lifespan, upgrade Starlette to 0.26.1. PR [#9245](https://github.com/tiangolo/fastapi/pull/9245) by [@tiangolo](https://github.com/tiangolo).
## 0.94.0
### Upgrades
* ⬆ Upgrade python-multipart to support 0.0.6. PR [#9212](https://github.com/tiangolo/fastapi/pull/9212) by [@musicinmybrain](https://github.com/musicinmybrain).
* ⬆️ Upgrade Starlette version, support new `lifespan` with state. PR [#9239](https://github.com/tiangolo/fastapi/pull/9239) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Update Sentry link in docs. PR [#9218](https://github.com/tiangolo/fastapi/pull/9218) by [@smeubank](https://github.com/smeubank).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/history-design-future.md`. PR [#5986](https://github.com/tiangolo/fastapi/pull/5986) by [@Xewus](https://github.com/Xewus).
### Internal
* ➕ Add `pydantic` to PyPI classifiers. PR [#5914](https://github.com/tiangolo/fastapi/pull/5914) by [@yezz123](https://github.com/yezz123).
* ⬆ Bump black from 22.10.0 to 23.1.0. PR [#5953](https://github.com/tiangolo/fastapi/pull/5953) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump types-ujson from 5.6.0.0 to 5.7.0.1. PR [#6027](https://github.com/tiangolo/fastapi/pull/6027) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump dawidd6/action-download-artifact from 2.24.3 to 2.26.0. PR [#6034](https://github.com/tiangolo/fastapi/pull/6034) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#5709](https://github.com/tiangolo/fastapi/pull/5709) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
## 0.93.0
### Features
* ✨ Add support for `lifespan` async context managers (superseding `startup` and `shutdown` events). Initial PR [#2944](https://github.com/tiangolo/fastapi/pull/2944) by [@uSpike](https://github.com/uSpike).
Now, instead of using independent `startup` and `shutdown` events, you can define that logic in a single function with `yield` decorated with `@asynccontextmanager` (an async context manager).
For example:
```Python
from contextlib import asynccontextmanager
from fastapi import FastAPI
def fake_answer_to_everything_ml_model(x: float):
return x * 42
ml_models = {}
@asynccontextmanager
async def lifespan(app: FastAPI):
# Load the ML model
ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
yield
# Clean up the ML models and release the resources
ml_models.clear()
app = FastAPI(lifespan=lifespan)
@app.get("/predict")
async def predict(x: float):
result = ml_models["answer_to_everything"](x)
return {"result": result}
```
**Note**: This is the recommended way going forward, instead of using `startup` and `shutdown` events.
Read more about it in the new docs: [Advanced User Guide: Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
### Docs
* ✏ Fix formatting in `docs/en/docs/tutorial/metadata.md` for `ReDoc`. PR [#6005](https://github.com/tiangolo/fastapi/pull/6005) by [@eykamp](https://github.com/eykamp).
### Translations
* 🌐 Tamil translations - initial setup. PR [#5564](https://github.com/tiangolo/fastapi/pull/5564) by [@gusty1g](https://github.com/gusty1g).
* 🌐 Add French translation for `docs/fr/docs/advanced/path-operation-advanced-configuration.md`. PR [#9221](https://github.com/tiangolo/fastapi/pull/9221) by [@axel584](https://github.com/axel584).
* 🌐 Add French translation for `docs/tutorial/debugging.md`. PR [#9175](https://github.com/tiangolo/fastapi/pull/9175) by [@frabc](https://github.com/frabc).
* 🌐 Initiate Armenian translation setup. PR [#5844](https://github.com/tiangolo/fastapi/pull/5844) by [@har8](https://github.com/har8).
* 🌐 Add French translation for `deployment/manually.md`. PR [#3693](https://github.com/tiangolo/fastapi/pull/3693) by [@rjNemo](https://github.com/rjNemo).
### Internal
* 👷 Update translation bot messages. PR [#9206](https://github.com/tiangolo/fastapi/pull/9206) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update translations bot to use Discussions, and notify when a PR is done. PR [#9183](https://github.com/tiangolo/fastapi/pull/9183) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors-badges. PR [#9182](https://github.com/tiangolo/fastapi/pull/9182) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People. PR [#9181](https://github.com/tiangolo/fastapi/pull/9181) by [@github-actions[bot]](https://github.com/apps/github-actions).
* 🔊 Log GraphQL errors in FastAPI People, because it returns 200, with a payload with an error. PR [#9171](https://github.com/tiangolo/fastapi/pull/9171) by [@tiangolo](https://github.com/tiangolo).
* 💚 Fix/workaround GitHub Actions in Docker with git for FastAPI People. PR [#9169](https://github.com/tiangolo/fastapi/pull/9169) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor FastAPI Experts to use only discussions now that questions are migrated. PR [#9165](https://github.com/tiangolo/fastapi/pull/9165) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade analytics. PR [#6025](https://github.com/tiangolo/fastapi/pull/6025) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade and re-enable installing Typer-CLI. PR [#6008](https://github.com/tiangolo/fastapi/pull/6008) by [@tiangolo](https://github.com/tiangolo).
## 0.92.0
🚨 This is a security fix. Please upgrade as soon as possible.
### Upgrades
* ⬆️ Upgrade Starlette to 0.25.0. PR [#5996](https://github.com/tiangolo/fastapi/pull/5996) by [@tiangolo](https://github.com/tiangolo).
* This solves a vulnerability that could allow denial of service attacks by using many small multipart fields/files (parts), consuming high CPU and memory.
* Only applications using forms (e.g. file uploads) could be affected.
* For most cases, upgrading won't have any breaking changes.
## 0.91.0
### Upgrades
* ⬆️ Upgrade Starlette version to `0.24.0` and refactor internals for compatibility. PR [#5985](https://github.com/tiangolo/fastapi/pull/5985) by [@tiangolo](https://github.com/tiangolo).
* This can solve nuanced errors when using middlewares. Before Starlette `0.24.0`, a new instance of each middleware class would be created when a new middleware was added. That normally was not a problem, unless the middleware class expected to be created only once, with only one instance, that happened in some cases. This upgrade would solve those cases (thanks [@adriangb](https://github.com/adriangb)! Starlette PR [#2017](https://github.com/encode/starlette/pull/2017)). Now the middleware class instances are created once, right before the first request (the first time the app is called).
* If you depended on that previous behavior, you might need to update your code. As always, make sure your tests pass before merging the upgrade.
## 0.90.1
### Upgrades
* ⬆️ Upgrade Starlette range to allow 0.23.1. PR [#5980](https://github.com/tiangolo/fastapi/pull/5980) by [@tiangolo](https://github.com/tiangolo).
### Docs
* ✏ Tweak wording to clarify `docs/en/docs/project-generation.md`. PR [#5930](https://github.com/tiangolo/fastapi/pull/5930) by [@chandra-deb](https://github.com/chandra-deb).
* ✏ Update Pydantic GitHub URLs. PR [#5952](https://github.com/tiangolo/fastapi/pull/5952) by [@yezz123](https://github.com/yezz123).
* 📝 Add opinion from Cisco. PR [#5981](https://github.com/tiangolo/fastapi/pull/5981) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/cookie-params.md`. PR [#5890](https://github.com/tiangolo/fastapi/pull/5890) by [@bnzone](https://github.com/bnzone).
### Internal
* ✏ Update `zip-docs.sh` internal script, remove extra space. PR [#5931](https://github.com/tiangolo/fastapi/pull/5931) by [@JuanPerdomo00](https://github.com/JuanPerdomo00).
## 0.90.0
### Upgrades
* ⬆️ Bump Starlette from 0.22.0 to 0.23.0. Initial PR [#5739](https://github.com/tiangolo/fastapi/pull/5739) by [@Kludex](https://github.com/Kludex).
### Docs
* 📝 Add article "Tortoise ORM / FastAPI 整合快速筆記" to External Links. PR [#5496](https://github.com/tiangolo/fastapi/pull/5496) by [@Leon0824](https://github.com/Leon0824).
* 👥 Update FastAPI People. PR [#5954](https://github.com/tiangolo/fastapi/pull/5954) by [@github-actions[bot]](https://github.com/apps/github-actions).
* 📝 Micro-tweak help docs. PR [#5960](https://github.com/tiangolo/fastapi/pull/5960) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update new issue chooser to direct to GitHub Discussions. PR [#5948](https://github.com/tiangolo/fastapi/pull/5948) by [@tiangolo](https://github.com/tiangolo).
* 📝 Recommend GitHub Discussions for questions. PR [#5944](https://github.com/tiangolo/fastapi/pull/5944) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/body-fields.md`. PR [#5898](https://github.com/tiangolo/fastapi/pull/5898) by [@simatheone](https://github.com/simatheone).
* 🌐 Add Russian translation for `docs/ru/docs/help-fastapi.md`. PR [#5970](https://github.com/tiangolo/fastapi/pull/5970) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/static-files.md`. PR [#5858](https://github.com/tiangolo/fastapi/pull/5858) by [@batlopes](https://github.com/batlopes).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/encoder.md`. PR [#5525](https://github.com/tiangolo/fastapi/pull/5525) by [@felipebpl](https://github.com/felipebpl).
* 🌐 Add Russian translation for `docs/ru/docs/contributing.md`. PR [#5870](https://github.com/tiangolo/fastapi/pull/5870) by [@Xewus](https://github.com/Xewus).
### Internal
* ⬆️ Upgrade Ubuntu version for docs workflow. PR [#5971](https://github.com/tiangolo/fastapi/pull/5971) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors badges. PR [#5943](https://github.com/tiangolo/fastapi/pull/5943) by [@tiangolo](https://github.com/tiangolo).
* ✨ Compute FastAPI Experts including GitHub Discussions. PR [#5941](https://github.com/tiangolo/fastapi/pull/5941) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade isort and update pre-commit. PR [#5940](https://github.com/tiangolo/fastapi/pull/5940) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add template for questions in Discussions. PR [#5920](https://github.com/tiangolo/fastapi/pull/5920) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update Sponsor Budget Insight to Powens. PR [#5916](https://github.com/tiangolo/fastapi/pull/5916) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update GitHub Sponsors badge data. PR [#5915](https://github.com/tiangolo/fastapi/pull/5915) by [@tiangolo](https://github.com/tiangolo).
## 0.89.1
### Fixes
* 🐛 Ignore Response classes on return annotation. PR [#5855](https://github.com/tiangolo/fastapi/pull/5855) by [@Kludex](https://github.com/Kludex). See the new docs in the PR below.
### Docs
* 📝 Update docs and examples for Response Model with Return Type Annotations, and update runtime error. PR [#5873](https://github.com/tiangolo/fastapi/pull/5873) by [@tiangolo](https://github.com/tiangolo). New docs at [Response Model - Return Type: Other Return Type Annotations](https://fastapi.tiangolo.com/tutorial/response-model/#other-return-type-annotations).
* 📝 Add External Link: FastAPI lambda container: serverless simplified. PR [#5784](https://github.com/tiangolo/fastapi/pull/5784) by [@rafrasenberg](https://github.com/rafrasenberg).
### Translations
* 🌐 Add Turkish translation for `docs/tr/docs/tutorial/first_steps.md`. PR [#5691](https://github.com/tiangolo/fastapi/pull/5691) by [@Kadermiyanyedi](https://github.com/Kadermiyanyedi).
## 0.89.0
### Features
* ✨ Add support for function return type annotations to declare the `response_model`. Initial PR [#1436](https://github.com/tiangolo/fastapi/pull/1436) by [@uriyyo](https://github.com/uriyyo).
Now you can declare the return type / `response_model` in the function return type annotation:
```python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.get("/items/")
async def read_items() -> list[Item]:
return [
Item(name="Portal Gun", price=42.0),
Item(name="Plumbus", price=32.0),
]
```
FastAPI will use the return type annotation to perform:
* Data validation
* Automatic documentation
* It could power automatic client generators
* **Data filtering**
Before this version it was only supported via the `response_model` parameter.
Read more about it in the new docs: [Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/).
### Docs
* 📝 Add External Link: Authorization on FastAPI with Casbin. PR [#5712](https://github.com/tiangolo/fastapi/pull/5712) by [@Xhy-5000](https://github.com/Xhy-5000).
* ✏ Fix typo in `docs/en/docs/async.md`. PR [#5785](https://github.com/tiangolo/fastapi/pull/5785) by [@Kingdageek](https://github.com/Kingdageek).
* ✏ Fix typo in `docs/en/docs/deployment/concepts.md`. PR [#5824](https://github.com/tiangolo/fastapi/pull/5824) by [@kelbyfaessler](https://github.com/kelbyfaessler).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/fastapi-people.md`. PR [#5577](https://github.com/tiangolo/fastapi/pull/5577) by [@Xewus](https://github.com/Xewus).
* 🌐 Fix typo in Chinese translation for `docs/zh/docs/benchmarks.md`. PR [#4269](https://github.com/tiangolo/fastapi/pull/4269) by [@15027668g](https://github.com/15027668g).
* 🌐 Add Korean translation for `docs/tutorial/cors.md`. PR [#3764](https://github.com/tiangolo/fastapi/pull/3764) by [@NinaHwang](https://github.com/NinaHwang).
### Internal
* ⬆ Update coverage[toml] requirement from <7.0,>=6.5.0 to >=6.5.0,<8.0. PR [#5801](https://github.com/tiangolo/fastapi/pull/5801) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Update uvicorn[standard] requirement from <0.19.0,>=0.12.0 to >=0.12.0,<0.21.0 for development. PR [#5795](https://github.com/tiangolo/fastapi/pull/5795) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump dawidd6/action-download-artifact from 2.24.2 to 2.24.3. PR [#5842](https://github.com/tiangolo/fastapi/pull/5842) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👥 Update FastAPI People. PR [#5825](https://github.com/tiangolo/fastapi/pull/5825) by [@github-actions[bot]](https://github.com/apps/github-actions).
* ⬆ Bump types-ujson from 5.5.0 to 5.6.0.0. PR [#5735](https://github.com/tiangolo/fastapi/pull/5735) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.5.2 to 1.6.4. PR [#5750](https://github.com/tiangolo/fastapi/pull/5750) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Add GitHub Action gate/check. PR [#5492](https://github.com/tiangolo/fastapi/pull/5492) by [@webknjaz](https://github.com/webknjaz).
* 🔧 Update sponsors, add Svix. PR [#5848](https://github.com/tiangolo/fastapi/pull/5848) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Remove Doist sponsor. PR [#5847](https://github.com/tiangolo/fastapi/pull/5847) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Update sqlalchemy requirement from <=1.4.41,>=1.3.18 to >=1.3.18,<1.4.43. PR [#5540](https://github.com/tiangolo/fastapi/pull/5540) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump nwtgck/actions-netlify from 1.2.4 to 2.0.0. PR [#5757](https://github.com/tiangolo/fastapi/pull/5757) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump nwtgck/actions-netlify from 1.2.4 to 2.0.0. PR [#5757](https://github.com/tiangolo/fastapi/pull/5757) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Refactor CI artifact upload/download for docs previews. PR [#5793](https://github.com/tiangolo/fastapi/pull/5793) by [@tiangolo](https://github.com/tiangolo). * 👷 Refactor CI artifact upload/download for docs previews. PR [#5793](https://github.com/tiangolo/fastapi/pull/5793) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.5.1 to 1.5.2. PR [#5714](https://github.com/tiangolo/fastapi/pull/5714) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pypa/gh-action-pypi-publish from 1.5.1 to 1.5.2. PR [#5714](https://github.com/tiangolo/fastapi/pull/5714) by [@dependabot[bot]](https://github.com/apps/dependabot).
@ -1130,7 +1378,7 @@ Thanks to [Dima Boger](https://twitter.com/b0g3r) for the security report! 🙇
### Security fixes ### Security fixes
* 📌 Upgrade pydantic pin, to handle security vulnerability [CVE-2021-29510](https://github.com/samuelcolvin/pydantic/security/advisories/GHSA-5jqp-qgf6-3pvh). PR [#3213](https://github.com/tiangolo/fastapi/pull/3213) by [@tiangolo](https://github.com/tiangolo). * 📌 Upgrade pydantic pin, to handle security vulnerability [CVE-2021-29510](https://github.com/pydantic/pydantic/security/advisories/GHSA-5jqp-qgf6-3pvh). PR [#3213](https://github.com/tiangolo/fastapi/pull/3213) by [@tiangolo](https://github.com/tiangolo).
## 0.65.0 ## 0.65.0
@ -1685,11 +1933,11 @@ Note: all the previous parameters are still there, so it's still possible to dec
## 0.55.1 ## 0.55.1
* Fix handling of enums with their own schema in path parameters. To support [samuelcolvin/pydantic#1432](https://github.com/samuelcolvin/pydantic/pull/1432) in FastAPI. PR [#1463](https://github.com/tiangolo/fastapi/pull/1463). * Fix handling of enums with their own schema in path parameters. To support [pydantic/pydantic#1432](https://github.com/pydantic/pydantic/pull/1432) in FastAPI. PR [#1463](https://github.com/tiangolo/fastapi/pull/1463).
## 0.55.0 ## 0.55.0
* Allow enums to allow them to have their own schemas in OpenAPI. To support [samuelcolvin/pydantic#1432](https://github.com/samuelcolvin/pydantic/pull/1432) in FastAPI. PR [#1461](https://github.com/tiangolo/fastapi/pull/1461). * Allow enums to allow them to have their own schemas in OpenAPI. To support [pydantic/pydantic#1432](https://github.com/pydantic/pydantic/pull/1432) in FastAPI. PR [#1461](https://github.com/tiangolo/fastapi/pull/1461).
* Add links for funding through [GitHub sponsors](https://github.com/sponsors/tiangolo). PR [#1425](https://github.com/tiangolo/fastapi/pull/1425). * Add links for funding through [GitHub sponsors](https://github.com/sponsors/tiangolo). PR [#1425](https://github.com/tiangolo/fastapi/pull/1425).
* Update issue template for for questions. PR [#1344](https://github.com/tiangolo/fastapi/pull/1344) by [@retnikt](https://github.com/retnikt). * Update issue template for for questions. PR [#1344](https://github.com/tiangolo/fastapi/pull/1344) by [@retnikt](https://github.com/retnikt).
* Update warning about storing passwords in docs. PR [#1336](https://github.com/tiangolo/fastapi/pull/1336) by [@skorokithakis](https://github.com/skorokithakis). * Update warning about storing passwords in docs. PR [#1336](https://github.com/tiangolo/fastapi/pull/1336) by [@skorokithakis](https://github.com/skorokithakis).

2
docs/en/docs/tutorial/bigger-applications.md

@ -189,7 +189,7 @@ The end result is that the item paths are now:
### Import the dependencies ### Import the dependencies
This codes lives in the module `app.routers.items`, the file `app/routers/items.py`. This code lives in the module `app.routers.items`, the file `app/routers/items.py`.
And we need to get the dependency function from the module `app.dependencies`, the file `app/dependencies.py`. And we need to get the dependency function from the module `app.dependencies`, the file `app/dependencies.py`.

2
docs/en/docs/tutorial/metadata.md

@ -101,7 +101,7 @@ You can configure the two documentation user interfaces included:
* **Swagger UI**: served at `/docs`. * **Swagger UI**: served at `/docs`.
* You can set its URL with the parameter `docs_url`. * You can set its URL with the parameter `docs_url`.
* You can disable it by setting `docs_url=None`. * You can disable it by setting `docs_url=None`.
* ReDoc: served at `/redoc`. * **ReDoc**: served at `/redoc`.
* You can set its URL with the parameter `redoc_url`. * You can set its URL with the parameter `redoc_url`.
* You can disable it by setting `redoc_url=None`. * You can disable it by setting `redoc_url=None`.

212
docs/en/docs/tutorial/response-model.md

@ -1,6 +1,51 @@
# Response Model # Response Model - Return Type
You can declare the model used for the response with the parameter `response_model` in any of the *path operations*: You can declare the type used for the response by annotating the *path operation function* **return type**.
You can use **type annotations** the same way you would for input data in function **parameters**, you can use Pydantic models, lists, dictionaries, scalar values like integers, booleans, etc.
=== "Python 3.6 and above"
```Python hl_lines="18 23"
{!> ../../../docs_src/response_model/tutorial001_01.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="18 23"
{!> ../../../docs_src/response_model/tutorial001_01_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="16 21"
{!> ../../../docs_src/response_model/tutorial001_01_py310.py!}
```
FastAPI will use this return type to:
* **Validate** the returned data.
* If the data is invalid (e.g. you are missing a field), it means that *your* app code is broken, not returning what it should, and it will return a server error instead of returning incorrect data. This way you and your clients can be certain that they will receive the data and the data shape expected.
* Add a **JSON Schema** for the response, in the OpenAPI *path operation*.
* This will be used by the **automatic docs**.
* It will also be used by automatic client code generation tools.
But most importantly:
* It will **limit and filter** the output data to what is defined in the return type.
* This is particularly important for **security**, we'll see more of that below.
## `response_model` Parameter
There are some cases where you need or want to return some data that is not exactly what the type declares.
For example, you could want to **return a dictionary** or a database object, but **declare it as a Pydantic model**. This way the Pydantic model would do all the data documentation, validation, etc. for the object that you returned (e.g. a dictionary or database object).
If you added the return type annotation, tools and editors would complain with a (correct) error telling you that your function is returning a type (e.g. a dict) that is different from what you declared (e.g. a Pydantic model).
In those cases, you can use the *path operation decorator* parameter `response_model` instead of the return type.
You can use the `response_model` parameter in any of the *path operations*:
* `@app.get()` * `@app.get()`
* `@app.post()` * `@app.post()`
@ -10,40 +55,41 @@ You can declare the model used for the response with the parameter `response_mod
=== "Python 3.6 and above" === "Python 3.6 and above"
```Python hl_lines="17" ```Python hl_lines="17 22 24-27"
{!> ../../../docs_src/response_model/tutorial001.py!} {!> ../../../docs_src/response_model/tutorial001.py!}
``` ```
=== "Python 3.9 and above" === "Python 3.9 and above"
```Python hl_lines="17" ```Python hl_lines="17 22 24-27"
{!> ../../../docs_src/response_model/tutorial001_py39.py!} {!> ../../../docs_src/response_model/tutorial001_py39.py!}
``` ```
=== "Python 3.10 and above" === "Python 3.10 and above"
```Python hl_lines="15" ```Python hl_lines="17 22 24-27"
{!> ../../../docs_src/response_model/tutorial001_py310.py!} {!> ../../../docs_src/response_model/tutorial001_py310.py!}
``` ```
!!! note !!! note
Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your *path operation function*, like all the parameters and body. Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your *path operation function*, like all the parameters and body.
It receives the same type you would declare for a Pydantic model attribute, so, it can be a Pydantic model, but it can also be, e.g. a `list` of Pydantic models, like `List[Item]`. `response_model` receives the same type you would declare for a Pydantic model field, so, it can be a Pydantic model, but it can also be, e.g. a `list` of Pydantic models, like `List[Item]`.
FastAPI will use this `response_model` to do all the data documentation, validation, etc. and also to **convert and filter the output data** to its type declaration.
FastAPI will use this `response_model` to: !!! tip
If you have strict type checks in your editor, mypy, etc, you can declare the function return type as `Any`.
* Convert the output data to its type declaration. That way you tell the editor that you are intentionally returning anything. But FastAPI will still do the data documentation, validation, filtering, etc. with the `response_model`.
* Validate the data.
* Add a JSON Schema for the response, in the OpenAPI *path operation*.
* Will be used by the automatic documentation systems.
But most importantly: ### `response_model` Priority
* Will limit the output data to that of the model. We'll see how that's important below. If you declare both a return type and a `response_model`, the `response_model` will take priority and be used by FastAPI.
!!! note "Technical Details" This way you can add correct type annotations to your functions even when you are returning a type different than the response model, to be used by the editor and tools like mypy. And still you can have FastAPI do the data validation, documentation, etc. using the `response_model`.
The response model is declared in this parameter instead of as a function return type annotation, because the path function may not actually return that response model but rather return a `dict`, database object or some other model, and then use the `response_model` to perform the field limiting and serialization.
You can also use `response_model=None` to disable creating a response model for that *path operation*, you might need to do it if you are adding type annotations for things that are not valid Pydantic fields, you will see an example of that in one of the sections below.
## Return the same input data ## Return the same input data
@ -71,24 +117,24 @@ And we are using this model to declare our input and the same model to declare o
=== "Python 3.6 and above" === "Python 3.6 and above"
```Python hl_lines="17-18" ```Python hl_lines="18"
{!> ../../../docs_src/response_model/tutorial002.py!} {!> ../../../docs_src/response_model/tutorial002.py!}
``` ```
=== "Python 3.10 and above" === "Python 3.10 and above"
```Python hl_lines="15-16" ```Python hl_lines="16"
{!> ../../../docs_src/response_model/tutorial002_py310.py!} {!> ../../../docs_src/response_model/tutorial002_py310.py!}
``` ```
Now, whenever a browser is creating a user with a password, the API will return the same password in the response. Now, whenever a browser is creating a user with a password, the API will return the same password in the response.
In this case, it might not be a problem, because the user themself is sending the password. In this case, it might not be a problem, because it's the same user sending the password.
But if we use the same model for another *path operation*, we could be sending our user's passwords to every client. But if we use the same model for another *path operation*, we could be sending our user's passwords to every client.
!!! danger !!! danger
Never store the plain password of a user or send it in a response. Never store the plain password of a user or send it in a response like this, unless you know all the caveats and you know what you are doing.
## Add an output model ## Add an output model
@ -102,7 +148,7 @@ We can instead create an input model with the plaintext password and an output m
=== "Python 3.10 and above" === "Python 3.10 and above"
```Python hl_lines="7 9 14" ```Python hl_lines="9 11 16"
{!> ../../../docs_src/response_model/tutorial003_py310.py!} {!> ../../../docs_src/response_model/tutorial003_py310.py!}
``` ```
@ -116,7 +162,7 @@ Here, even though our *path operation function* is returning the same input user
=== "Python 3.10 and above" === "Python 3.10 and above"
```Python hl_lines="22" ```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial003_py310.py!} {!> ../../../docs_src/response_model/tutorial003_py310.py!}
``` ```
@ -130,12 +176,66 @@ Here, even though our *path operation function* is returning the same input user
=== "Python 3.10 and above" === "Python 3.10 and above"
```Python hl_lines="20" ```Python hl_lines="22"
{!> ../../../docs_src/response_model/tutorial003_py310.py!} {!> ../../../docs_src/response_model/tutorial003_py310.py!}
``` ```
So, **FastAPI** will take care of filtering out all the data that is not declared in the output model (using Pydantic). So, **FastAPI** will take care of filtering out all the data that is not declared in the output model (using Pydantic).
### `response_model` or Return Type
In this case, because the two models are different, if we annotated the function return type as `UserOut`, the editor and tools would complain that we are returning an invalid type, as those are different classes.
That's why in this example we have to declare it in the `response_model` parameter.
...but continue reading below to see how to overcome that.
## Return Type and Data Filtering
Let's continue from the previous example. We wanted to **annotate the function with one type** but return something that includes **more data**.
We want FastAPI to keep **filtering** the data using the response model.
In the previous example, because the classes were different, we had to use the `response_model` parameter. But that also means that we don't get the support from the editor and tools checking the function return type.
But in most of the cases where we need to do something like this, we want the model just to **filter/remove** some of the data as in this example.
And in those cases, we can use classes and inheritance to take advantage of function **type annotations** to get better support in the editor and tools, and still get the FastAPI **data filtering**.
=== "Python 3.6 and above"
```Python hl_lines="9-13 15-16 20"
{!> ../../../docs_src/response_model/tutorial003_01.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7-10 13-14 18"
{!> ../../../docs_src/response_model/tutorial003_01_py310.py!}
```
With this, we get tooling support, from editors and mypy as this code is correct in terms of types, but we also get the data filtering from FastAPI.
How does this work? Let's check that out. 🤓
### Type Annotations and Tooling
First let's see how editors, mypy and other tools would see this.
`BaseUser` has the base fields. Then `UserIn` inherits from `BaseUser` and adds the `password` field, so, it will include all the fields from both models.
We annotate the function return type as `BaseUser`, but we are actually returning a `UserIn` instance.
The editor, mypy, and other tools won't complain about this because, in typing terms, `UserIn` is a subclass of `BaseUser`, which means it's a *valid* type when what is expected is anything that is a `BaseUser`.
### FastAPI Data Filtering
Now, for FastAPI, it will see the return type and make sure that what you return includes **only** the fields that are declared in the type.
FastAPI does several things internally with Pydantic to make sure that those same rules of class inheritance are not used for the returned data filtering, otherwise you could end up returning much more data than what you expected.
This way, you can get the best of both worlds: type annotations with **tooling support** and **data filtering**.
## See it in the docs ## See it in the docs
When you see the automatic docs, you can check that the input model and output model will both have their own JSON Schema: When you see the automatic docs, you can check that the input model and output model will both have their own JSON Schema:
@ -146,6 +246,74 @@ And both models will be used for the interactive API documentation:
<img src="/img/tutorial/response-model/image02.png"> <img src="/img/tutorial/response-model/image02.png">
## Other Return Type Annotations
There might be cases where you return something that is not a valid Pydantic field and you annotate it in the function, only to get the support provided by tooling (the editor, mypy, etc).
### Return a Response Directly
The most common case would be [returning a Response directly as explained later in the advanced docs](../advanced/response-directly.md){.internal-link target=_blank}.
```Python hl_lines="8 10-11"
{!> ../../../docs_src/response_model/tutorial003_02.py!}
```
This simple case is handled automatically by FastAPI because the return type annotation is the class (or a subclass) of `Response`.
And tools will also be happy because both `RedirectResponse` and `JSONResponse` are subclasses of `Response`, so the type annotation is correct.
### Annotate a Response Subclass
You can also use a subclass of `Response` in the type annotation:
```Python hl_lines="8-9"
{!> ../../../docs_src/response_model/tutorial003_03.py!}
```
This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case.
### Invalid Return Type Annotations
But when you return some other arbitrary object that is not a valid Pydantic type (e.g. a database object) and you annotate it like that in the function, FastAPI will try to create a Pydantic response model from that type annotation, and will fail.
The same would happen if you had something like a <abbr title='A union between multiple types means "any of these types".'>union</abbr> between different types where one or more of them are not valid Pydantic types, for example this would fail 💥:
=== "Python 3.6 and above"
```Python hl_lines="10"
{!> ../../../docs_src/response_model/tutorial003_04.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="8"
{!> ../../../docs_src/response_model/tutorial003_04_py310.py!}
```
...this fails because the type annotation is not a Pydantic type and is not just a single `Response` class or subclass, it's a union (any of the two) between a `Response` and a `dict`.
### Disable Response Model
Continuing from the example above, you might not want to have the default data validation, documentation, filtering, etc. that is performed by FastAPI.
But you might want to still keep the return type annotation in the function to get the support from tools like editors and type checkers (e.g. mypy).
In this case, you can disable the response model generation by setting `response_model=None`:
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/response_model/tutorial003_05.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/response_model/tutorial003_05_py310.py!}
```
This will make FastAPI skip the response model generation and that way you can have any return type annotations you need without it affecting your FastAPI application. 🤓
## Response Model encoding parameters ## Response Model encoding parameters
Your response model could have default values, like: Your response model could have default values, like:

8
docs/en/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -187,7 +189,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -218,6 +220,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -238,6 +242,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

6
docs/en/overrides/main.html

@ -34,12 +34,6 @@
<img class="sponsor-image" src="/img/sponsors/cryptapi-banner.svg" /> <img class="sponsor-image" src="/img/sponsors/cryptapi-banner.svg" />
</a> </a>
</div> </div>
<div class="item">
<a title="Help us migrate doist to FastAPI" style="display: block; position: relative;" href="https://doist.com/careers/9B437B1615-wa-senior-backend-engineer-python" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/doist-banner.svg" />
</a>
</div>
<div class="item"> <div class="item">
<a title="Build cross-modal and multimodal applications on the cloud" style="display: block; position: relative;" href="https://bit.ly/3dphxRq" target="_blank"> <a title="Build cross-modal and multimodal applications on the cloud" style="display: block; position: relative;" href="https://bit.ly/3dphxRq" target="_blank">
<span class="sponsor-badge">sponsor</span> <span class="sponsor-badge">sponsor</span>

8
docs/es/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -90,7 +92,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -121,6 +123,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -141,6 +145,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/fa/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

168
docs/fr/docs/advanced/path-operation-advanced-configuration.md

@ -0,0 +1,168 @@
# Configuration avancée des paramètres de chemin
## ID d'opération OpenAPI
!!! Attention
Si vous n'êtes pas un "expert" en OpenAPI, vous n'en avez probablement pas besoin.
Dans OpenAPI, les chemins sont des ressources, tels que /users/ ou /items/, exposées par votre API, et les opérations sont les méthodes HTTP utilisées pour manipuler ces chemins, telles que GET, POST ou DELETE. Les operationId sont des chaînes uniques facultatives utilisées pour identifier une opération d'un chemin. Vous pouvez définir l'OpenAPI `operationId` à utiliser dans votre *opération de chemin* avec le paramètre `operation_id`.
Vous devez vous assurer qu'il est unique pour chaque opération.
```Python hl_lines="6"
{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### Utilisation du nom *path operation function* comme operationId
Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`, vous pouvez les parcourir tous et remplacer chaque `operation_id` de l'*opération de chemin* en utilisant leur `APIRoute.name`.
Vous devriez le faire après avoir ajouté toutes vos *paramètres de chemin*.
```Python hl_lines="2 12-21 24"
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
!!! Astuce
Si vous appelez manuellement `app.openapi()`, vous devez mettre à jour les `operationId` avant.
!!! Attention
Pour faire cela, vous devez vous assurer que chacun de vos *chemin* ait un nom unique.
Même s'ils se trouvent dans des modules différents (fichiers Python).
## Exclusion d'OpenAPI
Pour exclure un *chemin* du schéma OpenAPI généré (et donc des systèmes de documentation automatiques), utilisez le paramètre `include_in_schema` et assignez-lui la valeur `False` :
```Python hl_lines="6"
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## Description avancée de docstring
Vous pouvez limiter le texte utilisé de la docstring d'une *fonction de chemin* qui sera affiché sur OpenAPI.
L'ajout d'un `\f` (un caractère d'échappement "form feed") va permettre à **FastAPI** de tronquer la sortie utilisée pour OpenAPI à ce stade.
Il n'apparaîtra pas dans la documentation, mais d'autres outils (tel que Sphinx) pourront utiliser le reste.
```Python hl_lines="19-29"
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```
## Réponses supplémentaires
Vous avez probablement vu comment déclarer le `response_model` et le `status_code` pour une *opération de chemin*.
Cela définit les métadonnées sur la réponse principale d'une *opération de chemin*.
Vous pouvez également déclarer des réponses supplémentaires avec leurs modèles, codes de statut, etc.
Il y a un chapitre entier ici dans la documentation à ce sujet, vous pouvez le lire sur [Réponses supplémentaires dans OpenAPI](./additional-responses.md){.internal-link target=_blank}.
## OpenAPI supplémentaire
Lorsque vous déclarez un *chemin* dans votre application, **FastAPI** génère automatiquement les métadonnées concernant ce *chemin* à inclure dans le schéma OpenAPI.
!!! note "Détails techniques"
La spécification OpenAPI appelle ces métaonnées des <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Objets d'opération</a>.
Il contient toutes les informations sur le *chemin* et est utilisé pour générer automatiquement la documentation.
Il inclut les `tags`, `parameters`, `requestBody`, `responses`, etc.
Ce schéma OpenAPI spécifique aux *operations* est normalement généré automatiquement par **FastAPI**, mais vous pouvez également l'étendre.
!!! Astuce
Si vous avez seulement besoin de déclarer des réponses supplémentaires, un moyen plus pratique de le faire est d'utiliser les [réponses supplémentaires dans OpenAPI](./additional-responses.md){.internal-link target=_blank}.
Vous pouvez étendre le schéma OpenAPI pour une *opération de chemin* en utilisant le paramètre `openapi_extra`.
### Extensions OpenAPI
Cet `openapi_extra` peut être utile, par exemple, pour déclarer [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) :
```Python hl_lines="6"
{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
```
Si vous ouvrez la documentation automatique de l'API, votre extension apparaîtra au bas du *chemin* spécifique.
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
Et dans le fichier openapi généré (`/openapi.json`), vous verrez également votre extension dans le cadre du *chemin* spécifique :
```JSON hl_lines="22"
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"summary": "Read Items",
"operationId": "read_items_items__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"x-aperture-labs-portal": "blue"
}
}
}
}
```
### Personnalisation du Schéma OpenAPI pour un chemin
Le dictionnaire contenu dans la variable `openapi_extra` sera fusionné avec le schéma OpenAPI généré automatiquement pour l'*opération de chemin*.
Ainsi, vous pouvez ajouter des données supplémentaires au schéma généré automatiquement.
Par exemple, vous pouvez décider de lire et de valider la requête avec votre propre code, sans utiliser les fonctionnalités automatiques de validation proposée par Pydantic, mais vous pouvez toujours définir la requête dans le schéma OpenAPI.
Vous pouvez le faire avec `openapi_extra` :
```Python hl_lines="20-37 39-40"
{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py !}
```
Dans cet exemple, nous n'avons déclaré aucun modèle Pydantic. En fait, le corps de la requête n'est même pas <abbr title="converti d'un format simple, comme des octets, en objets Python">parsé</abbr> en tant que JSON, il est lu directement en tant que `bytes`, et la fonction `magic_data_reader()` serait chargé de l'analyser d'une manière ou d'une autre.
Néanmoins, nous pouvons déclarer le schéma attendu pour le corps de la requête.
### Type de contenu OpenAPI personnalisé
En utilisant cette même astuce, vous pouvez utiliser un modèle Pydantic pour définir le schéma JSON qui est ensuite inclus dans la section de schéma OpenAPI personnalisée pour le *chemin* concerné.
Et vous pouvez le faire même si le type de données dans la requête n'est pas au format JSON.
Dans cet exemple, nous n'utilisons pas les fonctionnalités de FastAPI pour extraire le schéma JSON des modèles Pydantic ni la validation automatique pour JSON. En fait, nous déclarons le type de contenu de la requête en tant que YAML, et non JSON :
```Python hl_lines="17-22 24"
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
Néanmoins, bien que nous n'utilisions pas la fonctionnalité par défaut, nous utilisons toujours un modèle Pydantic pour générer manuellement le schéma JSON pour les données que nous souhaitons recevoir en YAML.
Ensuite, nous utilisons directement la requête et extrayons son contenu en tant qu'octets. Cela signifie que FastAPI n'essaiera même pas d'analyser le payload de la requête en tant que JSON.
Et nous analysons directement ce contenu YAML, puis nous utilisons à nouveau le même modèle Pydantic pour valider le contenu YAML :
```Python hl_lines="26-33"
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
!!! Astuce
Ici, nous réutilisons le même modèle Pydantic.
Mais nous aurions pu tout aussi bien pu le valider d'une autre manière.

153
docs/fr/docs/deployment/manually.md

@ -0,0 +1,153 @@
# Exécuter un serveur manuellement - Uvicorn
La principale chose dont vous avez besoin pour exécuter une application **FastAPI** sur une machine serveur distante est un programme serveur ASGI tel que **Uvicorn**.
Il existe 3 principales alternatives :
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> : un serveur ASGI haute performance.
* <a href="https://pgjones.gitlab.io/hypercorn/" class="external-link" target="_blank">Hypercorn</a> : un serveur
ASGI compatible avec HTTP/2 et Trio entre autres fonctionnalités.
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a> : le serveur ASGI
conçu pour Django Channels.
## Machine serveur et programme serveur
Il y a un petit détail sur les noms à garder à l'esprit. 💡
Le mot "**serveur**" est couramment utilisé pour désigner à la fois l'ordinateur distant/cloud (la machine physique ou virtuelle) et également le programme qui s'exécute sur cette machine (par exemple, Uvicorn).
Gardez cela à l'esprit lorsque vous lisez "serveur" en général, cela pourrait faire référence à l'une de ces deux choses.
Lorsqu'on se réfère à la machine distante, il est courant de l'appeler **serveur**, mais aussi **machine**, **VM** (machine virtuelle), **nœud**. Tout cela fait référence à un type de machine distante, exécutant Linux, en règle générale, sur laquelle vous exécutez des programmes.
## Installer le programme serveur
Vous pouvez installer un serveur compatible ASGI avec :
=== "Uvicorn"
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, un serveur ASGI rapide comme l'éclair, basé sur uvloop et httptools.
<div class="termy">
```console
$ pip install "uvicorn[standard]"
---> 100%
```
</div>
!!! tip "Astuce"
En ajoutant `standard`, Uvicorn va installer et utiliser quelques dépendances supplémentaires recommandées.
Cela inclut `uvloop`, le remplaçant performant de `asyncio`, qui fournit le gros gain de performance en matière de concurrence.
=== "Hypercorn"
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, un serveur ASGI également compatible avec HTTP/2.
<div class="termy">
```console
$ pip install hypercorn
---> 100%
```
</div>
...ou tout autre serveur ASGI.
## Exécutez le programme serveur
Vous pouvez ensuite exécuter votre application de la même manière que vous l'avez fait dans les tutoriels, mais sans l'option `--reload`, par exemple :
=== "Uvicorn"
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 80
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
</div>
=== "Hypercorn"
<div class="termy">
```console
$ hypercorn main:app --bind 0.0.0.0:80
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
```
</div>
!!! warning
N'oubliez pas de supprimer l'option `--reload` si vous l'utilisiez.
L'option `--reload` consomme beaucoup plus de ressources, est plus instable, etc.
Cela aide beaucoup pendant le **développement**, mais vous **ne devriez pas** l'utiliser en **production**.
## Hypercorn avec Trio
Starlette et **FastAPI** sont basés sur
<a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, qui les rend
compatibles avec <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a>, de la bibliothèque standard Python et
<a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
Néanmoins, Uvicorn n'est actuellement compatible qu'avec asyncio, et il utilise normalement <a href="https://github.
com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a >, le remplaçant hautes performances de `asyncio`.
Mais si vous souhaitez utiliser directement **Trio**, vous pouvez utiliser **Hypercorn** car il le prend en charge. ✨
### Installer Hypercorn avec Trio
Vous devez d'abord installer Hypercorn avec le support Trio :
<div class="termy">
```console
$ pip install "hypercorn[trio]"
---> 100%
```
</div>
### Exécuter avec Trio
Ensuite, vous pouvez passer l'option de ligne de commande `--worker-class` avec la valeur `trio` :
<div class="termy">
```console
$ hypercorn main:app --worker-class trio
```
</div>
Et cela démarrera Hypercorn avec votre application en utilisant Trio comme backend.
Vous pouvez désormais utiliser Trio en interne dans votre application. Ou mieux encore, vous pouvez utiliser AnyIO pour que votre code reste compatible avec Trio et asyncio. 🎉
## Concepts de déploiement
Ces exemples lancent le programme serveur (e.g. Uvicorn), démarrant **un seul processus**, sur toutes les IPs (`0.0.
0.0`) sur un port prédéfini (par example, `80`).
C'est l'idée de base. Mais vous vous préoccuperez probablement de certains concepts supplémentaires, tels que ... :
* la sécurité - HTTPS
* l'exécution au démarrage
* les redémarrages
* la réplication (le nombre de processus en cours d'exécution)
* la mémoire
* les étapes précédant le démarrage
Je vous en dirai plus sur chacun de ces concepts, sur la façon de les aborder, et donnerai quelques exemples concrets avec des stratégies pour les traiter dans les prochains chapitres. 🚀

112
docs/fr/docs/tutorial/debugging.md

@ -0,0 +1,112 @@
# <abbr title="En anglais: Debugging">Débogage</abbr>
Vous pouvez connecter le <abbr title="En anglais: debugger">débogueur</abbr> dans votre éditeur, par exemple avec Visual Studio Code ou PyCharm.
## Faites appel à `uvicorn`
Dans votre application FastAPI, importez et exécutez directement `uvicorn` :
```Python hl_lines="1 15"
{!../../../docs_src/debugging/tutorial001.py!}
```
### À propos de `__name__ == "__main__"`
Le but principal de `__name__ == "__main__"` est d'avoir du code qui est exécuté lorsque votre fichier est appelé avec :
<div class="termy">
```console
$ python myapp.py
```
</div>
mais qui n'est pas appelé lorsqu'un autre fichier l'importe, comme dans :
```Python
from myapp import app
```
#### Pour davantage de détails
Imaginons que votre fichier s'appelle `myapp.py`.
Si vous l'exécutez avec :
<div class="termy">
```console
$ python myapp.py
```
</div>
alors la variable interne `__name__` de votre fichier, créée automatiquement par Python, aura pour valeur la chaîne de caractères `"__main__"`.
Ainsi, la section :
```Python
uvicorn.run(app, host="0.0.0.0", port=8000)
```
va s'exécuter.
---
Cela ne se produira pas si vous importez ce module (fichier).
Par exemple, si vous avez un autre fichier `importer.py` qui contient :
```Python
from myapp import app
# Code supplémentaire
```
dans ce cas, la variable automatique `__name__` à l'intérieur de `myapp.py` n'aura pas la valeur `"__main__"`.
Ainsi, la ligne :
```Python
uvicorn.run(app, host="0.0.0.0", port=8000)
```
ne sera pas exécutée.
!!! info
Pour plus d'informations, consultez <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">la documentation officielle de Python</a>.
## Exécutez votre code avec votre <abbr title="En anglais: debugger">débogueur</abbr>
Parce que vous exécutez le serveur Uvicorn directement depuis votre code, vous pouvez appeler votre programme Python (votre application FastAPI) directement depuis le <abbr title="En anglais: debugger">débogueur</abbr>.
---
Par exemple, dans Visual Studio Code, vous pouvez :
- Cliquer sur l'onglet "Debug" de la barre d'activités de Visual Studio Code.
- "Add configuration...".
- Sélectionnez "Python".
- Lancez le <abbr title="En anglais: debugger">débogueur</abbr> avec l'option "`Python: Current File (Integrated Terminal)`".
Il démarrera alors le serveur avec votre code **FastAPI**, s'arrêtera à vos points d'arrêt, etc.
Voici à quoi cela pourrait ressembler :
<img src="/img/tutorial/debugging/image01.png">
---
Si vous utilisez Pycharm, vous pouvez :
- Ouvrir le menu "Run".
- Sélectionnez l'option "Debug...".
- Un menu contextuel s'affiche alors.
- Sélectionnez le fichier à déboguer (dans ce cas, `main.py`).
Il démarrera alors le serveur avec votre code **FastAPI**, s'arrêtera à vos points d'arrêt, etc.
Voici à quoi cela pourrait ressembler :
<img src="/img/tutorial/debugging/image02.png">

11
docs/fr/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -67,7 +69,9 @@ nav:
- tutorial/query-params.md - tutorial/query-params.md
- tutorial/body.md - tutorial/body.md
- tutorial/background-tasks.md - tutorial/background-tasks.md
- tutorial/debugging.md
- Guide utilisateur avancé: - Guide utilisateur avancé:
- advanced/path-operation-advanced-configuration.md
- advanced/additional-status-codes.md - advanced/additional-status-codes.md
- advanced/additional-responses.md - advanced/additional-responses.md
- async.md - async.md
@ -77,6 +81,7 @@ nav:
- deployment/https.md - deployment/https.md
- deployment/deta.md - deployment/deta.md
- deployment/docker.md - deployment/docker.md
- deployment/manually.md
- project-generation.md - project-generation.md
- alternatives.md - alternatives.md
- history-design-future.md - history-design-future.md
@ -104,7 +109,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -135,6 +140,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -155,6 +162,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/he/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

467
docs/hy/docs/index.md

@ -0,0 +1,467 @@
{!../../../docs/missing-translation.md!}
<p align="center">
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
</p>
<p align="center">
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
</p>
<p align="center">
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>
---
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
The key features are:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> 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: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* estimation based on tests on an internal development team, building production applications.</small>
## Sponsors
<!-- sponsors -->
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
<!-- /sponsors -->
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
## 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._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
---
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
---
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"_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._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
"_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 [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
**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:
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
## Installation
<div class="termy">
```console
$ pip install fastapi
---> 100%
```
</div>
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
```console
$ pip install "uvicorn[standard]"
---> 100%
```
</div>
## 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}
```
<details markdown="1">
<summary>Or use <code>async def</code>...</summary>
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 <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
</details>
### Run it
Run the server with:
<div class="termy">
```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.
```
</div>
<details markdown="1">
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
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.
</details>
### Check it
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
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` <em>operations</em> (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 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Alternative API docs
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## 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 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
* The interactive API documentation will be automatically updated, including the new body:
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* 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:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### Alternative API docs upgrade
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
* The alternative documentation will also reflect the new query parameter and body:
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Recap
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
You do that with standard modern Python types.
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
Just standard **Python 3.7+**.
For example, for an `int`:
```Python
item_id: int
```
or for a more complex `Item` model:
```Python
item: Item
```
...and with that single declaration you get:
* Editor support, including:
* Completion.
* Type checks.
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
* Cookies.
* Headers.
* Forms.
* Files.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> 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:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
**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 **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** 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 <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> 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 <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
## Optional Dependencies
Used by Pydantic:
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
Used by Starlette:
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
Used by FastAPI / Starlette:
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - 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.

148
docs/hy/mkdocs.yml

@ -0,0 +1,148 @@
site_name: FastAPI
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
site_url: https://fastapi.tiangolo.com/hy/
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: hy
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/
- hy: /hy/
- 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: /hy/
name: hy
- 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

0
docs/hy/overrides/.gitignore

8
docs/id/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/it/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/ja/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -124,7 +126,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -155,6 +157,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -175,6 +179,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

84
docs/ko/docs/tutorial/cors.md

@ -0,0 +1,84 @@
# 교차 출처 리소스 공유
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS 또는 "교차-출처 리소스 공유"</a>란, 브라우저에서 동작하는 프론트엔드가 자바스크립트로 코드로 백엔드와 통신하고, 백엔드는 해당 프론트엔드와 다른 "출처"에 존재하는 상황을 의미합니다.
## 출처
출처란 프로토콜(`http` , `https`), 도메인(`myapp.com`, `localhost`, `localhost.tiangolo.com` ), 그리고 포트(`80`, `443`, `8080` )의 조합을 의미합니다.
따라서, 아래는 모두 상이한 출처입니다:
* `http://localhost`
* `https://localhost`
* `http://localhost:8080`
모두 `localhost` 에 있지만, 서로 다른 프로토콜과 포트를 사용하고 있으므로 다른 "출처"입니다.
## 단계
브라우저 내 `http://localhost:8080`에서 동작하는 프론트엔드가 있고, 자바스크립트는 `http://localhost`를 통해 백엔드와 통신한다고 가정해봅시다(포트를 명시하지 않는 경우, 브라우저는 `80` 을 기본 포트로 간주합니다).
그러면 브라우저는 백엔드에 HTTP `OPTIONS` 요청을 보내고, 백엔드에서 이 다른 출처(`http://localhost:8080`)와의 통신을 허가하는 적절한 헤더를 보내면, 브라우저는 프론트엔드의 자바스크립트가 백엔드에 요청을 보낼 수 있도록 합니다.
이를 위해, 백엔드는 "허용된 출처(allowed origins)" 목록을 가지고 있어야만 합니다.
이 경우, 프론트엔드가 제대로 동작하기 위해 `http://localhost:8080`을 목록에 포함해야 합니다.
## 와일드카드
모든 출처를 허용하기 위해 목록을 `"*"` ("와일드카드")로 선언하는 것도 가능합니다.
하지만 이것은 특정한 유형의 통신만을 허용하며, 쿠키 및 액세스 토큰과 사용되는 인증 헤더(Authoriztion header) 등이 포함된 경우와 같이 자격 증명(credentials)이 포함된 통신은 허용되지 않습니다.
따라서 모든 작업을 의도한대로 실행하기 위해, 허용되는 출처를 명시적으로 지정하는 것이 좋습니다.
## `CORSMiddleware` 사용
`CORSMiddleware` 을 사용하여 **FastAPI** 응용 프로그램의 교차 출처 리소스 공유 환경을 설정할 수 있습니다.
* `CORSMiddleware` 임포트.
* 허용되는 출처(문자열 형식)의 리스트 생성.
* FastAPI 응용 프로그램에 "미들웨어(middleware)"로 추가.
백엔드에서 다음의 사항을 허용할지에 대해 설정할 수도 있습니다:
* 자격증명 (인증 헤더, 쿠키 등).
* 특정한 HTTP 메소드(`POST`, `PUT`) 또는 와일드카드 `"*"` 를 사용한 모든 HTTP 메소드.
* 특정한 HTTP 헤더 또는 와일드카드 `"*"` 를 사용한 모든 HTTP 헤더.
```Python hl_lines="2 6-11 13-19"
{!../../../docs_src/cors/tutorial001.py!}
```
`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` 입니다.
미들웨어는 두가지 특정한 종류의 HTTP 요청에 응답합니다...
### CORS 사전 요청
`Origin``Access-Control-Request-Method` 헤더와 함께 전송하는 모든 `OPTIONS` 요청입니다.
이 경우 미들웨어는 들어오는 요청을 가로채 적절한 CORS 헤더와, 정보 제공을 위한 `200` 또는 `400` 응답으로 응답합니다.
### 단순한 요청
`Origin` 헤더를 가진 모든 요청. 이 경우 미들웨어는 요청을 정상적으로 전달하지만, 적절한 CORS 헤더를 응답에 포함시킵니다.
## 더 많은 정보
<abbr title="교차-출처 리소스 공유">CORS</abbr>에 대한 더 많은 정보를 알고싶다면, <a href="https://developer.mozilla.org/ko/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS 문서</a>를 참고하기 바랍니다.
!!! note "기술적 세부 사항"
`from starlette.middleware.cors import CORSMiddleware` 역시 사용할 수 있습니다.
**FastAPI**는 개발자인 당신의 편의를 위해 `fastapi.middleware` 에서 몇가지의 미들웨어를 제공합니다. 하지만 대부분의 미들웨어가 Stralette으로부터 직접 제공됩니다.

9
docs/ko/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -69,6 +71,7 @@ nav:
- tutorial/request-files.md - tutorial/request-files.md
- tutorial/request-forms-and-files.md - tutorial/request-forms-and-files.md
- tutorial/encoder.md - tutorial/encoder.md
- tutorial/cors.md
markdown_extensions: markdown_extensions:
- toc: - toc:
permalink: true permalink: true
@ -91,7 +94,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -122,6 +125,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -142,6 +147,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/nl/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/pl/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -83,7 +85,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -114,6 +116,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -134,6 +138,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

42
docs/pt/docs/tutorial/encoder.md

@ -0,0 +1,42 @@
# Codificador Compatível com JSON
Existem alguns casos em que você pode precisar converter um tipo de dados (como um modelo Pydantic) para algo compatível com JSON (como um `dict`, `list`, etc).
Por exemplo, se você precisar armazená-lo em um banco de dados.
Para isso, **FastAPI** fornece uma função `jsonable_encoder()`.
## Usando a função `jsonable_encoder`
Vamos imaginar que você tenha um banco de dados `fake_db` que recebe apenas dados compatíveis com JSON.
Por exemplo, ele não recebe objetos `datetime`, pois estes objetos não são compatíveis com JSON.
Então, um objeto `datetime` teria que ser convertido em um `str` contendo os dados no formato <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO</a>.
Da mesma forma, este banco de dados não receberia um modelo Pydantic (um objeto com atributos), apenas um `dict`.
Você pode usar a função `jsonable_encoder` para resolver isso.
A função recebe um objeto, como um modelo Pydantic e retorna uma versão compatível com JSON:
=== "Python 3.6 e acima"
```Python hl_lines="5 22"
{!> ../../../docs_src/encoder/tutorial001.py!}
```
=== "Python 3.10 e acima"
```Python hl_lines="4 21"
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
```
Neste exemplo, ele converteria o modelo Pydantic em um `dict`, e o `datetime` em um `str`.
O resultado de chamar a função é algo que pode ser codificado com o padrão do Python <a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a>.
A função não retorna um grande `str` contendo os dados no formato JSON (como uma string). Mas sim, retorna uma estrutura de dados padrão do Python (por exemplo, um `dict`) com valores e subvalores compatíveis com JSON.
!!! nota
`jsonable_encoder` é realmente usado pelo **FastAPI** internamente para converter dados. Mas também é útil em muitos outros cenários.

39
docs/pt/docs/tutorial/static-files.md

@ -0,0 +1,39 @@
# Arquivos Estáticos
Você pode servir arquivos estáticos automaticamente de um diretório usando `StaticFiles`.
## Use `StaticFiles`
* Importe `StaticFiles`.
* "Monte" uma instância de `StaticFiles()` em um caminho específico.
```Python hl_lines="2 6"
{!../../../docs_src/static_files/tutorial001.py!}
```
!!! note "Detalhes técnicos"
Você também pode usar `from starlette.staticfiles import StaticFiles`.
O **FastAPI** fornece o mesmo que `starlette.staticfiles` como `fastapi.staticfiles` apenas como uma conveniência para você, o desenvolvedor. Mas na verdade vem diretamente da Starlette.
### O que é "Montagem"
"Montagem" significa adicionar um aplicativo completamente "independente" em uma rota específica, que então cuida de todas as subrotas.
Isso é diferente de usar um `APIRouter`, pois um aplicativo montado é completamente independente. A OpenAPI e a documentação do seu aplicativo principal não incluirão nada do aplicativo montado, etc.
Você pode ler mais sobre isso no **Guia Avançado do Usuário**.
## Detalhes
O primeiro `"/static"` refere-se à subrota em que este "subaplicativo" será "montado". Portanto, qualquer caminho que comece com `"/static"` será tratado por ele.
O `directory="static"` refere-se ao nome do diretório que contém seus arquivos estáticos.
O `name="static"` dá a ela um nome que pode ser usado internamente pelo FastAPI.
Todos esses parâmetros podem ser diferentes de "`static`", ajuste-os de acordo com as necessidades e detalhes específicos de sua própria aplicação.
## Mais informações
Para mais detalhes e opções, verifique <a href="https://www.starlette.io/staticfiles/" class="external-link" target="_blank">Starlette's docs about Static Files</a>.

10
docs/pt/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -77,9 +79,11 @@ nav:
- tutorial/request-forms.md - tutorial/request-forms.md
- tutorial/request-forms-and-files.md - tutorial/request-forms-and-files.md
- tutorial/handling-errors.md - tutorial/handling-errors.md
- tutorial/encoder.md
- Segurança: - Segurança:
- tutorial/security/index.md - tutorial/security/index.md
- tutorial/background-tasks.md - tutorial/background-tasks.md
- tutorial/static-files.md
- Guia de Usuário Avançado: - Guia de Usuário Avançado:
- advanced/index.md - advanced/index.md
- Implantação: - Implantação:
@ -115,7 +119,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -146,6 +150,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -166,6 +172,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

469
docs/ru/docs/contributing.md

@ -0,0 +1,469 @@
# Участие в разработке фреймворка
Возможно, для начала Вам стоит ознакомиться с основными способами [помочь FastAPI или получить помощь](help-fastapi.md){.internal-link target=_blank}.
## Разработка
Если Вы уже склонировали репозиторий и знаете, что Вам нужно более глубокое погружение в код фреймворка, то здесь представлены некоторые инструкции по настройке виртуального окружения.
### Виртуальное окружение с помощью `venv`
Находясь в нужной директории, Вы можете создать виртуальное окружение при помощи Python модуля `venv`.
<div class="termy">
```console
$ python -m venv env
```
</div>
Эта команда создаст директорию `./env/` с бинарными (двоичными) файлами Python, а затем Вы сможете скачивать и устанавливать необходимые библиотеки в изолированное виртуальное окружение.
### Активация виртуального окружения
Активируйте виртуально окружение командой:
=== "Linux, macOS"
<div class="termy">
```console
$ source ./env/bin/activate
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
$ .\env\Scripts\Activate.ps1
```
</div>
=== "Windows Bash"
Если Вы пользуетесь Bash для Windows (например: <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
<div class="termy">
```console
$ source ./env/Scripts/activate
```
</div>
Проверьте, что всё сработало:
=== "Linux, macOS, Windows Bash"
<div class="termy">
```console
$ which pip
some/directory/fastapi/env/bin/pip
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
$ Get-Command pip
some/directory/fastapi/env/bin/pip
```
</div>
Ели в терминале появится ответ, что бинарник `pip` расположен по пути `.../env/bin/pip`, значит всё в порядке. 🎉
Во избежание ошибок в дальнейших шагах, удостоверьтесь, что в Вашем виртуальном окружении установлена последняя версия `pip`:
<div class="termy">
```console
$ python -m pip install --upgrade pip
---> 100%
```
</div>
!!! tip "Подсказка"
Каждый раз, перед установкой новой библиотеки в виртуальное окружение при помощи `pip`, не забудьте активировать это виртуальное окружение.
Это гарантирует, что если Вы используете библиотеку, установленную этим пакетом, то Вы используете библиотеку из Вашего локального окружения, а не любую другую, которая может быть установлена глобально.
### pip
После активации виртуального окружения, как было указано ранее, введите следующую команду:
<div class="termy">
```console
$ pip install -e ."[dev,doc,test]"
---> 100%
```
</div>
Это установит все необходимые зависимости в локальное окружение для Вашего локального FastAPI.
#### Использование локального FastAPI
Если Вы создаёте Python файл, который импортирует и использует FastAPI,а затем запускаете его интерпретатором Python из Вашего локального окружения, то он будет использовать код из локального FastAPI.
И, так как при вводе вышеупомянутой команды был указан флаг `-e`, если Вы измените код локального FastAPI, то при следующем запуске этого файла, он будет использовать свежую версию локального FastAPI, который Вы только что изменили.
Таким образом, Вам не нужно "переустанавливать" Вашу локальную версию, чтобы протестировать каждое изменение.
### Форматировние
Скачанный репозиторий содержит скрипт, который может отформатировать и подчистить Ваш код:
<div class="termy">
```console
$ bash scripts/format.sh
```
</div>
Заодно он упорядочит Ваши импорты.
Чтобы он сортировал их правильно, необходимо, чтобы FastAPI был установлен локально в Вашей среде, с помощью команды из раздела выше, использующей флаг `-e`.
## Документация
Прежде всего, убедитесь, что Вы настроили своё окружение, как описано выше, для установки всех зависимостей.
Документация использует <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
Также существуют дополнительные инструменты/скрипты для работы с переводами в `./scripts/docs.py`.
!!! tip "Подсказка"
Нет необходимости заглядывать в `./scripts/docs.py`, просто используйте это в командной строке.
Вся документация имеет формат Markdown и расположена в директории `./docs/en/`.
Многие руководства содержат блоки кода.
В большинстве случаев эти блоки кода представляют собой вполне законченные приложения, которые можно запускать как есть.
На самом деле, эти блоки кода не написаны внутри Markdown, это Python файлы в директории `./docs_src/`.
И эти Python файлы включаются/вводятся в документацию при создании сайта.
### Тестирование документации
Фактически, большинство тестов запускаются с примерами исходных файлов в документации.
Это помогает убедиться, что:
* Документация находится в актуальном состоянии.
* Примеры из документации могут быть запущены как есть.
* Большинство функций описаны в документации и покрыты тестами.
Существует скрипт, который во время локальной разработки создаёт сайт и проверяет наличие любых изменений, перезагружая его в реальном времени:
<div class="termy">
```console
$ python ./scripts/docs.py live
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
Он запустит сайт документации по адресу: `http://127.0.0.1:8008`.
Таким образом, Вы сможете редактировать файлы с документацией или кодом и наблюдать изменения вживую.
#### Typer CLI (опционально)
Приведенная ранее инструкция показала Вам, как запускать скрипт `./scripts/docs.py` непосредственно через интерпретатор `python` .
Но также можно использовать <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">Typer CLI</a>, что позволит Вам воспользоваться автозаполнением команд в Вашем терминале.
Если Вы установили Typer CLI, то для включения функции автозаполнения, введите эту команду:
<div class="termy">
```console
$ typer --install-completion
zsh completion installed in /home/user/.bashrc.
Completion will take effect once you restart the terminal.
```
</div>
### Приложения и документация одновременно
Если Вы запускаете приложение, например так:
<div class="termy">
```console
$ uvicorn tutorial001:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
По умолчанию Uvicorn будет использовать порт `8000` и не будет конфликтовать с сайтом документации, использующим порт `8008`.
### Переводы на другие языки
Помощь с переводами ценится КРАЙНЕ ВЫСОКО! И переводы не могут быть сделаны без помощи сообщества. 🌎 🚀
Ниже приведены шаги, как помочь с переводами.
#### Подсказки и инструкции
* Проверьте <a href="https://github.com/tiangolo/fastapi/pulls" class="external-link" target="_blank">существующие пул-реквесты</a> для Вашего языка. Добавьте отзывы с просьбой внести изменения, если они необходимы, или одобрите их.
!!! tip "Подсказка"
Вы можете <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request" class="external-link" target="_blank">добавлять комментарии с предложениями по изменению</a> в существующие пул-реквесты.
Ознакомьтесь с документацией о <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews" class="external-link" target="_blank">добавлении отзыва к пул-реквесту</a>, чтобы утвердить его или запросить изменения.
* Проверьте <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">проблемы и вопросы</a>, чтобы узнать, есть ли кто-то, координирующий переводы для Вашего языка.
* Добавляйте один пул-реквест для каждой отдельной переведённой страницы. Это значительно облегчит другим его просмотр.
Для языков, которые я не знаю, прежде чем добавить перевод в основную ветку, я подожду пока несколько других участников сообщества проверят его.
* Вы также можете проверить, есть ли переводы для Вашего языка и добавить к ним отзыв, который поможет мне убедиться в правильности перевода. Тогда я смогу объединить его с основной веткой.
* Используйте те же самые примеры кода Python. Переводите только текст документации. Вам не нужно ничего менять, чтобы эти примеры работали.
* Используйте те же самые изображения, имена файлов и ссылки. Вы не должны менять ничего для сохранения работоспособности.
* Чтобы узнать 2-буквенный код языка, на который Вы хотите сделать перевод, Вы можете воспользоваться таблицей <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">Список кодов языков ISO 639-1</a>.
#### Существующий язык
Допустим, Вы хотите перевести страницу на язык, на котором уже есть какие-то переводы, например, на испанский.
Кодом испанского языка является `es`. А значит директория для переводов на испанский язык: `docs/es/`.
!!! tip "Подсказка"
Главный ("официальный") язык - английский, директория для него `docs/en/`.
Вы можете запустить сервер документации на испанском:
<div class="termy">
```console
// Используйте команду "live" и передайте код языка в качестве аргумента командной строки
$ python ./scripts/docs.py live es
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
Теперь Вы можете перейти по адресу: <a href="http://127.0.0.1:8008" class="external-link" target="_blank">http://127.0.0.1:8008</a> и наблюдать вносимые Вами изменения вживую.
Если Вы посмотрите на сайт документации FastAPI, то увидите, что все страницы есть на каждом языке. Но некоторые страницы не переведены и имеют уведомление об отсутствующем переводе.
Но когда Вы запускаете сайт локально, Вы видите только те страницы, которые уже переведены.
Предположим, что Вы хотите добавить перевод страницы [Основные свойства](features.md){.internal-link target=_blank}.
* Скопируйте файл:
```
docs/en/docs/features.md
```
* Вставьте его точно в то же место, но в директорию языка, на который Вы хотите сделать перевод, например:
```
docs/es/docs/features.md
```
!!! tip "Подсказка"
Заметьте, что в пути файла мы изменили только код языка с `en` на `es`.
* Теперь откройте файл конфигурации MkDocs для английского языка, расположенный тут:
```
docs/en/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/mkdocs.yml
```
* Добавьте строку `docs/features.md` точно в то же место, как и в случае для английского, как-то так:
```YAML hl_lines="8"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- features.md
```
Убедитесь, что при наличии других записей, новая запись с Вашим переводом находится точно в том же порядке, что и в английской версии.
Если Вы зайдёте в свой браузер, то увидите, что в документации стал отображаться Ваш новый раздел.🎉
Теперь Вы можете переводить эту страницу и смотреть, как она выглядит при сохранении файла.
#### Новый язык
Допустим, Вы хотите добавить перевод для языка, на который пока что не переведена ни одна страница.
Скажем, Вы решили сделать перевод для креольского языка, но его еще нет в документации.
Перейдите в таблицу кодов языков по ссылке указанной выше, где найдёте, что кодом креольского языка является `ht`.
Затем запустите скрипт, генерирующий директорию для переводов на новые языки:
<div class="termy">
```console
// Используйте команду new-lang и передайте код языка в качестве аргумента командной строки
$ python ./scripts/docs.py new-lang ht
Successfully initialized: docs/ht
Updating ht
Updating en
```
</div>
После чего Вы можете проверить в своем редакторе кода, что появился новый каталог `docs/ht/`.
!!! tip "Подсказка"
Создайте первый пул-реквест, который будет содержать только пустую директорию для нового языка, прежде чем добавлять переводы.
Таким образом, другие участники могут переводить другие страницы, пока Вы работаете над одной. 🚀
Начните перевод с главной страницы `docs/ht/index.md`.
В дальнейшем можно действовать, как указано в предыдущих инструкциях для "существующего языка".
##### Новый язык не поддерживается
Если при запуске скрипта `./scripts/docs.py live` Вы получаете сообщение об ошибке, что язык не поддерживается, что-то вроде:
```
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: partials/language/xx.html
```
Сие означает, что тема не поддерживает этот язык (в данном случае с поддельным 2-буквенным кодом `xx`).
Но не стоит переживать. Вы можете установить языком темы английский, а затем перевести текст документации.
Если возникла такая необходимость, отредактируйте `mkdocs.yml` для Вашего нового языка. Это будет выглядеть как-то так:
```YAML hl_lines="5"
site_name: FastAPI
# More stuff
theme:
# More stuff
language: xx
```
Измените `xx` (код Вашего языка) на `en` и перезапустите сервер.
#### Предпросмотр результата
Когда Вы запускаете скрипт `./scripts/docs.py` с командой `live`, то будут показаны файлы и переводы для указанного языка.
Но когда Вы закончите, то можете посмотреть, как это будет выглядеть по-настоящему.
Для этого сначала создайте всю документацию:
<div class="termy">
```console
// Используйте команду "build-all", это займёт немного времени
$ 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
```
</div>
Скрипт сгенерирует `./docs_build/` для каждого языка. Он добавит все файлы с отсутствующими переводами с пометкой о том, что "у этого файла еще нет перевода". Но Вам не нужно ничего делать с этим каталогом.
Затем он создаст независимые сайты MkDocs для каждого языка, объединит их и сгенерирует конечный результат на `./site/`.
После чего Вы сможете запустить сервер со всеми языками командой `serve`:
<div class="termy">
```console
// Используйте команду "serve" после того, как отработает команда "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
```
</div>
## Тесты
Также в репозитории есть скрипт, который Вы можете запустить локально, чтобы протестировать весь код и сгенерировать отчеты о покрытии тестами в HTML:
<div class="termy">
```console
$ bash scripts/test-cov-html.sh
```
</div>
Эта команда создаст директорию `./htmlcov/`, в которой будет файл `./htmlcov/index.html`. Открыв его в Вашем браузере, Вы можете в интерактивном режиме изучить, все ли части кода охвачены тестами.

180
docs/ru/docs/fastapi-people.md

@ -0,0 +1,180 @@
# Люди, поддерживающие FastAPI
У FastAPI замечательное сообщество, которое доброжелательно к людям с любым уровнем знаний.
## Создатель и хранитель
Ку! 👋
Это я:
{% if people %}
<div class="user-list user-list-center">
{% for user in people.maintainers %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Answers: {{ user.answers }}</div><div class="count">Pull Requests: {{ user.prs }}</div></div>
{% endfor %}
</div>
{% endif %}
Я создал и продолжаю поддерживать **FastAPI**. Узнать обо мне больше можно тут [Помочь FastAPI - Получить помощь - Связаться с автором](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}.
... но на этой странице я хочу показать вам наше сообщество.
---
**FastAPI** получает огромную поддержку от своего сообщества. И я хочу отметить вклад его участников.
Это люди, которые:
* [Помогают другим с их проблемами (вопросами) на GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}.
* [Создают пул-реквесты](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
* Делают ревью пул-реквестов, [что особенно важно для переводов на другие языки](contributing.md#translations){.internal-link target=_blank}.
Поаплодируем им! 👏 🙇
## Самые активные участники за прошедший месяц
Эти участники [оказали наибольшую помощь другим с решением их проблем (вопросов) на GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} в течение последнего месяца. ☕
{% if people %}
<div class="user-list user-list-center">
{% for user in people.last_month_active %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Issues replied: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Эксперты
Здесь представлены **Эксперты FastAPI**. 🤓
Эти участники [оказали наибольшую помощь другим с решением их проблем (вопросов) на GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} за *всё время*.
Оказывая помощь многим другим, они подтвердили свой уровень знаний. ✨
{% if people %}
<div class="user-list user-list-center">
{% for user in people.experts %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Issues replied: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Рейтинг участников, внёсших вклад в код
Здесь представлен **Рейтинг участников, внёсших вклад в код**. 👷
Эти люди [сделали наибольшее количество пул-реквестов](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}, *включённых в основной код*.
Они сделали наибольший вклад в исходный код, документацию, переводы и т.п. 📦
{% if people %}
<div class="user-list user-list-center">
{% for user in people.top_contributors %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Pull Requests: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
На самом деле таких людей довольно много (более сотни), вы можете увидеть всех на этой странице <a href="https://github.com/tiangolo/fastapi/graphs/contributors" class="external-link" target="_blank">FastAPI GitHub Contributors page</a>. 👷
## Рейтинг ревьюеров
Здесь представлен **Рейтинг ревьюеров**. 🕵️
### Проверки переводов на другие языки
Я знаю не очень много языков (и не очень хорошо 😅).
Итак, ревьюеры - это люди, которые могут [**подтвердить предложенный вами перевод** документации](contributing.md#translations){.internal-link target=_blank}. Без них не было бы документации на многих языках.
---
В **Рейтинге ревьюеров** 🕵️ представлены те, кто проверил наибольшее количество пул-реквестов других участников, обеспечивая качество кода, документации и, особенно, **переводов на другие языки**.
{% if people %}
<div class="user-list user-list-center">
{% for user in people.top_reviewers %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Reviews: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Спонсоры
Здесь представлены **Спонсоры**. 😎
Спонсоры поддерживают мою работу над **FastAPI** (и другими проектами) главным образом через <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
{% if sponsors %}
{% if sponsors.gold %}
### Золотые спонсоры
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
{% if sponsors.silver %}
### Серебрянные спонсоры
{% for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
{% if sponsors.bronze %}
### Бронзовые спонсоры
{% for sponsor in sponsors.bronze -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
{% endif %}
### Индивидуальные спонсоры
{% if github_sponsors %}
{% for group in github_sponsors.sponsors %}
<div class="user-list user-list-center">
{% for user in group %}
{% if user.login not in sponsors_badge.logins %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a></div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
{% endif %}
## О данных - технические детали
Основная цель этой страницы - подчеркнуть усилия сообщества по оказанию помощи другим.
Особенно это касается усилий, которые обычно менее заметны и во многих случаях более трудоемки, таких как помощь другим в решении проблем и проверка пул-реквестов с переводами.
Данные рейтинги подсчитываются каждый месяц, ознакомиться с тем, как это работает можно <a href="https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/app/main.py" class="external-link" target="_blank">тут</a>.
Кроме того, я также подчеркиваю вклад спонсоров.
И я оставляю за собой право обновлять алгоритмы подсчёта, виды рейтингов, пороговые значения и т.д. (так, на всякий случай 🤷).

257
docs/ru/docs/help-fastapi.md

@ -0,0 +1,257 @@
# Помочь FastAPI - Получить помощь
Нравится ли Вам **FastAPI**?
Хотели бы Вы помочь FastAPI, его пользователям и автору?
Может быть у Вас возникли трудности с **FastAPI** и Вам нужна помощь?
Есть несколько очень простых способов оказания помощи (иногда достаточно всего лишь одного или двух кликов).
И также есть несколько способов получить помощь.
## Подписаться на новостную рассылку
Вы можете подписаться на редкую [новостную рассылку **FastAPI и его друзья**](/newsletter/){.internal-link target=_blank} и быть в курсе о:
* Новостях о FastAPI и его друзьях 🚀
* Руководствах 📝
* Возможностях ✨
* Исправлениях 🚨
* Подсказках и хитростях ✅
## Подписаться на FastAPI в Twitter
<a href="https://twitter.com/fastapi" class="external-link" target="_blank">Подписаться на @fastapi в **Twitter**</a> для получения наисвежайших новостей о **FastAPI**. 🐦
## Добавить **FastAPI** звезду на GitHub
Вы можете добавить FastAPI "звезду" на GitHub (кликнуть на кнопку звезды в верхнем правом углу экрана): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. ⭐️
Чем больше звёзд, тем легче другим пользователям найти нас и увидеть, что проект уже стал полезным для многих.
## Отслеживать свежие выпуски в репозитории на GitHub
Вы можете "отслеживать" FastAPI на GitHub (кликните по кнопке "watch" наверху справа): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
Там же Вы можете указать в настройках - "Releases only".
С такой настройкой Вы будете получать уведомления на вашу электронную почту каждый раз, когда появится новый релиз (новая версия) **FastAPI** с исправлениями ошибок и новыми возможностями.
## Связаться с автором
Можно связаться со <a href="https://tiangolo.com" class="external-link" target="_blank">мной (Себястьян Рамирез / `tiangolo`)</a>, автором FastAPI.
Вы можете:
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">Подписаться на меня на **GitHub**</a>.
* Посмотреть другие мои проекты с открытым кодом, которые могут быть полезны Вам.
* Подписавшись на меня Вы сможете получать уведомления, что я создал новый проект с открытым кодом,.
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Подписаться на меня в **Twitter**</a> или в <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>.
* Поделиться со мной, как Вы используете FastAPI (я обожаю читать про это).
* Получать уведомления, когда я делаю объявления и представляю новые инструменты.
* Вы также можете <a href="https://twitter.com/fastapi" class="external-link" target="_blank">подписаться на @fastapi в Twitter</a> (это отдельный аккаунт).
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Подписаться на меня в **Linkedin**</a>.
* Получать уведомления, когда я делаю объявления и представляю новые инструменты (правда чаще всего я использую Twitter 🤷‍♂).
* Читать, что я пишу (или подписаться на меня) в <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> или в <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
* Читать другие идеи, статьи и читать об инструментах созданных мной.
* Подпишитесь на меня, чтобы прочитать, когда я опубликую что-нибудь новое.
## Оставить сообщение в Twitter о **FastAPI**
<a href="https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/tiangolo/fastapi" class="external-link" target="_blank">Оставьте сообщение в Twitter о **FastAPI**</a> и позвольте мне и другим узнать - почему он Вам нравится. 🎉
Я люблю узнавать о том, как **FastAPI** используется, что Вам понравилось в нём, в каких проектах/компаниях Вы используете его и т.п.
## Оставить голос за FastAPI
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Голосуйте за **FastAPI** в Slant</a>.
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">Голосуйте за **FastAPI** в AlternativeTo</a>.
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">Расскажите, как Вы используете **FastAPI** на StackShare</a>.
## Помочь другим с их проблемами на GitHub
Вы можете посмотреть, какие <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">проблемы</a> испытывают другие люди и попытаться помочь им. Чаще всего это вопросы, на которые, весьма вероятно, Вы уже знаете ответ. 🤓
Если Вы будете много помогать людям с решением их проблем, Вы можете стать официальным [Экспертом FastAPI](fastapi-people.md#experts){.internal-link target=_blank}. 🎉
Только помните, самое важное при этом - доброта. Столкнувшись с проблемой, люди расстраиваются и часто задают вопросы не лучшим образом, но постарайтесь быть максимально доброжелательным. 🤗
Идея сообщества **FastAPI** в том, чтобы быть добродушным и гостеприимными. Не допускайте издевательств или неуважительного поведения по отношению к другим. Мы должны заботиться друг о друге.
---
Как помочь другим с их проблемами:
### Понять вопрос
* Удостоверьтесь, что поняли **цель** и обстоятельства случая вопрошающего.
* Затем проверьте, что вопрос (в подавляющем большинстве - это вопросы) Вам **ясен**.
* Во многих случаях вопрос касается решения, которое пользователь придумал сам, но может быть и решение **получше**. Если Вы поймёте проблему и обстоятельства случая, то сможете предложить **альтернативное решение**.
* Ежели вопрос Вам непонятен, запросите больше **деталей**.
### Воспроизвести проблему
В большинстве случаев есть что-то связанное с **исходным кодом** вопрошающего.
И во многих случаях будет предоставлен только фрагмент этого кода, которого недостаточно для **воспроизведения проблемы**.
* Попросите предоставить <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">минимальный воспроизводимый пример</a>, который можно **скопировать** и запустить локально дабы увидеть такую же ошибку, или поведение, или лучше понять обстоятельства случая.
* Если на Вас нахлынуло великодушие, то можете попытаться **создать похожий пример** самостоятельно, основываясь только на описании проблемы. Но имейте в виду, что это может занять много времени и, возможно, стоит сначала позадавать вопросы для прояснения проблемы.
### Предложить решение
* После того как Вы поняли вопрос, Вы можете дать **ответ**.
* Следует понять **основную проблему и обстоятельства случая**, потому что может быть решение лучше, чем то, которое пытались реализовать.
### Попросить закрыть проблему
Если Вам ответили, высоки шансы, что Вам удалось решить проблему, поздравляю, **Вы - герой**! 🦸
* В таком случае, если вопрос решён, попросите **закрыть проблему**.
## Отслеживать репозиторий на GitHub
Вы можете "отслеживать" FastAPI на GitHub (кликните по кнопке "watch" наверху справа): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
Если Вы выберете "Watching" вместо "Releases only", то будете получать уведомления когда кто-либо попросит о помощи с решением его проблемы.
Тогда Вы можете попробовать решить эту проблему.
## Запросить помощь с решением проблемы
Вы можете <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">создать новый запрос с просьбой о помощи</a> в репозитории на GitHub, например:
* Задать **вопрос** или попросить помощи в решении **проблемы**.
* Предложить новое **улучшение**.
**Заметка**: Если Вы создаёте подобные запросы, то я попрошу Вас также оказывать аналогичную помощь другим. 😉
## Проверять пул-реквесты
Вы можете помочь мне проверять пул-реквесты других участников.
И повторюсь, постарайтесь быть доброжелательным. 🤗
---
О том, что нужно иметь в виду при проверке пул-реквестов:
### Понять проблему
* Во-первых, убедитесь, что **поняли проблему**, которую пул-реквест пытается решить. Для этого может потребоваться продолжительное обсуждение.
* Также есть вероятность, что пул-реквест не актуален, так как проблему можно решить **другим путём**. В таком случае Вы можете указать на этот факт.
### Не переживайте о стиле
* Не стоит слишком беспокоиться о таких вещах, как стиль сообщений в коммитах или количество коммитов. При слиянии пул-реквеста с основной веткой, я буду сжимать и настраивать всё вручную.
* Также не беспокойтесь о правилах стиля, для проверки сего есть автоматизированные инструменты.
И если всё же потребуется какой-то другой стиль, я попрошу Вас об этом напрямую или добавлю сам коммиты с необходимыми изменениями.
### Проверить код
* Проверьте и прочитайте код, посмотрите, какой он имеет смысл, **запустите его локально** и посмотрите, действительно ли он решает поставленную задачу.
* Затем, используя **комментарий**, сообщите, что Вы сделали проверку, тогда я буду знать, что Вы действительно проверили код.
!!! Информация
К сожалению, я не могу так просто доверять пул-реквестам, у которых уже есть несколько одобрений.
Бывали случаи, что пул-реквесты имели 3, 5 или больше одобрений, вероятно из-за привлекательного описания, но когда я проверял эти пул-реквесты, они оказывались сломаны, содержали ошибки или вовсе не решали проблему, которую, как они утверждали, должны были решить. 😅
Потому это действительно важно - проверять и запускать код, и комментарием уведомлять меня, что Вы проделали эти действия. 🤓
* Если Вы считаете, что пул-реквест можно упростить, то можете попросить об этом, но не нужно быть слишком придирчивым, может быть много субъективных точек зрения (и у меня тоже будет своя 🙈), поэтому будет лучше, если Вы сосредоточитесь на фундаментальных вещах.
### Тестировать
* Помогите мне проверить, что у пул-реквеста есть **тесты**.
* Проверьте, что тесты **падали** до пул-реквеста. 🚨
* Затем проверьте, что тесты **не валятся** после пул-реквеста. ✅
* Многие пул-реквесты не имеют тестов, Вы можете **напомнить** о необходимости добавления тестов или даже **предложить** какие-либо свои тесты. Это одна из тех вещей, которые отнимают много времени и Вы можете помочь с этим.
* Затем добавьте комментарий, что Вы испробовали в ходе проверки. Таким образом я буду знать, как Вы произвели проверку. 🤓
## Создать пул-реквест
Вы можете [сделать вклад](contributing.md){.internal-link target=_blank} в код фреймворка используя пул-реквесты, например:
* Исправить опечатку, которую Вы нашли в документации.
* Поделиться статьёй, видео или подкастом о FastAPI, которые Вы создали или нашли <a href="https://github.com/tiangolo/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">изменив этот файл</a>.
* Убедитесь, что Вы добавили свою ссылку в начало соответствующего раздела.
* Помочь с [переводом документации](contributing.md#translations){.internal-link target=_blank} на Ваш язык.
* Вы также можете проверять переводы сделанные другими.
* Предложить новые разделы документации.
* Исправить существующуе проблемы/баги.
* Убедитесь, что добавили тесты.
* Добавить новую возможность.
* Убедитесь, что добавили тесты.
* Убедитесь, что добавили документацию, если она необходима.
## Помочь поддерживать FastAPI
Помогите мне поддерживать **FastAPI**! 🤓
Предстоит ещё много работы и, по большей части, **ВЫ** можете её сделать.
Основные задачи, которые Вы можете выполнить прямо сейчас:
* [Помочь другим с их проблемами на GitHub](#help-others-with-issues-in-github){.internal-link target=_blank} (смотрите вышестоящую секцию).
* [Проверить пул-реквесты](#review-pull-requests){.internal-link target=_blank} (смотрите вышестоящую секцию).
Эти две задачи **отнимают больше всего времени**. Это основная работа по поддержке FastAPI.
Если Вы можете помочь мне с этим, **Вы помогаете поддерживать FastAPI** и следить за тем, чтобы он продолжал **развиваться быстрее и лучше**. 🚀
## Подключиться к чату
Подключайтесь к 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank"> чату в Discord</a> 👥 и общайтесь с другими участниками сообщества FastAPI.
!!! Подсказка
Вопросы по проблемам с фреймворком лучше задавать в <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">GitHub issues</a>, так больше шансов, что Вы получите помощь от [Экспертов FastAPI](fastapi-people.md#experts){.internal-link target=_blank}.
Используйте этот чат только для бесед на отвлечённые темы.
Существует также <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">чат в Gitter</a>, но поскольку в нем нет каналов и расширенных функций, общение в нём сложнее, потому рекомендуемой системой является Discord.
### Не использовать чаты для вопросов
Имейте в виду, что чаты позволяют больше "свободного общения", потому там легко задавать вопросы, которые слишком общие и на которые труднее ответить, так что Вы можете не получить нужные Вам ответы.
В разделе "проблемы" на GitHub, есть шаблон, который поможет Вам написать вопрос правильно, чтобы Вам было легче получить хороший ответ или даже решить проблему самостоятельно, прежде чем Вы зададите вопрос. В GitHub я могу быть уверен, что всегда отвечаю на всё, даже если это займет какое-то время. И я не могу сделать то же самое в чатах. 😅
Кроме того, общение в чатах не так легкодоступно для поиска, как в GitHub, потому вопросы и ответы могут потеряться среди другого общения. И только проблемы решаемые на GitHub учитываются в получении лычки [Эксперт FastAPI](fastapi-people.md#experts){.internal-link target=_blank}, так что весьма вероятно, что Вы получите больше внимания на GitHub.
С другой стороны, в чатах тысячи пользователей, а значит есть большие шансы в любое время найти там кого-то, с кем можно поговорить. 😄
## Спонсировать автора
Вы также можете оказать мне финансовую поддержку посредством <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">спонсорства через GitHub</a>.
Там можно просто купить мне кофе ☕️ в знак благодарности. 😄
А ещё Вы можете стать Серебряным или Золотым спонсором для FastAPI. 🏅🎉
## Спонсировать инструменты, на которых зиждется мощь FastAPI
Как Вы могли заметить в документации, FastAPI опирается на плечи титанов: Starlette и Pydantic.
Им тоже можно оказать спонсорскую поддержку:
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
---
Благодарствую! 🚀

77
docs/ru/docs/history-design-future.md

@ -0,0 +1,77 @@
# История создания и дальнейшее развитие
Однажды, <a href="https://github.com/tiangolo/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">один из пользователей **FastAPI** задал вопрос</a>:
> Какова история этого проекта? Создаётся впечатление, что он явился из ниоткуда и завоевал мир за несколько недель [...]
Что ж, вот небольшая часть истории проекта.
## Альтернативы
В течение нескольких лет я, возглавляя различные команды разработчиков, создавал довольно сложные API для машинного обучения, распределённых систем, асинхронных задач, баз данных NoSQL и т.д.
В рамках работы над этими проектами я исследовал, проверял и использовал многие фреймворки.
Во многом история **FastAPI** - история его предшественников.
Как написано в разделе [Альтернативы](alternatives.md){.internal-link target=_blank}:
<blockquote markdown="1">
**FastAPI** не существовал бы, если б не было более ранних работ других людей.
Они создали большое количество инструментов, которые и вдохновили меня на создание **FastAPI**.
Я всячески избегал создания нового фреймворка в течение нескольких лет. Сначала я пытался собрать все нужные возможности, которые ныне есть в **FastAPI**, используя множество различных фреймворков, плагинов и инструментов.
Но в какой-то момент не осталось другого выбора, кроме как создать что-то, что предоставляло бы все эти возможности сразу. Взять самые лучшие идеи из предыдущих инструментов и, используя введённые в Python подсказки типов (которых не было до версии 3.6), объединить их.
</blockquote>
## Исследования
Благодаря опыту использования существующих альтернатив, мы с коллегами изучили их основные идеи и скомбинировали собранные знания наилучшим образом.
Например, стало ясно, что необходимо брать за основу стандартные подсказки типов Python, а самым лучшим подходом является использование уже существующих стандартов.
Итак, прежде чем приступить к написанию **FastAPI**, я потратил несколько месяцев на изучение OpenAPI, JSON Schema, OAuth2, и т.п. для понимания их взаимосвязей, совпадений и различий.
## Дизайн
Затем я потратил некоторое время на придумывание "API" разработчика, который я хотел иметь как пользователь (как разработчик, использующий FastAPI).
Я проверил несколько идей на самых популярных редакторах кода среди Python-разработчиков: PyCharm, VS Code, Jedi.
Данные по редакторам я взял из <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">опроса Python-разработчиков</a>, который охватываает около 80% пользователей.
Это означает, что **FastAPI** был специально проверен на редакторах, используемых 80% Python-разработчиками. И поскольку большинство других редакторов, как правило, работают аналогичным образом, все его преимущества должны работать практически для всех редакторов.
Таким образом, я смог найти наилучшие способы сократить дублирование кода, обеспечить повсеместное автодополнение, проверку типов и ошибок и т.д.
И все это, чтобы все пользователи могли получать наилучший опыт разработки.
## Зависимости
Протестировав несколько вариантов, я решил, что в качестве основы буду использовать <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">**Pydantic**</a> и его преимущества.
По моим предложениям был изменён код этого фреймворка, чтобы сделать его полностью совместимым с JSON Schema, поддержать различные способы определения ограничений и улучшить помощь редакторов (проверки типов, автозаполнение).
В то же время, я принимал участие в разработке <a href="https://www.starlette.io/" class="external-link" target="_blank">**Starlette**</a>, ещё один из основных компонентов FastAPI.
## Разработка
К тому времени, когда я начал создавать **FastAPI**, большинство необходимых деталей уже существовало, дизайн был определён, зависимости и прочие инструменты были готовы, а знания о стандартах и спецификациях были четкими и свежими.
## Будущее
Сейчас уже ясно, что **FastAPI** со своими идеями стал полезен многим людям.
При сравнении с альтернативами, выбор падает на него, поскольку он лучше подходит для множества вариантов использования.
Многие разработчики и команды уже используют **FastAPI** в своих проектах (включая меня и мою команду).
Но, тем не менее, грядёт добавление ещё многих улучшений и возможностей.
У **FastAPI** великое будущее.
И [ваш вклад в это](help-fastapi.md){.internal-link target=_blank} - очень ценнен.

69
docs/ru/docs/tutorial/body-fields.md

@ -0,0 +1,69 @@
# Body - Поля
Таким же способом, как вы объявляете дополнительную валидацию и метаданные в параметрах *функции обработки пути* с помощью функций `Query`, `Path` и `Body`, вы можете объявлять валидацию и метаданные внутри Pydantic моделей, используя функцию `Field` из Pydantic.
## Импорт `Field`
Сначала вы должны импортировать его:
=== "Python 3.6 и выше"
```Python hl_lines="4"
{!> ../../../docs_src/body_fields/tutorial001.py!}
```
=== "Python 3.10 и выше"
```Python hl_lines="2"
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
!!! warning "Внимание"
Обратите внимание, что функция `Field` импортируется непосредственно из `pydantic`, а не из `fastapi`, как все остальные функции (`Query`, `Path`, `Body` и т.д.).
## Объявление атрибутов модели
Вы можете использовать функцию `Field` с атрибутами модели:
=== "Python 3.6 и выше"
```Python hl_lines="11-14"
{!> ../../../docs_src/body_fields/tutorial001.py!}
```
=== "Python 3.10 и выше"
```Python hl_lines="9-12"
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
Функция `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 схемы.

49
docs/ru/docs/tutorial/cookie-params.md

@ -0,0 +1,49 @@
# Параметры Cookie
Вы можете задать параметры Cookie таким же способом, как `Query` и `Path` параметры.
## Импорт `Cookie`
Сначала импортируйте `Cookie`:
=== "Python 3.6 и выше"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
```
=== "Python 3.10 и выше"
```Python hl_lines="1"
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
## Объявление параметров `Cookie`
Затем объявляйте параметры cookie, используя ту же структуру, что и с `Path` и `Query`.
Первое значение - это значение по умолчанию, вы можете передать все дополнительные параметры проверки или аннотации:
=== "Python 3.6 и выше"
```Python hl_lines="9"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
```
=== "Python 3.10 и выше"
```Python hl_lines="7"
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
!!! note "Технические детали"
`Cookie` - это класс, родственный `Path` и `Query`. Он также наследуется от общего класса `Param`.
Но помните, что когда вы импортируете `Query`, `Path`, `Cookie` и другое из `fastapi`, это фактически функции, которые возвращают специальные классы.
!!! info "Дополнительная информация"
Для объявления cookies, вам нужно использовать `Cookie`, иначе параметры будут интерпретированы как параметры запроса.
## Резюме
Объявляйте cookies с помощью `Cookie`, используя тот же общий шаблон, что и `Query`, и `Path`.

12
docs/ru/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -62,12 +64,16 @@ nav:
- fastapi-people.md - fastapi-people.md
- python-types.md - python-types.md
- Учебник - руководство пользователя: - Учебник - руководство пользователя:
- tutorial/body-fields.md
- tutorial/background-tasks.md - tutorial/background-tasks.md
- tutorial/cookie-params.md
- async.md - async.md
- Развёртывание: - Развёртывание:
- deployment/index.md - deployment/index.md
- deployment/versions.md - deployment/versions.md
- history-design-future.md
- external-links.md - external-links.md
- contributing.md
markdown_extensions: markdown_extensions:
- toc: - toc:
permalink: true permalink: true
@ -90,7 +96,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -121,6 +127,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -141,6 +149,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/sq/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/sv/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

148
docs/ta/mkdocs.yml

@ -0,0 +1,148 @@
site_name: FastAPI
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
site_url: https://fastapi.tiangolo.com/ta/
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/
- ta: /ta/
- tr: /tr/
- uk: /uk/
- zh: /zh/
markdown_extensions:
- toc:
permalink: true
- markdown.extensions.codehilite:
guess_lang: false
- mdx_include:
base_path: docs
- admonition
- codehilite
- extra
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
- attr_list
- md_in_html
extra:
analytics:
provider: google
property: 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: /ta/
name: ta - தமிழ்
- link: /tr/
name: tr - Türkçe
- link: /uk/
name: uk - українська мова
- link: /zh/
name: zh - 汉语
extra_css:
- https://fastapi.tiangolo.com/css/termynal.css
- https://fastapi.tiangolo.com/css/custom.css
extra_javascript:
- https://fastapi.tiangolo.com/js/termynal.js
- https://fastapi.tiangolo.com/js/custom.js

0
docs/ta/overrides/.gitignore

336
docs/tr/docs/tutorial/first_steps.md

@ -0,0 +1,336 @@
# İlk Adımlar
En basit FastAPI dosyası şu şekildedir:
```Python
{!../../../docs_src/first_steps/tutorial001.py!}
```
Bunu bir `main.py` dosyasına kopyalayın.
Projeyi çalıştırın:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
</div>
!!! note
`uvicorn main:app` komutu şunu ifade eder:
* `main`: `main.py` dosyası (the Python "module").
* `app`: `main.py` dosyası içerisinde `app = FastAPI()` satırıyla oluşturulan nesne.
* `--reload`: Kod değişikliği sonrasında sunucunun yeniden başlatılmasını sağlar. Yalnızca geliştirme için kullanın.
Çıktıda şu şekilde bir satır vardır:
```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 sunulduğu URL'yi gösterir.
### Kontrol Et
Tarayıcınızda <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> adresini açın.
Bir JSON yanıtı göreceksiniz:
```JSON
{"message": "Hello World"}
```
### İnteraktif API dokümantasyonu
<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> adresine gidin.
Otomatik oluşturulmuş( <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tarafından sağlanan) interaktif bir API dokümanı göreceksiniz:
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Alternatif API dokümantasyonu
Şimdi, <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> adresine gidin.
Otomatik oluşturulmuş(<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tarafından sağlanan) bir API dokümanı göreceksiniz:
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
### OpenAPI
**FastAPI**, **OpenAPI** standardını kullanarak tüm API'lerinizi açıklayan bir "şema" oluşturur.
#### "Şema"
Bir "şema", bir şeyin tanımı veya açıklamasıdır. Soyut bir açıklamadır, uygulayan kod değildir.
#### API "şemaları"
Bu durumda, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>, API şemasını nasıl tanımlayacağınızı belirten şartnamelerdir.
Bu şema tanımı, API yollarınızı, aldıkları olası parametreleri vb. içerir.
#### Data "şema"
"Şema" terimi, JSON içeriği gibi bazı verilerin şeklini de ifade edebilir.
Bu durumda, JSON öznitelikleri ve sahip oldukları veri türleri vb. anlamına gelir.
#### OpenAPI and 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` kontrol et
OpenAPI şemasının nasıl göründüğünü merak ediyorsanız, FastAPI otomatik olarak tüm API'nizin açıklamalarını içeren bir JSON (şema) oluşturur.
Doğrudan şu adreste görebilirsiniz: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
Aşağıdaki gibi bir şeyle başlayan bir JSON gösterecektir:
```JSON
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
...
```
#### OpenAPI ne içindir?
OpenAPI şeması, dahili olarak bulunan iki etkileşimli dokümantasyon sistemine güç veren şeydir.
Ve tamamen OpenAPI'ye dayalı düzinelerce alternatif vardır. **FastAPI** ile oluşturulmuş uygulamanıza bu alternatiflerden herhangi birini kolayca ekleyebilirsiniz.
API'nizle iletişim kuran istemciler için otomatik olarak kod oluşturmak için de kullanabilirsiniz. Örneğin, frontend, mobil veya IoT uygulamaları.
## Adım adım özet
### Adım 1: `FastAPI`yi içe aktarın
```Python hl_lines="1"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI`, API'niz için tüm fonksiyonları sağlayan bir Python sınıfıdır.
!!! note "Teknik Detaylar"
`FastAPI` doğrudan `Starlette` kalıtım alan bir sınıftır.
Tüm <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> fonksiyonlarını `FastAPI` ile de kullanabilirsiniz.
### Adım 2: Bir `FastAPI` örneği oluşturun
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Burada `app` değişkeni `FastAPI` sınıfının bir örneği olacaktır.
Bu tüm API'yi oluşturmak için ana etkileşim noktası olacaktır.
`uvicorn` komutunda atıfta bulunulan `app` ile aynıdır.
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Uygulamanızı aşağıdaki gibi oluşturursanız:
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial002.py!}
```
Ve bunu `main.py` dosyasına koyduktan sonra `uvicorn` komutunu şu şekilde çağırabilirsiniz:
<div class="termy">
```console
$ uvicorn main:my_awesome_api --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Adım 3: *Path işlemleri* oluşturmak
#### Path
Burada "Path" URL'de ilk "\" ile başlayan son bölümü ifade eder.
Yani, şu şekilde bir URL'de:
```
https://example.com/items/foo
```
... path şöyle olabilir:
```
/items/foo
```
!!! info
Genellikle bir "path", "endpoint" veya "route" olarak adlandırılabilir.
Bir API oluştururken, "path", "resource" ile "concern" ayırmanın ana yoludur.
#### İşlemler
Burada "işlem" HTTP methodlarından birini ifade eder.
Onlardan biri:
* `POST`
* `GET`
* `PUT`
* `DELETE`
... ve daha egzotik olanları:
* `OPTIONS`
* `HEAD`
* `PATCH`
* `TRACE`
HTTP protokolünde, bu "methodlardan" birini (veya daha fazlasını) kullanarak her path ile iletişim kurabilirsiniz.
---
API'lerinizi oluştururkan, belirli bir işlemi gerçekleştirirken belirli HTTP methodları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'de HTTP methodlarından her birine "işlem" denir.
Bizde onlara "**işlemler**" diyeceğiz.
#### Bir *Path işlem decoratorleri* tanımlanmak
```Python hl_lines="6"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`@app.get("/")` **FastAPI'ye** aşağıdaki fonksiyonun adresine giden istekleri işlemekten sorumlu olduğunu söyler:
* path `/`
* <abbr title="an HTTP GET method"><code>get</code> işlemi</abbr> kullanılarak
!!! info "`@decorator` Bilgisi"
Python `@something` şeklinde ifadeleri "decorator" olarak adlandırır.
Decoratoru bir fonksiyonun üzerine koyarsınız. Dekoratif bir şapka gibi (Sanırım terim buradan gelmektedir).
Bir "decorator" fonksiyonu alır ve bazı işlemler gerçekleştir.
Bizim durumumzda decarator **FastAPI'ye** fonksiyonun bir `get` işlemi ile `/` pathine geldiğini söyler.
Bu **path işlem decoratordür**
Ayrıca diğer işlemleri de kullanabilirsiniz:
* `@app.post()`
* `@app.put()`
* `@app.delete()`
Ve daha egzotik olanları:
* `@app.options()`
* `@app.head()`
* `@app.patch()`
* `@app.trace()`
!!! tip
Her işlemi (HTTP method) istediğiniz gibi kullanmakta özgürsünüz.
**FastAPI** herhangi bir özel anlamı zorlamaz.
Buradaki bilgiler bir gereklilik değil, bir kılavuz olarak sunulmaktadır.
Örneğin, GraphQL kullanırkan normalde tüm işlemleri yalnızca `POST` işlemini kullanarak gerçekleştirirsiniz.
### Adım 4: **path işlem fonksiyonunu** tanımlayın
Aşağıdakiler bizim **path işlem fonksiyonlarımızdır**:
* **path**: `/`
* **işlem**: `get`
* **function**: "decorator"ün altındaki fonksiyondur (`@app.get("/")` altında).
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Bu bir Python fonksiyonudur.
Bir `GET` işlemi kullanarak "`/`" URL'sine bir istek geldiğinde **FastAPI** tarafından çağrılır.
Bu durumda bir `async` fonksiyonudur.
---
Bunu `async def` yerine normal bir fonksiyon olarakta tanımlayabilirsiniz.
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial003.py!}
```
!!! note
Eğer farkı bilmiyorsanız, [Async: *"Acelesi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} kontrol edebilirsiniz.
### Adım 5: İçeriği geri döndürün
```Python hl_lines="8"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Bir `dict`, `list` döndürebilir veya `str`, `int` gibi tekil değerler döndürebilirsiniz.
Ayrıca, Pydantic modellerini de döndürebilirsiniz. (Bununla ilgili daha sonra ayrıntılı bilgi göreceksiniz.)
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`'yi içe aktarın.
* Bir `app` örneği oluşturun.
* **path işlem decorator** yazın. (`@app.get("/")` gibi)
* **path işlem fonksiyonu** yazın. (`def root(): ...` gibi)
* Development sunucunuzu çalıştırın. (`uvicorn main:app --reload` gibi)

10
docs/tr/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,12 +56,15 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
- features.md - features.md
- fastapi-people.md - fastapi-people.md
- python-types.md - python-types.md
- Tutorial - User Guide:
- tutorial/first-steps.md
markdown_extensions: markdown_extensions:
- toc: - toc:
permalink: true permalink: true
@ -83,7 +87,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -114,6 +118,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -134,6 +140,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

8
docs/uk/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -80,7 +82,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -111,6 +113,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -131,6 +135,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

2
docs/zh/docs/benchmarks.md

@ -1,6 +1,6 @@
# 基准测试 # 基准测试
第三方机构 TechEmpower 的基准测试表明在 Uvicorn 下运行的 **FastAPI** 应用程序是 <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">可用的最快的 Python 框架之一</a>,仅次 Starlette 和 Uvicorn 本身 (由 FastAPI 内部使用)。(*) 第三方机构 TechEmpower 的基准测试表明在 Uvicorn 下运行的 **FastAPI** 应用程序是 <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">可用的最快的 Python 框架之一</a>,仅次 Starlette 和 Uvicorn 本身 (由 FastAPI 内部使用)。(*)
但是在查看基准得分和对比时,请注意以下几点。 但是在查看基准得分和对比时,请注意以下几点。

2
docs/zh/docs/index.md

@ -28,7 +28,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
关键特性: 关键特性:
* **快速**:可与 **NodeJS****Go** 肩的极高性能(归功于 Starlette 和 Pydantic)。[最快的 Python web 框架之一](#_11)。 * **快速**:可与 **NodeJS****Go** 肩的极高性能(归功于 Starlette 和 Pydantic)。[最快的 Python web 框架之一](#_11)。
* **高效编码**:提高功能开发速度约 200% 至 300%。* * **高效编码**:提高功能开发速度约 200% 至 300%。*
* **更少 bug**:减少约 40% 的人为(开发者)导致错误。* * **更少 bug**:减少约 40% 的人为(开发者)导致错误。*

8
docs/zh/mkdocs.yml

@ -45,6 +45,7 @@ nav:
- fa: /fa/ - fa: /fa/
- fr: /fr/ - fr: /fr/
- he: /he/ - he: /he/
- hy: /hy/
- id: /id/ - id: /id/
- it: /it/ - it: /it/
- ja: /ja/ - ja: /ja/
@ -55,6 +56,7 @@ nav:
- ru: /ru/ - ru: /ru/
- sq: /sq/ - sq: /sq/
- sv: /sv/ - sv: /sv/
- ta: /ta/
- tr: /tr/ - tr: /tr/
- uk: /uk/ - uk: /uk/
- zh: /zh/ - zh: /zh/
@ -137,7 +139,7 @@ markdown_extensions:
extra: extra:
analytics: analytics:
provider: google provider: google
property: UA-133183413-1 property: G-YNEVN69SC3
social: social:
- icon: fontawesome/brands/github-alt - icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi link: https://github.com/tiangolo/fastapi
@ -168,6 +170,8 @@ extra:
name: fr - français name: fr - français
- link: /he/ - link: /he/
name: he name: he
- link: /hy/
name: hy
- link: /id/ - link: /id/
name: id name: id
- link: /it/ - link: /it/
@ -188,6 +192,8 @@ extra:
name: sq - shqip name: sq - shqip
- link: /sv/ - link: /sv/
name: sv - svenska name: sv - svenska
- link: /ta/
name: ta - தமிழ்
- link: /tr/ - link: /tr/
name: tr - Türkçe name: tr - Türkçe
- link: /uk/ - link: /uk/

2
docs_src/app_testing/tutorial002.py

@ -10,7 +10,7 @@ async def read_main():
return {"msg": "Hello World"} return {"msg": "Hello World"}
@app.websocket_route("/ws") @app.websocket("/ws")
async def websocket(websocket: WebSocket): async def websocket(websocket: WebSocket):
await websocket.accept() await websocket.accept()
await websocket.send_json({"msg": "Hello WebSocket"}) await websocket.send_json({"msg": "Hello WebSocket"})

2
docs_src/body_multiple_params/tutorial004.py

@ -25,7 +25,7 @@ async def update_item(
item: Item, item: Item,
user: User, user: User,
importance: int = Body(gt=0), importance: int = Body(gt=0),
q: Union[str, None] = None q: Union[str, None] = None,
): ):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance} results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
if q: if q:

2
docs_src/body_multiple_params/tutorial004_py310.py

@ -23,7 +23,7 @@ async def update_item(
item: Item, item: Item,
user: User, user: User,
importance: int = Body(gt=0), importance: int = Body(gt=0),
q: str | None = None q: str | None = None,
): ):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance} results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
if q: if q:

28
docs_src/events/tutorial003.py

@ -0,0 +1,28 @@
from contextlib import asynccontextmanager
from fastapi import FastAPI
def fake_answer_to_everything_ml_model(x: float):
return x * 42
ml_models = {}
@asynccontextmanager
async def lifespan(app: FastAPI):
# Load the ML model
ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
yield
# Clean up the ML models and release the resources
ml_models.clear()
app = FastAPI(lifespan=lifespan)
@app.get("/predict")
async def predict(x: float):
result = ml_models["answer_to_everything"](x)
return {"result": result}

2
docs_src/path_params_numeric_validations/tutorial006.py

@ -8,7 +8,7 @@ async def read_items(
*, *,
item_id: int = Path(title="The ID of the item to get", ge=0, le=1000), item_id: int = Path(title="The ID of the item to get", ge=0, le=1000),
q: str, q: str,
size: float = Query(gt=0, lt=10.5) size: float = Query(gt=0, lt=10.5),
): ):
results = {"item_id": item_id} results = {"item_id": item_id}
if q: if q:

12
docs_src/response_model/tutorial001.py

@ -1,4 +1,4 @@
from typing import List, Union from typing import Any, List, Union
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel from pydantic import BaseModel
@ -15,5 +15,13 @@ class Item(BaseModel):
@app.post("/items/", response_model=Item) @app.post("/items/", response_model=Item)
async def create_item(item: Item): async def create_item(item: Item) -> Any:
return item return item
@app.get("/items/", response_model=List[Item])
async def read_items() -> Any:
return [
{"name": "Portal Gun", "price": 42.0},
{"name": "Plumbus", "price": 32.0},
]

27
docs_src/response_model/tutorial001_01.py

@ -0,0 +1,27 @@
from typing import List, Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: List[str] = []
@app.post("/items/")
async def create_item(item: Item) -> Item:
return item
@app.get("/items/")
async def read_items() -> List[Item]:
return [
Item(name="Portal Gun", price=42.0),
Item(name="Plumbus", price=32.0),
]

25
docs_src/response_model/tutorial001_01_py310.py

@ -0,0 +1,25 @@
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: list[str] = []
@app.post("/items/")
async def create_item(item: Item) -> Item:
return item
@app.get("/items/")
async def read_items() -> list[Item]:
return [
Item(name="Portal Gun", price=42.0),
Item(name="Plumbus", price=32.0),
]

27
docs_src/response_model/tutorial001_01_py39.py

@ -0,0 +1,27 @@
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: list[str] = []
@app.post("/items/")
async def create_item(item: Item) -> Item:
return item
@app.get("/items/")
async def read_items() -> list[Item]:
return [
Item(name="Portal Gun", price=42.0),
Item(name="Plumbus", price=32.0),
]

12
docs_src/response_model/tutorial001_py310.py

@ -1,3 +1,5 @@
from typing import Any
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel from pydantic import BaseModel
@ -13,5 +15,13 @@ class Item(BaseModel):
@app.post("/items/", response_model=Item) @app.post("/items/", response_model=Item)
async def create_item(item: Item): async def create_item(item: Item) -> Any:
return item return item
@app.get("/items/", response_model=list[Item])
async def read_items() -> Any:
return [
{"name": "Portal Gun", "price": 42.0},
{"name": "Plumbus", "price": 32.0},
]

12
docs_src/response_model/tutorial001_py39.py

@ -1,4 +1,4 @@
from typing import Union from typing import Any, Union
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel from pydantic import BaseModel
@ -15,5 +15,13 @@ class Item(BaseModel):
@app.post("/items/", response_model=Item) @app.post("/items/", response_model=Item)
async def create_item(item: Item): async def create_item(item: Item) -> Any:
return item return item
@app.get("/items/", response_model=list[Item])
async def read_items() -> Any:
return [
{"name": "Portal Gun", "price": 42.0},
{"name": "Plumbus", "price": 32.0},
]

4
docs_src/response_model/tutorial002.py

@ -14,6 +14,6 @@ class UserIn(BaseModel):
# Don't do this in production! # Don't do this in production!
@app.post("/user/", response_model=UserIn) @app.post("/user/")
async def create_user(user: UserIn): async def create_user(user: UserIn) -> UserIn:
return user return user

4
docs_src/response_model/tutorial002_py310.py

@ -12,6 +12,6 @@ class UserIn(BaseModel):
# Don't do this in production! # Don't do this in production!
@app.post("/user/", response_model=UserIn) @app.post("/user/")
async def create_user(user: UserIn): async def create_user(user: UserIn) -> UserIn:
return user return user

4
docs_src/response_model/tutorial003.py

@ -1,4 +1,4 @@
from typing import Union from typing import Any, Union
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel, EmailStr from pydantic import BaseModel, EmailStr
@ -20,5 +20,5 @@ class UserOut(BaseModel):
@app.post("/user/", response_model=UserOut) @app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn): async def create_user(user: UserIn) -> Any:
return user return user

21
docs_src/response_model/tutorial003_01.py

@ -0,0 +1,21 @@
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class BaseUser(BaseModel):
username: str
email: EmailStr
full_name: Union[str, None] = None
class UserIn(BaseUser):
password: str
@app.post("/user/")
async def create_user(user: UserIn) -> BaseUser:
return user

19
docs_src/response_model/tutorial003_01_py310.py

@ -0,0 +1,19 @@
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class BaseUser(BaseModel):
username: str
email: EmailStr
full_name: str | None = None
class UserIn(BaseUser):
password: str
@app.post("/user/")
async def create_user(user: UserIn) -> BaseUser:
return user

11
docs_src/response_model/tutorial003_02.py

@ -0,0 +1,11 @@
from fastapi import FastAPI, Response
from fastapi.responses import JSONResponse, RedirectResponse
app = FastAPI()
@app.get("/portal")
async def get_portal(teleport: bool = False) -> Response:
if teleport:
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
return JSONResponse(content={"message": "Here's your interdimensional portal."})

9
docs_src/response_model/tutorial003_03.py

@ -0,0 +1,9 @@
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/teleport")
async def get_teleport() -> RedirectResponse:
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")

13
docs_src/response_model/tutorial003_04.py

@ -0,0 +1,13 @@
from typing import Union
from fastapi import FastAPI, Response
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/portal")
async def get_portal(teleport: bool = False) -> Union[Response, dict]:
if teleport:
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
return {"message": "Here's your interdimensional portal."}

11
docs_src/response_model/tutorial003_04_py310.py

@ -0,0 +1,11 @@
from fastapi import FastAPI, Response
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/portal")
async def get_portal(teleport: bool = False) -> Response | dict:
if teleport:
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
return {"message": "Here's your interdimensional portal."}

13
docs_src/response_model/tutorial003_05.py

@ -0,0 +1,13 @@
from typing import Union
from fastapi import FastAPI, Response
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/portal", response_model=None)
async def get_portal(teleport: bool = False) -> Union[Response, dict]:
if teleport:
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
return {"message": "Here's your interdimensional portal."}

11
docs_src/response_model/tutorial003_05_py310.py

@ -0,0 +1,11 @@
from fastapi import FastAPI, Response
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/portal", response_model=None)
async def get_portal(teleport: bool = False) -> Response | dict:
if teleport:
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
return {"message": "Here's your interdimensional portal."}

4
docs_src/response_model/tutorial003_py310.py

@ -1,3 +1,5 @@
from typing import Any
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel, EmailStr from pydantic import BaseModel, EmailStr
@ -18,5 +20,5 @@ class UserOut(BaseModel):
@app.post("/user/", response_model=UserOut) @app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn): async def create_user(user: UserIn) -> Any:
return user return user

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save