mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-25 15:18:36 -05:00
Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b6e198d31 | ||
|
|
6ac35b1c2a | ||
|
|
dc9c570733 | ||
|
|
20d4834546 | ||
|
|
f7d7c6c865 | ||
|
|
c03b9b2d4c | ||
|
|
70f1b8ebd0 | ||
|
|
13bf477579 | ||
|
|
ab5afd0b42 | ||
|
|
b5dcd98605 | ||
|
|
2280a48c67 | ||
|
|
8c5d1f30dc | ||
|
|
98a0fe8628 | ||
|
|
38c52fa12d | ||
|
|
7c2ed25d6f | ||
|
|
dda105c50d | ||
|
|
326837443f | ||
|
|
cb5b4e1b7e | ||
|
|
a23eaaeda8 | ||
|
|
d0ced2c7c9 | ||
|
|
3409c9e32f | ||
|
|
53a86a885d | ||
|
|
4ac310875d | ||
|
|
30e742d566 | ||
|
|
84490a2160 | ||
|
|
4d4452ede5 | ||
|
|
25a48287ed | ||
|
|
9a33a0e24c | ||
|
|
27fd954a45 | ||
|
|
ab33ba27af | ||
|
|
e9ba01dc59 | ||
|
|
e809bdc170 | ||
|
|
717a1ec409 | ||
|
|
eba2c66532 | ||
|
|
3788ca4640 | ||
|
|
97fa743ecb | ||
|
|
e726b7b771 | ||
|
|
6a22b75afd | ||
|
|
4093d9b22a | ||
|
|
18daf8f301 | ||
|
|
962578bec2 | ||
|
|
85cff59109 | ||
|
|
b869c7c872 | ||
|
|
016c3f0d5b | ||
|
|
4eb9c60652 | ||
|
|
8879757a88 | ||
|
|
fadfcfda4a | ||
|
|
b8c4149e89 | ||
|
|
836bb97a2d | ||
|
|
7db359182d | ||
|
|
4eada92883 | ||
|
|
6a74f3a0c1 | ||
|
|
daa0765653 | ||
|
|
27e26b5939 | ||
|
|
6f45f43709 | ||
|
|
6c80e9a8e0 | ||
|
|
3b2e891917 | ||
|
|
9121fccf55 | ||
|
|
fa2c750443 | ||
|
|
29e7b31ee6 | ||
|
|
bb6c6ed5d1 | ||
|
|
1a5273773e | ||
|
|
3f40c37905 | ||
|
|
996dfd05bd | ||
|
|
0a1dd7894c | ||
|
|
dbfd3f7e18 | ||
|
|
a0209a0d2c | ||
|
|
099aab79e6 | ||
|
|
7dc5b94d45 | ||
|
|
684c0077cc | ||
|
|
75d8a6b5c2 | ||
|
|
96fdfc53cc | ||
|
|
49517d3310 | ||
|
|
9355cc4eaa | ||
|
|
1ce59152e7 | ||
|
|
1241f7f0b7 | ||
|
|
fd74c0f6a4 | ||
|
|
e4eac12c34 | ||
|
|
b235653a6c | ||
|
|
4cb4bdb984 | ||
|
|
ba596152d9 | ||
|
|
a1227624c8 | ||
|
|
9ce1ae771c | ||
|
|
b9fed9b485 | ||
|
|
0d97e1f97d | ||
|
|
1ce7258a01 | ||
|
|
bcd06fdfdf | ||
|
|
fc35b7d18d | ||
|
|
8c12ab0d5b | ||
|
|
38194a29bc | ||
|
|
6b65de6033 | ||
|
|
f80230d654 | ||
|
|
f6cc418d79 | ||
|
|
3ce9407093 | ||
|
|
ef1716c39e | ||
|
|
9ab7da6562 | ||
|
|
fcfff5e8e5 | ||
|
|
67ef62a4dd | ||
|
|
7741635b3b | ||
|
|
3d81bc638b | ||
|
|
c1801738b0 | ||
|
|
ba84f167f5 | ||
|
|
0a38c51b9e | ||
|
|
db5b2bdf56 | ||
|
|
5ac84120b3 | ||
|
|
2d296c5d07 | ||
|
|
71c96d9eb9 | ||
|
|
5342a0a00f | ||
|
|
163b086f21 | ||
|
|
0876d3df1d | ||
|
|
50baf5e804 | ||
|
|
3d6da2c32d | ||
|
|
e721d04350 | ||
|
|
8cc6f9baac | ||
|
|
dfd453e001 | ||
|
|
7e9d5aacf8 | ||
|
|
d27a218bc3 | ||
|
|
0c4ded88fe | ||
|
|
0e0931d308 | ||
|
|
dcfa9eb8fe | ||
|
|
6ebf60b175 | ||
|
|
a4d0724a97 | ||
|
|
c235e9b78c | ||
|
|
5fa3e239db | ||
|
|
3d1b107d70 | ||
|
|
18e0828daf | ||
|
|
f16c7729bd | ||
|
|
9f3c8cd139 | ||
|
|
a7a35aee61 | ||
|
|
dc5a966548 | ||
|
|
ea8d7f689e | ||
|
|
0ed6c92341 |
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1 +1,4 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Security Contact
|
||||
about: Please report security vulnerabilities to security@tiangolo.com
|
||||
|
||||
181
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
181
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
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.
|
||||
104
.github/ISSUE_TEMPLATE/feature_request.md
vendored
104
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,104 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ""
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### First check
|
||||
|
||||
* [ ] I added a very descriptive title to this issue.
|
||||
* [ ] I used the GitHub search to find a similar issue and didn't find it.
|
||||
* [ ] I searched the FastAPI documentation, with the integrated search.
|
||||
* [ ] I already searched in Google "How to X in FastAPI" and didn't find any information.
|
||||
* [ ] I already read and followed all the tutorial in the docs and didn't find an answer.
|
||||
* [ ] I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
|
||||
* [ ] I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
|
||||
* [ ] I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
|
||||
* [ ] After submitting this, I commit to:
|
||||
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
|
||||
* Or, 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.
|
||||
|
||||
<!--
|
||||
|
||||
I'm asking all this because answering questions and solving problems in GitHub issues consumes a lot of 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 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 😅).
|
||||
|
||||
-->
|
||||
|
||||
### Example
|
||||
|
||||
Here's a self-contained [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with my use case:
|
||||
|
||||
<!-- Replace the code below with your own self-contained, minimal, reproducible, example -->
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
<!-- Replace the content below with your own feature request -->
|
||||
|
||||
* 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.
|
||||
|
||||
### The solution you would like
|
||||
|
||||
<!-- Replace this with your own content -->
|
||||
|
||||
I would like it to have a `teleport_to_moon` parameter that defaults to `False`, and can be set to `True` to teleport me:
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/", teleport_to_moon=True)
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
```
|
||||
|
||||
### Describe alternatives you've considered
|
||||
|
||||
<!-- Replace this with your own ideas -->
|
||||
|
||||
To wait for Space X moon travel plans to drop down long after they release them. But I would rather teleport.
|
||||
|
||||
### Environment
|
||||
|
||||
* OS: [e.g. Linux / Windows / macOS]:
|
||||
* FastAPI Version [e.g. 0.3.0]:
|
||||
|
||||
To know the FastAPI version use:
|
||||
|
||||
```bash
|
||||
python -c "import fastapi; print(fastapi.__version__)"
|
||||
```
|
||||
|
||||
* Python version:
|
||||
|
||||
To know the Python version use:
|
||||
|
||||
```bash
|
||||
python --version
|
||||
```
|
||||
|
||||
### Additional context
|
||||
|
||||
<!-- Add any other context or screenshots about the question here. -->
|
||||
81
.github/ISSUE_TEMPLATE/question.md
vendored
81
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,81 +0,0 @@
|
||||
---
|
||||
name: Question or Problem
|
||||
about: Ask a question or ask about a problem
|
||||
title: ""
|
||||
labels: question
|
||||
assignees: ""
|
||||
|
||||
---
|
||||
|
||||
### First check
|
||||
|
||||
* [ ] I added a very descriptive title to this issue.
|
||||
* [ ] I used the GitHub search to find a similar issue and didn't find it.
|
||||
* [ ] I searched the FastAPI documentation, with the integrated search.
|
||||
* [ ] I already searched in Google "How to X in FastAPI" and didn't find any information.
|
||||
* [ ] I already read and followed all the tutorial in the docs and didn't find an answer.
|
||||
* [ ] I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
|
||||
* [ ] I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
|
||||
* [ ] I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
|
||||
* [ ] 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.
|
||||
|
||||
<!--
|
||||
|
||||
I'm asking all this because answering questions and solving problems in GitHub issues consumes a lot of 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 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 😅).
|
||||
|
||||
-->
|
||||
|
||||
### Example
|
||||
|
||||
Here's a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with my use case:
|
||||
|
||||
<!-- Replace the code below with your own self-contained, minimal, reproducible, example, 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 -->
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
<!-- Replace the content below with your own problem, question, or error -->
|
||||
|
||||
* Open the browser and call the endpoint `/`.
|
||||
* It returns a JSON with `{"Hello": "World"}`.
|
||||
* But I expected it to return `{"Hello": "Sara"}`.
|
||||
|
||||
### Environment
|
||||
|
||||
* OS: [e.g. Linux / Windows / macOS]:
|
||||
* FastAPI Version [e.g. 0.3.0]:
|
||||
|
||||
To know the FastAPI version use:
|
||||
|
||||
```bash
|
||||
python -c "import fastapi; print(fastapi.__version__)"
|
||||
```
|
||||
|
||||
* Python version:
|
||||
|
||||
To know the Python version use:
|
||||
|
||||
```bash
|
||||
python --version
|
||||
```
|
||||
|
||||
### Additional context
|
||||
|
||||
<!-- Add any other context or screenshots about the question here. -->
|
||||
146
.github/ISSUE_TEMPLATE/question.yml
vendored
Normal file
146
.github/ISSUE_TEMPLATE/question.yml
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
name: Question or Problem
|
||||
description: Ask a question or ask about a problem
|
||||
labels: [question]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your interest in FastAPI! 🚀
|
||||
|
||||
Please follow these instructions, fill every question, and do every step. 🙏
|
||||
|
||||
I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the time.
|
||||
|
||||
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling issues.
|
||||
|
||||
All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
|
||||
|
||||
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
|
||||
|
||||
By asking questions in a structured way (following this) it will be much easier to help you.
|
||||
|
||||
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
|
||||
|
||||
As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: First Check
|
||||
description: Please confirm and check all the following options.
|
||||
options:
|
||||
- label: I added a very descriptive title to this issue.
|
||||
required: true
|
||||
- label: I used the GitHub search to find a similar issue and didn't find it.
|
||||
required: true
|
||||
- label: I searched the FastAPI documentation, with the integrated search.
|
||||
required: true
|
||||
- label: I already searched in Google "How to X in FastAPI" and didn't find any information.
|
||||
required: true
|
||||
- label: I already read and followed all the tutorial in the docs and didn't find an answer.
|
||||
required: true
|
||||
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
|
||||
required: true
|
||||
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
|
||||
required: true
|
||||
- label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: help
|
||||
attributes:
|
||||
label: Commit to Help
|
||||
description: |
|
||||
After submitting this, I commit to one of:
|
||||
|
||||
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
|
||||
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
|
||||
* Implement a Pull Request for a confirmed bug.
|
||||
|
||||
options:
|
||||
- label: I commit to help with one of those options 👆
|
||||
required: true
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: Example Code
|
||||
description: |
|
||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
|
||||
|
||||
If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
|
||||
|
||||
placeholder: |
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
render: python
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
What is the problem, question, or error?
|
||||
|
||||
Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
|
||||
placeholder: |
|
||||
* Open the browser and call the endpoint `/`.
|
||||
* It returns a JSON with `{"Hello": "World"}`.
|
||||
* But I expected it to return `{"Hello": "Sara"}`.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: What operating system are you on?
|
||||
multiple: true
|
||||
options:
|
||||
- Linux
|
||||
- Windows
|
||||
- macOS
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: os-details
|
||||
attributes:
|
||||
label: Operating System Details
|
||||
description: You can add more details about your operating system here, in particular if you chose "Other".
|
||||
- type: input
|
||||
id: fastapi-version
|
||||
attributes:
|
||||
label: FastAPI Version
|
||||
description: |
|
||||
What FastAPI version are you using?
|
||||
|
||||
You can find the FastAPI version with:
|
||||
|
||||
```bash
|
||||
python -c "import fastapi; print(fastapi.__version__)"
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: python-version
|
||||
attributes:
|
||||
label: Python Version
|
||||
description: |
|
||||
What Python version are you using?
|
||||
|
||||
You can find the Python version with:
|
||||
|
||||
```bash
|
||||
python --version
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Add any additional context information or screenshots you think are useful.
|
||||
7
.github/actions/notify-translations/Dockerfile
vendored
Normal file
7
.github/actions/notify-translations/Dockerfile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
10
.github/actions/notify-translations/action.yml
vendored
Normal file
10
.github/actions/notify-translations/action.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
name: "Notify Translations"
|
||||
description: "Notify in the issue for a translation when there's a new PR available"
|
||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||
inputs:
|
||||
token:
|
||||
description: 'Token, to read the GitHub API. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
87
.github/actions/notify-translations/app/main.py
vendored
Normal file
87
.github/actions/notify-translations/app/main.py
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
|
||||
import yaml
|
||||
from github import Github
|
||||
from pydantic import BaseModel, BaseSettings, SecretStr
|
||||
|
||||
awaiting_label = "awaiting review"
|
||||
lang_all_label = "lang-all"
|
||||
approved_label = "approved-2"
|
||||
translations_path = Path(__file__).parent / "translations.yml"
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
github_repository: str
|
||||
input_token: SecretStr
|
||||
github_event_path: Path
|
||||
github_event_name: Optional[str] = None
|
||||
input_debug: Optional[bool] = False
|
||||
|
||||
|
||||
class PartialGitHubEventIssue(BaseModel):
|
||||
number: int
|
||||
|
||||
|
||||
class PartialGitHubEvent(BaseModel):
|
||||
pull_request: PartialGitHubEventIssue
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
settings = Settings()
|
||||
if settings.input_debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.debug(f"Using config: {settings.json()}")
|
||||
g = Github(settings.input_token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
if not settings.github_event_path.is_file():
|
||||
raise RuntimeError(
|
||||
f"No github event file available at: {settings.github_event_path}"
|
||||
)
|
||||
contents = settings.github_event_path.read_text()
|
||||
github_event = PartialGitHubEvent.parse_raw(contents)
|
||||
translations_map: Dict[str, int] = yaml.safe_load(translations_path.read_text())
|
||||
logging.debug(f"Using translations map: {translations_map}")
|
||||
pr = repo.get_pull(github_event.pull_request.number)
|
||||
logging.debug(f"Processing PR: {pr.number}")
|
||||
if pr.state == "open":
|
||||
logging.debug(f"PR is open: {pr.number}")
|
||||
label_strs = set([label.name for label in pr.get_labels()])
|
||||
if lang_all_label in label_strs and awaiting_label in label_strs:
|
||||
logging.info(
|
||||
f"This PR seems to be a language translation and awaiting reviews: {pr.number}"
|
||||
)
|
||||
if approved_label in label_strs:
|
||||
message = (
|
||||
f"It seems this PR already has the approved label: {pr.number}"
|
||||
)
|
||||
logging.error(message)
|
||||
raise RuntimeError(message)
|
||||
langs = []
|
||||
for label in label_strs:
|
||||
if label.startswith("lang-") and not label == lang_all_label:
|
||||
langs.append(label[5:])
|
||||
for lang in langs:
|
||||
if lang in translations_map:
|
||||
num = translations_map[lang]
|
||||
logging.info(f"Found a translation issue for language: {lang} in issue: {num}")
|
||||
issue = repo.get_issue(num)
|
||||
message = f"Good news everyone! 😉 There's a new translation PR to be reviewed: #{pr.number} 🎉"
|
||||
already_notified = False
|
||||
logging.info(f"Checking current comments in issue: {num} to see if already notified about this PR: {pr.number}")
|
||||
for comment in issue.get_comments():
|
||||
if message in comment.body:
|
||||
already_notified = True
|
||||
if not already_notified:
|
||||
logging.info(f"Writing comment in issue: {num} about PR: {pr.number}")
|
||||
issue.create_comment(message)
|
||||
else:
|
||||
logging.info(f"Issue: {num} was already notified of PR: {pr.number}")
|
||||
else:
|
||||
logging.info(
|
||||
f"Changing labels in a closed PR doesn't trigger comments, PR: {pr.number}"
|
||||
)
|
||||
logging.info("Finished")
|
||||
14
.github/actions/notify-translations/app/translations.yml
vendored
Normal file
14
.github/actions/notify-translations/app/translations.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
pt: 1211
|
||||
es: 1218
|
||||
zh: 1228
|
||||
ru: 1362
|
||||
it: 1556
|
||||
ja: 1572
|
||||
uk: 1748
|
||||
tr: 1892
|
||||
fr: 1972
|
||||
ko: 2017
|
||||
sq: 2041
|
||||
pl: 3169
|
||||
de: 3716
|
||||
id: 3717
|
||||
24
.github/actions/people/app/main.py
vendored
24
.github/actions/people/app/main.py
vendored
@@ -476,21 +476,16 @@ if __name__ == "__main__":
|
||||
)
|
||||
|
||||
tiers = get_individual_sponsors(settings=settings)
|
||||
sponsors_50 = []
|
||||
for login, sponsor in tiers[50].items():
|
||||
sponsors_50.append(
|
||||
{"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
|
||||
)
|
||||
keys = list(tiers.keys())
|
||||
keys.sort(reverse=True)
|
||||
sponsors = []
|
||||
for key in keys:
|
||||
if key >= 50:
|
||||
continue
|
||||
sponsor_group = []
|
||||
for login, sponsor in tiers[key].items():
|
||||
sponsors.append(
|
||||
sponsor_group.append(
|
||||
{"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
|
||||
)
|
||||
sponsors.append(sponsor_group)
|
||||
|
||||
people = {
|
||||
"maintainers": maintainers,
|
||||
@@ -498,16 +493,21 @@ if __name__ == "__main__":
|
||||
"last_month_active": last_month_active,
|
||||
"top_contributors": top_contributors,
|
||||
"top_reviewers": top_reviewers,
|
||||
"sponsors_50": sponsors_50,
|
||||
}
|
||||
github_sponsors = {
|
||||
"sponsors": sponsors,
|
||||
}
|
||||
people_path = Path("./docs/en/data/people.yml")
|
||||
github_sponsors_path = Path("./docs/en/data/github_sponsors.yml")
|
||||
people_old_content = people_path.read_text(encoding="utf-8")
|
||||
new_content = yaml.dump(people, sort_keys=False, width=200, allow_unicode=True)
|
||||
if people_old_content == new_content:
|
||||
github_sponsors_old_content = github_sponsors_path.read_text(encoding="utf-8")
|
||||
new_people_content = yaml.dump(people, sort_keys=False, width=200, allow_unicode=True)
|
||||
new_github_sponsors_content = yaml.dump(github_sponsors, sort_keys=False, width=200, allow_unicode=True)
|
||||
if people_old_content == new_people_content and github_sponsors_old_content == new_github_sponsors_content:
|
||||
logging.info("The FastAPI People data hasn't changed, finishing.")
|
||||
sys.exit(0)
|
||||
people_path.write_text(new_content, encoding="utf-8")
|
||||
people_path.write_text(new_people_content, encoding="utf-8")
|
||||
github_sponsors_path.write_text(new_github_sponsors_content, encoding="utf-8")
|
||||
logging.info("Setting up GitHub Actions git user")
|
||||
subprocess.run(["git", "config", "user.name", "github-actions"], check=True)
|
||||
subprocess.run(
|
||||
|
||||
2
.github/workflows/build-docs.yml
vendored
2
.github/workflows/build-docs.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
jobs:
|
||||
build:
|
||||
build-docs:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
|
||||
15
.github/workflows/latest-changes.yml
vendored
15
.github/workflows/latest-changes.yml
vendored
@@ -11,12 +11,27 @@ on:
|
||||
number:
|
||||
description: PR number
|
||||
required: true
|
||||
debug_enabled:
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
latest-changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
# To allow latest-changes to commit to master
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: docker://tiangolo/latest-changes:0.0.3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
21
.github/workflows/notify-translations.yml
vendored
Normal file
21
.github/workflows/notify-translations.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Notify Translations
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
notify-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- uses: ./.github/actions/notify-translations
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
2
.github/workflows/preview-docs.yml
vendored
2
.github/workflows/preview-docs.yml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
preview-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -10,9 +10,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
fail-fast: false
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
|
||||
@@ -44,11 +44,12 @@ The key features are:
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
<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://bit.ly/2QSouzH" target="_blank" title="Jina: build neural search-as-a-service for any kind of data in just minutes."><img src="https://fastapi.tiangolo.com/img/sponsors/jina.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.vim.so/?utm_source=FastAPI" target="_blank" title="We help you master vim with interactive exercises"><img src="https://fastapi.tiangolo.com/img/sponsors/vimso.png"></a>
|
||||
<a href="https://talkpython.fm/fastapi-sponsor" 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>
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
|
||||
467
docs/de/docs/index.md
Normal file
467
docs/de/docs/index.md
Normal file
@@ -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" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi?color=%2334D058" 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>
|
||||
</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.6+ based on standard Python type hints.
|
||||
|
||||
The key features are:
|
||||
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
|
||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
|
||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Intuitive**: Great editor support. <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.6+
|
||||
|
||||
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://gitlab.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 Optional
|
||||
|
||||
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: Optional[str] = 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 Optional
|
||||
|
||||
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: Optional[str] = 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>):
|
||||
|
||||

|
||||
|
||||
### 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>):
|
||||
|
||||

|
||||
|
||||
## 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 Optional
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Optional[bool] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = 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:
|
||||
|
||||

|
||||
|
||||
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
|
||||
|
||||

|
||||
|
||||
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
|
||||
And now, go to <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:
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.6+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
or for a more complex `Item` model:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...and with that single declaration you get:
|
||||
|
||||
* Editor support, including:
|
||||
* Completion.
|
||||
* Type checks.
|
||||
* Validation of data:
|
||||
* Automatic and clear errors when the data is invalid.
|
||||
* Validation even for deeply nested JSON objects.
|
||||
* <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:
|
||||
|
||||

|
||||
|
||||
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).
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* **GraphQL**
|
||||
* extremely easy tests based on `requests` 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://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <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://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
|
||||
* <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.
|
||||
125
docs/de/mkdocs.yml
Normal file
125
docs/de/mkdocs.yml
Normal file
@@ -0,0 +1,125 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/de/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to light mode
|
||||
- scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: de
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- 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
|
||||
extra:
|
||||
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: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- 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/de/overrides/.gitignore
vendored
Normal file
0
docs/de/overrides/.gitignore
vendored
Normal file
@@ -1,258 +1,278 @@
|
||||
articles:
|
||||
english:
|
||||
- link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59
|
||||
title: FastAPI/Starlette debug vs prod
|
||||
author_link: https://medium.com/@williamhayes
|
||||
author: William Hayes
|
||||
- link: https://medium.com/data-rebels/fastapi-google-as-an-external-authentication-provider-3a527672cf33
|
||||
title: FastAPI — Google as an external authentication provider
|
||||
author_link: https://medium.com/@nilsdebruin
|
||||
author: Nils de Bruin
|
||||
- link: https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3
|
||||
title: FastAPI — How to add basic and cookie authentication
|
||||
author_link: https://medium.com/@nilsdebruin
|
||||
author: Nils de Bruin
|
||||
- link: https://dev.to/errietta/introduction-to-the-fastapi-python-framework-2n10
|
||||
title: Introduction to the fastapi python framework
|
||||
author_link: https://dev.to/errietta
|
||||
author: Errieta Kostala
|
||||
- link: https://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
|
||||
title: "FastAPI and Scikit-Learn: Easily Deploy Models"
|
||||
author_link: https://nickc1.github.io/
|
||||
author: Nick Cortale
|
||||
- link: https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680
|
||||
title: "FastAPI authentication revisited: Enabling API key authentication"
|
||||
author_link: https://medium.com/@nilsdebruin
|
||||
author: Nils de Bruin
|
||||
- link: https://medium.com/@nico.axtmann95/deploying-a-scikit-learn-model-with-onnx-und-fastapi-1af398268915
|
||||
title: Deploying a scikit-learn model with ONNX and FastAPI
|
||||
author_link: https://www.linkedin.com/in/nico-axtmann
|
||||
author: Nico Axtmann
|
||||
- link: https://geekflare.com/python-asynchronous-web-frameworks/
|
||||
title: Top 5 Asynchronous Web Frameworks for Python
|
||||
author_link: https://geekflare.com/author/ankush/
|
||||
author: Ankush Thakur
|
||||
- link: https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e
|
||||
title: JWT Authentication with FastAPI and AWS Cognito
|
||||
author_link: https://twitter.com/gntrm
|
||||
author: Johannes Gontrum
|
||||
- link: https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf
|
||||
title: How to Deploy a Machine Learning Model
|
||||
author_link: https://www.linkedin.com/in/mgrootendorst/
|
||||
author: Maarten Grootendorst
|
||||
- link: https://eng.uber.com/ludwig-v0-2/
|
||||
title: "Uber: Ludwig v0.2 Adds New Features and Other Improvements to its Deep Learning Toolbox [including a FastAPI server]"
|
||||
author_link: https://eng.uber.com
|
||||
author: Uber Engineering
|
||||
- link: https://gitlab.com/euri10/fastapi_cheatsheet
|
||||
title: A FastAPI and Swagger UI visual cheatsheet
|
||||
author_link: https://gitlab.com/euri10
|
||||
author: "@euri10"
|
||||
- link: https://medium.com/@mike.p.moritz/using-docker-compose-to-deploy-a-lightweight-python-rest-api-with-a-job-queue-37e6072a209b
|
||||
title: Using Docker Compose to deploy a lightweight Python REST API with a job queue
|
||||
author_link: https://medium.com/@mike.p.moritz
|
||||
author: Mike Moritz
|
||||
- link: https://robwagner.dev/tortoise-fastapi-setup/
|
||||
title: Setting up Tortoise ORM with FastAPI
|
||||
author_link: https://robwagner.dev/
|
||||
author: Rob Wagner
|
||||
- link: https://dev.to/dbanty/why-i-m-leaving-flask-3ki6
|
||||
title: Why I'm Leaving Flask
|
||||
author_link: https://dev.to/dbanty
|
||||
author: Dylan Anthony
|
||||
- link: https://medium.com/python-data/how-to-deploy-tensorflow-2-0-models-as-an-api-service-with-fastapi-docker-128b177e81f3
|
||||
title: How To Deploy Tensorflow 2.0 Models As An API Service With FastAPI & Docker
|
||||
author_link: https://medium.com/@bbrenyah
|
||||
author: Bernard Brenyah
|
||||
- link: https://testdriven.io/blog/fastapi-crud/
|
||||
title: "TestDriven.io: Developing and Testing an Asynchronous API with FastAPI and Pytest"
|
||||
author_link: https://testdriven.io/authors/herman
|
||||
author: Michael Herman
|
||||
- link: https://towardsdatascience.com/deploying-iris-classifications-with-fastapi-and-docker-7c9b83fdec3a
|
||||
title: "Towards Data Science: Deploying Iris Classifications with FastAPI and Docker"
|
||||
author_link: https://towardsdatascience.com/@mandygu
|
||||
author: Mandy Gu
|
||||
- link: https://medium.com/analytics-vidhya/deploy-machine-learning-models-with-keras-fastapi-redis-and-docker-4940df614ece
|
||||
title: Deploy Machine Learning Models with Keras, FastAPI, Redis and Docker
|
||||
author_link: https://medium.com/@shane.soh
|
||||
author: Shane Soh
|
||||
- link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb
|
||||
title: "Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest"
|
||||
author_link: https://twitter.com/arthurheinrique
|
||||
author: Arthur Henrique
|
||||
- link: https://iwpnd.pw/articles/2020-01/deploy-fastapi-to-aws-lambda
|
||||
title: How to continuously deploy a FastAPI to AWS Lambda with AWS SAM
|
||||
author_link: https://iwpnd.pw
|
||||
author: Benjamin Ramser
|
||||
- link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/
|
||||
title: Create and Deploy FastAPI app to Heroku without using Docker
|
||||
author_link: https://www.linkedin.com/in/navule/
|
||||
author: Navule Pavan Kumar Rao
|
||||
- link: https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream
|
||||
title: Apache Kafka producer and consumer with FastAPI and aiokafka
|
||||
author_link: https://iwpnd.pw
|
||||
author: Benjamin Ramser
|
||||
- link: https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/
|
||||
title: Real-time Notifications with Python and Postgres
|
||||
author_link: https://wuilly.com/
|
||||
author: Guillermo Cruz
|
||||
- link: https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc
|
||||
title: Microservice in Python using FastAPI
|
||||
author_link: https://twitter.com/PaurakhSharma
|
||||
author: Paurakh Sharma Humagain
|
||||
- link: https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o
|
||||
title: Build simple API service with Python FastAPI — Part 1
|
||||
author_link: https://dev.to/cuongld2
|
||||
author: cuongld2
|
||||
- link: https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/
|
||||
title: FastAPI + Zeit.co = 🚀
|
||||
author_link: https://twitter.com/PaulWebSec
|
||||
author: Paul Sec
|
||||
- link: https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe
|
||||
title: Build a web API from scratch with FastAPI - the workshop
|
||||
author_link: https://twitter.com/tiangolo
|
||||
author: Sebastián Ramírez (tiangolo)
|
||||
- link: https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi
|
||||
title: Build a Secure Twilio Webhook with Python and FastAPI
|
||||
author_link: https://www.twilio.com
|
||||
author: Twilio
|
||||
- link: https://www.stavros.io/posts/fastapi-with-django/
|
||||
title: Using FastAPI with Django
|
||||
author_link: https://twitter.com/Stavros
|
||||
author: Stavros Korokithakis
|
||||
- link: https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072
|
||||
title: Introducing Dispatch
|
||||
author_link: https://netflixtechblog.com/
|
||||
author: Netflix
|
||||
- link: https://davidefiocco.github.io/streamlit-fastapi-ml-serving/
|
||||
title: Machine learning model serving in Python using FastAPI and streamlit
|
||||
author_link: https://github.com/davidefiocco
|
||||
author: Davide Fiocco
|
||||
- link: https://www.tutlinks.com/deploy-fastapi-on-azure/
|
||||
title: Deploy FastAPI on Azure App Service
|
||||
author_link: https://www.linkedin.com/in/navule/
|
||||
author: Navule Pavan Kumar Rao
|
||||
- link: https://towardsdatascience.com/build-and-host-fast-data-science-applications-using-fastapi-823be8a1d6a0
|
||||
title: Build And Host Fast Data Science Applications Using FastAPI
|
||||
author_link: https://medium.com/@farhadmalik
|
||||
author: Farhad Malik
|
||||
- link: https://medium.com/@gabbyprecious2000/creating-a-crud-app-with-fastapi-part-one-7c049292ad37
|
||||
title: Creating a CRUD App with FastAPI (Part one)
|
||||
author_link: https://medium.com/@gabbyprecious2000
|
||||
author: Precious Ndubueze
|
||||
- link: https://julienharbulot.com/notification-server.html
|
||||
title: HTTP server to display desktop notifications
|
||||
author_link: https://julienharbulot.com/
|
||||
author: Julien Harbulot
|
||||
- link: https://guitton.co/posts/fastapi-monitoring/
|
||||
title: How to monitor your FastAPI service
|
||||
author_link: https://twitter.com/louis_guitton
|
||||
author: Louis Guitton
|
||||
- link: https://amitness.com/2020/06/fastapi-vs-flask/
|
||||
title: FastAPI for Flask Users
|
||||
author_link: https://twitter.com/amitness
|
||||
author: Amit Chaudhary
|
||||
- link: https://valonjanuzaj.medium.com/deploy-a-dockerized-fastapi-application-to-aws-cc757830ba1b
|
||||
title: Deploy a dockerized FastAPI application to AWS
|
||||
author_link: https://www.linkedin.com/in/valon-januzaj-b02692187/
|
||||
author: Valon Januzaj
|
||||
- link: https://dompatmore.com/blog/authenticate-your-fastapi-app-with-auth0
|
||||
title: Authenticate Your FastAPI App with auth0
|
||||
author_link: https://twitter.com/dompatmore
|
||||
author: Dom Patmore
|
||||
japanese:
|
||||
- link: https://qiita.com/mtitg/items/47770e9a562dd150631d
|
||||
title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築
|
||||
author_link: https://qiita.com/mtitg
|
||||
author: "@mtitg"
|
||||
- link: https://qiita.com/ryoryomaru/items/59958ed385b3571d50de
|
||||
title: python製の最新APIフレームワーク FastAPI を触ってみた
|
||||
author_link: https://qiita.com/ryoryomaru
|
||||
author: "@ryoryomaru"
|
||||
- link: https://qiita.com/angel_katayoku/items/0e1f5dbbe62efc612a78
|
||||
title: FastAPIでCORSを回避
|
||||
author_link: https://qiita.com/angel_katayoku
|
||||
author: "@angel_katayoku"
|
||||
- link: https://qiita.com/angel_katayoku/items/4fbc1a4e2b33fa2237d2
|
||||
title: FastAPIをMySQLと接続してDockerで管理してみる
|
||||
author_link: https://qiita.com/angel_katayoku
|
||||
author: "@angel_katayoku"
|
||||
- link: https://qiita.com/angel_katayoku/items/8a458a8952f50b73f420
|
||||
title: FastAPIでPOSTされたJSONのレスポンスbodyを受け取る
|
||||
author_link: https://qiita.com/angel_katayoku
|
||||
author: "@angel_katayoku"
|
||||
- link: https://qiita.com/hikarut/items/b178af2e2440c67c6ac4
|
||||
title: フロントエンド開発者向けのDockerによるPython開発環境構築
|
||||
author_link: https://qiita.com/hikarut
|
||||
author: Hikaru Takahashi
|
||||
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment
|
||||
title: "【第1回】FastAPIチュートリアル: ToDoアプリを作ってみよう【環境構築編】"
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
author: ライトコードメディア編集部
|
||||
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-model-building
|
||||
title: "【第2回】FastAPIチュートリアル: ToDoアプリを作ってみよう【モデル構築編】"
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
author: ライトコードメディア編集部
|
||||
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-authentication-user-registration
|
||||
title: "【第3回】FastAPIチュートリアル: toDoアプリを作ってみよう【認証・ユーザ登録編】"
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
author: ライトコードメディア編集部
|
||||
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-admin-page-improvement
|
||||
title: "【第4回】FastAPIチュートリアル: toDoアプリを作ってみよう【管理者ページ改良編】"
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
author: ライトコードメディア編集部
|
||||
- link: https://qiita.com/bee2/items/0ad260ab9835a2087dae
|
||||
title: PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)
|
||||
author_link: https://qiita.com/bee2
|
||||
author: "@bee2"
|
||||
- link: https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9
|
||||
title: "[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する"
|
||||
author_link: https://qiita.com/bee2
|
||||
author: "@bee2"
|
||||
vietnamese:
|
||||
- link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
|
||||
title: "FASTAPI: TRIỂN KHAI BẰNG DOCKER"
|
||||
author_link: https://fullstackstation.com/author/figonking/
|
||||
author: Nguyễn Nhân
|
||||
russian:
|
||||
- link: https://habr.com/ru/post/454440/
|
||||
title: "Мелкая питонячая радость #2: Starlette - Солидная примочка – FastAPI"
|
||||
author_link: https://habr.com/ru/users/57uff3r/
|
||||
author: Andrey Korchak
|
||||
- link: https://habr.com/ru/post/478620/
|
||||
title: Почему Вы должны попробовать FastAPI?
|
||||
author_link: https://github.com/prostomarkeloff
|
||||
author: prostomarkeloff
|
||||
- link: https://trkohler.com/fast-api-introduction-to-framework
|
||||
title: "FastAPI: знакомимся с фреймворком"
|
||||
author_link: https://www.linkedin.com/in/trkohler/
|
||||
author: Troy Köhler
|
||||
- author: "@pystar"
|
||||
author_link: https://pystar.substack.com/
|
||||
link: https://pystar.substack.com/p/how-to-create-a-fake-certificate
|
||||
title: How to Create A Fake Certificate Authority And Generate TLS Certs for FastAPI
|
||||
- author: Shahriyar(Shako) Rzayev
|
||||
author_link: https://www.linkedin.com/in/shahriyar-rzayev/
|
||||
link: https://www.azepug.az/posts/fastapi/#building-simple-e-commerce-with-nuxtjs-and-fastapi-series
|
||||
title: Building simple E-Commerce with NuxtJS and FastAPI
|
||||
- author: Rodrigo Arenas
|
||||
author_link: https://rodrigo-arenas.medium.com/
|
||||
link: https://medium.com/analytics-vidhya/serve-a-machine-learning-model-using-sklearn-fastapi-and-docker-85aabf96729b
|
||||
title: "Serve a machine learning model using Sklearn, FastAPI and Docker"
|
||||
- author: Navule Pavan Kumar Rao
|
||||
author_link: https://www.linkedin.com/in/navule/
|
||||
link: https://www.tutlinks.com/deploy-fastapi-on-ubuntu-gunicorn-caddy-2/
|
||||
title: Deploy FastAPI on Ubuntu and Serve using Caddy 2 Web Server
|
||||
- author: Patrick Ladon
|
||||
author_link: https://dev.to/factorlive
|
||||
link: https://dev.to/factorlive/python-facebook-messenger-webhook-with-fastapi-on-glitch-4n90
|
||||
title: Python Facebook messenger webhook with FastAPI on Glitch
|
||||
- author: Dom Patmore
|
||||
author_link: https://twitter.com/dompatmore
|
||||
link: https://dompatmore.com/blog/authenticate-your-fastapi-app-with-auth0
|
||||
title: Authenticate Your FastAPI App with auth0
|
||||
- author: Valon Januzaj
|
||||
author_link: https://www.linkedin.com/in/valon-januzaj-b02692187/
|
||||
link: https://valonjanuzaj.medium.com/deploy-a-dockerized-fastapi-application-to-aws-cc757830ba1b
|
||||
title: Deploy a dockerized FastAPI application to AWS
|
||||
- author: Amit Chaudhary
|
||||
author_link: https://twitter.com/amitness
|
||||
link: https://amitness.com/2020/06/fastapi-vs-flask/
|
||||
title: FastAPI for Flask Users
|
||||
- author: Louis Guitton
|
||||
author_link: https://twitter.com/louis_guitton
|
||||
link: https://guitton.co/posts/fastapi-monitoring/
|
||||
title: How to monitor your FastAPI service
|
||||
- author: Julien Harbulot
|
||||
author_link: https://julienharbulot.com/
|
||||
link: https://julienharbulot.com/notification-server.html
|
||||
title: HTTP server to display desktop notifications
|
||||
- author: Precious Ndubueze
|
||||
author_link: https://medium.com/@gabbyprecious2000
|
||||
link: https://medium.com/@gabbyprecious2000/creating-a-crud-app-with-fastapi-part-one-7c049292ad37
|
||||
title: Creating a CRUD App with FastAPI (Part one)
|
||||
- author: Farhad Malik
|
||||
author_link: https://medium.com/@farhadmalik
|
||||
link: https://towardsdatascience.com/build-and-host-fast-data-science-applications-using-fastapi-823be8a1d6a0
|
||||
title: Build And Host Fast Data Science Applications Using FastAPI
|
||||
- author: Navule Pavan Kumar Rao
|
||||
author_link: https://www.linkedin.com/in/navule/
|
||||
link: https://www.tutlinks.com/deploy-fastapi-on-azure/
|
||||
title: Deploy FastAPI on Azure App Service
|
||||
- author: Davide Fiocco
|
||||
author_link: https://github.com/davidefiocco
|
||||
link: https://davidefiocco.github.io/streamlit-fastapi-ml-serving/
|
||||
title: Machine learning model serving in Python using FastAPI and streamlit
|
||||
- author: Netflix
|
||||
author_link: https://netflixtechblog.com/
|
||||
link: https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072
|
||||
title: Introducing Dispatch
|
||||
- author: Stavros Korokithakis
|
||||
author_link: https://twitter.com/Stavros
|
||||
link: https://www.stavros.io/posts/fastapi-with-django/
|
||||
title: Using FastAPI with Django
|
||||
- author: Twilio
|
||||
author_link: https://www.twilio.com
|
||||
link: https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi
|
||||
title: Build a Secure Twilio Webhook with Python and FastAPI
|
||||
- author: Sebastián Ramírez (tiangolo)
|
||||
author_link: https://twitter.com/tiangolo
|
||||
link: https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe
|
||||
title: Build a web API from scratch with FastAPI - the workshop
|
||||
- author: Paul Sec
|
||||
author_link: https://twitter.com/PaulWebSec
|
||||
link: https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/
|
||||
title: FastAPI + Zeit.co = 🚀
|
||||
- author: cuongld2
|
||||
author_link: https://dev.to/cuongld2
|
||||
link: https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o
|
||||
title: Build simple API service with Python FastAPI — Part 1
|
||||
- author: Paurakh Sharma Humagain
|
||||
author_link: https://twitter.com/PaurakhSharma
|
||||
link: https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc
|
||||
title: Microservice in Python using FastAPI
|
||||
- author: Guillermo Cruz
|
||||
author_link: https://wuilly.com/
|
||||
link: https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/
|
||||
title: Real-time Notifications with Python and Postgres
|
||||
- author: Benjamin Ramser
|
||||
author_link: https://iwpnd.pw
|
||||
link: https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream
|
||||
title: Apache Kafka producer and consumer with FastAPI and aiokafka
|
||||
- author: Navule Pavan Kumar Rao
|
||||
author_link: https://www.linkedin.com/in/navule/
|
||||
link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/
|
||||
title: Create and Deploy FastAPI app to Heroku without using Docker
|
||||
- author: Benjamin Ramser
|
||||
author_link: https://iwpnd.pw
|
||||
link: https://iwpnd.pw/articles/2020-01/deploy-fastapi-to-aws-lambda
|
||||
title: How to continuously deploy a FastAPI to AWS Lambda with AWS SAM
|
||||
- author: Arthur Henrique
|
||||
author_link: https://twitter.com/arthurheinrique
|
||||
link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb
|
||||
title: 'Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest'
|
||||
- author: Shane Soh
|
||||
author_link: https://medium.com/@shane.soh
|
||||
link: https://medium.com/analytics-vidhya/deploy-machine-learning-models-with-keras-fastapi-redis-and-docker-4940df614ece
|
||||
title: Deploy Machine Learning Models with Keras, FastAPI, Redis and Docker
|
||||
- author: Mandy Gu
|
||||
author_link: https://towardsdatascience.com/@mandygu
|
||||
link: https://towardsdatascience.com/deploying-iris-classifications-with-fastapi-and-docker-7c9b83fdec3a
|
||||
title: 'Towards Data Science: Deploying Iris Classifications with FastAPI and Docker'
|
||||
- author: Michael Herman
|
||||
author_link: https://testdriven.io/authors/herman
|
||||
link: https://testdriven.io/blog/fastapi-crud/
|
||||
title: 'TestDriven.io: Developing and Testing an Asynchronous API with FastAPI and Pytest'
|
||||
- author: Bernard Brenyah
|
||||
author_link: https://medium.com/@bbrenyah
|
||||
link: https://medium.com/python-data/how-to-deploy-tensorflow-2-0-models-as-an-api-service-with-fastapi-docker-128b177e81f3
|
||||
title: How To Deploy Tensorflow 2.0 Models As An API Service With FastAPI & Docker
|
||||
- author: Dylan Anthony
|
||||
author_link: https://dev.to/dbanty
|
||||
link: https://dev.to/dbanty/why-i-m-leaving-flask-3ki6
|
||||
title: Why I'm Leaving Flask
|
||||
- author: Rob Wagner
|
||||
author_link: https://robwagner.dev/
|
||||
link: https://robwagner.dev/tortoise-fastapi-setup/
|
||||
title: Setting up Tortoise ORM with FastAPI
|
||||
- author: Mike Moritz
|
||||
author_link: https://medium.com/@mike.p.moritz
|
||||
link: https://medium.com/@mike.p.moritz/using-docker-compose-to-deploy-a-lightweight-python-rest-api-with-a-job-queue-37e6072a209b
|
||||
title: Using Docker Compose to deploy a lightweight Python REST API with a job queue
|
||||
- author: '@euri10'
|
||||
author_link: https://gitlab.com/euri10
|
||||
link: https://gitlab.com/euri10/fastapi_cheatsheet
|
||||
title: A FastAPI and Swagger UI visual cheatsheet
|
||||
- author: Uber Engineering
|
||||
author_link: https://eng.uber.com
|
||||
link: https://eng.uber.com/ludwig-v0-2/
|
||||
title: 'Uber: Ludwig v0.2 Adds New Features and Other Improvements to its Deep Learning Toolbox [including a FastAPI server]'
|
||||
- author: Maarten Grootendorst
|
||||
author_link: https://www.linkedin.com/in/mgrootendorst/
|
||||
link: https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf
|
||||
title: How to Deploy a Machine Learning Model
|
||||
- author: Johannes Gontrum
|
||||
author_link: https://twitter.com/gntrm
|
||||
link: https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e
|
||||
title: JWT Authentication with FastAPI and AWS Cognito
|
||||
- author: Ankush Thakur
|
||||
author_link: https://geekflare.com/author/ankush/
|
||||
link: https://geekflare.com/python-asynchronous-web-frameworks/
|
||||
title: Top 5 Asynchronous Web Frameworks for Python
|
||||
- author: Nico Axtmann
|
||||
author_link: https://www.linkedin.com/in/nico-axtmann
|
||||
link: https://medium.com/@nico.axtmann95/deploying-a-scikit-learn-model-with-onnx-und-fastapi-1af398268915
|
||||
title: Deploying a scikit-learn model with ONNX and FastAPI
|
||||
- author: Nils de Bruin
|
||||
author_link: https://medium.com/@nilsdebruin
|
||||
link: https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680
|
||||
title: 'FastAPI authentication revisited: Enabling API key authentication'
|
||||
- author: Nick Cortale
|
||||
author_link: https://nickc1.github.io/
|
||||
link: https://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
|
||||
title: 'FastAPI and Scikit-Learn: Easily Deploy Models'
|
||||
- author: Errieta Kostala
|
||||
author_link: https://dev.to/errietta
|
||||
link: https://dev.to/errietta/introduction-to-the-fastapi-python-framework-2n10
|
||||
title: Introduction to the fastapi python framework
|
||||
- author: Nils de Bruin
|
||||
author_link: https://medium.com/@nilsdebruin
|
||||
link: https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3
|
||||
title: FastAPI — How to add basic and cookie authentication
|
||||
- author: Nils de Bruin
|
||||
author_link: https://medium.com/@nilsdebruin
|
||||
link: https://medium.com/data-rebels/fastapi-google-as-an-external-authentication-provider-3a527672cf33
|
||||
title: FastAPI — Google as an external authentication provider
|
||||
- author: William Hayes
|
||||
author_link: https://medium.com/@williamhayes
|
||||
link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59
|
||||
title: FastAPI/Starlette debug vs prod
|
||||
german:
|
||||
- link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
|
||||
title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI
|
||||
author_link: https://twitter.com/_nicoax
|
||||
author: Nico Axtmann
|
||||
- author: Nico Axtmann
|
||||
author_link: https://twitter.com/_nicoax
|
||||
link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
|
||||
title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI
|
||||
japanese:
|
||||
- author: '@bee2'
|
||||
author_link: https://qiita.com/bee2
|
||||
link: https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9
|
||||
title: '[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する'
|
||||
- author: '@bee2'
|
||||
author_link: https://qiita.com/bee2
|
||||
link: https://qiita.com/bee2/items/0ad260ab9835a2087dae
|
||||
title: PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)
|
||||
- author: ライトコードメディア編集部
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-admin-page-improvement
|
||||
title: '【第4回】FastAPIチュートリアル: toDoアプリを作ってみよう【管理者ページ改良編】'
|
||||
- author: ライトコードメディア編集部
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-authentication-user-registration
|
||||
title: '【第3回】FastAPIチュートリアル: toDoアプリを作ってみよう【認証・ユーザ登録編】'
|
||||
- author: ライトコードメディア編集部
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-model-building
|
||||
title: '【第2回】FastAPIチュートリアル: ToDoアプリを作ってみよう【モデル構築編】'
|
||||
- author: ライトコードメディア編集部
|
||||
author_link: https://rightcode.co.jp/author/jun
|
||||
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment
|
||||
title: '【第1回】FastAPIチュートリアル: ToDoアプリを作ってみよう【環境構築編】'
|
||||
- author: Hikaru Takahashi
|
||||
author_link: https://qiita.com/hikarut
|
||||
link: https://qiita.com/hikarut/items/b178af2e2440c67c6ac4
|
||||
title: フロントエンド開発者向けのDockerによるPython開発環境構築
|
||||
- author: '@angel_katayoku'
|
||||
author_link: https://qiita.com/angel_katayoku
|
||||
link: https://qiita.com/angel_katayoku/items/8a458a8952f50b73f420
|
||||
title: FastAPIでPOSTされたJSONのレスポンスbodyを受け取る
|
||||
- author: '@angel_katayoku'
|
||||
author_link: https://qiita.com/angel_katayoku
|
||||
link: https://qiita.com/angel_katayoku/items/4fbc1a4e2b33fa2237d2
|
||||
title: FastAPIをMySQLと接続してDockerで管理してみる
|
||||
- author: '@angel_katayoku'
|
||||
author_link: https://qiita.com/angel_katayoku
|
||||
link: https://qiita.com/angel_katayoku/items/0e1f5dbbe62efc612a78
|
||||
title: FastAPIでCORSを回避
|
||||
- author: '@ryoryomaru'
|
||||
author_link: https://qiita.com/ryoryomaru
|
||||
link: https://qiita.com/ryoryomaru/items/59958ed385b3571d50de
|
||||
title: python製の最新APIフレームワーク FastAPI を触ってみた
|
||||
- author: '@mtitg'
|
||||
author_link: https://qiita.com/mtitg
|
||||
link: https://qiita.com/mtitg/items/47770e9a562dd150631d
|
||||
title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築
|
||||
russian:
|
||||
- author: Troy Köhler
|
||||
author_link: https://www.linkedin.com/in/trkohler/
|
||||
link: https://trkohler.com/fast-api-introduction-to-framework
|
||||
title: 'FastAPI: знакомимся с фреймворком'
|
||||
- author: prostomarkeloff
|
||||
author_link: https://github.com/prostomarkeloff
|
||||
link: https://habr.com/ru/post/478620/
|
||||
title: Почему Вы должны попробовать FastAPI?
|
||||
- author: Andrey Korchak
|
||||
author_link: https://habr.com/ru/users/57uff3r/
|
||||
link: https://habr.com/ru/post/454440/
|
||||
title: 'Мелкая питонячая радость #2: Starlette - Солидная примочка – FastAPI'
|
||||
vietnamese:
|
||||
- author: Nguyễn Nhân
|
||||
author_link: https://fullstackstation.com/author/figonking/
|
||||
link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
|
||||
title: 'FASTAPI: TRIỂN KHAI BẰNG DOCKER'
|
||||
podcasts:
|
||||
english:
|
||||
- link: https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855
|
||||
title: FastAPI on PythonBytes
|
||||
author_link: https://pythonbytes.fm/
|
||||
author: Python Bytes FM
|
||||
- link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
|
||||
title: "Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)"
|
||||
author_link: https://www.pythonpodcast.com/
|
||||
author: Podcast.`__init__`
|
||||
- author: Podcast.`__init__`
|
||||
author_link: https://www.pythonpodcast.com/
|
||||
link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
|
||||
title: Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)
|
||||
- author: Python Bytes FM
|
||||
author_link: https://pythonbytes.fm/
|
||||
link: https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855
|
||||
title: FastAPI on PythonBytes
|
||||
talks:
|
||||
english:
|
||||
- link: https://www.youtube.com/watch?v=3DLwPcrE5mA
|
||||
title: "PyCon UK 2019: FastAPI from the ground up"
|
||||
author_link: https://twitter.com/chriswithers13
|
||||
author: Chris Withers
|
||||
- link: https://www.youtube.com/watch?v=z9K5pwb0rt8
|
||||
title: "PyConBY 2020: Serve ML models easily with FastAPI"
|
||||
author_link: https://twitter.com/tiangolo
|
||||
author: "Sebastián Ramírez (tiangolo)"
|
||||
- link: https://www.youtube.com/watch?v=PnpTY1f4k2U
|
||||
title: "[VIRTUAL] Py.Amsterdam's flying Software Circus: Intro to FastAPI"
|
||||
author_link: https://twitter.com/tiangolo
|
||||
author: "Sebastián Ramírez (tiangolo)"
|
||||
- author: Sebastián Ramírez (tiangolo)
|
||||
author_link: https://twitter.com/tiangolo
|
||||
link: https://www.youtube.com/watch?v=PnpTY1f4k2U
|
||||
title: '[VIRTUAL] Py.Amsterdam''s flying Software Circus: Intro to FastAPI'
|
||||
- author: Sebastián Ramírez (tiangolo)
|
||||
author_link: https://twitter.com/tiangolo
|
||||
link: https://www.youtube.com/watch?v=z9K5pwb0rt8
|
||||
title: 'PyConBY 2020: Serve ML models easily with FastAPI'
|
||||
- author: Chris Withers
|
||||
author_link: https://twitter.com/chriswithers13
|
||||
link: https://www.youtube.com/watch?v=3DLwPcrE5mA
|
||||
title: 'PyCon UK 2019: FastAPI from the ground up'
|
||||
|
||||
379
docs/en/data/github_sponsors.yml
Normal file
379
docs/en/data/github_sponsors.yml
Normal file
@@ -0,0 +1,379 @@
|
||||
sponsors:
|
||||
- - login: jina-ai
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
|
||||
url: https://github.com/jina-ai
|
||||
- - login: mikeckennedy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2035561?v=4
|
||||
url: https://github.com/mikeckennedy
|
||||
- login: RodneyU215
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3329665?u=ec6a9adf8e7e8e306eed7d49687c398608d1604f&v=4
|
||||
url: https://github.com/RodneyU215
|
||||
- login: Trivie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
|
||||
url: https://github.com/Trivie
|
||||
- login: deta
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47275976?v=4
|
||||
url: https://github.com/deta
|
||||
- login: investsuite
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/73833632?v=4
|
||||
url: https://github.com/investsuite
|
||||
- login: vimsoHQ
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/77627231?v=4
|
||||
url: https://github.com/vimsoHQ
|
||||
- - login: newrelic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31739?v=4
|
||||
url: https://github.com/newrelic
|
||||
- login: qaas
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8503759?u=10a6b4391ad6ab4cf9487ce54e3fcb61322d1efc&v=4
|
||||
url: https://github.com/qaas
|
||||
- - login: johnadjei
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
|
||||
url: https://github.com/johnadjei
|
||||
- login: wdwinslow
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
|
||||
url: https://github.com/wdwinslow
|
||||
- - login: kamalgill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
|
||||
url: https://github.com/kamalgill
|
||||
- login: grillazz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=16d7d0ffa5dfb99f8834f8f76d90e138ba09b94a&v=4
|
||||
url: https://github.com/grillazz
|
||||
- login: tizz98
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
|
||||
url: https://github.com/tizz98
|
||||
- login: jmaralc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
|
||||
url: https://github.com/jmaralc
|
||||
- login: AlexandruSimion
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/71321732?v=4
|
||||
url: https://github.com/AlexandruSimion
|
||||
- - login: samuelcolvin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: jokull
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/701?u=0532b62166893d5160ef795c4c8b7512d971af05&v=4
|
||||
url: https://github.com/jokull
|
||||
- login: wshayes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
|
||||
url: https://github.com/wshayes
|
||||
- login: koxudaxi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
|
||||
url: https://github.com/koxudaxi
|
||||
- login: falkben
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: jqueguiner
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/690878?u=e4835b2a985a0f2d52018e4926cb5a58c26a62e8&v=4
|
||||
url: https://github.com/jqueguiner
|
||||
- login: Mazyod
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/860511?v=4
|
||||
url: https://github.com/Mazyod
|
||||
- login: ltieman
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1084689?u=e69b17de17cb3ca141a17daa7ccbe173ceb1eb17&v=4
|
||||
url: https://github.com/ltieman
|
||||
- login: mrmattwright
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1277725?v=4
|
||||
url: https://github.com/mrmattwright
|
||||
- login: westonsteimel
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1593939?u=0f2c0e3647f916fe295d62fa70da7a4c177115e3&v=4
|
||||
url: https://github.com/westonsteimel
|
||||
- login: timdrijvers
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1694939?v=4
|
||||
url: https://github.com/timdrijvers
|
||||
- login: mrgnw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2504532?u=7ec43837a6d0afa80f96f0788744ea6341b89f97&v=4
|
||||
url: https://github.com/mrgnw
|
||||
- login: madisonmay
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2645393?u=f22b93c6ea345a4d26a90a3834dfc7f0789fcb63&v=4
|
||||
url: https://github.com/madisonmay
|
||||
- login: saivarunk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2976867?u=71f4385e781e9a9e871a52f2d4686f9a8d69ba2f&v=4
|
||||
url: https://github.com/saivarunk
|
||||
- login: andre1sk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
|
||||
url: https://github.com/andre1sk
|
||||
- login: Shark009
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3163309?v=4
|
||||
url: https://github.com/Shark009
|
||||
- login: peterHoburg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
|
||||
url: https://github.com/peterHoburg
|
||||
- login: jaredtrog
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
|
||||
url: https://github.com/jaredtrog
|
||||
- login: CINOAdam
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4728508?u=34c3d58cb900fed475d0172b436c66a94ad739ed&v=4
|
||||
url: https://github.com/CINOAdam
|
||||
- login: dudil
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4785835?u=58b7ea39123e0507f3b2996448a27256b16fd697&v=4
|
||||
url: https://github.com/dudil
|
||||
- login: ennui93
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
|
||||
url: https://github.com/ennui93
|
||||
- login: MacroPower
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5648814?u=e13991efd1e03c44c911f919872e750530ded633&v=4
|
||||
url: https://github.com/MacroPower
|
||||
- login: ginomempin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6091865?v=4
|
||||
url: https://github.com/ginomempin
|
||||
- login: iwpnd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=b2286006daafff5f991557344fee20b5da59639a&v=4
|
||||
url: https://github.com/iwpnd
|
||||
- login: s3ich4n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6926298?u=ba3025d698e1c986655e776ae383a3d60d9d578e&v=4
|
||||
url: https://github.com/s3ich4n
|
||||
- login: Rehket
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
|
||||
url: https://github.com/Rehket
|
||||
- login: christippett
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7218120?u=434b9d29287d7de25772d94ddc74a9bd6d969284&v=4
|
||||
url: https://github.com/christippett
|
||||
- login: Kludex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: Shackelford-Arden
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
|
||||
url: https://github.com/Shackelford-Arden
|
||||
- login: cristeaadrian
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9112724?v=4
|
||||
url: https://github.com/cristeaadrian
|
||||
- login: otivvormes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11317418?u=6de1edefb6afd0108c0ad2816bd6efc4464a9c44&v=4
|
||||
url: https://github.com/otivvormes
|
||||
- login: iambobmae
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12390270?u=c9a35c2ee5092a9b4135ebb1f91b7f521c467031&v=4
|
||||
url: https://github.com/iambobmae
|
||||
- login: ronaldnwilliams
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13632749?u=ac41a086d0728bf66a9d2bee9e5e377041ff44a4&v=4
|
||||
url: https://github.com/ronaldnwilliams
|
||||
- login: pablonnaoji
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=afc15bd5a4ba9c5c7206bbb1bcaeef606a0932e0&v=4
|
||||
url: https://github.com/pablonnaoji
|
||||
- login: natenka
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15850513?u=00d1083c980d0b4ce32835dc07eee7f43f34fd2f&v=4
|
||||
url: https://github.com/natenka
|
||||
- login: la-mar
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16618300?u=7755c0521d2bb0d704f35a51464b15c1e2e6c4da&v=4
|
||||
url: https://github.com/la-mar
|
||||
- login: robintully
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17059673?u=862b9bb01513f5acd30df97433cb97a24dbfb772&v=4
|
||||
url: https://github.com/robintully
|
||||
- login: ShaulAb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/18129076?u=2c8d48e47f2dbee15c3f89c3d17d4c356504386c&v=4
|
||||
url: https://github.com/ShaulAb
|
||||
- login: wedwardbeck
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
|
||||
url: https://github.com/wedwardbeck
|
||||
- login: linusg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19366641?u=125e390abef8fff3b3b0d370c369cba5d7fd4c67&v=4
|
||||
url: https://github.com/linusg
|
||||
- login: RedCarpetUp
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20360440?v=4
|
||||
url: https://github.com/RedCarpetUp
|
||||
- login: Filimoa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4
|
||||
url: https://github.com/Filimoa
|
||||
- login: raminsj13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24259406?u=d51f2a526312ebba150a06936ed187ca0727d329&v=4
|
||||
url: https://github.com/raminsj13
|
||||
- login: comoelcometa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=c6751efa038561b9bc5fa56d1033d5174e10cd65&v=4
|
||||
url: https://github.com/comoelcometa
|
||||
- login: veprimk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
|
||||
url: https://github.com/veprimk
|
||||
- login: orihomie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29889683?u=6bc2135a52fcb3a49e69e7d50190796618185fda&v=4
|
||||
url: https://github.com/orihomie
|
||||
- login: SaltyCoco
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31451104?u=6ee4e17c07d21b7054f54a12fa9cc377a1b24ff9&v=4
|
||||
url: https://github.com/SaltyCoco
|
||||
- login: mauroalejandrojm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
|
||||
url: https://github.com/mauroalejandrojm
|
||||
- login: bulkw4r3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35562532?u=0b812a14a02de14bf73d05fb2b2760a67bacffc2&v=4
|
||||
url: https://github.com/bulkw4r3
|
||||
- login: ybressler
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=6621dc9ab53b697912ab2a32211bb29ae90a9112&v=4
|
||||
url: https://github.com/ybressler
|
||||
- login: dbanty
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
|
||||
url: https://github.com/dbanty
|
||||
- login: dudikbender
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
|
||||
url: https://github.com/dudikbender
|
||||
- login: primer-io
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
|
||||
url: https://github.com/primer-io
|
||||
- login: tkrestiankova
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67013045?v=4
|
||||
url: https://github.com/tkrestiankova
|
||||
- login: daverin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
|
||||
url: https://github.com/daverin
|
||||
- login: anthonycepeda
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
|
||||
url: https://github.com/anthonycepeda
|
||||
- login: an-tho-ny
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/74874159?v=4
|
||||
url: https://github.com/an-tho-ny
|
||||
- - login: linux-china
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46711?v=4
|
||||
url: https://github.com/linux-china
|
||||
- login: jhb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
|
||||
url: https://github.com/jhb
|
||||
- login: yourkin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/178984?v=4
|
||||
url: https://github.com/yourkin
|
||||
- login: jmagnusson
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/190835?v=4
|
||||
url: https://github.com/jmagnusson
|
||||
- login: sakti
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/196178?u=0110be74c4270244546f1b610334042cd16bb8ad&v=4
|
||||
url: https://github.com/sakti
|
||||
- login: slafs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
|
||||
url: https://github.com/slafs
|
||||
- login: adamghill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
|
||||
url: https://github.com/adamghill
|
||||
- login: eteq
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4
|
||||
url: https://github.com/eteq
|
||||
- login: dmig
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
|
||||
url: https://github.com/dmig
|
||||
- login: hongqn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/405587?u=470b4c04832e45141fd5264d3354845cc9fc6466&v=4
|
||||
url: https://github.com/hongqn
|
||||
- login: rinckd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/546002?u=1fcc7e664dc86524a0af6837a0c222829c3fd4e5&v=4
|
||||
url: https://github.com/rinckd
|
||||
- login: hardbyte
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/855189?u=aa29e92f34708814d6b67fcd47ca4cf2ce1c04ed&v=4
|
||||
url: https://github.com/hardbyte
|
||||
- login: Pytlicek
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=169dba3bfbc04ed214a914640ff435969f19ddb3&v=4
|
||||
url: https://github.com/Pytlicek
|
||||
- login: okken
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1568356?u=0a991a21bdc62e2bea9ad311652f2c45f453dc84&v=4
|
||||
url: https://github.com/okken
|
||||
- login: cbonoz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
|
||||
url: https://github.com/cbonoz
|
||||
- login: Abbe98
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2631719?u=8a064aba9a710229ad28c616549d81a24191a5df&v=4
|
||||
url: https://github.com/Abbe98
|
||||
- login: rglsk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2768101?u=e349c88673f2155fe021331377c656a9d74bcc25&v=4
|
||||
url: https://github.com/rglsk
|
||||
- login: Atem18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2875254?v=4
|
||||
url: https://github.com/Atem18
|
||||
- login: paul121
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
|
||||
url: https://github.com/paul121
|
||||
- login: igorcorrea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4
|
||||
url: https://github.com/igorcorrea
|
||||
- login: anthcor
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
|
||||
url: https://github.com/anthcor
|
||||
- login: zsinx6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
|
||||
url: https://github.com/zsinx6
|
||||
- login: pawamoy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
|
||||
url: https://github.com/pawamoy
|
||||
- login: spyker77
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4953435?u=03c724c6f8fbab5cd6575b810c0c91c652fa4f79&v=4
|
||||
url: https://github.com/spyker77
|
||||
- login: JonasKs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5310116?u=98a049f3e1491bffb91e1feb7e93def6881a9389&v=4
|
||||
url: https://github.com/JonasKs
|
||||
- login: holec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
|
||||
url: https://github.com/holec
|
||||
- login: BartlomiejRasztabiga
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8852711?u=ed213d60f7a423df31ceb1004aa3ec60e612cb98&v=4
|
||||
url: https://github.com/BartlomiejRasztabiga
|
||||
- login: davanstrien
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8995957?u=fb2aad2b52bb4e7b56db6d7c8ecc9ae1eac1b984&v=4
|
||||
url: https://github.com/davanstrien
|
||||
- login: and-semakin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9129071?u=ea77ddf7de4bc375d546bf2825ed420eaddb7666&v=4
|
||||
url: https://github.com/and-semakin
|
||||
- login: VivianSolide
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9358572?u=ffb2e2ec522a15dcd3f0af1f9fd1df4afe418afa&v=4
|
||||
url: https://github.com/VivianSolide
|
||||
- login: hard-coders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: satwikkansal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10217535?u=b12d6ef74ea297de9e46da6933b1a5b7ba9e6a61&v=4
|
||||
url: https://github.com/satwikkansal
|
||||
- login: pheanex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
|
||||
url: https://github.com/pheanex
|
||||
- login: wotori
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10486621?u=0044c295b91694b8c9bccc0a805681f794250f7b&v=4
|
||||
url: https://github.com/wotori
|
||||
- login: JimFawkes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
|
||||
url: https://github.com/JimFawkes
|
||||
- login: logan-connolly
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
|
||||
url: https://github.com/logan-connolly
|
||||
- login: iPr0ger
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19322290?v=4
|
||||
url: https://github.com/iPr0ger
|
||||
- login: ghandic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: MoronVV
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24293616?v=4
|
||||
url: https://github.com/MoronVV
|
||||
- login: fstau
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24669867?u=60e7c8c09f8dafabee8fc3edcd6f9e19abbff918&v=4
|
||||
url: https://github.com/fstau
|
||||
- login: mertguvencli
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
|
||||
url: https://github.com/mertguvencli
|
||||
- login: rgreen32
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35779241?u=c9d64ad1ab364b6a1ec8e3d859da9ca802d681d8&v=4
|
||||
url: https://github.com/rgreen32
|
||||
- login: askurihin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37978981?v=4
|
||||
url: https://github.com/askurihin
|
||||
- login: JitPackJoyride
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40203625?u=9638bfeacfa5940358188f8205ce662bba022b53&v=4
|
||||
url: https://github.com/JitPackJoyride
|
||||
- login: es3n1n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40367813?u=e881a3880f1e342d19a1ea7c8e1b6d76c52dc294&v=4
|
||||
url: https://github.com/es3n1n
|
||||
- login: ilias-ant
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=a2d6121bac4d125d92ec207460fa3f1842d37e66&v=4
|
||||
url: https://github.com/ilias-ant
|
||||
- login: arrrrrmin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=05600727f1cfe75f440bb3fddd49bfea84b1e894&v=4
|
||||
url: https://github.com/arrrrrmin
|
||||
- login: akanz1
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
|
||||
url: https://github.com/akanz1
|
||||
- - login: leogregianin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1684053?u=94ddd387601bd1805034dbe83e6eba0491c15323&v=4
|
||||
url: https://github.com/leogregianin
|
||||
- login: sadikkuzu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=765ed469c44c004560079210ccdad5b29938eaa9&v=4
|
||||
url: https://github.com/sadikkuzu
|
||||
- login: gabrielmbmb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29572918?u=92084ed7242160dee4d20aece923a10c59758ee5&v=4
|
||||
url: https://github.com/gabrielmbmb
|
||||
- login: starhype
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36908028?u=6df41f7b62f0f673f1ecbc87e9cbadaa4fcb0767&v=4
|
||||
url: https://github.com/starhype
|
||||
- login: pixel365
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53819609?u=9e0309c5420ec4624aececd3ca2d7105f7f68133&v=4
|
||||
url: https://github.com/pixel365
|
||||
@@ -1,12 +1,12 @@
|
||||
maintainers:
|
||||
- login: tiangolo
|
||||
answers: 1225
|
||||
prs: 232
|
||||
answers: 1229
|
||||
prs: 250
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=05f95ca7fdead36edd9c86be46b4ef6c3c71f876&v=4
|
||||
url: https://github.com/tiangolo
|
||||
experts:
|
||||
- login: Kludex
|
||||
count: 267
|
||||
count: 278
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: dmontagu
|
||||
@@ -14,11 +14,11 @@ experts:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
|
||||
url: https://github.com/dmontagu
|
||||
- login: ycd
|
||||
count: 216
|
||||
count: 217
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
|
||||
url: https://github.com/ycd
|
||||
- login: Mause
|
||||
count: 182
|
||||
count: 202
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
|
||||
url: https://github.com/Mause
|
||||
- login: euri10
|
||||
@@ -30,35 +30,35 @@ experts:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
|
||||
url: https://github.com/phy25
|
||||
- login: ArcLightSlavik
|
||||
count: 64
|
||||
count: 66
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: falkben
|
||||
count: 56
|
||||
count: 57
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: sm-Fifteen
|
||||
count: 48
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
|
||||
url: https://github.com/sm-Fifteen
|
||||
- login: raphaelauv
|
||||
count: 47
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: sm-Fifteen
|
||||
count: 46
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
|
||||
url: https://github.com/sm-Fifteen
|
||||
- login: includeamin
|
||||
count: 38
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
|
||||
url: https://github.com/includeamin
|
||||
- login: Dustyposa
|
||||
count: 38
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
- login: prostomarkeloff
|
||||
count: 33
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
|
||||
url: https://github.com/prostomarkeloff
|
||||
- login: Dustyposa
|
||||
count: 32
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
- login: krishnardt
|
||||
count: 30
|
||||
count: 31
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
|
||||
url: https://github.com/krishnardt
|
||||
- login: insomnes
|
||||
@@ -78,7 +78,7 @@ experts:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
|
||||
url: https://github.com/SirTelemak
|
||||
- login: chbndrhnns
|
||||
count: 22
|
||||
count: 23
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
|
||||
url: https://github.com/chbndrhnns
|
||||
- login: acnebs
|
||||
@@ -91,7 +91,7 @@ experts:
|
||||
url: https://github.com/nsidnev
|
||||
- login: frankie567
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=72adf1cb1d29787305c99700d669561952cea0af&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
|
||||
url: https://github.com/frankie567
|
||||
- login: chris-allnutt
|
||||
count: 21
|
||||
@@ -114,13 +114,25 @@ experts:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
|
||||
url: https://github.com/nkhitrov
|
||||
- login: waynerv
|
||||
count: 15
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
|
||||
url: https://github.com/waynerv
|
||||
- login: adriangb
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
|
||||
url: https://github.com/adriangb
|
||||
- login: panla
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: haizaar
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
|
||||
url: https://github.com/haizaar
|
||||
- login: STeveShary
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
|
||||
url: https://github.com/STeveShary
|
||||
- login: acidjunk
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
@@ -129,6 +141,10 @@ experts:
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
|
||||
url: https://github.com/zamiramir
|
||||
- login: David-Lor
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17401854?u=474680c02b94cba810cb9032fb7eb787d9cc9d22&v=4
|
||||
url: https://github.com/David-Lor
|
||||
- login: juntatalor
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
|
||||
@@ -145,39 +161,47 @@ experts:
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20441825?u=ee1e59446b98f8ec2363caeda4c17164d0d9cc7d&v=4
|
||||
url: https://github.com/stefanondisponibile
|
||||
- login: hellocoldworld
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47581948?v=4
|
||||
url: https://github.com/hellocoldworld
|
||||
last_month_active:
|
||||
- login: Kludex
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: frankie567
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=72adf1cb1d29787305c99700d669561952cea0af&v=4
|
||||
url: https://github.com/frankie567
|
||||
- login: Mause
|
||||
count: 6
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
|
||||
url: https://github.com/Mause
|
||||
- login: ArcLightSlavik
|
||||
- login: Kludex
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: panla
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: adriangb
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: gyKa
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1000842?v=4
|
||||
url: https://github.com/gyKa
|
||||
- login: ricky-sb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
|
||||
url: https://github.com/adriangb
|
||||
- login: Dustyposa
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
- login: STeveShary
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
|
||||
url: https://github.com/STeveShary
|
||||
- login: Cosmicoppai
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10700079?v=4
|
||||
url: https://github.com/ricky-sb
|
||||
- login: captainCapitalism
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63765823?u=b97c98ddd6eaf06cd5a0d312db36f97996ac5b23&v=4
|
||||
url: https://github.com/Cosmicoppai
|
||||
- login: AlexanderPodorov
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32553875?v=4
|
||||
url: https://github.com/captainCapitalism
|
||||
- login: acidjunk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/54511144?v=4
|
||||
url: https://github.com/AlexanderPodorov
|
||||
- login: SamuelHeath
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12291364?v=4
|
||||
url: https://github.com/SamuelHeath
|
||||
top_contributors:
|
||||
- login: waynerv
|
||||
count: 25
|
||||
@@ -196,9 +220,13 @@ top_contributors:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
|
||||
url: https://github.com/euri10
|
||||
- login: mariacamilagl
|
||||
count: 9
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
|
||||
url: https://github.com/mariacamilagl
|
||||
- login: jaystone776
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
|
||||
url: https://github.com/jaystone776
|
||||
- login: RunningIkkyu
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
|
||||
@@ -207,6 +235,10 @@ top_contributors:
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
|
||||
url: https://github.com/Serrones
|
||||
- login: Kludex
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: hard-coders
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
@@ -225,11 +257,15 @@ top_contributors:
|
||||
url: https://github.com/Attsun1031
|
||||
- login: jekirl
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2546697?v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
|
||||
url: https://github.com/jekirl
|
||||
- login: jfunez
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
|
||||
url: https://github.com/jfunez
|
||||
- login: komtaki
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=5a44657c0544111ee3c132d9bb9951c2804f7969&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
|
||||
url: https://github.com/komtaki
|
||||
- login: Smlep
|
||||
count: 4
|
||||
@@ -237,25 +273,25 @@ top_contributors:
|
||||
url: https://github.com/Smlep
|
||||
top_reviewers:
|
||||
- login: Kludex
|
||||
count: 80
|
||||
count: 85
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: tokusumi
|
||||
count: 44
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
|
||||
url: https://github.com/tokusumi
|
||||
- login: Laineyzhang55
|
||||
count: 42
|
||||
count: 47
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
|
||||
url: https://github.com/Laineyzhang55
|
||||
- login: tokusumi
|
||||
count: 46
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
|
||||
url: https://github.com/tokusumi
|
||||
- login: waynerv
|
||||
count: 43
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
|
||||
url: https://github.com/waynerv
|
||||
- login: ycd
|
||||
count: 41
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
|
||||
url: https://github.com/ycd
|
||||
- login: waynerv
|
||||
count: 38
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
|
||||
url: https://github.com/waynerv
|
||||
- login: AdrianDeAnda
|
||||
count: 28
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
|
||||
@@ -266,14 +302,14 @@ top_reviewers:
|
||||
url: https://github.com/dmontagu
|
||||
- login: komtaki
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=5a44657c0544111ee3c132d9bb9951c2804f7969&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
|
||||
url: https://github.com/komtaki
|
||||
- login: ArcLightSlavik
|
||||
count: 20
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: cassiobotaro
|
||||
count: 16
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
|
||||
url: https://github.com/cassiobotaro
|
||||
- login: yanever
|
||||
@@ -292,18 +328,26 @@ top_reviewers:
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
|
||||
url: https://github.com/delhi09
|
||||
- login: lsglucas
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: RunningIkkyu
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
|
||||
url: https://github.com/RunningIkkyu
|
||||
- login: sh0nk
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
|
||||
url: https://github.com/sh0nk
|
||||
- login: rjNemo
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
|
||||
url: https://github.com/rjNemo
|
||||
- login: hard-coders
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: sh0nk
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
|
||||
url: https://github.com/sh0nk
|
||||
- login: mariacamilagl
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
|
||||
@@ -316,6 +360,10 @@ top_reviewers:
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
|
||||
url: https://github.com/maoyibo
|
||||
- login: Smlep
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
url: https://github.com/Smlep
|
||||
- login: PandaHun
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
|
||||
@@ -324,14 +372,6 @@ top_reviewers:
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
|
||||
url: https://github.com/bezaca
|
||||
- login: lsglucas
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: rjNemo
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
|
||||
url: https://github.com/rjNemo
|
||||
- login: blt232018
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
|
||||
@@ -348,22 +388,22 @@ top_reviewers:
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: graingert
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
|
||||
url: https://github.com/graingert
|
||||
- login: NastasiaSaby
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
|
||||
url: https://github.com/NastasiaSaby
|
||||
- login: Smlep
|
||||
- login: Mause
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
url: https://github.com/Smlep
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
|
||||
url: https://github.com/Mause
|
||||
- login: jovicon
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
|
||||
url: https://github.com/jovicon
|
||||
- login: Mause
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
|
||||
url: https://github.com/Mause
|
||||
- login: nimctl
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/49960770?u=e39b11d47188744ee07b2a1c7ce1a1bdf3c80760&v=4
|
||||
@@ -376,10 +416,22 @@ top_reviewers:
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63564282?u=0078826509dbecb2fdb543f4e881c9cd06157893&v=4
|
||||
url: https://github.com/SnkSynthesis
|
||||
- login: solomein-sv
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
|
||||
url: https://github.com/solomein-sv
|
||||
- login: anthonycepeda
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
|
||||
url: https://github.com/anthonycepeda
|
||||
- login: ComicShrimp
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
|
||||
url: https://github.com/ComicShrimp
|
||||
- login: oandersonmagalhaes
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
|
||||
url: https://github.com/oandersonmagalhaes
|
||||
- login: euri10
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
|
||||
@@ -392,6 +444,10 @@ top_reviewers:
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41201924?u=6883cc4fc13a7b2e60d4deddd4be06f9c5287880&v=4
|
||||
url: https://github.com/aviramha
|
||||
- login: Cajuteq
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26676532?u=8ee0422981810e51480855de1c0d67b6b79cd3f2&v=4
|
||||
url: https://github.com/Cajuteq
|
||||
- login: Zxilly
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31370133?v=4
|
||||
@@ -400,353 +456,3 @@ top_reviewers:
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/38372706?u=c9d28aff15958d6ebf1971148bfb3154ff943c4f&v=4
|
||||
url: https://github.com/Bluenix2
|
||||
sponsors_50:
|
||||
- login: johnadjei
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
|
||||
url: https://github.com/johnadjei
|
||||
- login: wdwinslow
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
|
||||
url: https://github.com/wdwinslow
|
||||
- login: bingwu-chime
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67026650?u=603a6b345f25c20c6706a8a6c7f71ae688d649a5&v=4
|
||||
url: https://github.com/bingwu-chime
|
||||
sponsors:
|
||||
- login: kamalgill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
|
||||
url: https://github.com/kamalgill
|
||||
- login: grillazz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=16d7d0ffa5dfb99f8834f8f76d90e138ba09b94a&v=4
|
||||
url: https://github.com/grillazz
|
||||
- login: tizz98
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
|
||||
url: https://github.com/tizz98
|
||||
- login: jmaralc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
|
||||
url: https://github.com/jmaralc
|
||||
- login: psgandalf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8134158?v=4
|
||||
url: https://github.com/psgandalf
|
||||
- login: samuelcolvin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: jokull
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/701?u=0532b62166893d5160ef795c4c8b7512d971af05&v=4
|
||||
url: https://github.com/jokull
|
||||
- login: wshayes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
|
||||
url: https://github.com/wshayes
|
||||
- login: koxudaxi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
|
||||
url: https://github.com/koxudaxi
|
||||
- login: falkben
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: jqueguiner
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/690878?u=e4835b2a985a0f2d52018e4926cb5a58c26a62e8&v=4
|
||||
url: https://github.com/jqueguiner
|
||||
- login: Mazyod
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/860511?v=4
|
||||
url: https://github.com/Mazyod
|
||||
- login: ltieman
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1084689?u=e69b17de17cb3ca141a17daa7ccbe173ceb1eb17&v=4
|
||||
url: https://github.com/ltieman
|
||||
- login: mrmattwright
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1277725?v=4
|
||||
url: https://github.com/mrmattwright
|
||||
- login: westonsteimel
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1593939?u=0f2c0e3647f916fe295d62fa70da7a4c177115e3&v=4
|
||||
url: https://github.com/westonsteimel
|
||||
- login: timdrijvers
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1694939?v=4
|
||||
url: https://github.com/timdrijvers
|
||||
- login: mrgnw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2504532?u=7ec43837a6d0afa80f96f0788744ea6341b89f97&v=4
|
||||
url: https://github.com/mrgnw
|
||||
- login: madisonmay
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2645393?u=f22b93c6ea345a4d26a90a3834dfc7f0789fcb63&v=4
|
||||
url: https://github.com/madisonmay
|
||||
- login: saivarunk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2976867?u=71f4385e781e9a9e871a52f2d4686f9a8d69ba2f&v=4
|
||||
url: https://github.com/saivarunk
|
||||
- login: andre1sk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
|
||||
url: https://github.com/andre1sk
|
||||
- login: Shark009
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3163309?v=4
|
||||
url: https://github.com/Shark009
|
||||
- login: peterHoburg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
|
||||
url: https://github.com/peterHoburg
|
||||
- login: dudil
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4785835?u=58b7ea39123e0507f3b2996448a27256b16fd697&v=4
|
||||
url: https://github.com/dudil
|
||||
- login: ennui93
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
|
||||
url: https://github.com/ennui93
|
||||
- login: sco1
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5323929?u=2b8434060d0c9d93de80a2a945baed94a412c31e&v=4
|
||||
url: https://github.com/sco1
|
||||
- login: MacroPower
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5648814?u=b2730000c9f9a471282b9849d2cc85711d7973d4&v=4
|
||||
url: https://github.com/MacroPower
|
||||
- login: ginomempin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6091865?v=4
|
||||
url: https://github.com/ginomempin
|
||||
- login: iwpnd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=b2286006daafff5f991557344fee20b5da59639a&v=4
|
||||
url: https://github.com/iwpnd
|
||||
- login: s3ich4n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6926298?u=ba3025d698e1c986655e776ae383a3d60d9d578e&v=4
|
||||
url: https://github.com/s3ich4n
|
||||
- login: Rehket
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
|
||||
url: https://github.com/Rehket
|
||||
- login: christippett
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7218120?u=434b9d29287d7de25772d94ddc74a9bd6d969284&v=4
|
||||
url: https://github.com/christippett
|
||||
- login: Kludex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: Shackelford-Arden
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
|
||||
url: https://github.com/Shackelford-Arden
|
||||
- login: macleodmac
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8996312?u=e39c68c3e0b1d264dcba4850134a291680f46355&v=4
|
||||
url: https://github.com/macleodmac
|
||||
- login: cristeaadrian
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9112724?v=4
|
||||
url: https://github.com/cristeaadrian
|
||||
- login: otivvormes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11317418?u=6de1edefb6afd0108c0ad2816bd6efc4464a9c44&v=4
|
||||
url: https://github.com/otivvormes
|
||||
- login: iambobmae
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12390270?u=c9a35c2ee5092a9b4135ebb1f91b7f521c467031&v=4
|
||||
url: https://github.com/iambobmae
|
||||
- login: ronaldnwilliams
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13632749?u=ac41a086d0728bf66a9d2bee9e5e377041ff44a4&v=4
|
||||
url: https://github.com/ronaldnwilliams
|
||||
- login: uselessscat
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15332878?u=8485a1b7383c274b28f383370ee2d5f9a6cd423b&v=4
|
||||
url: https://github.com/uselessscat
|
||||
- login: natenka
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15850513?u=00d1083c980d0b4ce32835dc07eee7f43f34fd2f&v=4
|
||||
url: https://github.com/natenka
|
||||
- login: la-mar
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16618300?u=7755c0521d2bb0d704f35a51464b15c1e2e6c4da&v=4
|
||||
url: https://github.com/la-mar
|
||||
- login: robintully
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17059673?u=862b9bb01513f5acd30df97433cb97a24dbfb772&v=4
|
||||
url: https://github.com/robintully
|
||||
- login: ShaulAb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/18129076?u=2c8d48e47f2dbee15c3f89c3d17d4c356504386c&v=4
|
||||
url: https://github.com/ShaulAb
|
||||
- login: wedwardbeck
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
|
||||
url: https://github.com/wedwardbeck
|
||||
- login: linusg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19366641?u=125e390abef8fff3b3b0d370c369cba5d7fd4c67&v=4
|
||||
url: https://github.com/linusg
|
||||
- login: RedCarpetUp
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20360440?v=4
|
||||
url: https://github.com/RedCarpetUp
|
||||
- login: daddycocoaman
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21189155?u=756f6a17c71c538b11470f70839baacab43807ef&v=4
|
||||
url: https://github.com/daddycocoaman
|
||||
- login: Filimoa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4
|
||||
url: https://github.com/Filimoa
|
||||
- login: raminsj13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24259406?u=d51f2a526312ebba150a06936ed187ca0727d329&v=4
|
||||
url: https://github.com/raminsj13
|
||||
- login: comoelcometa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=c6751efa038561b9bc5fa56d1033d5174e10cd65&v=4
|
||||
url: https://github.com/comoelcometa
|
||||
- login: veprimk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
|
||||
url: https://github.com/veprimk
|
||||
- login: orihomie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29889683?u=6bc2135a52fcb3a49e69e7d50190796618185fda&v=4
|
||||
url: https://github.com/orihomie
|
||||
- login: SaltyCoco
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31451104?u=6ee4e17c07d21b7054f54a12fa9cc377a1b24ff9&v=4
|
||||
url: https://github.com/SaltyCoco
|
||||
- login: mauroalejandrojm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
|
||||
url: https://github.com/mauroalejandrojm
|
||||
- login: public-daniel
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32238294?u=0377e38dd023395c9643d5388b4e9489a24b4d34&v=4
|
||||
url: https://github.com/public-daniel
|
||||
- login: ybressler
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=6621dc9ab53b697912ab2a32211bb29ae90a9112&v=4
|
||||
url: https://github.com/ybressler
|
||||
- login: dbanty
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
|
||||
url: https://github.com/dbanty
|
||||
- login: dudikbender
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
|
||||
url: https://github.com/dudikbender
|
||||
- login: primer-io
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
|
||||
url: https://github.com/primer-io
|
||||
- login: tkrestiankova
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67013045?v=4
|
||||
url: https://github.com/tkrestiankova
|
||||
- login: daverin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
|
||||
url: https://github.com/daverin
|
||||
- login: anthonycepeda
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
|
||||
url: https://github.com/anthonycepeda
|
||||
- login: linux-china
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46711?v=4
|
||||
url: https://github.com/linux-china
|
||||
- login: jhb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
|
||||
url: https://github.com/jhb
|
||||
- login: yourkin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/178984?v=4
|
||||
url: https://github.com/yourkin
|
||||
- login: jmagnusson
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/190835?v=4
|
||||
url: https://github.com/jmagnusson
|
||||
- login: slafs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
|
||||
url: https://github.com/slafs
|
||||
- login: adamghill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
|
||||
url: https://github.com/adamghill
|
||||
- login: eteq
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4
|
||||
url: https://github.com/eteq
|
||||
- login: dmig
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
|
||||
url: https://github.com/dmig
|
||||
- login: hongqn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/405587?u=470b4c04832e45141fd5264d3354845cc9fc6466&v=4
|
||||
url: https://github.com/hongqn
|
||||
- login: rinckd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/546002?u=1fcc7e664dc86524a0af6837a0c222829c3fd4e5&v=4
|
||||
url: https://github.com/rinckd
|
||||
- login: Pytlicek
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=169dba3bfbc04ed214a914640ff435969f19ddb3&v=4
|
||||
url: https://github.com/Pytlicek
|
||||
- login: okken
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1568356?u=0a991a21bdc62e2bea9ad311652f2c45f453dc84&v=4
|
||||
url: https://github.com/okken
|
||||
- login: leogregianin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1684053?u=94ddd387601bd1805034dbe83e6eba0491c15323&v=4
|
||||
url: https://github.com/leogregianin
|
||||
- login: cbonoz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
|
||||
url: https://github.com/cbonoz
|
||||
- login: rglsk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2768101?u=e349c88673f2155fe021331377c656a9d74bcc25&v=4
|
||||
url: https://github.com/rglsk
|
||||
- login: Atem18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2875254?v=4
|
||||
url: https://github.com/Atem18
|
||||
- login: paul121
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
|
||||
url: https://github.com/paul121
|
||||
- login: igorcorrea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4
|
||||
url: https://github.com/igorcorrea
|
||||
- login: zsinx6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
|
||||
url: https://github.com/zsinx6
|
||||
- login: pawamoy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
|
||||
url: https://github.com/pawamoy
|
||||
- login: spyker77
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4953435?u=568baae6469628e020fe0bab16e395b7ae10c7d3&v=4
|
||||
url: https://github.com/spyker77
|
||||
- login: serfer2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5196592?u=e8798d87120952ed41876778f0cc8a1ddb47f901&v=4
|
||||
url: https://github.com/serfer2
|
||||
- login: JonasKs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5310116?u=98a049f3e1491bffb91e1feb7e93def6881a9389&v=4
|
||||
url: https://github.com/JonasKs
|
||||
- login: holec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
|
||||
url: https://github.com/holec
|
||||
- login: BartlomiejRasztabiga
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8852711?u=ed213d60f7a423df31ceb1004aa3ec60e612cb98&v=4
|
||||
url: https://github.com/BartlomiejRasztabiga
|
||||
- login: davanstrien
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8995957?u=fb2aad2b52bb4e7b56db6d7c8ecc9ae1eac1b984&v=4
|
||||
url: https://github.com/davanstrien
|
||||
- login: and-semakin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9129071?u=ea77ddf7de4bc375d546bf2825ed420eaddb7666&v=4
|
||||
url: https://github.com/and-semakin
|
||||
- login: VivianSolide
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9358572?u=ffb2e2ec522a15dcd3f0af1f9fd1df4afe418afa&v=4
|
||||
url: https://github.com/VivianSolide
|
||||
- login: hard-coders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: satwikkansal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10217535?u=b12d6ef74ea297de9e46da6933b1a5b7ba9e6a61&v=4
|
||||
url: https://github.com/satwikkansal
|
||||
- login: pheanex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
|
||||
url: https://github.com/pheanex
|
||||
- login: wotori
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10486621?u=0044c295b91694b8c9bccc0a805681f794250f7b&v=4
|
||||
url: https://github.com/wotori
|
||||
- login: JimFawkes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
|
||||
url: https://github.com/JimFawkes
|
||||
- login: logan-connolly
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
|
||||
url: https://github.com/logan-connolly
|
||||
- login: iPr0ger
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19322290?v=4
|
||||
url: https://github.com/iPr0ger
|
||||
- login: sadikkuzu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=765ed469c44c004560079210ccdad5b29938eaa9&v=4
|
||||
url: https://github.com/sadikkuzu
|
||||
- login: ghandic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: MoronVV
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24293616?v=4
|
||||
url: https://github.com/MoronVV
|
||||
- login: AngusWG
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26385612?u=f4d4c8bd2097cdd58eb9e385932b83c78777f3c0&v=4
|
||||
url: https://github.com/AngusWG
|
||||
- login: mertguvencli
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
|
||||
url: https://github.com/mertguvencli
|
||||
- login: rgreen32
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35779241?u=c9d64ad1ab364b6a1ec8e3d859da9ca802d681d8&v=4
|
||||
url: https://github.com/rgreen32
|
||||
- login: askurihin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37978981?v=4
|
||||
url: https://github.com/askurihin
|
||||
- login: berrysauce
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/38889179?u=758ed15a5be8bbd03855f5a74f42c19f7946ee32&v=4
|
||||
url: https://github.com/berrysauce
|
||||
- login: JitPackJoyride
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40203625?u=9638bfeacfa5940358188f8205ce662bba022b53&v=4
|
||||
url: https://github.com/JitPackJoyride
|
||||
- login: es3n1n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40367813?u=e881a3880f1e342d19a1ea7c8e1b6d76c52dc294&v=4
|
||||
url: https://github.com/es3n1n
|
||||
- login: ilias-ant
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=a2d6121bac4d125d92ec207460fa3f1842d37e66&v=4
|
||||
url: https://github.com/ilias-ant
|
||||
- login: kbhatiya999
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47816034?v=4
|
||||
url: https://github.com/kbhatiya999
|
||||
- login: akanz1
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
|
||||
url: https://github.com/akanz1
|
||||
- login: rychardvale
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/54805553?u=3d20ab05301d05f9ac3500fb79a2bfee3842b753&v=4
|
||||
url: https://github.com/rychardvale
|
||||
- login: athemeart
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61623624?v=4
|
||||
url: https://github.com/athemeart
|
||||
- login: Rhythmicc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29839231?u=2100781089a259707c475c4547bd7995b0fc18ee&v=4
|
||||
url: https://github.com/Rhythmicc
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
gold:
|
||||
- url: https://www.deta.sh/?ref=fastapi
|
||||
title: The launchpad for all your (team's) ideas
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/deta.svg
|
||||
- url: https://bit.ly/2QSouzH
|
||||
title: "Jina: build neural search-as-a-service for any kind of data in just minutes."
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/jina.svg
|
||||
silver:
|
||||
- url: https://www.deta.sh/?ref=fastapi
|
||||
title: The launchpad for all your (team's) ideas
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/deta.svg
|
||||
- url: https://www.investsuite.com/jobs
|
||||
title: Wealthtech jobs with FastAPI
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/investsuite.svg
|
||||
@@ -15,7 +15,6 @@ silver:
|
||||
- url: https://talkpython.fm/fastapi-sponsor
|
||||
title: FastAPI video courses on demand from people you trust
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/talkpython.png
|
||||
bronze:
|
||||
- url: https://testdriven.io/courses/tdd-fastapi/
|
||||
title: Learn to build high-quality web apps with best practices
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
|
||||
|
||||
6
docs/en/data/sponsors_badge.yml
Normal file
6
docs/en/data/sponsors_badge.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
logins:
|
||||
- jina-ai
|
||||
- deta
|
||||
- investsuite
|
||||
- vimsoHQ
|
||||
- mikeckennedy
|
||||
@@ -161,10 +161,33 @@ An alternative JSON response using <a href="https://github.com/ultrajson/ultrajs
|
||||
|
||||
Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.
|
||||
|
||||
You can return a `RedirectResponse` directly:
|
||||
|
||||
```Python hl_lines="2 9"
|
||||
{!../../../docs_src/custom_response/tutorial006.py!}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Or you can use it in the `response_class` parameter:
|
||||
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../../docs_src/custom_response/tutorial006b.py!}
|
||||
```
|
||||
|
||||
If you do that, then you can return the URL directly from your *path operation* function.
|
||||
|
||||
In this case, the `status_code` used will be the default one for the `RedirectResponse`, which is `307`.
|
||||
|
||||
---
|
||||
|
||||
You can also use the `status_code` parameter combined with the `response_class` parameter:
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../../docs_src/custom_response/tutorial006c.py!}
|
||||
```
|
||||
|
||||
### `StreamingResponse`
|
||||
|
||||
Takes an async generator or a normal generator/iterator and streams the response body.
|
||||
@@ -175,14 +198,24 @@ Takes an async generator or a normal generator/iterator and streams the response
|
||||
|
||||
#### Using `StreamingResponse` with file-like objects
|
||||
|
||||
If you have a file-like object (e.g. the object returned by `open()`), you can return it in a `StreamingResponse`.
|
||||
If you have a file-like object (e.g. the object returned by `open()`), you can create a generator function to iterate over that file-like object.
|
||||
|
||||
That way, you don't have to read it all first in memory, and you can pass that generator function to the `StreamingResponse`, and return it.
|
||||
|
||||
This includes many libraries to interact with cloud storage, video processing, and others.
|
||||
|
||||
```Python hl_lines="2 10-11"
|
||||
```{ .python .annotate hl_lines="2 10-12 14" }
|
||||
{!../../../docs_src/custom_response/tutorial008.py!}
|
||||
```
|
||||
|
||||
1. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
|
||||
2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
|
||||
3. This `yield from` tells the function to iterate over that thing named `file_like`. And then, for each part iterated, yield that part as coming from this generator function.
|
||||
|
||||
So, it is a generator function that transfers the "generating" work to something else internally.
|
||||
|
||||
By doing it this way, we can put it in a `with` block, and that way, ensure that it is closed after finishing.
|
||||
|
||||
!!! tip
|
||||
Notice that here as we are using standard `open()` that doesn't support `async` and `await`, we declare the path operation with normal `def`.
|
||||
|
||||
@@ -203,6 +236,14 @@ File responses will include appropriate `Content-Length`, `Last-Modified` and `E
|
||||
{!../../../docs_src/custom_response/tutorial009.py!}
|
||||
```
|
||||
|
||||
You can also use the `response_class` parameter:
|
||||
|
||||
```Python hl_lines="2 8 10"
|
||||
{!../../../docs_src/custom_response/tutorial009b.py!}
|
||||
```
|
||||
|
||||
In this case, you can return the file path directly from your *path operation* function.
|
||||
|
||||
## Default response class
|
||||
|
||||
When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default.
|
||||
|
||||
98
docs/en/docs/advanced/dataclasses.md
Normal file
98
docs/en/docs/advanced/dataclasses.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Using Dataclasses
|
||||
|
||||
FastAPI is built on top of **Pydantic**, and I have been showing you how to use Pydantic models to declare requests and responses.
|
||||
|
||||
But FastAPI also supports using <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> the same way:
|
||||
|
||||
```Python hl_lines="1 7-12 19-20"
|
||||
{!../../../docs_src/dataclasses/tutorial001.py!}
|
||||
```
|
||||
|
||||
This is still thanks to **Pydantic**, as it has <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.
|
||||
|
||||
So, even with the code above that doesn't use Pydantic explicitly, FastAPI is using Pydantic to convert those standard dataclasses to Pydantic's own flavor of dataclasses.
|
||||
|
||||
And of course, it supports the same:
|
||||
|
||||
* data validation
|
||||
* data serialization
|
||||
* data documentation, etc.
|
||||
|
||||
This works the same way as with Pydantic models. And it is actually achieved in the same way underneath, using Pydantic.
|
||||
|
||||
!!! info
|
||||
Have in mind that dataclasses can't do everything Pydantic models can do.
|
||||
|
||||
So, you might still need to use Pydantic models.
|
||||
|
||||
But if you have a bunch of dataclasses laying around, this is a nice trick to use them to power a web API using FastAPI. 🤓
|
||||
|
||||
## Dataclasses in `response_model`
|
||||
|
||||
You can also use `dataclasses` in the `response_model` parameter:
|
||||
|
||||
```Python hl_lines="1 7-13 19"
|
||||
{!../../../docs_src/dataclasses/tutorial002.py!}
|
||||
```
|
||||
|
||||
The dataclass will be automatically converted to a Pydantic dataclass.
|
||||
|
||||
This way, its schema will show up in the API docs user interface:
|
||||
|
||||
<img src="/img/tutorial/dataclasses/image01.png">
|
||||
|
||||
## Dataclasses in Nested Data Structures
|
||||
|
||||
You can also combine `dataclasses` with other type annotations to make nested data structures.
|
||||
|
||||
In some cases, you might still have to use Pydantic's version of `dataclasses`. For example, if you have errors with the automatically generated API documentation.
|
||||
|
||||
In that case, you can simply swap the standard `dataclasses` with `pydantic.dataclasses`, which is a drop-in replacement:
|
||||
|
||||
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
|
||||
{!../../../docs_src/dataclasses/tutorial003.py!}
|
||||
```
|
||||
|
||||
1. We still import `field` from standard `dataclasses`.
|
||||
|
||||
2. `pydantic.dataclasses` is a drop-in replacement for `dataclasses`.
|
||||
|
||||
3. The `Author` dataclass includes a list of `Item` dataclasses.
|
||||
|
||||
4. The `Author` dataclass is used as the `response_model` parameter.
|
||||
|
||||
5. You can use other standard type annotations with dataclasses as the request body.
|
||||
|
||||
In this case, it's a list of `Item` dataclasses.
|
||||
|
||||
6. Here we are returning a dictionary that contains `items` which is a list of dataclasses.
|
||||
|
||||
FastAPI is still capable of <abbr title="converting the data to a format that can be transmitted">serializing</abbr> the data to JSON.
|
||||
|
||||
7. Here the `response_model` is using a type annotation of a list of `Author` dataclasses.
|
||||
|
||||
Again, you can combine `dataclasses` with standard type annotations.
|
||||
|
||||
8. Notice that this *path operation function* uses regular `def` instead of `async def`.
|
||||
|
||||
As always, in FastAPI you can combine `def` and `async def` as needed.
|
||||
|
||||
If you need a refresher about when to use which, check out the section _"In a hurry?"_ in the docs about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank" class="internal-link">`async` and `await`</a>.
|
||||
|
||||
9. This *path operation function* is not returning dataclasses (although it could), but a list of dictionaries with internal data.
|
||||
|
||||
FastAPI will use the `response_model` parameter (that includes dataclasses) to convert the response.
|
||||
|
||||
You can combine `dataclasses` with other type annotations in many different combinations to form complex data structures.
|
||||
|
||||
Check the in-code annotation tips above to see more specific details.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can also combine `dataclasses` with other Pydantic models, inherit from them, include them in your own models, etc.
|
||||
|
||||
To learn more, check the <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/" class="external-link" target="_blank">Pydantic docs about dataclasses</a>.
|
||||
|
||||
## Version
|
||||
|
||||
This is available since FastAPI version `0.67.0`. 🔖
|
||||
@@ -33,7 +33,7 @@ You should do it after adding all your *path operations*.
|
||||
|
||||
## Exclude from OpenAPI
|
||||
|
||||
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`;
|
||||
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
|
||||
@@ -50,3 +50,121 @@ It won't show up in the documentation, but other tools (such as Sphinx) will be
|
||||
```Python hl_lines="19-29"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Additional Responses
|
||||
|
||||
You probably have seen how to declare the `response_model` and `status_code` for a *path operation*.
|
||||
|
||||
That defines the metadata about the main response of a *path operation*.
|
||||
|
||||
You can also declare additional responses with their models, status codes, etc.
|
||||
|
||||
There's a whole chapter here in the documentation about it, you can read it at [Additional Responses in OpenAPI](./additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
## OpenAPI Extra
|
||||
|
||||
When you declare a *path operation* in your application, **FastAPI** automatically generates the relevant metadata about that *path operation* to be included in the OpenAPI schema.
|
||||
|
||||
!!! note "Technical details"
|
||||
In the OpenAPI specification it is called the <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Object</a>.
|
||||
|
||||
It has all the information about the *path operation* and is used to generate the automatic documentation.
|
||||
|
||||
It includes the `tags`, `parameters`, `requestBody`, `responses`, etc.
|
||||
|
||||
This *path operation*-specific OpenAPI schema is normally generated automatically by **FastAPI**, but you can also extend it.
|
||||
|
||||
!!! tip
|
||||
This is a low level extension point.
|
||||
|
||||
If you only need to declare additonal responses, a more convenient way to do it is with [Additional Responses in OpenAPI](./additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
You can extend the OpenAPI schema for a *path operation* using the parameter `openapi_extra`.
|
||||
|
||||
### OpenAPI Extensions
|
||||
|
||||
This `openapi_extra` can be helpful, for example, to declare [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!}
|
||||
```
|
||||
|
||||
If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*.
|
||||
|
||||
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
|
||||
|
||||
And if you see the resulting OpenAPI (at `/openapi.json` in your API), you will see your extension as part of the specific *path operation* too:
|
||||
|
||||
```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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Custom OpenAPI *path operation* schema
|
||||
|
||||
The dictionary in `openapi_extra` will be deeply merged with the automatically generated OpenAPI schema for the *path operation*.
|
||||
|
||||
So, you could add additional data to the automatically generated schema.
|
||||
|
||||
For example, you could decide to read and validate the request with your own code, without using the automatic features of FastAPI with Pydantic, but you could still want to define the request in the OpenAPI schema.
|
||||
|
||||
You could do that with `openapi_extra`:
|
||||
|
||||
```Python hl_lines="20-37 39-40"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
|
||||
```
|
||||
|
||||
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <abbr title="converted from some plain format, like bytes, into Python objects">parsed</abbr> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
|
||||
|
||||
Nevertheless, we can declare the expected schema for the request body.
|
||||
|
||||
### Custom OpenAPI content type
|
||||
|
||||
Using this same trick, you could use a Pydantic model to define the JSON Schema that is then included in the custom OpenAPI schema section for the *path operation*.
|
||||
|
||||
And you could do this even if the data type in the request is not JSON.
|
||||
|
||||
For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:
|
||||
|
||||
```Python hl_lines="17-22 24"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
|
||||
Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.
|
||||
|
||||
Then we use the request directly, and extract the body as `bytes`. This means that FastAPI won't even try to parse the request payload as JSON.
|
||||
|
||||
And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:
|
||||
|
||||
```Python hl_lines="26-33"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Here we re-use the same Pydantic model.
|
||||
|
||||
But the same way, we could have validated it in some other way.
|
||||
|
||||
@@ -235,7 +235,7 @@ And then we can require it from the *path operation function* as a dependency an
|
||||
|
||||
Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
|
||||
|
||||
```Python hl_lines="8-9 12 21"
|
||||
```Python hl_lines="9-10 13 21"
|
||||
{!../../../docs_src/settings/app02/test_main.py!}
|
||||
```
|
||||
|
||||
@@ -288,7 +288,7 @@ Reading a file from disk is normally a costly (slow) operation, so you probably
|
||||
But every time we do:
|
||||
|
||||
```Python
|
||||
config.Settings()
|
||||
Settings()
|
||||
```
|
||||
|
||||
a new `Settings` object would be created, and at creation it would read the `.env` file again.
|
||||
@@ -297,7 +297,7 @@ If the dependency function was just like:
|
||||
|
||||
```Python
|
||||
def get_settings():
|
||||
return config.Settings()
|
||||
return Settings()
|
||||
```
|
||||
|
||||
we would create that object for each request, and we would be reading the `.env` file for each request. ⚠️
|
||||
|
||||
@@ -102,13 +102,15 @@ To see the difference, imagine the following story about burgers:
|
||||
|
||||
### Concurrent Burgers
|
||||
|
||||
<!-- The gender neutral cook emoji "🧑🍳" does not render well in browsers. In the meantime, I'm using a mix of male "👨🍳" and female "👩🍳" cooks. -->
|
||||
|
||||
You go with your crush 😍 to get fast food 🍔, you stand in line while the cashier 💁 takes the orders from the people in front of you.
|
||||
|
||||
Then it's your turn, you place your order of 2 very fancy burgers 🍔 for your crush 😍 and you.
|
||||
|
||||
You pay 💸.
|
||||
|
||||
The cashier 💁 says something to the guy in the kitchen 👨🍳 so he knows he has to prepare your burgers 🍔 (even though he is currently preparing the ones for the previous clients).
|
||||
The cashier 💁 says something to the cook in the kitchen 👨🍳 so they know they have to prepare your burgers 🍔 (even though they are currently preparing the ones for the previous clients).
|
||||
|
||||
The cashier 💁 gives you the number of your turn.
|
||||
|
||||
@@ -146,9 +148,9 @@ Now let's imagine these aren't "Concurrent Burgers", but "Parallel Burgers".
|
||||
|
||||
You go with your crush 😍 to get parallel fast food 🍔.
|
||||
|
||||
You stand in line while several (let's say 8) cashiers that at the same time are cooks 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳 take the orders from the people in front of you.
|
||||
You stand in line while several (let's say 8) cashiers that at the same time are cooks 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 take the orders from the people in front of you.
|
||||
|
||||
Everyone before you is waiting 🕙 for their burgers 🍔 to be ready before leaving the counter because each of the 8 cashiers goes himself and prepares the burger right away before getting the next order.
|
||||
Everyone before you is waiting 🕙 for their burgers 🍔 to be ready before leaving the counter because each of the 8 cashiers goes and prepares the burger right away before getting the next order.
|
||||
|
||||
Then it's finally your turn, you place your order of 2 very fancy burgers 🍔 for your crush 😍 and you.
|
||||
|
||||
@@ -174,7 +176,7 @@ There was not much talk or flirting as most of the time was spent waiting 🕙 i
|
||||
|
||||
In this scenario of the parallel burgers, you are a computer / program 🤖 with two processors (you and your crush 😍), both waiting 🕙 and dedicating their attention ⏯ to be "waiting on the counter" 🕙 for a long time.
|
||||
|
||||
The fast food store has 8 processors (cashiers/cooks) 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳. While the concurrent burgers store might have had only 2 (one cashier and one cook) 💁 👨🍳.
|
||||
The fast food store has 8 processors (cashiers/cooks) 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳. While the concurrent burgers store might have had only 2 (one cashier and one cook) 💁 👨🍳.
|
||||
|
||||
But still, the final experience is not the best 😞.
|
||||
|
||||
@@ -236,7 +238,7 @@ You could have turns as in the burgers example, first the living room, then the
|
||||
|
||||
It would take the same amount of time to finish with or without turns (concurrency) and you would have done the same amount of work.
|
||||
|
||||
But in this case, if you could bring the 8 ex-cashier/cooks/now-cleaners 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳, and each one of them (plus you) could take a zone of the house to clean it, you could do all the work in **parallel**, with the extra help, and finish much sooner.
|
||||
But in this case, if you could bring the 8 ex-cashier/cooks/now-cleaners 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳, and each one of them (plus you) could take a zone of the house to clean it, you could do all the work in **parallel**, with the extra help, and finish much sooner.
|
||||
|
||||
In this scenario, each one of the cleaners (including you) would be a processor, doing their part of the job.
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ a.internal-link::after {
|
||||
.user-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.user-list-center {
|
||||
@@ -99,3 +100,7 @@ a.announce-link:hover {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.twitter {
|
||||
color: #00acee;
|
||||
}
|
||||
|
||||
@@ -114,54 +114,55 @@ These are the **Sponsors**. 😎
|
||||
|
||||
They are supporting my work with **FastAPI** (and others), mainly through <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
|
||||
|
||||
{% if sponsors %}
|
||||
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### Gold Sponsors
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors.silver %}
|
||||
|
||||
### Silver Sponsors
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors.bronze %}
|
||||
|
||||
### Bronze Sponsors
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.bronze -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
### Individual Sponsors
|
||||
|
||||
{% if people %}
|
||||
{% if people.sponsors_50 %}
|
||||
{% if github_sponsors %}
|
||||
{% for group in github_sponsors.sponsors %}
|
||||
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors_50 %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if people %}
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors %}
|
||||
|
||||
<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>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
## About the data - technical details
|
||||
|
||||
@@ -32,7 +32,6 @@ If you need a 2 minute refresher of how to use Python types (even if you don't u
|
||||
You write standard Python with types:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -20,6 +20,10 @@ You can subscribe to the (infrequent) [**FastAPI and friends** newsletter](/news
|
||||
* Breaking changes 🚨
|
||||
* Tips and tricks ✅
|
||||
|
||||
## Follow FastAPI on Twitter
|
||||
|
||||
<a href="https://twitter.com/fastapi" class="external-link" target="_blank">Follow @fastapi on **Twitter**</a> to get the latest news about **FastAPI**. 🐦
|
||||
|
||||
## Star **FastAPI** in GitHub
|
||||
|
||||
You can "star" FastAPI in GitHub (clicking the star button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. ⭐️
|
||||
@@ -32,7 +36,7 @@ You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right)
|
||||
|
||||
There you can select "Releases only".
|
||||
|
||||
Doing it, you will receive notifications (in your email) whenever there's a new release (a new version) of **FastAPI** with bug fixes and new features.
|
||||
By doing it, you will receive notifications (in your email) whenever there's a new release (a new version) of **FastAPI** with bug fixes and new features.
|
||||
|
||||
## Connect with the author
|
||||
|
||||
@@ -46,17 +50,18 @@ You can:
|
||||
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Follow me on **Twitter**</a>.
|
||||
* Tell me how you use FastAPI (I love to hear that).
|
||||
* Hear when I make announcements or release new tools.
|
||||
* You can also <a href="https://twitter.com/fastapi" class="external-link" target="_blank">follow @fastapi on Twitter</a> (a separate account).
|
||||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Connect with me on **Linkedin**</a>.
|
||||
* Hear when I make announcements or release new tools (although I use Twitter more often 🤷♂).
|
||||
* Read what I write (or follow me) on <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> or <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
|
||||
* Read other ideas, articles, and about tools I have created.
|
||||
* Read other ideas, articles, and read about tools I have created.
|
||||
* Follow me to read when I publish something new.
|
||||
|
||||
## Tweet about **FastAPI**
|
||||
|
||||
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank">Tweet about **FastAPI**</a> and let me and others know why you like it. 🎉
|
||||
<a href="https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/tiangolo/fastapi" class="external-link" target="_blank">Tweet about **FastAPI**</a> and let me and others know why you like it. 🎉
|
||||
|
||||
I love to hear about how **FastAPI** is being used, what have you liked in it, in which project/company are you using it, etc.
|
||||
I love to hear about how **FastAPI** is being used, what you have liked in it, in which project/company are you using it, etc.
|
||||
|
||||
## Vote for FastAPI
|
||||
|
||||
@@ -67,15 +72,15 @@ I love to hear about how **FastAPI** is being used, what have you liked in it, i
|
||||
|
||||
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 they are questions that you might already know the answer for. 🤓
|
||||
|
||||
If you are helping a lot of people on issues you might become an official [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}. 🎉
|
||||
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}. 🎉
|
||||
|
||||
## 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>. 👀
|
||||
|
||||
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.
|
||||
|
||||
Then you can try and help them solving those issues.
|
||||
Then you can try and help them solve those issues.
|
||||
|
||||
## Create issues
|
||||
|
||||
@@ -84,7 +89,7 @@ You can <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="e
|
||||
* Ask a **question** or ask about a **problem**.
|
||||
* Suggest a new **feature**.
|
||||
|
||||
**Note**: if you create an issue then I'm going to ask you to also help others. 😉
|
||||
**Note**: if you create an issue, then I'm going to ask you to also help others. 😉
|
||||
|
||||
## Create a Pull Request
|
||||
|
||||
@@ -92,9 +97,9 @@ You can [contribute](contributing.md){.internal-link target=_blank} to the sourc
|
||||
|
||||
* To fix a typo you found on the documentation.
|
||||
* To share an article, video, or podcast you created or found about FastAPI by <a href="https://github.com/tiangolo/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">editing this file</a>.
|
||||
* Make sure you add your link to the end of the corresponding section.
|
||||
* Make sure you add your link to the start of the corresponding section.
|
||||
* To help [translate the documentation](contributing.md#translations){.internal-link target=_blank} to your language.
|
||||
* You can also help reviewing the translations created by others.
|
||||
* You can also help to review the translations created by others.
|
||||
* To propose new documentation sections.
|
||||
* To fix an existing issue/bug.
|
||||
* To add a new feature.
|
||||
|
||||
BIN
docs/en/docs/img/tutorial/dataclasses/image01.png
Normal file
BIN
docs/en/docs/img/tutorial/dataclasses/image01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 88 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
@@ -46,10 +46,10 @@ The key features are:
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 }}"></a>
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -3,6 +3,118 @@
|
||||
## Latest Changes
|
||||
|
||||
|
||||
## 0.68.1
|
||||
|
||||
* ✨ Add support for `read_with_orm_mode`, to support [SQLModel](https://sqlmodel.tiangolo.com/) relationship attributes. PR [#3757](https://github.com/tiangolo/fastapi/pull/3757) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Portuguese translation of `docs/fastapi-people.md`. PR [#3461](https://github.com/tiangolo/fastapi/pull/3461) by [@ComicShrimp](https://github.com/ComicShrimp).
|
||||
* 🌐 Add Chinese translation for `docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#3492](https://github.com/tiangolo/fastapi/pull/3492) by [@jaystone776](https://github.com/jaystone776).
|
||||
* 🔧 Add new Translation tracking issues for German and Indonesian. PR [#3718](https://github.com/tiangolo/fastapi/pull/3718) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🌐 Add Chinese translation for `docs/tutorial/dependencies/sub-dependencies.md`. PR [#3491](https://github.com/tiangolo/fastapi/pull/3491) by [@jaystone776](https://github.com/jaystone776).
|
||||
* 🌐 Add Portuguese translation for `docs/advanced/index.md`. PR [#3460](https://github.com/tiangolo/fastapi/pull/3460) by [@ComicShrimp](https://github.com/ComicShrimp).
|
||||
* 🌐 Portuguese translation of `docs/async.md`. PR [#1330](https://github.com/tiangolo/fastapi/pull/1330) by [@Serrones](https://github.com/Serrones).
|
||||
* 🌐 Add French translation for `docs/async.md`. PR [#3416](https://github.com/tiangolo/fastapi/pull/3416) by [@Smlep](https://github.com/Smlep).
|
||||
|
||||
### Internal
|
||||
|
||||
* ✨ Add GitHub Action: Notify Translations. PR [#3715](https://github.com/tiangolo/fastapi/pull/3715) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ✨ Update computation of FastAPI People and sponsors. PR [#3714](https://github.com/tiangolo/fastapi/pull/3714) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ✨ Enable recent Material for MkDocs Insiders features. PR [#3710](https://github.com/tiangolo/fastapi/pull/3710) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔥 Remove/clean extra imports from examples in docs for features. PR [#3709](https://github.com/tiangolo/fastapi/pull/3709) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ➕ Update docs library to include sources in Markdown. PR [#3648](https://github.com/tiangolo/fastapi/pull/3648) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Enable tests for Python 3.9. PR [#2298](https://github.com/tiangolo/fastapi/pull/2298) by [@Kludex](https://github.com/Kludex).
|
||||
* 👥 Update FastAPI People. PR [#3642](https://github.com/tiangolo/fastapi/pull/3642) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
|
||||
## 0.68.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add support for extensions and updates to the OpenAPI schema in each *path operation*. New docs: [FastAPI Path Operation Advanced Configuration - OpenAPI Extra](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#openapi-extra). Initial PR [#1922](https://github.com/tiangolo/fastapi/pull/1922) by [@edouardlp](https://github.com/edouardlp).
|
||||
* ✨ Add additonal OpenAPI metadata parameters to `FastAPI` class, shown on the automatic API docs UI. New docs: [Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/). Initial PR [#1812](https://github.com/tiangolo/fastapi/pull/1812) by [@dkreeft](https://github.com/dkreeft).
|
||||
* ✨ Add `description` parameter to all the security scheme classes, e.g. `APIKeyQuery(name="key", description="A very cool API key")`. PR [#1757](https://github.com/tiangolo/fastapi/pull/1757) by [@hylkepostma](https://github.com/hylkepostma).
|
||||
* ✨ Update OpenAPI models, supporting recursive models and extensions. PR [#3628](https://github.com/tiangolo/fastapi/pull/3628) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ✨ Import and re-export data structures from Starlette, used by Request properties, on `fastapi.datastructures`. Initial PR [#1872](https://github.com/tiangolo/fastapi/pull/1872) by [@jamescurtin](https://github.com/jamescurtin).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Update docs about async and response-model with more gender neutral language. PR [#1869](https://github.com/tiangolo/fastapi/pull/1869) by [@Edward-Knight](https://github.com/Edward-Knight).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Russian translation for `docs/python-types.md`. PR [#3039](https://github.com/tiangolo/fastapi/pull/3039) by [@dukkee](https://github.com/dukkee).
|
||||
* 🌐 Add Chinese translation for `docs/tutorial/dependencies/index.md`. PR [#3489](https://github.com/tiangolo/fastapi/pull/3489) by [@jaystone776](https://github.com/jaystone776).
|
||||
* 🌐 Add Russian translation for `docs/external-links.md`. PR [#3036](https://github.com/tiangolo/fastapi/pull/3036) by [@dukkee](https://github.com/dukkee).
|
||||
* 🌐 Add Chinese translation for `docs/tutorial/dependencies/global-dependencies.md`. PR [#3493](https://github.com/tiangolo/fastapi/pull/3493) by [@jaystone776](https://github.com/jaystone776).
|
||||
* 🌐 Add Portuguese translation for `docs/deployment/versions.md`. PR [#3618](https://github.com/tiangolo/fastapi/pull/3618) by [@lsglucas](https://github.com/lsglucas).
|
||||
* 🌐 Add Japanese translation for `docs/tutorial/security/oauth2-jwt.md`. PR [#3526](https://github.com/tiangolo/fastapi/pull/3526) by [@sattosan](https://github.com/sattosan).
|
||||
|
||||
### Internal
|
||||
|
||||
* ✅ Add the `docs_src` directory to test coverage and update tests. Initial PR [#1904](https://github.com/tiangolo/fastapi/pull/1904) by [@Kludex](https://github.com/Kludex).
|
||||
* 🔧 Add new GitHub templates with forms for new issues. PR [#3612](https://github.com/tiangolo/fastapi/pull/3612) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 📝 Add official FastAPI Twitter to docs: [@fastapi](https://twitter.com/fastapi). PR [#3578](https://github.com/tiangolo/fastapi/pull/3578) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.67.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add support for `dataclasses` in request bodies and `response_model`. New documentation: [Advanced User Guide - Using Dataclasses](https://fastapi.tiangolo.com/advanced/dataclasses/). PR [#3577](https://github.com/tiangolo/fastapi/pull/3577) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ✨ Support `dataclasses` in responses. PR [#3576](https://github.com/tiangolo/fastapi/pull/3576) by [@tiangolo](https://github.com/tiangolo), continuation from initial PR [#2722](https://github.com/tiangolo/fastapi/pull/2722) by [@amitlissack](https://github.com/amitlissack).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Add external link: How to Create A Fake Certificate Authority And Generate TLS Certs for FastAPI. PR [#2839](https://github.com/tiangolo/fastapi/pull/2839) by [@aitoehigie](https://github.com/aitoehigie).
|
||||
* ✏ Fix code highlighted line in: `body-nested-models.md`. PR [#3463](https://github.com/tiangolo/fastapi/pull/3463) by [@jaystone776](https://github.com/jaystone776).
|
||||
* ✏ Fix typo in `body-nested-models.md`. PR [#3462](https://github.com/tiangolo/fastapi/pull/3462) by [@jaystone776](https://github.com/jaystone776).
|
||||
* ✏ Fix typo "might me" -> "might be" in `docs/en/docs/tutorial/schema-extra-example.md`. PR [#3362](https://github.com/tiangolo/fastapi/pull/3362) by [@dbrakman](https://github.com/dbrakman).
|
||||
* 📝 Add external link: Building simple E-Commerce with NuxtJS and FastAPI. PR [#3271](https://github.com/tiangolo/fastapi/pull/3271) by [@ShahriyarR](https://github.com/ShahriyarR).
|
||||
* 📝 Add external link: Serve a machine learning model using Sklearn, FastAPI and Docker. PR [#2974](https://github.com/tiangolo/fastapi/pull/2974) by [@rodrigo-arenas](https://github.com/rodrigo-arenas).
|
||||
* ✏️ Fix typo on docstring in datastructures file. PR [#2887](https://github.com/tiangolo/fastapi/pull/2887) by [@Kludex](https://github.com/Kludex).
|
||||
* 📝 Add External Link: Deploy FastAPI on Ubuntu and Serve using Caddy 2 Web Server. PR [#3572](https://github.com/tiangolo/fastapi/pull/3572) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 📝 Add External Link, replaces #1898. PR [#3571](https://github.com/tiangolo/fastapi/pull/3571) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🎨 Improve style for sponsors, add radius border. PR [#2388](https://github.com/tiangolo/fastapi/pull/2388) by [@Kludex](https://github.com/Kludex).
|
||||
* 👷 Update GitHub Action latest-changes. PR [#3574](https://github.com/tiangolo/fastapi/pull/3574) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Update GitHub Action latest-changes. PR [#3573](https://github.com/tiangolo/fastapi/pull/3573) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Rename and clarify CI workflow job names. PR [#3570](https://github.com/tiangolo/fastapi/pull/3570) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Update GitHub Action latest-changes, strike 2 ⚾. PR [#3575](https://github.com/tiangolo/fastapi/pull/3575) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Sort external links in docs to have the most recent at the top. PR [#3568](https://github.com/tiangolo/fastapi/pull/3568) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.66.1
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add basic setup for German translations. PR [#3522](https://github.com/tiangolo/fastapi/pull/3522) by [@0x4Dark](https://github.com/0x4Dark).
|
||||
* 🌐 Add Portuguese translation for `docs/tutorial/security/index.md`. PR [#3507](https://github.com/tiangolo/fastapi/pull/3507) by [@oandersonmagalhaes](https://github.com/oandersonmagalhaes).
|
||||
* 🌐 Add Portuguese translation for `docs/deployment/index.md`. PR [#3337](https://github.com/tiangolo/fastapi/pull/3337) by [@lsglucas](https://github.com/lsglucas).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔧 Configure strict pytest options and update/refactor tests. Upgrade pytest to `>=6.2.4,<7.0.0` and pytest-cov to `>=2.12.0,<3.0.0`. Initial PR [#2790](https://github.com/tiangolo/fastapi/pull/2790) by [@graingert](https://github.com/graingert).
|
||||
* ⬆️ Upgrade python-jose dependency to `>=3.3.0,<4.0.0` for tests. PR [#3468](https://github.com/tiangolo/fastapi/pull/3468) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.66.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Allow setting the `response_class` to `RedirectResponse` or `FileResponse` and returning the URL from the function. New and updated docs are in the tutorial section **Custom Response - HTML, Stream, File, others**, in [RedirectResponse](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse) and in [FileResponse](https://fastapi.tiangolo.com/advanced/custom-response/#fileresponse). PR [#3457](https://github.com/tiangolo/fastapi/pull/3457) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix include/exclude for dicts in `jsonable_encoder`. PR [#2016](https://github.com/tiangolo/fastapi/pull/2016) by [@Rubikoid](https://github.com/Rubikoid).
|
||||
* 🐛 Support custom OpenAPI / JSON Schema fields in the generated output OpenAPI. PR [#1429](https://github.com/tiangolo/fastapi/pull/1429) by [@jmagnusson](https://github.com/jmagnusson).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Spanish translation for `tutorial/query-params.md`. PR [#2243](https://github.com/tiangolo/fastapi/pull/2243) by [@mariacamilagl](https://github.com/mariacamilagl).
|
||||
* 🌐 Add Spanish translation for `advanced/response-directly.md`. PR [#1253](https://github.com/tiangolo/fastapi/pull/1253) by [@jfunez](https://github.com/jfunez).
|
||||
* 🌐 Add Spanish translation for `advanced/additional-status-codes.md`. PR [#1252](https://github.com/tiangolo/fastapi/pull/1252) by [@jfunez](https://github.com/jfunez).
|
||||
* 🌐 Add Spanish translation for `advanced/path-operation-advanced-configuration.md`. PR [#1251](https://github.com/tiangolo/fastapi/pull/1251) by [@jfunez](https://github.com/jfunez).
|
||||
|
||||
## 0.65.3
|
||||
|
||||
### Fixes
|
||||
|
||||
@@ -198,7 +198,7 @@ Even for items inside of lists:
|
||||
|
||||
<img src="/img/tutorial/body-nested-models/image01.png">
|
||||
|
||||
You couldn't get this kind of editor support if you where working directly with `dict` instead of Pydantic models.
|
||||
You couldn't get this kind of editor support if you were working directly with `dict` instead of Pydantic models.
|
||||
|
||||
But you don't have to worry about them either, incoming dicts are converted automatically and your output is converted automatically to JSON too.
|
||||
|
||||
@@ -218,7 +218,7 @@ That's what we are going to see here.
|
||||
|
||||
In this case, you would accept any `dict` as long as it has `int` keys with `float` values:
|
||||
|
||||
```Python hl_lines="15"
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/body_nested_models/tutorial009.py!}
|
||||
```
|
||||
|
||||
|
||||
@@ -2,21 +2,28 @@
|
||||
|
||||
You can customize several metadata configurations in your **FastAPI** application.
|
||||
|
||||
## Title, description, and version
|
||||
## Metadata for API
|
||||
|
||||
You can set the:
|
||||
You can set the following fields that are used in the OpenAPI specification and the automatic API docs UIs:
|
||||
|
||||
* **Title**: used as your API's title/name, in OpenAPI and the automatic API docs UIs.
|
||||
* **Description**: the description of your API, in OpenAPI and the automatic API docs UIs.
|
||||
* **Version**: the version of your API, e.g. `v2` or `2.5.0`.
|
||||
* Useful for example if you had a previous version of the application, also using OpenAPI.
|
||||
| Parameter | Type | Description |
|
||||
|------------|------|-------------|
|
||||
| `title` | `str` | The title of the API. |
|
||||
| `description` | `str` | A short description of the API. It can use Markdown. |
|
||||
| `version` | `string` | The version of the API. This is the version of your own application, not of OpenAPI. For example `2.5.0`. |
|
||||
| `terms_of_service` | `str` | A URL to the Terms of Service for the API. If provided, this has to be a URL. |
|
||||
| `contact` | `dict` | The contact information for the exposed API. It can contain several fields. <details><summary><code>contact</code> fields</summary><table><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>The identifying name of the contact person/organization.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>The URL pointing to the contact information. MUST be in the format of a URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>The email address of the contact person/organization. MUST be in the format of an email address.</td></tr></tbody></table></details> |
|
||||
| `license_info` | `dict` | The license information for the exposed API. It can contain several fields. <details><summary><code>license_info</code> fields</summary><table><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>REQUIRED</strong> (if a <code>license_info</code> is set). The license name used for the API.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>A URL to the license used for the API. MUST be in the format of a URL.</td></tr></tbody></table></details> |
|
||||
|
||||
To set them, use the parameters `title`, `description`, and `version`:
|
||||
You can set them as follows:
|
||||
|
||||
```Python hl_lines="4-6"
|
||||
```Python hl_lines="3-16 19-31"
|
||||
{!../../../docs_src/metadata/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
You can write Markdown in the `description` field and it will be rendered in the output.
|
||||
|
||||
With this configuration, the automatic API docs would look like:
|
||||
|
||||
<img src="/img/tutorial/metadata/image01.png">
|
||||
|
||||
@@ -47,7 +47,7 @@ And we are using this model to declare our input and the same model to declare o
|
||||
|
||||
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 himself is sending the password.
|
||||
In this case, it might not be a problem, because the user themself is 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.
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ With `examples` added to `Body()` the `/docs` would look like:
|
||||
!!! warning
|
||||
These are very technical details about the standards **JSON Schema** and **OpenAPI**.
|
||||
|
||||
If the ideas above already work for you, that might me enough, and you probably don't need these details, feel free to skip them.
|
||||
If the ideas above already work for you, that might be enough, and you probably don't need these details, feel free to skip them.
|
||||
|
||||
When you add an example inside of a Pydantic model, using `schema_extra` or `Field(example="something")` that example is added to the **JSON Schema** for that Pydantic model.
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -118,6 +120,7 @@ nav:
|
||||
- advanced/security/oauth2-scopes.md
|
||||
- advanced/security/http-basic-auth.md
|
||||
- advanced/using-request-directly.md
|
||||
- advanced/dataclasses.md
|
||||
- advanced/middleware.md
|
||||
- advanced/sql-databases-peewee.md
|
||||
- advanced/async-sql-databases.md
|
||||
@@ -160,7 +163,10 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
# Uncomment these 2 lines during development to more easily add highlights
|
||||
# - pymdownx.highlight:
|
||||
# linenums: true
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -169,7 +175,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -178,7 +184,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -190,6 +196,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -220,6 +228,5 @@ extra_css:
|
||||
- css/termynal.css
|
||||
- css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- js/termynal.js
|
||||
- js/custom.js
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
{% block announce %}
|
||||
<div class="announce-wrapper">
|
||||
<div id="announce-left">
|
||||
<div class="item">
|
||||
<a class="announce-link" href="https://twitter.com/fastapi" target="_blank">
|
||||
<span class="twemoji twitter">
|
||||
{% include ".icons/fontawesome/brands/twitter.svg" %}
|
||||
</span> Follow <strong>@fastapi</strong> on <strong>Twitter</strong> to stay updated
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a class="announce-link" href="https://fastapi.tiangolo.com/newsletter/">
|
||||
<span class="twemoji">
|
||||
@@ -15,12 +22,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="announce-right" style="position: relative;">
|
||||
<div class="item">
|
||||
<!-- <div class="item">
|
||||
<a title="The launchpad for all your (team's) ideas" style="display: block; position: relative;" href="https://www.deta.sh/?ref=fastapi" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
<img class="sponsor-image" src="/img/sponsors/deta-banner.svg" />
|
||||
</a>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="item">
|
||||
<a title="Get three courses at 10% off their current prices! Plus, we'll be donating 10% of all profits from sales of this bundle to the FastAPI team." style="display: block; position: relative;" href="https://testdriven.io/talkpython/" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
|
||||
37
docs/es/docs/advanced/additional-status-codes.md
Normal file
37
docs/es/docs/advanced/additional-status-codes.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Códigos de estado adicionales
|
||||
|
||||
Por defecto, **FastAPI** devolverá las respuestas utilizando una `JSONResponse`, poniendo el contenido que devuelves en tu *operación de path* dentro de esa `JSONResponse`.
|
||||
|
||||
Utilizará el código de estado por defecto, o el que hayas asignado en tu *operación de path*.
|
||||
|
||||
## Códigos de estado adicionales
|
||||
|
||||
Si quieres devolver códigos de estado adicionales además del principal, puedes hacerlo devolviendo directamente una `Response`, como una `JSONResponse`, y asignar directamente el código de estado adicional.
|
||||
|
||||
Por ejemplo, digamos que quieres tener una *operación de path* que permita actualizar ítems y devolver códigos de estado HTTP 200 "OK" cuando sea exitosa.
|
||||
|
||||
Pero también quieres que acepte nuevos ítems. Cuando los ítems no existan anteriormente, serán creados y devolverá un código de estado HTTP 201 "Created".
|
||||
|
||||
Para conseguir esto importa `JSONResponse` y devuelve ahí directamente tu contenido, asignando el `status_code` que quieras:
|
||||
|
||||
```Python hl_lines="2 19"
|
||||
{!../../../docs_src/additional_status_codes/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! warning "Advertencia"
|
||||
Cuando devuelves directamente una `Response`, como en los ejemplos anteriores, será devuelta directamente.
|
||||
|
||||
No será serializado con el modelo, etc.
|
||||
|
||||
Asegurate de que la respuesta tenga los datos que quieras, y que los valores sean JSON válidos (si estás usando `JSONResponse`).
|
||||
|
||||
!!! note "Detalles Técnicos"
|
||||
También podrías utilizar `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** provee las mismas `starlette.responses` que `fastapi.responses` simplemente como una convención para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette. Lo mismo con `status`.
|
||||
|
||||
## OpenAPI y documentación de API
|
||||
|
||||
Si quieres devolver códigos de estado y respuestas adicionales directamente, estas no estarán incluidas en el schema de OpenAPI (documentación de API), porque FastAPI no tiene una manera de conocer de antemano lo que vas a devolver.
|
||||
|
||||
Pero puedes documentar eso en tu código usando [Respuestas Adicionales](additional-responses.md){.internal-link target=_blank}.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Configuración avanzada de las operaciones de path
|
||||
|
||||
## OpenAPI operationId
|
||||
|
||||
!!! warning "Advertencia"
|
||||
Si no eres una persona "experta" en OpenAPI, probablemente no necesitas leer esto.
|
||||
|
||||
Puedes asignar el `operationId` de OpenAPI para ser usado en tu *operación de path* con el parámetro `operation_id`.
|
||||
|
||||
En este caso tendrías que asegurarte de que sea único para cada operación.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Usando el nombre de la *función de la operación de path* en el operationId
|
||||
|
||||
Si quieres usar tus nombres de funciones de API como `operationId`s, puedes iterar sobre todos ellos y sobrescribir `operation_id` de cada *operación de path* usando su `APIRoute.name`.
|
||||
|
||||
Deberías hacerlo después de adicionar todas tus *operaciones de path*.
|
||||
|
||||
```Python hl_lines="2 12 13 14 15 16 17 18 19 20 21 24"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! tip "Consejo"
|
||||
Si llamas manualmente a `app.openapi()`, debes actualizar el `operationId`s antes de hacerlo.
|
||||
|
||||
!!! warning "Advertencia"
|
||||
Si haces esto, debes asegurarte de que cada una de tus *funciones de las operaciones de path* tenga un nombre único.
|
||||
|
||||
Incluso si están en diferentes módulos (archivos Python).
|
||||
|
||||
## Excluir de OpenAPI
|
||||
|
||||
Para excluir una *operación de path* del esquema OpenAPI generado (y por tanto del la documentación generada automáticamente), usa el parámetro `include_in_schema` y asigna el valor como `False`;
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
## Descripción avanzada desde el docstring
|
||||
|
||||
Puedes limitar las líneas usadas desde el docstring de una *operación de path* para OpenAPI.
|
||||
|
||||
Agregar un `\f` (un carácter de "form feed" escapado) hace que **FastAPI** trunque el output utilizada para OpenAPI en ese punto.
|
||||
|
||||
No será mostrado en la documentación, pero otras herramientas (como Sphinx) serán capaces de usar el resto.
|
||||
|
||||
```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
|
||||
```
|
||||
63
docs/es/docs/advanced/response-directly.md
Normal file
63
docs/es/docs/advanced/response-directly.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Devolver una respuesta directamente
|
||||
|
||||
Cuando creas una *operación de path* normalmente puedes devolver cualquier dato: un `dict`, una `list`, un modelo Pydantic, un modelo de base de datos, etc.
|
||||
|
||||
Por defecto, **FastAPI** convertiría automáticamente ese valor devuelto a JSON usando el `jsonable_encoder` explicado en [Codificador Compatible JSON](../tutorial/encoder.md){.internal-link target=_blank}.
|
||||
|
||||
Luego, tras bastidores, pondría esos datos compatibles con JSON (por ejemplo, un `dict`) dentro de una `JSONResponse` que se usaría para enviar la respuesta al cliente.
|
||||
|
||||
Pero puedes devolver una `JSONResponse` directamente de tu *operación de path*.
|
||||
|
||||
Esto puede ser útil, por ejemplo, para devolver cookies o headers personalizados.
|
||||
|
||||
## Devolver una `Response`
|
||||
|
||||
De hecho, puedes devolver cualquier `Response` o cualquier subclase de la misma.
|
||||
|
||||
!!! tip "Consejo"
|
||||
`JSONResponse` en sí misma es una subclase de `Response`.
|
||||
|
||||
Y cuando devuelves una `Response`, **FastAPI** la pasará directamente.
|
||||
|
||||
No hará ninguna conversión de datos con modelos Pydantic, no convertirá el contenido a ningún tipo, etc.
|
||||
|
||||
Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de dato, sobrescribir cualquer declaración de datos o validación, etc.
|
||||
|
||||
## Usando el `jsonable_encoder` en una `Response`
|
||||
|
||||
Como **FastAPI** no realiza ningún cambio en la `Response` que devuelves, debes asegurarte de que el contenido está listo.
|
||||
|
||||
Por ejemplo, no puedes poner un modelo Pydantic en una `JSONResponse` sin primero convertirlo a un `dict` con todos los tipos de datos (como `datetime`, `UUID`, etc) convertidos a tipos compatibles con JSON.
|
||||
|
||||
Para esos casos, puedes usar el `jsonable_encoder` para convertir tus datos antes de pasarlos a la respuesta:
|
||||
|
||||
```Python hl_lines="4 6 20 21"
|
||||
{!../../../docs_src/response_directly/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Detalles Técnicos"
|
||||
También puedes usar `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** provee `starlette.responses` como `fastapi.responses`, simplemente como una conveniencia para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette.
|
||||
|
||||
## Devolviendo una `Response` personalizada
|
||||
|
||||
El ejemplo anterior muestra las partes que necesitas, pero no es muy útil todavía, dado que podrías simplemente devolver el `item` directamente, y **FastAPI** lo pondría en una `JSONResponse` por ti, convirtiéndolo en un `dict`, etc. Todo esto por defecto.
|
||||
|
||||
Ahora, veamos cómo puedes usarlo para devolver una respuesta personalizada.
|
||||
|
||||
Digamos que quieres devolver una respuesta <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a>.
|
||||
|
||||
Podrías poner tu contenido XML en un string, ponerlo en una `Response` y devolverlo:
|
||||
|
||||
```Python hl_lines="1 18"
|
||||
{!../../../docs_src/response_directly/tutorial002.py!}
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Cuando devuelves una `Response` directamente, los datos no son validados, convertidos (serializados), ni documentados automáticamente.
|
||||
|
||||
Pero todavía es posible documentarlo como es descrito en [Respuestas adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
Puedes ver en secciones posteriores como usar/declarar esas `Response`s personalizadas aún teniendo conversión automática de datos, documentación, etc.
|
||||
@@ -32,7 +32,6 @@ Si necesitas un repaso de 2 minutos de cómo usar los tipos de Python (así no u
|
||||
Escribes Python estándar con tipos así:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -39,13 +39,16 @@ Sus características principales son:
|
||||
|
||||
<small>* Esta estimación está basada en pruebas con un equipo de desarrollo interno contruyendo aplicaciones listas para producción.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
197
docs/es/docs/tutorial/query-params.md
Normal file
197
docs/es/docs/tutorial/query-params.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Parámetros de query
|
||||
|
||||
Cuando declaras otros parámetros de la función que no hacen parte de los parámetros de path estos se interpretan automáticamente como parámetros de "query".
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
El query es el conjunto de pares de key-value que van después del `?` en la URL, separados por caracteres `&`.
|
||||
|
||||
Por ejemplo, en la URL:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||
```
|
||||
|
||||
...los parámetros de query son:
|
||||
|
||||
* `skip`: con un valor de `0`
|
||||
* `limit`: con un valor de `10`
|
||||
|
||||
Dado que son parte de la URL son strings "naturalmente".
|
||||
|
||||
Pero cuando los declaras con tipos de Python (en el ejemplo arriba, como `int`) son convertidos a ese tipo y son validados con él.
|
||||
|
||||
Todo el proceso que aplicaba a los parámetros de path también aplica a los parámetros de query:
|
||||
|
||||
* Soporte del editor (obviamente)
|
||||
* <abbr title="convertir el string que viene de un HTTP request a datos de Python">"Parsing"</abbr> de datos
|
||||
* Validación de datos
|
||||
* Documentación automática
|
||||
|
||||
## Configuraciones por defecto
|
||||
|
||||
Como los parámetros de query no están fijos en una parte del path pueden ser opcionales y pueden tener valores por defecto.
|
||||
|
||||
El ejemplo arriba tiene `skip=0` y `limit=10` como los valores por defecto.
|
||||
|
||||
Entonces, si vas a la URL:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/
|
||||
```
|
||||
|
||||
Sería lo mismo que ir a:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||
```
|
||||
|
||||
Pero, si por ejemplo vas a:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?skip=20
|
||||
```
|
||||
|
||||
Los valores de los parámetros en tu función serán:
|
||||
|
||||
* `skip=20`: porque lo definiste en la URL
|
||||
* `limit=10`: porque era el valor por defecto
|
||||
|
||||
## Parámetros opcionales
|
||||
|
||||
Del mismo modo puedes declarar parámetros de query opcionales definiendo el valor por defecto como `None`:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
En este caso el parámetro de la función `q` será opcional y será `None` por defecto.
|
||||
|
||||
!!! check "Revisa"
|
||||
También puedes notar que **FastAPI** es lo suficientemente inteligente para darse cuenta de que el parámetro de path `item_id` es un parámetro de path y que `q` no lo es, y por lo tanto es un parámetro de query.
|
||||
|
||||
!!! note "Nota"
|
||||
FastAPI sabrá que `q` es opcional por el `= None`.
|
||||
|
||||
El `Optional` en `Optional[str]` no es usado por FastAPI (FastAPI solo usará la parte `str`), pero el `Optional[str]` le permitirá a tu editor ayudarte a encontrar errores en tu código.
|
||||
|
||||
## Conversión de tipos de parámetros de query
|
||||
|
||||
También puedes declarar tipos `bool` y serán convertidos:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
En este caso, si vas a:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=1
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=True
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=true
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=on
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=yes
|
||||
```
|
||||
|
||||
o cualquier otra variación (mayúsculas, primera letra en mayúscula, etc.) tu función verá el parámetro `short` con un valor `bool` de `True`. Si no, lo verá como `False`.
|
||||
|
||||
## Múltiples parámetros de path y query
|
||||
|
||||
Puedes declarar múltiples parámetros de path y parámetros de query al mismo tiempo. **FastAPI** sabe cuál es cuál.
|
||||
|
||||
No los tienes que declarar en un orden específico.
|
||||
|
||||
Serán detectados por nombre:
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!../../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Parámetros de query requeridos
|
||||
|
||||
Cuando declaras un valor por defecto para los parámetros que no son de path (por ahora solo hemos visto parámetros de query), entonces no es requerido.
|
||||
|
||||
Si no quieres añadir un valor específico sino solo hacerlo opcional, pon el valor por defecto como `None`.
|
||||
|
||||
Pero cuando quieres hacer que un parámetro de query sea requerido, puedes simplemente no declararle un valor por defecto:
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!../../../docs_src/query_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
Aquí el parámetro de query `needy` es un parámetro de query requerido, del tipo `str`.
|
||||
|
||||
Si abres tu navegador en una URL como:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo-item
|
||||
```
|
||||
|
||||
...sin añadir el parámetro `needy` requerido, verás un error como:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": [
|
||||
"query",
|
||||
"needy"
|
||||
],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Dado que `needy` es un parámetro requerido necesitarías declararlo en la URL:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
```
|
||||
|
||||
...esto funcionaría:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item_id": "foo-item",
|
||||
"needy": "sooooneedy"
|
||||
}
|
||||
```
|
||||
|
||||
Por supuesto que también puedes definir algunos parámetros como requeridos, con un valor por defecto y otros completamente opcionales:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
|
||||
En este caso hay 3 parámetros de query:
|
||||
|
||||
* `needy`, un `str` requerido.
|
||||
* `skip`, un `int` con un valor por defecto de `0`.
|
||||
* `limit`, un `int` opcional.
|
||||
|
||||
!!! tip "Consejo"
|
||||
También podrías usar los `Enum`s de la misma manera que con los [Parámetros de path](path-params.md#predefined-values){.internal-link target=_blank}.
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -58,6 +60,7 @@ nav:
|
||||
- tutorial/index.md
|
||||
- tutorial/first-steps.md
|
||||
- tutorial/path-params.md
|
||||
- tutorial/query-params.md
|
||||
- Guía de Usuario Avanzada:
|
||||
- advanced/index.md
|
||||
- async.md
|
||||
@@ -66,7 +69,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -75,7 +78,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -84,7 +87,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -96,6 +99,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -126,6 +131,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
394
docs/fr/docs/async.md
Normal file
394
docs/fr/docs/async.md
Normal file
@@ -0,0 +1,394 @@
|
||||
# Concurrence et les mots-clés async et await
|
||||
|
||||
Cette page vise à fournir des détails sur la syntaxe `async def` pour les *fonctions de chemins* et quelques rappels sur le code asynchrone, la concurrence et le parallélisme.
|
||||
|
||||
## Vous êtes pressés ?
|
||||
|
||||
<abbr title="'too long; didn't read' en anglais, ou 'trop long ; j'ai pas lu'"><strong>TL;DR :</strong></abbr>
|
||||
|
||||
Si vous utilisez des bibliothèques tierces qui nécessitent d'être appelées avec `await`, telles que :
|
||||
|
||||
```Python
|
||||
results = await some_library()
|
||||
```
|
||||
Alors, déclarez vos *fonctions de chemins* avec `async def` comme ceci :
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
async def read_results():
|
||||
results = await some_library()
|
||||
return results
|
||||
```
|
||||
|
||||
!!! note
|
||||
Vous pouvez uniquement utiliser `await` dans les fonctions créées avec `async def`.
|
||||
|
||||
---
|
||||
|
||||
Si vous utilisez une bibliothèque externe qui communique avec quelque chose (une BDD, une API, un système de fichiers, etc.) et qui ne supporte pas l'utilisation d'`await` (ce qui est actuellement le cas pour la majorité des bibliothèques de BDD), alors déclarez vos *fonctions de chemin* normalement, avec le classique `def`, comme ceci :
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
def results():
|
||||
results = some_library()
|
||||
return results
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Si votre application n'a pas à communiquer avec une bibliothèque externe et pas à attendre de réponse, utilisez `async def`.
|
||||
|
||||
---
|
||||
|
||||
Si vous ne savez pas, utilisez seulement `def` comme vous le feriez habituellement.
|
||||
|
||||
---
|
||||
|
||||
**Note** : vous pouvez mélanger `def` et `async def` dans vos *fonctions de chemin* autant que nécessaire, **FastAPI** saura faire ce qu'il faut avec.
|
||||
|
||||
Au final, peu importe le cas parmi ceux ci-dessus, **FastAPI** fonctionnera de manière asynchrone et sera extrêmement rapide.
|
||||
|
||||
Mais si vous suivez bien les instructions ci-dessus, alors **FastAPI** pourra effectuer quelques optimisations et ainsi améliorer les performances.
|
||||
|
||||
## Détails techniques
|
||||
|
||||
Les versions modernes de Python supportent le **code asynchrone** grâce aux **"coroutines"** avec les syntaxes **`async` et `await`**.
|
||||
|
||||
Analysons les différentes parties de cette phrase dans les sections suivantes :
|
||||
|
||||
* **Code asynchrone**
|
||||
* **`async` et `await`**
|
||||
* **Coroutines**
|
||||
|
||||
## Code asynchrone
|
||||
|
||||
Faire du code asynchrone signifie que le langage 💬 est capable de dire à l'ordinateur / au programme 🤖 qu'à un moment du code, il 🤖 devra attendre que *quelque chose d'autre* se termine autre part. Disons que ce *quelque chose d'autre* est appelé "fichier-lent" 📝.
|
||||
|
||||
Donc, pendant ce temps, l'ordinateur pourra effectuer d'autres tâches, pendant que "fichier-lent" 📝 se termine.
|
||||
|
||||
Ensuite l'ordinateur / le programme 🤖 reviendra à chaque fois qu'il en a la chance que ce soit parce qu'il attend à nouveau, ou car il 🤖 a fini tout le travail qu'il avait à faire. Il 🤖 regardera donc si les tâches qu'il attend ont terminé d'être effectuées.
|
||||
|
||||
Ensuite, il 🤖 prendra la première tâche à finir (disons, notre "fichier-lent" 📝) et continuera à faire avec cette dernière ce qu'il était censé.
|
||||
|
||||
Ce "attendre quelque chose d'autre" fait généralement référence à des opérations <abbr title="Input/Output ou Entrées et Sorties ">I/O</abbr> qui sont relativement "lentes" (comparées à la vitesse du processeur et de la mémoire RAM) telles qu'attendre que :
|
||||
|
||||
* de la donnée soit envoyée par le client à travers le réseau
|
||||
* de la donnée envoyée depuis votre programme soit reçue par le client à travers le réseau
|
||||
* le contenu d'un fichier sur le disque soit lu par le système et passé à votre programme
|
||||
* le contenu que votre programme a passé au système soit écrit sur le disque
|
||||
* une opération effectuée à distance par une API se termine
|
||||
* une opération en BDD se termine
|
||||
* une requête à une BDD renvoie un résultat
|
||||
* etc.
|
||||
|
||||
Le temps d'exécution étant consommé majoritairement par l'attente d'opérations <abbr title="Input/Output ou Entrées et Sorties ">I/O</abbr> on appelle ceci des opérations <a href="https://fr.wikipedia.org/wiki/I/O_bound" class="external-link" target="_blank">"I/O bound"</a>.
|
||||
|
||||
Ce concept se nomme l'"asynchronisme" car l'ordinateur / le programme n'a pas besoin d'être "synchronisé" avec la tâche, attendant le moment exact où cette dernière se terminera en ne faisant rien, pour être capable de récupérer le résultat de la tâche et l'utiliser dans la suite des opérations.
|
||||
|
||||
À la place, en étant "asynchrone", une fois terminée, une tâche peut légèrement attendre (quelques microsecondes) que l'ordinateur / le programme finisse ce qu'il était en train de faire, et revienne récupérer le résultat.
|
||||
|
||||
Pour parler de tâches "synchrones" (en opposition à "asynchrones"), on utilise souvent le terme "séquentiel", car l'ordinateur / le programme va effectuer toutes les étapes d'une tâche séquentiellement avant de passer à une autre tâche, même si ces étapes impliquent de l'attente.
|
||||
|
||||
### Concurrence et Burgers
|
||||
|
||||
L'idée de code **asynchrone** décrite ci-dessus est parfois aussi appelée **"concurrence"**. Ce qui est différent du **"parallélisme"**.
|
||||
|
||||
La **concurrence** et le **parallélisme** sont tous deux liés à l'idée de "différentes choses arrivant plus ou moins au même moment".
|
||||
|
||||
Mais les détails entre la **concurrence** et le **parallélisme** diffèrent sur de nombreux points.
|
||||
|
||||
Pour expliquer la différence, voici une histoire de burgers :
|
||||
|
||||
#### Burgers concurrents
|
||||
|
||||
Vous amenez votre crush 😍 dans votre fast food 🍔 favori, et faites la queue pendant que le serveur 💁 prend les commandes des personnes devant vous.
|
||||
|
||||
Puis vient votre tour, vous commandez alors 2 magnifiques burgers 🍔 pour votre crush 😍 et vous.
|
||||
|
||||
Vous payez 💸.
|
||||
|
||||
Le serveur 💁 dit quelque chose à son collègue dans la cuisine 👨🍳 pour qu'il sache qu'il doit préparer vos burgers 🍔 (bien qu'il soit déjà en train de préparer ceux des clients précédents).
|
||||
|
||||
Le serveur 💁 vous donne le numéro assigné à votre commande.
|
||||
|
||||
Pendant que vous attendez, vous allez choisir une table avec votre crush 😍, vous discutez avec votre crush 😍 pendant un long moment (les burgers étant "magnifiques" ils sont très longs à préparer ✨🍔✨).
|
||||
|
||||
Pendant que vous êtes assis à table, en attendant que les burgers 🍔 soient prêts, vous pouvez passer ce temps à admirer à quel point votre crush 😍 est géniale, mignonne et intelligente ✨😍✨.
|
||||
|
||||
Pendant que vous discutez avec votre crush 😍, de temps en temps vous jetez un coup d'oeil au nombre affiché au-dessus du comptoir pour savoir si c'est à votre tour d'être servis.
|
||||
|
||||
Jusqu'au moment où c'est (enfin) votre tour. Vous allez au comptoir, récupérez vos burgers 🍔 et revenez à votre table.
|
||||
|
||||
Vous et votre crush 😍 mangez les burgers 🍔 et passez un bon moment ✨.
|
||||
|
||||
---
|
||||
|
||||
Imaginez que vous êtes l'ordinateur / le programme 🤖 dans cette histoire.
|
||||
|
||||
Pendant que vous faites la queue, vous être simplement inactif 😴, attendant votre tour, ne faisant rien de "productif". Mais la queue est rapide car le serveur 💁 prend seulement les commandes (et ne les prépare pas), donc tout va bien.
|
||||
|
||||
Ensuite, quand c'est votre tour, vous faites des actions "productives" 🤓, vous étudiez le menu, décidez ce que vous voulez, demandez à votre crush 😍 son choix, payez 💸, vérifiez que vous utilisez la bonne carte de crédit, vérifiez que le montant débité sur la carte est correct, vérifiez que la commande contient les bons produits, etc.
|
||||
|
||||
Mais ensuite, même si vous n'avez pas encore vos burgers 🍔, votre travail avec le serveur 💁 est "en pause" ⏸, car vous devez attendre 🕙 que vos burgers soient prêts.
|
||||
|
||||
Après vous être écarté du comptoir et vous être assis à votre table avec le numéro de votre commande, vous pouvez tourner 🔀 votre attention vers votre crush 😍, et "travailler" ⏯ 🤓 là-dessus. Vous êtes donc à nouveau en train de faire quelque chose de "productif" 🤓, vous flirtez avec votre crush 😍.
|
||||
|
||||
Puis le serveur 💁 dit "J'ai fini de préparer les burgers" 🍔 en mettant votre numéro sur l'affichage du comptoir, mais vous ne courrez pas immédiatement au moment où votre numéro s'affiche. Vous savez que personne ne volera vos burgers 🍔 car vous avez votre numéro et les autres clients ont le leur.
|
||||
|
||||
Vous attendez donc que votre crush 😍 finisse son histoire, souriez gentiment et dites que vous allez chercher les burgers ⏸.
|
||||
|
||||
Pour finir vous allez au comptoir 🔀, vers la tâche initiale qui est désormais terminée ⏯, récupérez les burgers 🍔, remerciez le serveur et ramenez les burgers 🍔 à votre table. Ceci termine l'étape / la tâche d'interaction avec le comptoir ⏹. Ce qui ensuite, crée une nouvelle tâche de "manger les burgers" 🔀 ⏯, mais la précédente, "récupérer les burgers" est terminée ⏹.
|
||||
|
||||
#### Burgers parallèles
|
||||
|
||||
Imaginons désormais que ce ne sont pas des "burgers concurrents" mais des "burgers parallèles".
|
||||
|
||||
Vous allez avec votre crush 😍 dans un fast food 🍔 parallélisé.
|
||||
|
||||
Vous attendez pendant que plusieurs (disons 8) serveurs qui sont aussi des cuisiniers 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳 prennent les commandes des personnes devant vous.
|
||||
|
||||
Chaque personne devant vous attend 🕙 que son burger 🍔 soit prêt avant de quitter le comptoir car chacun des 8 serveurs va lui-même préparer le burger directement avant de prendre la commande suivante.
|
||||
|
||||
Puis c'est enfin votre tour, vous commandez 2 magnifiques burgers 🍔 pour vous et votre crush 😍.
|
||||
|
||||
Vous payez 💸.
|
||||
|
||||
Le serveur va dans la cuisine 👨🍳.
|
||||
|
||||
Vous attendez devant le comptoir afin que personne ne prenne vos burgers 🍔 avant vous, vu qu'il n'y a pas de numéro de commande.
|
||||
|
||||
Vous et votre crush 😍 étant occupés à vérifier que personne ne passe devant vous prendre vos burgers au moment où ils arriveront 🕙, vous ne pouvez pas vous préoccuper de votre crush 😞.
|
||||
|
||||
C'est du travail "synchrone", vous être "synchronisés" avec le serveur/cuisinier 👨🍳. Vous devez attendre 🕙 et être présent au moment exact où le serveur/cuisinier 👨🍳 finira les burgers 🍔 et vous les donnera, sinon quelqu'un risque de vous les prendre.
|
||||
|
||||
Puis le serveur/cuisinier 👨🍳 revient enfin avec vos burgers 🍔, après un long moment d'attente 🕙 devant le comptoir.
|
||||
|
||||
Vous prenez vos burgers 🍔 et allez à une table avec votre crush 😍
|
||||
|
||||
Vous les mangez, et vous avez terminé 🍔 ⏹.
|
||||
|
||||
Durant tout ce processus, il n'y a presque pas eu de discussions ou de flirts car la plupart de votre temps à été passé à attendre 🕙 devant le comptoir 😞.
|
||||
|
||||
---
|
||||
|
||||
Dans ce scénario de burgers parallèles, vous êtes un ordinateur / programme 🤖 avec deux processeurs (vous et votre crush 😍) attendant 🕙 à deux et dédiant votre attention 🕙 à "attendre devant le comptoir" pour une longue durée.
|
||||
|
||||
Le fast-food a 8 processeurs (serveurs/cuisiniers) 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳. Alors que le fast-food de burgers concurrents en avait 2 (un serveur et un cuisinier).
|
||||
|
||||
Et pourtant l'expérience finale n'est pas meilleure 😞.
|
||||
|
||||
---
|
||||
|
||||
C'est donc l'histoire équivalente parallèle pour les burgers 🍔.
|
||||
|
||||
Pour un exemple plus courant dans la "vie réelle", imaginez une banque.
|
||||
|
||||
Jusqu'à récemment, la plupart des banques avaient plusieurs caisses (et banquiers) 👨💼👨💼👨💼👨💼 et une unique file d'attente 🕙🕙🕙🕙🕙🕙🕙🕙.
|
||||
|
||||
Tous les banquiers faisaient l'intégralité du travail avec chaque client avant de passer au suivant 👨💼⏯.
|
||||
|
||||
Et vous deviez attendre 🕙 dans la file pendant un long moment ou vous perdiez votre place.
|
||||
|
||||
Vous n'auriez donc probablement pas envie d'amener votre crush 😍 avec vous à la banque 🏦.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Dans ce scénario des "burgers du fast-food avec votre crush", comme il y a beaucoup d'attente 🕙, il est très logique d'avoir un système concurrent ⏸🔀⏯.
|
||||
|
||||
Et c'est le cas pour la plupart des applications web.
|
||||
|
||||
Vous aurez de nombreux, nombreux utilisateurs, mais votre serveur attendra 🕙 que leur connexion peu performante envoie des requêtes.
|
||||
|
||||
Puis vous attendrez 🕙 de nouveau que leurs réponses reviennent.
|
||||
|
||||
Cette "attente" 🕙 se mesure en microsecondes, mais tout de même, en cumulé cela fait beaucoup d'attente.
|
||||
|
||||
C'est pourquoi il est logique d'utiliser du code asynchrone ⏸🔀⏯ pour des APIs web.
|
||||
|
||||
La plupart des frameworks Python existants (y compris Flask et Django) ont été créés avant que les nouvelles fonctionnalités asynchrones de Python n'existent. Donc, les façons dont ils peuvent être déployés supportent l'exécution parallèle et une ancienne forme d'exécution asynchrone qui n'est pas aussi puissante que les nouvelles fonctionnalités de Python.
|
||||
|
||||
Et cela, bien que les spécifications principales du web asynchrone en Python (ou ASGI) ont été développées chez Django, pour ajouter le support des WebSockets.
|
||||
|
||||
Ce type d'asynchronicité est ce qui a rendu NodeJS populaire (bien que NodeJS ne soit pas parallèle) et c'est la force du Go en tant que langage de programmation.
|
||||
|
||||
Et c'est le même niveau de performance que celui obtenu avec **FastAPI**.
|
||||
|
||||
Et comme on peut avoir du parallélisme et de l'asynchronicité en même temps, on obtient des performances plus hautes que la plupart des frameworks NodeJS et égales à celles du Go, qui est un langage compilé plus proche du C <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(tout ça grâce à Starlette)</a>.
|
||||
|
||||
### Est-ce que la concurrence est mieux que le parallélisme ?
|
||||
|
||||
Nope ! C'est ça la morale de l'histoire.
|
||||
|
||||
La concurrence est différente du parallélisme. C'est mieux sur des scénarios **spécifiques** qui impliquent beaucoup d'attente. À cause de ça, c'est généralement bien meilleur que le parallélisme pour le développement d'applications web. Mais pas pour tout.
|
||||
|
||||
Donc pour équilibrer tout ça, imaginez l'histoire suivante :
|
||||
|
||||
> Vous devez nettoyer une grande et sale maison.
|
||||
|
||||
*Oui, c'est toute l'histoire*.
|
||||
|
||||
---
|
||||
|
||||
Il n'y a plus d'attente 🕙 nulle part, juste beaucoup de travail à effectuer, dans différentes pièces de la maison.
|
||||
|
||||
Vous pourriez diviser en différentes sections comme avec les burgers, d'abord le salon, puis la cuisine, etc. Mais vous n'attendez 🕙 rien, vous ne faites que nettoyer et nettoyer, la séparation en sections ne changerait rien au final.
|
||||
|
||||
Cela prendrait autant de temps pour finir avec ou sans sections (concurrence) et vous auriez effectué la même quantité de travail.
|
||||
|
||||
Mais dans ce cas, si pouviez amener 8 ex-serveurs/cuisiniers/devenus-nettoyeurs 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳, et que chacun d'eux (plus vous) pouvait prendre une zone de la maison pour la nettoyer, vous pourriez faire tout le travail en parallèle, et finir plus tôt.
|
||||
|
||||
Dans ce scénario, chacun des nettoyeurs (vous y compris) serait un processeur, faisant sa partie du travail.
|
||||
|
||||
Et comme la plupart du temps d'exécution est pris par du "vrai" travail (et non de l'attente), et que le travail dans un ordinateur est fait par un <abbr title="Central Processing Unit">CPU</abbr>, ce sont des problèmes dits "CPU bound".
|
||||
|
||||
---
|
||||
|
||||
Des exemples communs d'opérations "CPU bounds" sont les procédés qui requièrent des traitements mathématiques complexes.
|
||||
|
||||
Par exemple :
|
||||
|
||||
* Traitements d'**audio** et d'**images**.
|
||||
* La **vision par ordinateur** : une image est composée de millions de pixels, chaque pixel ayant 3 valeurs / couleurs, les traiter tous va nécessiter d'effectuer des traitements sur chaque pixel, et de préférence tous en même temps.
|
||||
* L'apprentissage automatique (ou **Machine Learning**) : cela nécessite de nombreuses multiplications de matrices et vecteurs. Imaginez une énorme feuille de calcul remplie de nombres que vous multiplierez entre eux tous au même moment.
|
||||
* L'apprentissage profond (ou **Deep Learning**) : est un sous-domaine du **Machine Learning**, donc les mêmes raisons s'appliquent. Avec la différence qu'il n'y a pas une unique feuille de calcul de nombres à multiplier, mais une énorme quantité d'entre elles, et dans de nombreux cas, on utilise un processeur spécial pour construire et / ou utiliser ces modèles.
|
||||
|
||||
### Concurrence + Parallélisme : Web + Machine Learning
|
||||
|
||||
Avec **FastAPI** vous pouvez bénéficier de la concurrence qui est très courante en developement web (c'est l'attrait principal de NodeJS).
|
||||
|
||||
Mais vous pouvez aussi profiter du parallélisme et multiprocessing afin de gérer des charges **CPU bound** qui sont récurrentes dans les systèmes de *Machine Learning*.
|
||||
|
||||
Ça, ajouté au fait que Python soit le langage le plus populaire pour la **Data Science**, le **Machine Learning** et surtout le **Deep Learning**, font de **FastAPI** un très bon choix pour les APIs et applications de **Data Science** / **Machine Learning**.
|
||||
|
||||
Pour comprendre comment mettre en place ce parallélisme en production, allez lire la section [Déploiement](deployment/index.md){.internal-link target=_blank}.
|
||||
|
||||
## `async` et `await`
|
||||
|
||||
Les versions modernes de Python ont une manière très intuitive de définir le code asynchrone, tout en gardant une apparence de code "séquentiel" classique en laissant Python faire l'attente pour vous au bon moment.
|
||||
|
||||
Pour une opération qui nécessite de l'attente avant de donner un résultat et qui supporte ces nouvelles fonctionnalités Python, vous pouvez l'utiliser comme tel :
|
||||
|
||||
```Python
|
||||
burgers = await get_burgers(2)
|
||||
```
|
||||
|
||||
Le mot-clé important ici est `await`. Il informe Python qu'il faut attendre ⏸ que `get_burgers(2)` finisse d'effectuer ses opérations 🕙 avant de stocker les résultats dans la variable `burgers`. Grâce à cela, Python saura qu'il peut aller effectuer d'autres opérations 🔀 ⏯ pendant ce temps (comme par exemple recevoir une autre requête).
|
||||
|
||||
Pour que `await` fonctionne, il doit être placé dans une fonction qui supporte l'asynchronicité. Pour que ça soit le cas, il faut déclarer cette dernière avec `async def` :
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def get_burgers(number: int):
|
||||
# Opérations asynchrones pour créer les burgers
|
||||
return burgers
|
||||
```
|
||||
|
||||
...et non `def` :
|
||||
|
||||
```Python hl_lines="2"
|
||||
# Ceci n'est pas asynchrone
|
||||
def get_sequential_burgers(number: int):
|
||||
# Opérations asynchrones pour créer les burgers
|
||||
return burgers
|
||||
```
|
||||
|
||||
Avec `async def`, Python sait que dans cette fonction il doit prendre en compte les expressions `await`, et qu'il peut mettre en pause ⏸ l'exécution de la fonction pour aller faire autre chose 🔀 avant de revenir.
|
||||
|
||||
Pour appeler une fonction définie avec `async def`, vous devez utiliser `await`. Donc ceci ne marche pas :
|
||||
|
||||
```Python
|
||||
# Ceci ne fonctionne pas, car get_burgers a été défini avec async def
|
||||
burgers = get_burgers(2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Donc, si vous utilisez une bibliothèque qui nécessite que ses fonctions soient appelées avec `await`, vous devez définir la *fonction de chemin* en utilisant `async def` comme dans :
|
||||
|
||||
```Python hl_lines="2-3"
|
||||
@app.get('/burgers')
|
||||
async def read_burgers():
|
||||
burgers = await get_burgers(2)
|
||||
return burgers
|
||||
```
|
||||
|
||||
### Plus de détails techniques
|
||||
|
||||
Vous avez donc compris que `await` peut seulement être utilisé dans des fonctions définies avec `async def`.
|
||||
|
||||
Mais en même temps, les fonctions définies avec `async def` doivent être appelées avec `await` et donc dans des fonctions définies elles aussi avec `async def`.
|
||||
|
||||
Vous avez donc remarqué ce paradoxe d'oeuf et de la poule, comment appelle-t-on la première fonction `async` ?
|
||||
|
||||
Si vous utilisez **FastAPI**, pas besoin de vous en inquiéter, car cette "première" fonction sera votre *fonction de chemin* ; et **FastAPI** saura comment arriver au résultat attendu.
|
||||
|
||||
Mais si vous utilisez `async` / `await` sans **FastAPI**, <a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" class="external-link" target="_blank">allez jetez un coup d'oeil à la documentation officielle de Python</a>.
|
||||
|
||||
### Autres formes de code asynchrone
|
||||
|
||||
L'utilisation d'`async` et `await` est relativement nouvelle dans ce langage.
|
||||
|
||||
Mais cela rend la programmation asynchrone bien plus simple.
|
||||
|
||||
Cette même syntaxe (ou presque) était aussi incluse dans les versions modernes de Javascript (dans les versions navigateur et NodeJS).
|
||||
|
||||
Mais avant ça, gérer du code asynchrone était bien plus complexe et difficile.
|
||||
|
||||
Dans les versions précédentes de Python, vous auriez utilisé des *threads* ou <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>. Mais le code aurait été bien plus difficile à comprendre, débugger, et concevoir.
|
||||
|
||||
Dans les versions précédentes de Javascript NodeJS / Navigateur, vous auriez utilisé des "callbacks". Menant potentiellement à ce que l'on appelle <a href="http://callbackhell.com/" class="external-link" target="_blank">le "callback hell"</a>.
|
||||
|
||||
|
||||
## Coroutines
|
||||
|
||||
**Coroutine** est juste un terme élaboré pour désigner ce qui est retourné par une fonction définie avec `async def`. Python sait que c'est comme une fonction classique qui va démarrer à un moment et terminer à un autre, mais qu'elle peut aussi être mise en pause ⏸, du moment qu'il y a un `await` dans son contenu.
|
||||
|
||||
Mais toutes ces fonctionnalités d'utilisation de code asynchrone avec `async` et `await` sont souvent résumées comme l'utilisation des *coroutines*. On peut comparer cela à la principale fonctionnalité clé de Go, les "Goroutines".
|
||||
|
||||
## Conclusion
|
||||
|
||||
Reprenons la phrase du début de la page :
|
||||
|
||||
> Les versions modernes de Python supportent le **code asynchrone** grâce aux **"coroutines"** avec les syntaxes **`async` et `await`**.
|
||||
|
||||
Ceci devrait être plus compréhensible désormais. ✨
|
||||
|
||||
Tout ceci est donc ce qui donne sa force à **FastAPI** (à travers Starlette) et lui permet d'avoir des performances aussi impressionnantes.
|
||||
|
||||
## Détails très techniques
|
||||
|
||||
!!! warning "Attention !"
|
||||
Vous pouvez probablement ignorer cela.
|
||||
|
||||
Ce sont des détails très poussés sur comment **FastAPI** fonctionne en arrière-plan.
|
||||
|
||||
Si vous avez de bonnes connaissances techniques (coroutines, threads, code bloquant, etc.) et êtes curieux de comment **FastAPI** gère `async def` versus le `def` classique, cette partie est faite pour vous.
|
||||
|
||||
### Fonctions de chemin
|
||||
|
||||
Quand vous déclarez une *fonction de chemin* avec un `def` normal et non `async def`, elle est exécutée dans un groupe de threads (threadpool) externe qui est ensuite attendu, plutôt que d'être appelée directement (car cela bloquerait le serveur).
|
||||
|
||||
Si vous venez d'un autre framework asynchrone qui ne fonctionne pas comme de la façon décrite ci-dessus et que vous êtes habitués à définir des *fonctions de chemin* basiques avec un simple `def` pour un faible gain de performance (environ 100 nanosecondes), veuillez noter que dans **FastAPI**, l'effet serait plutôt contraire. Dans ces cas-là, il vaut mieux utiliser `async def` à moins que votre *fonction de chemin* utilise du code qui effectue des opérations <abbr title="Input/Output ou Entrées et Sorties ">I/O</abbr> bloquantes.
|
||||
|
||||
Au final, dans les deux situations, il est fort probable que **FastAPI** soit tout de même [plus rapide](/#performance){.internal-link target=_blank} que (ou au moins de vitesse égale à) votre framework précédent.
|
||||
|
||||
### Dépendances
|
||||
|
||||
La même chose s'applique aux dépendances. Si une dépendance est définie avec `def` plutôt que `async def`, elle est exécutée dans la threadpool externe.
|
||||
|
||||
### Sous-dépendances
|
||||
|
||||
Vous pouvez avoir de multiples dépendances et sous-dépendances dépendant les unes des autres (en tant que paramètres de la définition de la *fonction de chemin*), certaines créées avec `async def` et d'autres avec `def`. Cela fonctionnerait aussi, et celles définies avec un simple `def` seraient exécutées sur un thread externe (venant de la threadpool) plutôt que d'être "attendues".
|
||||
|
||||
### Autres fonctions utilitaires
|
||||
|
||||
Toute autre fonction utilitaire que vous appelez directement peut être créée avec un classique `def` ou avec `async def` et **FastAPI** n'aura pas d'impact sur la façon dont vous l'appelez.
|
||||
|
||||
Contrairement aux fonctions que **FastAPI** appelle pour vous : les *fonctions de chemin* et dépendances.
|
||||
|
||||
Si votre fonction utilitaire est une fonction classique définie avec `def`, elle sera appelée directement (telle qu'écrite dans votre code), pas dans une threadpool, si la fonction est définie avec `async def` alors vous devrez attendre (avec `await`) que cette fonction se termine avant de passer à la suite du code.
|
||||
|
||||
---
|
||||
|
||||
Encore une fois, ce sont des détails très techniques qui peuvent être utiles si vous venez ici les chercher.
|
||||
|
||||
Sinon, les instructions de la section <a href="#vous-etes-presses">Vous êtes pressés ?</a> ci-dessus sont largement suffisantes.
|
||||
@@ -114,14 +114,51 @@ Ce sont les **Sponsors**. 😎
|
||||
|
||||
Ils soutiennent mon travail avec **FastAPI** (et d'autres) avec <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
|
||||
|
||||
{% if people %}
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### Gold 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 %}
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors.silver %}
|
||||
|
||||
### Silver Sponsors
|
||||
|
||||
{% 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 %}
|
||||
|
||||
### Bronze Sponsors
|
||||
|
||||
{% 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 %}
|
||||
|
||||
### Individual Sponsors
|
||||
|
||||
{% if github_sponsors %}
|
||||
{% for group in github_sponsors.sponsors %}
|
||||
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors %}
|
||||
|
||||
{% 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 %}
|
||||
|
||||
## À propos des données - détails techniques
|
||||
|
||||
@@ -32,7 +32,6 @@ Si vous souhaitez un rappel de 2 minutes sur l'utilisation des types en Python (
|
||||
Vous écrivez du python standard avec des annotations de types:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -57,6 +59,7 @@ nav:
|
||||
- python-types.md
|
||||
- Tutoriel - Guide utilisateur:
|
||||
- tutorial/background-tasks.md
|
||||
- async.md
|
||||
- project-generation.md
|
||||
- alternatives.md
|
||||
- external-links.md
|
||||
@@ -65,7 +68,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -74,7 +77,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -83,7 +86,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -95,6 +98,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -125,6 +130,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,12 +40,14 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
@@ -56,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -65,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -74,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -86,6 +89,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -98,6 +103,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
@@ -114,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
0
docs/id/overrides/.gitignore
vendored
Normal file
0
docs/id/overrides/.gitignore
vendored
Normal file
@@ -1,13 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block announce %}
|
||||
<a class="announce" href="https://fastapi.tiangolo.com/newsletter/">
|
||||
<span class="twemoji">
|
||||
{% include ".icons/material/email.svg" %}
|
||||
</span> Subscribe to the <strong>FastAPI and friends</strong> newsletter 🎉
|
||||
</a>
|
||||
<!-- <a class="announce" href="https://tripetto.app/run/RXZ6OLDBXX?s=dc" target="_blank">
|
||||
<span class="twemoji">
|
||||
</span>Fill the first-ever <strong>FastAPI user survey</strong> for a chance to win official <strong>FastAPI and Typer stickers</strong> 🎁
|
||||
</a> -->
|
||||
{% endblock %}
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -57,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -66,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -75,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -87,6 +89,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -117,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -179,7 +179,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
これにはクラウドストレージとの連携や映像処理など、多くのライブラリが含まれています。
|
||||
|
||||
```Python hl_lines="2 10-11"
|
||||
```Python hl_lines="2 10-12 14"
|
||||
{!../../../docs_src/custom_response/tutorial008.py!}
|
||||
```
|
||||
|
||||
|
||||
@@ -115,48 +115,51 @@ FastAPIには、様々なバックグラウンドの人々を歓迎する素晴
|
||||
|
||||
彼らは、<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a> を介して私の **FastAPI** などに関する活動を支援してくれています。
|
||||
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### Gold Sponsors
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors.silver %}
|
||||
|
||||
### Silver Sponsors
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if people %}
|
||||
{% if people.sponsors_50 %}
|
||||
{% if sponsors.bronze %}
|
||||
|
||||
### Bronze Sponsors
|
||||
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors_50 %}
|
||||
|
||||
<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>
|
||||
{% for sponsor in sponsors.bronze -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
### Individual Sponsors
|
||||
|
||||
{% if people %}
|
||||
{% if github_sponsors %}
|
||||
{% for group in github_sponsors.sponsors %}
|
||||
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors %}
|
||||
|
||||
{% 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 %}
|
||||
|
||||
## データについて - 技術詳細
|
||||
|
||||
@@ -31,7 +31,6 @@ FastAPIの機能はすべて、標準のPython 3.6型宣言に基づいていま
|
||||
型を使用した標準的なPythonを記述します:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -40,13 +40,16 @@ FastAPI は、Pythonの標準である型ヒントに基づいてPython 3.6 以
|
||||
|
||||
<small>\* 本番アプリケーションを構築している開発チームのテストによる見積もり。</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
266
docs/ja/docs/tutorial/security/oauth2-jwt.md
Normal file
266
docs/ja/docs/tutorial/security/oauth2-jwt.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# パスワード(およびハッシュ化)によるOAuth2、JWTトークンによるBearer
|
||||
|
||||
これでセキュリティの流れが全てわかったので、<abbr title="JSON Web Tokens">JWT</abbr>トークンと安全なパスワードのハッシュ化を使用して、実際にアプリケーションを安全にしてみましょう。
|
||||
|
||||
このコードは、アプリケーションで実際に使用したり、パスワードハッシュをデータベースに保存するといった用途に利用できます。
|
||||
|
||||
本章では、前章の続きから始めて、コードをアップデートしていきます。
|
||||
|
||||
## JWT について
|
||||
|
||||
JWTとは「JSON Web Tokens」の略称です。
|
||||
|
||||
JSONオブジェクトをスペースのない長く密集した文字列で表現したトークンの仕様です。例えば次のようになります:
|
||||
|
||||
```
|
||||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||
```
|
||||
|
||||
これらは暗号化されていないので、誰でもコンテンツから情報を復元できてしまいます。
|
||||
|
||||
しかし、トークンは署名されているため、あなたが発行したトークンを受け取った人は、あなたが実際に発行したということを検証できます。
|
||||
|
||||
例えば、1週間の有効期限を持つトークンを作成したとします。ユーザーが翌日そのトークンを持って戻ってきたとき、そのユーザーはまだシステムにログインしていることがわかります。
|
||||
|
||||
1週間後、トークンが期限切れとなるとどうなるでしょうか?ユーザーは認可されず、新しいトークンを得るために再びサインインしなければなりません。また、ユーザー(または第三者)がトークンを修正して有効期限を変更しようとした場合、署名が一致しないため、トークンの修正を検知できます。
|
||||
|
||||
JWT トークンを使って遊んでみたいという方は、<a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> をチェックしてください。
|
||||
|
||||
## `python-jose` のインストール
|
||||
|
||||
PythonでJWTトークンの生成と検証を行うために、`python-jose`をインストールする必要があります:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install python-jose[cryptography]
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
また、<a href="https://github.com/mpdavis/python-jose" class="external-link" target="_blank">Python-jose</a>だけではなく、暗号を扱うためのパッケージを追加で必要とします。
|
||||
|
||||
ここでは、推奨されているものを使用します:<a href="https://cryptography.io/" class="external-link" target="_blank">pyca/cryptography</a>。
|
||||
|
||||
!!! tip "豆知識"
|
||||
このチュートリアルでは以前、<a href="https://pyjwt.readthedocs.io/" class="external-link" target="_blank">PyJWT</a>を使用していました。
|
||||
|
||||
しかし、Python-joseは、PyJWTのすべての機能に加えて、後に他のツールと統合して構築する際におそらく必要となる可能性のあるいくつかの追加機能を提供しています。そのため、代わりにPython-joseを使用するように更新されました。
|
||||
|
||||
## パスワードのハッシュ化
|
||||
|
||||
「ハッシュ化」とは、あるコンテンツ(ここではパスワード)を、規則性のないバイト列(単なる文字列)に変換することです。
|
||||
|
||||
特徴として、全く同じ内容(全く同じパスワード)を渡すと、全く同じ規則性のないバイト列に変換されます。
|
||||
|
||||
しかし、規則性のないバイト列から元のパスワードに戻すことはできません。
|
||||
|
||||
### パスワードのハッシュ化を使う理由
|
||||
|
||||
データベースが盗まれても、ユーザーの平文のパスワードは盗まれず、ハッシュ値だけが盗まれます。
|
||||
|
||||
したがって、泥棒はそのパスワードを別のシステムで使えません(多くのユーザーはどこでも同じパスワードを使用しているため、危険性があります)。
|
||||
|
||||
## `passlib` のインストール
|
||||
|
||||
PassLib は、パスワードのハッシュを処理するための優れたPythonパッケージです。
|
||||
|
||||
このパッケージは、多くの安全なハッシュアルゴリズムとユーティリティをサポートします。
|
||||
|
||||
推奨されるアルゴリズムは「Bcrypt」です。
|
||||
|
||||
そのため、Bcryptを指定してPassLibをインストールします:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install passlib[bcrypt]
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip "豆知識"
|
||||
`passlib`を使用すると、**Django**や**Flask**のセキュリティプラグインなどで作成されたパスワードを読み取れるように設定できます。
|
||||
|
||||
例えば、Djangoアプリケーションからデータベース内の同じデータをFastAPIアプリケーションと共有できるだけではなく、同じデータベースを使用してDjangoアプリケーションを徐々に移行することもできます。
|
||||
|
||||
また、ユーザーはDjangoアプリまたは**FastAPI**アプリからも、同時にログインできるようになります。
|
||||
|
||||
|
||||
## パスワードのハッシュ化と検証
|
||||
|
||||
必要なツールを `passlib`からインポートします。
|
||||
|
||||
PassLib の「context」を作成します。これは、パスワードのハッシュ化と検証に使用されるものです。
|
||||
|
||||
!!! tip "豆知識"
|
||||
PassLibのcontextには、検証だけが許された非推奨の古いハッシュアルゴリズムを含む、様々なハッシュアルゴリズムを使用した検証機能もあります。
|
||||
|
||||
例えば、この機能を使用して、別のシステム(Djangoなど)によって生成されたパスワードを読み取って検証し、Bcryptなどの別のアルゴリズムを使用して新しいパスワードをハッシュするといったことができます。
|
||||
|
||||
そして、同時にそれらはすべてに互換性があります。
|
||||
|
||||
ユーザーから送られてきたパスワードをハッシュ化するユーティリティー関数を作成します。
|
||||
|
||||
また、受け取ったパスワードが保存されているハッシュと一致するかどうかを検証するユーティリティも作成します。
|
||||
|
||||
さらに、ユーザーを認証して返す関数も作成します。
|
||||
|
||||
```Python hl_lines="7 48 55-56 59-60 69-75"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! note "備考"
|
||||
新しい(偽の)データベース`fake_users_db`を確認すると、ハッシュ化されたパスワードが次のようになっていることがわかります:`"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`
|
||||
|
||||
## JWTトークンの取り扱い
|
||||
|
||||
インストールした複数のモジュールをインポートします。
|
||||
|
||||
JWTトークンの署名に使用されるランダムな秘密鍵を生成します。
|
||||
|
||||
安全なランダム秘密鍵を生成するには、次のコマンドを使用します:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ openssl rand -hex 32
|
||||
|
||||
09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
そして、出力された文字列を変数`SECRET_KEY`にコピーします。(例に記載している秘密鍵は実際に使用しないでください)
|
||||
|
||||
JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定した変数`ALGORITHM`を作成します。
|
||||
|
||||
トークンの有効期限を指定した変数`ACCESS_TOKEN_EXPIRE_MINUTES`を作成します。
|
||||
|
||||
レスポンスのトークンエンドポイントで使用するPydanticモデルを定義します。
|
||||
|
||||
新しいアクセストークンを生成するユーティリティ関数を作成します。
|
||||
|
||||
```Python hl_lines="6 12-14 28-30 78-86"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
## 依存関係の更新
|
||||
|
||||
`get_current_user`を更新して、先ほどと同じトークンを受け取るようにしますが、今回はJWTトークンを使用します。
|
||||
|
||||
受け取ったトークンを復号して検証し、現在のユーザーを返します。
|
||||
|
||||
トークンが無効な場合は、すぐにHTTPエラーを返します。
|
||||
|
||||
```Python hl_lines="89-106"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
## `/token` パスオペレーションの更新
|
||||
|
||||
トークンの有効期限を表す`timedelta`を作成します。
|
||||
|
||||
JWTアクセストークンを作成し、それを返します。
|
||||
|
||||
```Python hl_lines="115-128"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
### JWTの"subject" `sub` についての技術的な詳細
|
||||
|
||||
JWTの仕様では、トークンのsubjectを表すキー`sub`があるとされています。
|
||||
|
||||
使用するかどうかは任意ですが、`sub`はユーザーの識別情報を入れるように規定されているので、ここで使用します。
|
||||
|
||||
JWTは、ユーザーを識別して、そのユーザーがAPI上で直接操作を実行できるようにする以外にも、他の用途で使用されることがあります。
|
||||
|
||||
例えば、「車」や「ブログ記事」を識別することができます。
|
||||
|
||||
そして、「ドライブ」(車の場合)や「編集」(ブログの場合)など、そのエンティティに関する権限も追加できます。
|
||||
|
||||
また、JWTトークンをユーザー(またはボット)に渡すことができます。ユーザーは、JWTトークンを使用するだけで、アカウントを持っていなくても、APIが生成したJWTトークンを使ってそれらの行動(車の運転、ブログ投稿の編集)を実行できるのです。
|
||||
|
||||
これらのアイデアを使用すると、JWTをより高度なシナリオに使用できます。
|
||||
|
||||
しかしながら、それらのエンティティのいくつかが同じIDを持つ可能性があります。例えば、`foo`(ユーザー`foo`、車 `foo`、ブログ投稿`foo`)などです。
|
||||
|
||||
IDの衝突を回避するために、ユーザーのJWTトークンを作成するとき、subキーの値にプレフィックスを付けることができます(例えば、`username:`)。したがって、この例では、`sub`の値は次のようになっている可能性があります:`username:johndoe`
|
||||
|
||||
覚えておくべき重要なことは、`sub`キーはアプリケーション全体で一意の識別子を持ち、文字列である必要があるということです。
|
||||
|
||||
## 確認
|
||||
|
||||
サーバーを実行し、ドキュメントに移動します:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
|
||||
|
||||
次のようなユーザーインターフェイスが表示されます:
|
||||
|
||||
<img src="/img/tutorial/security/image07.png">
|
||||
|
||||
前回と同じ方法でアプリケーションの認可を行います。
|
||||
|
||||
次の認証情報を使用します:
|
||||
|
||||
Username: `johndoe`
|
||||
Password: `secret`
|
||||
|
||||
!!! check "確認"
|
||||
コードのどこにも平文のパスワード"`secret`"はなく、ハッシュ化されたものしかないことを確認してください。
|
||||
|
||||
<img src="/img/tutorial/security/image08.png">
|
||||
|
||||
エンドポイント`/users/me/`を呼び出すと、次のようなレスポンスが得られます:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"username": "johndoe",
|
||||
"email": "johndoe@example.com",
|
||||
"full_name": "John Doe",
|
||||
"disabled": false
|
||||
}
|
||||
```
|
||||
|
||||
<img src="/img/tutorial/security/image09.png">
|
||||
|
||||
開発者ツールを開くと、送信されるデータにはトークンだけが含まれており、パスワードはユーザーを認証してアクセストークンを取得する最初のリクエストでのみ送信され、その後は送信されないことがわかります。
|
||||
|
||||
<img src="/img/tutorial/security/image10.png">
|
||||
|
||||
!!! note "備考"
|
||||
ヘッダーの`Authorization`には、`Bearer`で始まる値があります。
|
||||
|
||||
## `scopes` を使った高度なユースケース
|
||||
|
||||
OAuth2には、「スコープ」という概念があります。
|
||||
|
||||
これらを利用して、JWTトークンに特定の権限セットを追加することができます。
|
||||
|
||||
そして、このトークンをユーザーに直接、または第三者に与えて、制限付きでAPIを操作できます。
|
||||
|
||||
これらの使用方法や**FastAPI**への統合方法については、**高度なユーザーガイド**で後ほど説明します。
|
||||
|
||||
## まとめ
|
||||
|
||||
ここまでの説明で、OAuth2やJWTなどの規格を使った安全な**FastAPI**アプリケーションを設定することができます。
|
||||
|
||||
ほとんどのフレームワークにおいて、セキュリティを扱うことは非常に複雑な課題となります。
|
||||
|
||||
簡略化しすぎたパッケージの多くは、データモデルやデータベース、利用可能な機能について多くの妥協をしなければなりません。そして、あまりにも単純化されたパッケージの中には、実はセキュリティ上の欠陥があるものもあります。
|
||||
|
||||
---
|
||||
|
||||
**FastAPI**は、どのようなデータベース、データモデル、ツールに対しても妥協することはありません。
|
||||
|
||||
そのため、プロジェクトに合わせて自由に選択することができます。
|
||||
|
||||
また、**FastAPI**は外部パッケージを統合するために複雑な仕組みを必要としないため、`passlib`や`python-jose`のようなよく整備され広く使われている多くのパッケージを直接使用することができます。
|
||||
|
||||
しかし、柔軟性、堅牢性、セキュリティを損なうことなく、可能な限りプロセスを簡素化するためのツールを提供します。
|
||||
|
||||
また、OAuth2のような安全で標準的なプロトコルを比較的簡単な方法で使用できるだけではなく、実装することもできます。
|
||||
|
||||
OAuth2の「スコープ」を使って、同じ基準でより細かい権限システムを実現する方法については、**高度なユーザーガイド**で詳しく説明しています。スコープ付きのOAuth2は、Facebook、Google、GitHub、Microsoft、Twitterなど、多くの大手認証プロバイダが、サードパーティのアプリケーションと自社のAPIとのやり取りをユーザーに代わって認可するために使用している仕組みです。
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -67,6 +69,7 @@ nav:
|
||||
- tutorial/body-updates.md
|
||||
- セキュリティ:
|
||||
- tutorial/security/first-steps.md
|
||||
- tutorial/security/oauth2-jwt.md
|
||||
- tutorial/middleware.md
|
||||
- tutorial/cors.md
|
||||
- tutorial/static-files.md
|
||||
@@ -96,7 +99,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -105,7 +108,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -114,7 +117,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -126,6 +129,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -156,6 +161,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -46,7 +46,10 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -63,7 +65,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -72,7 +74,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -81,7 +83,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -93,6 +95,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -123,6 +127,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,8 +40,10 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
@@ -56,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -65,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -74,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -86,10 +89,14 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
@@ -114,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
24
docs/pt/docs/advanced/index.md
Normal file
24
docs/pt/docs/advanced/index.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Guia de Usuário Avançado - Introdução
|
||||
|
||||
## Recursos Adicionais
|
||||
|
||||
O [Tutorial - Guia de Usuário](../tutorial/){.internal-link target=_blank} deve ser o suficiente para dar a você um tour por todos os principais recursos do **FastAPI**.
|
||||
|
||||
Na próxima seção você verá outras opções, configurações, e recursos adicionais.
|
||||
|
||||
!!! tip "Dica"
|
||||
As próximas seções **não são necessáriamente "avançadas"**
|
||||
|
||||
E é possível que para seu caso de uso, a solução esteja em uma delas.
|
||||
|
||||
## Leia o Tutorial primeiro
|
||||
|
||||
Você ainda pode usar a maior parte dos recursos no **FastAPI** com o conhecimento do [Tutorial - Guia de Usuário](../tutorial/){.internal-link target=_blank}.
|
||||
|
||||
E as próximas seções assumem que você já leu ele, e que você conhece suas ideias principais.
|
||||
|
||||
## Curso TestDriven.io
|
||||
|
||||
Se você gostaria de fazer um curso avançado-iniciante para complementar essa seção da documentação, você pode querer conferir: <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development com FastAPI e Docker</a> por **TestDriven.io**.
|
||||
|
||||
Eles estão atualmente doando 10% de todos os lucros para o desenvolvimento do **FastAPI**. 🎉 😄
|
||||
394
docs/pt/docs/async.md
Normal file
394
docs/pt/docs/async.md
Normal file
@@ -0,0 +1,394 @@
|
||||
# Concorrência e async / await
|
||||
|
||||
Detalhes sobre a sintaxe `async def` para *funções de operação de rota* e alguns conceitos de código assíncrono, concorrência e paralelismo.
|
||||
|
||||
## Com pressa?
|
||||
|
||||
<abbr title="muito longo; não li"><strong>TL;DR:</strong></abbr>
|
||||
|
||||
Se você estiver utilizando bibliotecas de terceiros que dizem para você chamar as funções com `await`, como:
|
||||
|
||||
```Python
|
||||
results = await some_library()
|
||||
```
|
||||
|
||||
Então, declare sua *função de operação de rota* com `async def` como:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
async def read_results():
|
||||
results = await some_library()
|
||||
return results
|
||||
```
|
||||
|
||||
!!! note
|
||||
Você só pode usar `await` dentro de funções criadas com `async def`.
|
||||
|
||||
---
|
||||
|
||||
Se você está usando biblioteca de terceiros que se comunica com alguma coisa (um banco de dados, uma API, sistema de arquivos etc) e não tem suporte para utilizar `await` (esse é atualmente o caso para a maioria das bibliotecas de banco de dados), então declare suas *funções de operação de rota* normalmente, com apenas `def`, como:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
def results():
|
||||
results = some_library()
|
||||
return results
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Se sua aplicação (de alguma forma) não tem que se comunicar com nada mais e tem que esperar que o respondam, use `async def`.
|
||||
|
||||
---
|
||||
|
||||
Se você simplesmente não sabe, use apenas `def`.
|
||||
|
||||
---
|
||||
|
||||
**Note**: Você pode misturar `def` e `async def` nas suas *funções de operação de rota* tanto quanto necessário e definir cada função usando a melhor opção para você. FastAPI irá fazer a coisa certa com elas.
|
||||
|
||||
De qualquer forma, em ambos os casos acima, FastAPI irá trabalhar assincronamente e ser extremamente rápido.
|
||||
|
||||
Seguindo os passos acima, ele será capaz de fazer algumas otimizações de performance.
|
||||
|
||||
## Detalhes Técnicos
|
||||
|
||||
Versões modernas de Python tem suporte para **"código assíncrono"** usando algo chamado **"corrotinas"**, com sintaxe **`async` e `await`**.
|
||||
|
||||
Vamos ver aquela frase por partes na seção abaixo:
|
||||
|
||||
* **Código assíncrono**
|
||||
* **`async` e `await`**
|
||||
* **Corrotinas**
|
||||
|
||||
## Código assíncrono
|
||||
|
||||
Código assíncrono apenas significa que a linguagem 💬 tem um jeito de dizer para o computador / programa 🤖 que em certo ponto, ele 🤖 terá que esperar por *algo* para finalizar em outro lugar. Vamos dizer que esse *algo* seja chamado "arquivo lento" 📝.
|
||||
|
||||
Então, durante esse tempo, o computador pode ir e fazer outro trabalho, enquanto o "arquivo lento" 📝 termine.
|
||||
|
||||
Então o computador / programa 🤖 irá voltar toda hora que tiver uma chance porquê ele ainda está esperando o "arquivo lento", ou ele 🤖 nunca irá terminar todo o trabalho que tem até esse ponto. E ele 🤖 irá ver se alguma das tarefas que estava esperando já terminaram, fazendo o que quer que tinham que fazer.
|
||||
|
||||
Depois, ele 🤖 pega a primeira tarefa para finalizar (vamos dizer, nosso "arquivo lento" 📝) e continua o que ele tem que fazer com isso.
|
||||
|
||||
Esse "esperar por algo" normalmente se refere a operações <abbr title="Entrada e Saída">I/O</abbr> que são relativamente "lentas" (comparadas a velocidade do processador e da memória RAM), como esperar por:
|
||||
|
||||
* dados do cliente para serem enviados através da rede
|
||||
* dados enviados pelo seu programa para serem recebidos pelo clente através da rede
|
||||
* conteúdo de um arquivo no disco pra ser lido pelo sistema e entregar ao seu programa
|
||||
* conteúdo que seu programa deu ao sistema para ser escrito no disco
|
||||
* uma operação remota API
|
||||
* uma operação no banco de dados para finalizar
|
||||
* uma solicitação no banco de dados esperando o retorno do resultado
|
||||
* etc.
|
||||
|
||||
Enquanto o tempo de execução é consumido mais pela espera das operações <abbr title="Entrada e Saída">I/O</abbr>, essas operações são chamadas de operações "limitadas por I/O".
|
||||
|
||||
Isso é chamado de "assíncrono" porquê o computador / programa não tem que ser "sincronizado" com a tarefa lenta, esperando pelo exato momento que a tarefa finalize, enquanto não faz nada, para ser capaz de pegar o resultado da tarefa e dar continuidade ao trabalho.
|
||||
|
||||
Ao invés disso, sendo um sistema "assíncrono", uma vez finalizada, a tarefa pode esperar um pouco (alguns microssegundos) para que o computador / programa finalize o que quer que esteja fazendo,e então volte para pegar o resultado e continue trabalhando com ele.
|
||||
|
||||
Para "síncrono" (contrário de "assíncrono") também é utilizado o termo "sequencial", porquê o computador / programa segue todos os passos, na sequência, antes de trocar para uma tarefa diferente, mesmo se alguns passos envolvam esperar.
|
||||
|
||||
### Concorrência e hambúrgueres
|
||||
|
||||
Essa idéia de código **assíncrono** descrito acima é algo às vezes chamado de **"concorrência"**. E é diferente de **"paralelismo"**.
|
||||
|
||||
**Concorrência** e **paralelismo** ambos são relacionados a "diferentes coisas acontecendo mais ou menos ao mesmo tempo".
|
||||
|
||||
Mas os detalhes entre *concorrência* e *paralelismo* são bem diferentes.
|
||||
|
||||
Para ver essa diferença, imagine a seguinte história sobre hambúrgueres:
|
||||
|
||||
### Hambúrgueres concorrentes
|
||||
|
||||
Você vai com seu _crush_ :heart_eyes: na lanchonete, fica na fila enquanto o caixa pega os pedidos das pessoas na sua frente.
|
||||
|
||||
Então chega a sua vez, você pede dois saborosos hambúrgueres para você e seu _crush_ :heart_eyes:.
|
||||
|
||||
Você paga.
|
||||
|
||||
O caixa diz alguma coisa para o cara na cozinha para que ele tenha que preparar seus hambúrgueres (mesmo embora ele esteja preparando os lanches dos outros clientes).
|
||||
|
||||
O caixa te entrega seu número de chamada.
|
||||
|
||||
Enquanto você espera, você vai com seu _crush_ :heart_eyes: e pega uma mesa, senta e conversa com seu _crush_ :heart_eyes: por um bom tempo (como seus hambúrgueres são muito saborosos, leva um tempo para serem preparados).
|
||||
|
||||
Enquanto você está sentado na mesa com seu _crush_ :heart_eyes:, esperando os hambúrgueres, você pode gastar o tempo admirando como lindo, maravilhoso e esperto é seu _crush_ :heart_eyes:.
|
||||
|
||||
Enquanto espera e conversa com seu _crush_ :heart_eyes:, de tempos em tempos, você verifica o número de chamada exibido no balcão para ver se já é sua vez.
|
||||
|
||||
Então a certo ponto, é finalmente sua vez. Você vai no balcão, pega seus hambúrgueres e volta para a mesa.
|
||||
|
||||
Você e seu _crush_ :heart_eyes: comem os hambúrgueres e aproveitam o tempo.
|
||||
|
||||
---
|
||||
|
||||
Imagine que você seja o computador / programa nessa história.
|
||||
|
||||
Enquanto você está na fila, tranquilo, esperando por sua vez, não está fazendo nada "produtivo". Mas a fila é rápida porquê o caixa só está pegando os pedidos, então está tudo bem.
|
||||
|
||||
Então, quando é sua vez, você faz o trabalho "produtivo" de verdade, você processa o menu, decide o que quer, pega a escolha de seu _crush_ :heart_eyes:, paga, verifica se entregou o valor correto em dinheiro ou cartão de crédito, verifica se foi cobrado corretamente, verifica se seu pedido está correto etc.
|
||||
|
||||
Mas então, embora você ainda não tenha os hambúrgueres, seu trabalho no caixa está "pausado", porquê você tem que esperar seus hambúrgueres estarem prontos.
|
||||
|
||||
Mas enquanto você se afasta do balcão e senta na mesa com o número da sua chamada, você pode trocar sua atenção para seu _crush_ :heart_eyes:, e "trabalhar" nisso. Então você está novamente fazendo algo muito "produtivo", como flertar com seu _crush_ :heart_eyes:.
|
||||
|
||||
Então o caixa diz que "seus hambúrgueres estão prontos" colocando seu número no balcão, mas você não corre que nem um maluco imediatamente quando o número exibido é o seu. Você sabe que ninguém irá roubar seus hambúrgueres porquê você tem o número de chamada, e os outros tem os números deles.
|
||||
|
||||
Então você espera que seu _crush_ :heart_eyes: termine a história que estava contando (terminar o trabalho atual / tarefa sendo processada), sorri gentilmente e diz que você está indo buscar os hambúrgueres.
|
||||
|
||||
Então você vai no balcão, para a tarefa inicial que agora está finalizada, pega os hambúrgueres, e leva para a mesa. Isso finaliza esse passo / tarefa da interação com o balcão. Agora é criada uma nova tarefa, "comer hambúrgueres", mas a tarefa anterior, "pegar os hambúrgueres" já está finalizada.
|
||||
|
||||
### Hambúrgueres paralelos
|
||||
|
||||
Você vai com seu _crush_ :heart_eyes: em uma lanchonete paralela.
|
||||
|
||||
Você fica na fila enquanto alguns (vamos dizer 8) caixas pegam os pedidos das pessoas na sua frente.
|
||||
|
||||
Todo mundo antes de você está esperando pelos hambúrgueres estarem prontos antes de deixar o caixa porquê cada um dos 8 caixas vai e prepara o hambúrguer antes de pegar o próximo pedido.
|
||||
|
||||
Então é finalmente sua vez, e pede 2 hambúrgueres muito saborosos para você e seu _crush_ :heart_eyes:.
|
||||
|
||||
Você paga.
|
||||
|
||||
O caixa vai para a cozinha.
|
||||
|
||||
Você espera, na frente do balcão, para que ninguém pegue seus hambúrgueres antes de você, já que não tem números de chamadas.
|
||||
|
||||
Enquanto você e seu _crush_ :heart_eyes: estão ocupados não permitindo que ninguém passe a frente e pegue seus hambúrgueres assim que estiverem prontos, você não pode dar atenção ao seu _crush_ :heart_eyes:.
|
||||
|
||||
Isso é trabalho "síncrono", você está "sincronizado" com o caixa / cozinheiro. Você tem que esperar e estar lá no exato momento que o caixa / cozinheiro terminar os hambúrgueres e dá-los a você, ou então, outro alguém pode pegá-los.
|
||||
|
||||
Então seu caixa / cozinheiro finalmente volta com seus hambúrgueres, depois de um longo tempo esperando por eles em frente ao balcão.
|
||||
|
||||
Você pega seus hambúrgueres e vai para a mesa com seu _crush_ :heart_eyes:.
|
||||
|
||||
Vocês comem os hambúrgueres, e o trabalho está terminado.
|
||||
|
||||
Não houve muita conversa ou flerte já que a maior parte do tempo foi gasto esperando os lanches na frente do balcão.
|
||||
|
||||
---
|
||||
|
||||
Nesse cenário dos hambúrgueres paralelos, você é um computador / programa com dois processadores (você e seu _crush_ :heart_eyes:), ambos esperando e dedicando a atenção de estar "esperando no balcão" por um bom tempo.
|
||||
|
||||
A lanchonete paralela tem 8 processadores (caixas / cozinheiros). Enquanto a lanchonete dos hambúrgueres concorrentes tinham apenas 2 (um caixa e um cozinheiro).
|
||||
|
||||
Ainda assim, a última experiência não foi a melhor.
|
||||
|
||||
---
|
||||
|
||||
Essa poderia ser a história paralela equivalente aos hambúrgueres.
|
||||
|
||||
Para um exemplo "mais real", imagine um banco.
|
||||
|
||||
Até recentemente, a maioria dos bancos tinha muitos caixas e uma grande fila.
|
||||
|
||||
Todos os caixas fazendo todo o trabalho, um cliente após o outro.
|
||||
|
||||
E você tinha que esperar na fila por um longo tempo ou poderia perder a vez.
|
||||
|
||||
Você provavelmente não gostaria de levar seu _crush_ :heart_eyes: com você para um rolezinho no banco.
|
||||
|
||||
### Conclusão dos hambúrgueres
|
||||
|
||||
Nesse cenário dos "hambúrgueres com seu _crush_ :heart_eyes:", como tem muita espera, faz mais sentido ter um sistema concorrente.
|
||||
|
||||
Esse é o caso da maioria das aplicações web.
|
||||
|
||||
Geralmente são muitos usuários, e seu servidor está esperando pelas suas conexões não tão boas para enviar as requisições.
|
||||
|
||||
E então esperando novamente pelas respostas voltarem.
|
||||
|
||||
Essa "espera" é medida em microssegundos, e ainda assim, somando tudo, é um monte de espera no final.
|
||||
|
||||
Por isso que faz muito mais sentido utilizar código assíncrono para APIs web.
|
||||
|
||||
A maioria dos frameworks Python existentes mais populares (incluindo Flask e Django) foram criados antes que os novos recursos assíncronos existissem em Python. Então, os meios que eles podem ser colocados em produção para suportar execução paralela mais a forma antiga de execução assíncrona não são tão poderosos quanto as novas capacidades.
|
||||
|
||||
Mesmo embora a especificação principal para web assíncrono em Python (ASGI) foi desenvolvida no Django, para adicionar suporte para WebSockets.
|
||||
|
||||
Esse tipo de assincronicidade é o que fez NodeJS popular (embora NodeJS não seja paralelo) e que essa seja a força do Go como uma linguagem de programa.
|
||||
|
||||
E esse é o mesmo nível de performance que você tem com o **FastAPI**.
|
||||
|
||||
E como você pode ter paralelismo e sincronicidade ao mesmo tempo, você tem uma maior performance do que a maioria dos frameworks NodeJS testados e lado a lado com Go, que é uma linguagem compilada próxima ao C <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(tudo graças ao Starlette)</a>.
|
||||
|
||||
### Concorrência é melhor que paralelismo?
|
||||
|
||||
Não! Essa não é a moral da história.
|
||||
|
||||
Concorrência é diferente de paralelismo. E é melhor em cenários **específicos** que envolvam um monte de espera. Por isso, geralmente é muito melhor do que paralelismo para desenvolvimento de aplicações web. Mas não para tudo.
|
||||
|
||||
Então, para equilibrar tudo, imagine a seguinte historinha:
|
||||
|
||||
> Você tem que limpar uma grande casa suja.
|
||||
|
||||
*Sim, essa é toda a história*.
|
||||
|
||||
---
|
||||
|
||||
Não há espera em lugar algum, apenas um monte de trabalho para ser feito, em múltiplos cômodos da casa.
|
||||
|
||||
Você poderia ter chamadas como no exemplo dos hambúrgueres, primeiro a sala de estar, então a cozinha, mas você não está esperando por nada, apenas limpar e limpar, as chamadas não afetariam em nada.
|
||||
|
||||
Levaria o mesmo tempo para finalizar com ou sem chamadas (concorrência) e você teria feito o mesmo tanto de trabalho.
|
||||
|
||||
Mas nesse caso, se você trouxesse os 8 ex-caixas / cozinheiros / agora-faxineiros, e cada um deles (mais você) pudessem dividir a casa para limpá-la, vocês fariam toda a limpeza em **paralelo**, com a ajuda extra, e terminariam muito mais cedo.
|
||||
|
||||
Nesse cenário, cada um dos faxineiros (incluindo você) poderia ser um processador, fazendo a sua parte do trabalho.
|
||||
|
||||
E a maior parte do tempo de execução é tomada por trabalho (ao invés de ficar esperando), e o trabalho em um computador é feito pela <abbr title="Unidade de Processamento Central">CPU</abbr>, que podem gerar problemas que são chamados de "limite de CPU".
|
||||
|
||||
---
|
||||
|
||||
Exemplos comuns de limite de CPU são coisas que exigem processamento matemático complexo.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
* **Processamento de áudio** ou **imagem**
|
||||
* **Visão do Computador**: uma imagem é composta por milhões de pixels, cada pixel tem 3 valores (cores, processamento que normalmente exige alguma computação em todos esses pixels ao mesmo tempo)
|
||||
|
||||
* **Machine Learning**: Normalmente exige muita multiplicação de matrizes e vetores. Pense numa grande folha de papel com números e multiplicando todos eles juntos e ao mesmo tempo.
|
||||
|
||||
* **Deep Learning**: Esse é um subcampo do Machine Learning, então o mesmo se aplica. A diferença é que não há apenas uma grande folha de papel com números para multiplicar, mas um grande conjunto de folhas de papel, e em muitos casos, você utiliza um processador especial para construir e/ou usar modelos.
|
||||
|
||||
### Concorrência + Paralelismo: Web + Machine learning
|
||||
|
||||
Com **FastAPI** você pode levar a vantagem da concorrência que é muito comum para desenvolvimento web (o mesmo atrativo de NodeJS).
|
||||
|
||||
Mas você também pode explorar os benefícios do paralelismo e multiprocessamento (tendo múltiplos processadores rodando em paralelo) para trabalhos pesados que geram **limite de CPU** como aqueles em sistemas de Machine Learning.
|
||||
|
||||
Isso, mais o simples fato que Python é a principal linguagem para **Data Science**, Machine Learning e especialmente Deep Learning, faz do FastAPI uma ótima escolha para APIs web e aplicações com Data Science / Machine Learning (entre muitas outras).
|
||||
|
||||
Para ver como alcançar esse paralelismo em produção veja a seção sobre [Deployment](deployment.md){.internal-link target=_blank}.
|
||||
|
||||
## `async` e `await`
|
||||
|
||||
Versões modernas do Python tem um modo muito intuitivo para definir código assíncrono. Isso faz parecer normal o código "sequencial" e fazer o "esperar" para você nos momentos certos.
|
||||
|
||||
Quando tem uma operação que exigirá espera antes de dar os resultados e tem suporte para esses recursos Python, você pode escrever assim:
|
||||
|
||||
```Python
|
||||
burgers = await get_burgers(2)
|
||||
```
|
||||
|
||||
A chave aqui é o `await`. Ele diz ao Python que ele tem que esperar por `get_burgers(2)` para finalizar suas coisas antes de armazenar os resultados em `burgers`. Com isso, o Python saberá que ele pode ir e fazer outras coisas nesse meio tempo (como receber outra requisição).
|
||||
|
||||
Para o `await` funcionar, tem que estar dentro de uma função que suporte essa assincronicidade. Para fazer isso, apenas declare a função com `async def`:
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def get_burgers(number: int):
|
||||
# Fazer alguma coisa assíncrona para criar os hambúrgueres
|
||||
return burgers
|
||||
```
|
||||
|
||||
...ao invés de `def`:
|
||||
|
||||
```Python hl_lines="2"
|
||||
# Isso não é assíncrono
|
||||
def get_sequential_burgers(number: int):
|
||||
# Faz alguma coisa sequencial para criar os hambúrgueres
|
||||
return burgers
|
||||
```
|
||||
|
||||
Com `async def`, o Python sabe que, dentro dessa função, tem que estar ciente das expressões `await`, e que isso pode "pausar" a execução dessa função, e poderá fazer outra coisa antes de voltar.
|
||||
|
||||
Quando você quiser chamar uma função `async def`, você tem que "esperar". Então, isso não funcionará:
|
||||
|
||||
```Python
|
||||
# Isso não irá funcionar, porquê get_burgers foi definido com: async def
|
||||
burgers = get_burgers(2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Então, se você está usando uma biblioteca que diz que você pode chamá-la com `await`, você precisa criar as *funções de operação de rota* com `async def`, como em:
|
||||
|
||||
```Python hl_lines="2 3"
|
||||
@app.get('/burgers')
|
||||
async def read_burgers():
|
||||
burgers = await get_burgers(2)
|
||||
return burgers
|
||||
```
|
||||
|
||||
### Mais detalhes técnicos
|
||||
|
||||
Você deve ter observado que `await` pode ser usado somente dentro de funções definidas com `async def`.
|
||||
|
||||
Mas ao mesmo tempo, funções definidas com `async def` tem que ser aguardadas. Então, funções com `async def` pdem ser chamadas somente dentro de funções definidas com `async def` também.
|
||||
|
||||
Então, sobre o ovo e a galinha, como você chama a primeira função async?
|
||||
|
||||
Se você estivar trabalhando com **FastAPI** não terá que se preocupar com isso, porquê essa "primeira" função será a sua *função de operação de rota*, e o FastAPI saberá como fazer a coisa certa.
|
||||
|
||||
Mas se você quiser usar `async` / `await` sem FastAPI, <a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" class="external-link" target="_blank">verifique a documentação oficial Python</a>.
|
||||
|
||||
### Outras formas de código assíncrono
|
||||
|
||||
Esse estilo de usar `async` e `await` é relativamente novo na linguagem.
|
||||
|
||||
Mas ele faz o trabalho com código assíncrono muito mais fácil.
|
||||
|
||||
Essa mesma sintaxe (ou quase a mesma) foi também incluída recentemente em versões modernas do JavaScript (no navegador e NodeJS).
|
||||
|
||||
Mas antes disso, controlar código assíncrono era bem mais complexo e difícil.
|
||||
|
||||
Nas versões anteriores do Python, você poderia utilizar threads ou <a href="http://www.gevent.org/" class="external-link" target="_blank">Gevent</a>. Mas o código é um pouco mais complexo de entender, debugar, e pensar sobre.
|
||||
|
||||
Nas versões anteriores do NodeJS / Navegador JavaScript, você poderia utilizar "callbacks". O que leva ao <a href="http://callbackhell.com/" class="external-link" target="_blank">inferno do callback</a>.
|
||||
|
||||
## Corrotinas
|
||||
|
||||
**Corrotina** é apenas um jeito bonitinho para a coisa que é retornada de uma função `async def`. O Python sabe que é uma função que pode começar e terminar em algum ponto, mas que pode ser pausada internamente também, sempre que tiver um `await` dentro dela.
|
||||
|
||||
Mas toda essa funcionalidade de código assíncrono com `async` e `await` é muitas vezes resumida como "corrotina". É comparável ao principal recurso chave do Go, a "Gorotina".
|
||||
|
||||
## Conclusão
|
||||
|
||||
Vamos ver a mesma frase com o conteúdo cima:
|
||||
|
||||
> Versões modernas do Python tem suporte para **"código assíncrono"** usando algo chamado **"corrotinas"**, com sintaxe **`async` e `await`**.
|
||||
|
||||
Isso pode fazer mais sentido agora.
|
||||
|
||||
Tudo isso é o que deixa o FastAPI poderoso (através do Starlette) e que o faz ter uma performance impressionante.
|
||||
|
||||
## Detalhes muito técnicos
|
||||
|
||||
!!! warning
|
||||
Você pode provavelmente pular isso.
|
||||
|
||||
Esses são detalhes muito técnicos de como **FastAPI** funciona por baixo do capô.
|
||||
|
||||
Se você tem algum conhecimento técnico (corrotinas, threads, blocking etc) e está curioso sobre como o FastAPI controla o `async def` vs normal `def`, vá em frente.
|
||||
|
||||
### Funções de operação de rota
|
||||
|
||||
Quando você declara uma *função de operação de rota* com `def` normal ao invés de `async def`, ela é rodada em uma threadpool externa que então é aguardada, ao invés de ser chamada diretamente (ela poderia bloquear o servidor).
|
||||
|
||||
Se você está chegando de outro framework assíncrono que não faz o trabalho descrito acima e você está acostumado a definir triviais *funções de operação de rota* com simples `def` para ter um mínimo ganho de performance (cerca de 100 nanosegundos), por favor observe que no **FastAPI** o efeito pode ser bem o oposto. Nesses casos, é melhor usar `async def` a menos que suas *funções de operação de rota* utilizem código que performem bloqueamento <abbr title="Input/Output: disco lendo ou escrevendo, comunicações de rede.">IO</abbr>.
|
||||
|
||||
Ainda, em ambas as situações, as chances são que o **FastAPI** será [ainda mais rápido](/#performance){.internal-link target=_blank} do que (ou ao menos comparável a) seus frameworks antecessores.
|
||||
|
||||
### Dependências
|
||||
|
||||
O mesmo se aplica para as dependências. Se uma dependência tem as funções com padrão `def` ao invés de `async def`, ela é rodada no threadpool externo.
|
||||
|
||||
### Sub-dependências
|
||||
|
||||
Você pode ter múltiplas dependências e sub-dependências exigindo uma a outra (como parâmetros de definições de funções), algumas delas podem ser criadas com `async def` e algumas com `def` normal. Isso ainda poderia funcionar, e aquelas criadas com `def` podem ser chamadas em uma thread externa ao invés de serem "aguardadas".
|
||||
|
||||
### Outras funções de utilidade
|
||||
|
||||
Qualquer outra função de utilidade que você chame diretamente pode ser criada com `def` normal ou `async def` e o FastAPI não irá afetar o modo como você a chama.
|
||||
|
||||
Isso está em contraste às funções que o FastAPI chama para você: *funções de operação de rota* e dependências.
|
||||
|
||||
Se sua função de utilidade é uma função normal com `def`, ela será chamada diretamente (como você a escreve no código), não em uma threadpool, se a função é criada com `async def` então você deve esperar por essa função quando você chamá-la no seu código.
|
||||
|
||||
---
|
||||
|
||||
Novamente, esses são detalhes muito técnicos que provavelmente possam ser úteis caso você esteja procurando por eles.
|
||||
|
||||
Caso contrário, você deve ficar bem com as dicas da seção acima: <a href="#in-a-hurry">Com pressa?</a>.
|
||||
7
docs/pt/docs/deployment/index.md
Normal file
7
docs/pt/docs/deployment/index.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Implantação - Introdução
|
||||
|
||||
A implantação de uma aplicação **FastAPI** é relativamente simples.
|
||||
|
||||
Existem várias maneiras para fazer isso, dependendo do seu caso específico e das ferramentas que você utiliza.
|
||||
|
||||
Você verá mais detalhes para se ter em mente e algumas das técnicas para a implantação nas próximas seções.
|
||||
87
docs/pt/docs/deployment/versions.md
Normal file
87
docs/pt/docs/deployment/versions.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Sobre as versões do FastAPI
|
||||
|
||||
**FastAPI** já está sendo usado em produção em diversas aplicações e sistemas, a cobertura de testes é mantida em 100%, mas seu desenvolvimento está avançando rapidamente.
|
||||
|
||||
Novos recursos são adicionados com frequência, bugs são corrigidos regularmente e o código está sempre melhorando.
|
||||
|
||||
Esse é o motivo das versões atuais estarem em `0.x.x`, significando que em cada versão pode haver mudanças significativas, tudo isso seguindo as <a href="https://semver.org/lang/pt-BR/" class="external-link" target="_blank">convenções de controle de versão semântica.</a>
|
||||
|
||||
Já é possível criar aplicativos de produção com **FastAPI** (e provavelmente você já faz isso há algum tempo), apenas precisando ter certeza de usar uma versão que funcione corretamente com o resto do seu código.
|
||||
|
||||
## Fixe a sua versão de `fastapi`
|
||||
|
||||
A primeira coisa que você deve fazer é "fixar" a versão do **FastAPI** que você está utilizando na mais atual, na qual você sabe que funciona corretamente para o seu aplicativo.
|
||||
|
||||
Por exemplo, supondo que você está usando a versão `0.45.0` em sua aplicação.
|
||||
|
||||
Caso você utilize o arquivo `requirements.txt`, você poderia especificar a versão com:
|
||||
|
||||
```txt
|
||||
fastapi==0.45.0
|
||||
```
|
||||
|
||||
Isso significa que você conseguiria utilizar a versão exata `0.45.0`.
|
||||
|
||||
Ou, você poderia fixá-la com:
|
||||
|
||||
```txt
|
||||
fastapi>=0.45.0,<0.46.0
|
||||
```
|
||||
|
||||
isso significa que você iria usar as versões `0.45.0` ou acima, mas inferiores à `0.46.0`, por exemplo, a versão `0.45.2` ainda seria aceita.
|
||||
|
||||
Se você usar qualquer outra ferramenta para gerenciar suas instalações, como Poetry, Pipenv ou outras, todas elas têm uma maneira que você pode usar para definir as versões específicas dos seus pacotes.
|
||||
|
||||
## Versões disponíveis
|
||||
|
||||
Você pode ver as versões disponíveis (por exemplo, para verificar qual é a versão atual) em [Release Notes](../release-notes.md){.internal-link target=\_blank}.
|
||||
|
||||
## Sobre versões
|
||||
|
||||
Seguindo as convenções de controle de versão semântica, qualquer versão abaixo de `1.0.0` pode adicionar mudanças significativas.
|
||||
|
||||
FastAPI também segue a convenção de que qualquer alteração de versão "PATCH" é para correção de bugs e alterações não significativas.
|
||||
|
||||
!!! tip "Dica"
|
||||
O "PATCH" é o último número, por exemplo, em `0.2.3`, a versão PATCH é `3`.
|
||||
|
||||
Logo, você deveria conseguir fixar a versão, como:
|
||||
|
||||
```txt
|
||||
fastapi>=0.45.0,<0.46.0
|
||||
```
|
||||
|
||||
Mudanças significativas e novos recursos são adicionados em versões "MINOR".
|
||||
|
||||
!!! tip "Dica"
|
||||
O "MINOR" é o número que está no meio, por exemplo, em `0.2.3`, a versão MINOR é `2`.
|
||||
|
||||
## Atualizando as versões do FastAPI
|
||||
|
||||
Você deve adicionar testes para a sua aplicação.
|
||||
|
||||
Com **FastAPI** isso é muito fácil (graças a Starlette), verifique a documentação: [Testing](../tutorial/testing.md){.internal-link target=\_blank}
|
||||
|
||||
Após a criação dos testes, você pode atualizar a sua versão do **FastAPI** para uma mais recente, execute os testes para se certificar de que todo o seu código está funcionando corretamente.
|
||||
|
||||
Se tudo estiver funcionando, ou após você realizar as alterações necessárias e todos os testes estiverem passando, então você pode fixar sua versão de `FastAPI` para essa mais nova.
|
||||
|
||||
## Sobre Starlette
|
||||
|
||||
Não é recomendado fixar a versão de `starlette`.
|
||||
|
||||
Versões diferentes de **FastAPI** utilizarão uma versão específica e mais recente de Starlette.
|
||||
|
||||
Então, você pode deixar **FastAPI** escolher a versão compatível e correta de Starlette.
|
||||
|
||||
## Sobre Pydantic
|
||||
|
||||
Pydantic incluí os testes para **FastAPI** em seus próprios testes, então as novas versões de Pydantic (acima da `1.0.0`) sempre serão compatíveis com FastAPI.
|
||||
|
||||
Você pode fixar qualquer versão de Pydantic que desejar, desde que seja acima da `1.0.0` e abaixo da `2.0.0`.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
```txt
|
||||
pydantic>=1.2.0,<2.0.0
|
||||
```
|
||||
178
docs/pt/docs/fastapi-people.md
Normal file
178
docs/pt/docs/fastapi-people.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# Pessoas do FastAPI
|
||||
|
||||
FastAPI possue uma comunidade incrível que recebe pessoas de todos os níveis.
|
||||
|
||||
## Criador - Mantenedor
|
||||
|
||||
Ei! 👋
|
||||
|
||||
Este sou eu:
|
||||
|
||||
{% 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">Respostas: {{ user.answers }}</div><div class="count">Pull Requests: {{ user.prs }}</div></div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
Eu sou o criador e mantenedor do **FastAPI**. Você pode ler mais sobre isso em [Help FastAPI - Get Help - Connect with the author](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}.
|
||||
|
||||
...Mas aqui eu quero mostrar a você a comunidade.
|
||||
|
||||
---
|
||||
|
||||
**FastAPI** recebe muito suporte da comunidade. E quero destacar suas contribuições.
|
||||
|
||||
Estas são as pessoas que:
|
||||
|
||||
* [Help others with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}.
|
||||
* [Create Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
|
||||
* Revisar Pull Requests, [especially important for translations](contributing.md#translations){.internal-link target=_blank}.
|
||||
|
||||
Uma salva de palmas para eles. 👏 🙇
|
||||
|
||||
## Usuários mais ativos do ultimo mês
|
||||
|
||||
Estes são os usuários que estão [helping others the most with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} durante o ultimo mês. ☕
|
||||
|
||||
{% 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 respondidas: {{ user.count }}</div></div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
## Especialistas
|
||||
|
||||
Aqui está os **Especialistas do FastAPI**. 🤓
|
||||
|
||||
|
||||
Estes são os usuários que [helped others the most with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} em *todo o tempo*.
|
||||
|
||||
Eles provaram ser especialistas ajudando muitos outros. ✨
|
||||
|
||||
{% 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 respondidas: {{ user.count }}</div></div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
## Top Contribuidores
|
||||
|
||||
Aqui está os **Top Contribuidores**. 👷
|
||||
|
||||
Esses usuários têm [created the most Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} que tem sido *mergeado*.
|
||||
|
||||
Eles contribuíram com o código-fonte, documentação, traduções, etc. 📦
|
||||
|
||||
{% 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 %}
|
||||
|
||||
Existem muitos outros contribuidores (mais de uma centena), você pode ver todos eles em <a href="https://github.com/tiangolo/fastapi/graphs/contributors" class="external-link" target="_blank">Página de Contribuidores do FastAPI no GitHub</a>. 👷
|
||||
|
||||
## Top Revisores
|
||||
|
||||
Esses usuários são os **Top Revisores**. 🕵️
|
||||
|
||||
### Revisões para Traduções
|
||||
|
||||
Eu só falo algumas línguas (e não muito bem 😅). Então, os revisores são aqueles que têm o [**poder de aprovar traduções**](contributing.md#translations){.internal-link target=_blank} da documentação. Sem eles, não haveria documentação em vários outros idiomas.
|
||||
|
||||
---
|
||||
|
||||
Os **Top Revisores** 🕵️ revisaram a maior parte de Pull Requests de outros, garantindo a qualidade do código, documentação, e especialmente, as **traduções**.
|
||||
|
||||
{% 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">Revisões: {{ user.count }}</div></div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
## Patrocinadores
|
||||
|
||||
Esses são os **Patrocinadores**. 😎
|
||||
|
||||
Eles estão apoiando meu trabalho **FastAPI** (e outros), principalmente através de <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
|
||||
|
||||
{% if sponsors %}
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### Patrocinadores Ouro
|
||||
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors.silver %}
|
||||
|
||||
### Patrocinadores Prata
|
||||
|
||||
{% for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors.bronze %}
|
||||
|
||||
### Patrocinadores Bronze
|
||||
|
||||
{% for sponsor in sponsors.bronze -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
### Patrocinadores Individuais
|
||||
|
||||
{% 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 %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
## Sobre os dados - detalhes técnicos
|
||||
|
||||
A principal intenção desta página é destacar o esforço da comunidade para ajudar os outros.
|
||||
|
||||
Especialmente incluindo esforços que normalmente são menos visíveis, e em muitos casos mais árduo, como ajudar os outros com issues e revisando Pull Requests com traduções.
|
||||
|
||||
Os dados são calculados todo mês, você pode ler o <a href="https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/app/main.py" class="external-link" target="_blank">código fonte aqui</a>.
|
||||
|
||||
Aqui também estou destacando contribuições de patrocinadores.
|
||||
|
||||
Eu também me reservo o direito de atualizar o algoritmo, seções, limites, etc (só para prevenir 🤷).
|
||||
@@ -32,7 +32,6 @@ Se você precisa refrescar a memória rapidamente sobre como usar tipos do Pytho
|
||||
Você escreve Python padrão com tipos:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -39,19 +39,22 @@ Os recursos chave são:
|
||||
|
||||
<small>* estimativas baseadas em testes realizados com equipe interna de desenvolvimento, construindo aplicações em produção.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Patrocinadores Ouro
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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>
|
||||
<a href="https://fastapi.tiangolo.com/pt/fastapi-people/#patrocinadores" class="external-link" target="_blank">Outros patrocinadores</a>
|
||||
|
||||
## Opiniões
|
||||
|
||||
|
||||
101
docs/pt/docs/tutorial/security/index.md
Normal file
101
docs/pt/docs/tutorial/security/index.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Introdução à segurança
|
||||
|
||||
Há várias formas de lidar segurança, autenticação e autorização.
|
||||
|
||||
E isso normalmente é um tópico “difícil” e complexo.
|
||||
|
||||
Em muitos frameworks e sistemas, apenas lidar com segurança e autenticação exige muito esforço e código (em muitos casos isso pode ser 50% ou mais de todo o código escrito).
|
||||
|
||||
**FastAPI** tem muitas ferramentas para ajudar você com a parte de **Segurança** facilmente, rapidamente, de uma forma padrão, sem ter que estudar e aprender tudo sobre especificações de segurança.
|
||||
|
||||
Mas primeiro, vamos verificar alguns pequenos conceitos.
|
||||
|
||||
## Está com pressa?
|
||||
|
||||
Se você não se importa com qualquer um desses termos e só precisa adicionar segurança com autenticação baseada em usuário e senha _agora_, pule para os próximos capítulos.
|
||||
|
||||
## OAuth2
|
||||
|
||||
OAuth2 é uma especificação que define várias formas para lidar com autenticação e autorização.
|
||||
|
||||
Ela é bastante extensiva na especificação e cobre casos de uso muito complexos.
|
||||
|
||||
Ela inclui uma forma para autenticação usando “third party”/aplicações de terceiros.
|
||||
|
||||
Isso é o que todos os sistemas com “Login with Facebook, Google, Twitter, GitHub” usam por baixo.
|
||||
|
||||
### OAuth 1
|
||||
|
||||
Havia um OAuth 1, que é bem diferente do OAuth2, e mais complexo, isso incluía diretamente as especificações de como criptografar a comunicação.
|
||||
|
||||
Não é muito popular ou usado nos dias atuais.
|
||||
|
||||
OAuth2 não especifica como criptografar a comunicação, ele espera que você tenha sua aplicação em um servidor HTTPS.
|
||||
|
||||
!!! tip "Dica"
|
||||
Na seção sobre **deployment** você irá ver como configurar HTTPS de modo gratuito, usando Traefik e Let’s Encrypt.
|
||||
|
||||
|
||||
## OpenID Connect
|
||||
|
||||
OpenID Connect é outra especificação, baseada em **OAuth2**.
|
||||
|
||||
Ela é apenas uma extensão do OAuth2 especificando algumas coisas que são relativamente ambíguas no OAuth2, para tentar torná-lo mais interoperável.
|
||||
|
||||
Por exemplo, o login do Google usa OpenID Connect (que por baixo dos panos usa OAuth2).
|
||||
|
||||
Mas o login do Facebook não tem suporte para OpenID Connect. Ele tem a própria implementação do OAuth2.
|
||||
|
||||
### OpenID (não "OpenID Connect")
|
||||
|
||||
Houve também uma especificação “OpenID”. Ela tentou resolver a mesma coisa que a **OpenID Connect**, mas não baseada em OAuth2.
|
||||
|
||||
Então, ela foi um sistema adicional completo.
|
||||
|
||||
Ela não é muito popular ou usada nos dias de hoje.
|
||||
|
||||
## OpenAPI
|
||||
|
||||
OpenAPI (anteriormente conhecido como Swagger) é a especificação aberta para a criação de APIs (agora parte da Linux Foundation).
|
||||
|
||||
**FastAPI** é baseado no **OpenAPI**.
|
||||
|
||||
Isso é o que torna possível ter múltiplas automações interativas de interfaces de documentação, geração de código, etc.
|
||||
|
||||
OpenAPI tem uma forma para definir múltiplos “esquemas” de segurança.
|
||||
|
||||
Por usá-los, você pode ter vantagens de todas essas ferramentas baseadas nos padrões, incluindo os sistemas de documentação interativa.
|
||||
|
||||
OpenAPI define os seguintes esquemas de segurança:
|
||||
|
||||
* `apiKey`: uma chave específica de aplicação que pode vir de:
|
||||
* Um parâmetro query.
|
||||
* Um header.
|
||||
* Um cookie.
|
||||
* `http`: padrão HTTP de sistemas autenticação, incluindo:
|
||||
* `bearer`: um header de `Authorization` com valor de `Bearer` adicionado de um token. Isso é herança do OAuth2.
|
||||
* HTTP Basic authentication.
|
||||
* HTTP Digest, etc.
|
||||
* `oauth2`: todas as formas do OAuth2 para lidar com segurança (chamados "fluxos").
|
||||
* Vários desses fluxos são apropriados para construir um provedor de autenticação OAuth2 (como Google, Facebook, Twitter, GitHub, etc):
|
||||
* `implicit`
|
||||
* `clientCredentials`
|
||||
* `authorizationCode`
|
||||
* Mas existe um “fluxo” específico que pode ser perfeitamente usado para resolver autenticação diretamente na mesma aplicação:
|
||||
* `password`: alguns dos próximos capítulos tratarão disso.
|
||||
* `openIdConnect`: tem uma forma para definir como descobrir automaticamente o dado da autenticação OAuth2.
|
||||
* Essa descoberta automática é o que é definido na especificação OpenID Connect.
|
||||
|
||||
|
||||
!!! tip "Dica"
|
||||
Integração com outros provedores de autenticação/autorização como Google, Facebook, Twitter, GitHub, etc. é bem possível e relativamente fácil.
|
||||
|
||||
O problema mais complexo é criar um provedor de autenticação/autorização como eles, mas o FastAPI dá a você ferramentas para fazer isso facilmente, enquanto faz o trabalho pesado para você.
|
||||
|
||||
## **FastAPI** utilitários
|
||||
|
||||
**FastAPI** fornece várias ferramentas para cada um desses esquemas de segurança no módulo `fastapi.security` que simplesmente usa esses mecanismos de segurança.
|
||||
|
||||
Nos próximos capítulos você irá ver como adicionar segurança à sua API usando essas ferramentas disponibilizadas pelo **FastAPI**.
|
||||
|
||||
E você irá ver também como isso é automaticamente integrado dentro do sistema de documentação interativo.
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -53,10 +55,18 @@ nav:
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
- features.md
|
||||
- fastapi-people.md
|
||||
- Tutorial - Guia de Usuário:
|
||||
- tutorial/index.md
|
||||
- tutorial/first-steps.md
|
||||
- tutorial/body-fields.md
|
||||
- Segurança:
|
||||
- tutorial/security/index.md
|
||||
- Guia de Usuário Avançado:
|
||||
- advanced/index.md
|
||||
- Implantação:
|
||||
- deployment/index.md
|
||||
- deployment/versions.md
|
||||
- alternatives.md
|
||||
- history-design-future.md
|
||||
- external-links.md
|
||||
@@ -66,7 +76,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -75,7 +85,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -84,7 +94,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -96,6 +106,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -126,6 +138,6 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
|
||||
82
docs/ru/docs/external-links.md
Normal file
82
docs/ru/docs/external-links.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Внешние ссылки и статьи
|
||||
|
||||
**FastAPI** имеет отличное и постоянно растущее сообщество.
|
||||
|
||||
Существует множество сообщений, статей, инструментов и проектов, связанных с **FastAPI**.
|
||||
|
||||
Вот неполный список некоторых из них.
|
||||
|
||||
!!! tip
|
||||
Если у вас есть статья, проект, инструмент или что-либо, связанное с **FastAPI**, что еще не перечислено здесь, создайте <a href="https://github.com/tiangolo/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">Pull Request</a>.
|
||||
|
||||
## Статьи
|
||||
|
||||
### На английском
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.articles.english %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
### На японском
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.articles.japanese %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
### На вьетнамском
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.articles.vietnamese %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
### На русском
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.articles.russian %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
### На немецком
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.articles.german %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
## Подкасты
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.podcasts.english %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
## Talks
|
||||
|
||||
{% if external_links %}
|
||||
{% for article in external_links.talks.english %}
|
||||
|
||||
* <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 %}
|
||||
|
||||
## Проекты
|
||||
|
||||
Последние GitHub-проекты с пометкой `fastapi`:
|
||||
|
||||
<div class="github-topic-projects">
|
||||
</div>
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
314
docs/ru/docs/python-types.md
Normal file
314
docs/ru/docs/python-types.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Введение в аннотации типов Python
|
||||
|
||||
Python имеет поддержку необязательных аннотаций типов.
|
||||
|
||||
**Аннотации типов** являются специальным синтаксисом, который позволяет определять <abbr title="например: str, int, float, bool">тип</abbr> переменной.
|
||||
|
||||
Объявление типов для переменных позволяет улучшить поддержку вашего кода редакторами и различными инструментами.
|
||||
|
||||
Это просто **краткое руководство / напоминание** об аннотациях типов в Python. Оно охватывает только минимум, необходимый для их использования с **FastAPI**... что на самом деле очень мало.
|
||||
|
||||
**FastAPI** целиком основан на аннотациях типов, у них много выгод и преимуществ.
|
||||
|
||||
Но даже если вы никогда не используете **FastAPI**, вам будет полезно немного узнать о них.
|
||||
|
||||
!!! note
|
||||
Если вы являетесь экспертом в Python и уже знаете всё об аннотациях типов, переходите к следующему разделу.
|
||||
|
||||
## Мотивация
|
||||
|
||||
Давайте начнем с простого примера:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/python_types/tutorial001.py!}
|
||||
```
|
||||
|
||||
Вызов этой программы выводит:
|
||||
|
||||
```
|
||||
John Doe
|
||||
```
|
||||
|
||||
Функция делает следующее:
|
||||
|
||||
* Принимает `first_name` и `last_name`.
|
||||
* Преобразует первую букву содержимого каждой переменной в верхний регистр с `title()`.
|
||||
* <abbr title="Объединяет в одно целое, последовательно, друг за другом.">Соединяет</abbr> их через пробел.
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!../../../docs_src/python_types/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Отредактируем пример
|
||||
|
||||
Это очень простая программа.
|
||||
|
||||
А теперь представьте, что вы пишете её с нуля.
|
||||
|
||||
В какой-то момент вы бы начали определение функции, у вас были бы готовы параметры...
|
||||
|
||||
Но затем вы должны вызвать «тот метод, который преобразует первую букву в верхний регистр».
|
||||
|
||||
Было это `upper`? Или `uppercase`? `first_uppercase`? `capitalize`?
|
||||
|
||||
Тогда вы попробуете с давним другом программиста: автодополнением редактора.
|
||||
|
||||
Вы вводите первый параметр функции, `first_name`, затем точку (`.`), а затем нажимаете `Ctrl+Space`, чтобы запустить дополнение.
|
||||
|
||||
Но, к сожалению, ничего полезного не выходит:
|
||||
|
||||
<img src="/img/python-types/image01.png">
|
||||
|
||||
### Добавим типы
|
||||
|
||||
Давайте изменим одну строчку в предыдущей версии.
|
||||
|
||||
Мы изменим именно этот фрагмент, параметры функции, с:
|
||||
|
||||
```Python
|
||||
first_name, last_name
|
||||
```
|
||||
|
||||
на:
|
||||
|
||||
```Python
|
||||
first_name: str, last_name: str
|
||||
```
|
||||
|
||||
Вот и все.
|
||||
|
||||
Это аннотации типов:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/python_types/tutorial002.py!}
|
||||
```
|
||||
|
||||
Это не то же самое, что объявление значений по умолчанию, например:
|
||||
|
||||
```Python
|
||||
first_name="john", last_name="doe"
|
||||
```
|
||||
|
||||
Это другая вещь.
|
||||
|
||||
Мы используем двоеточия (`:`), а не равно (`=`).
|
||||
|
||||
И добавление аннотаций типов обычно не меняет происходящего по сравнению с тем, что произошло бы без неё.
|
||||
|
||||
Но теперь представьте, что вы снова находитесь в процессе создания этой функции, но уже с аннотациями типов.
|
||||
|
||||
В тот же момент вы пытаетесь запустить автодополнение с помощью `Ctrl+Space` и вы видите:
|
||||
|
||||
<img src="/img/python-types/image02.png">
|
||||
|
||||
При этом вы можете просматривать варианты, пока не найдёте подходящий:
|
||||
|
||||
<img src="/img/python-types/image03.png">
|
||||
|
||||
## Больше мотивации
|
||||
|
||||
Проверьте эту функцию, она уже имеет аннотации типов:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/python_types/tutorial003.py!}
|
||||
```
|
||||
|
||||
Поскольку редактор знает типы переменных, вы получаете не только дополнение, но и проверки ошибок:
|
||||
|
||||
<img src="/img/python-types/image04.png">
|
||||
|
||||
Теперь вы знаете, что вам нужно исправить, преобразовав `age` в строку с `str(age)`:
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!../../../docs_src/python_types/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Объявление типов
|
||||
|
||||
Вы только что видели основное место для объявления подсказок типов. В качестве параметров функции.
|
||||
|
||||
Это также основное место, где вы можете использовать их с **FastAPI**.
|
||||
|
||||
### Простые типы
|
||||
|
||||
Вы можете объявить все стандартные типы Python, а не только `str`.
|
||||
|
||||
Вы можете использовать, к примеру:
|
||||
|
||||
* `int`
|
||||
* `float`
|
||||
* `bool`
|
||||
* `bytes`
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/python_types/tutorial005.py!}
|
||||
```
|
||||
|
||||
### Generic-типы с параметрами типов
|
||||
|
||||
Существуют некоторые структуры данных, которые могут содержать другие значения, например, `dict`, `list`, `set` и `tuple`. И внутренние значения тоже могут иметь свой тип.
|
||||
|
||||
Чтобы объявить эти типы и внутренние типы, вы можете использовать стандартный Python-модуль `typing`.
|
||||
|
||||
Он существует специально для поддержки подсказок этих типов.
|
||||
|
||||
#### `List`
|
||||
|
||||
Например, давайте определим переменную как `list`, состоящий из `str`.
|
||||
|
||||
Импортируйте `List` из `typing` (с заглавной `L`):
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
Объявите переменную с тем же синтаксисом двоеточия (`:`).
|
||||
|
||||
В качестве типа укажите `List`.
|
||||
|
||||
Поскольку список является типом, содержащим некоторые внутренние типы, вы помещаете их в квадратные скобки:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Эти внутренние типы в квадратных скобках называются «параметрами типов».
|
||||
|
||||
В этом случае `str` является параметром типа, передаваемым в `List`.
|
||||
|
||||
Это означает: "переменная `items` является `list`, и каждый из элементов этого списка является `str`".
|
||||
|
||||
Если вы будете так поступать, редактор может оказывать поддержку даже при обработке элементов списка:
|
||||
|
||||
<img src="/img/python-types/image05.png">
|
||||
|
||||
Без типов добиться этого практически невозможно.
|
||||
|
||||
Обратите внимание, что переменная `item` является одним из элементов списка `items`.
|
||||
|
||||
И все же редактор знает, что это `str`, и поддерживает это.
|
||||
|
||||
#### `Tuple` и `Set`
|
||||
|
||||
Вы бы сделали то же самое, чтобы объявить `tuple` и `set`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial007.py!}
|
||||
```
|
||||
|
||||
Это означает:
|
||||
|
||||
* Переменная `items_t` является `tuple` с 3 элементами: `int`, другим `int` и `str`.
|
||||
* Переменная `items_s` является `set` и каждый элемент имеет тип `bytes`.
|
||||
|
||||
#### `Dict`
|
||||
|
||||
Чтобы определить `dict`, вы передаёте 2 параметра типов, разделённых запятыми.
|
||||
|
||||
Первый параметр типа предназначен для ключей `dict`.
|
||||
|
||||
Второй параметр типа предназначен для значений `dict`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial008.py!}
|
||||
```
|
||||
|
||||
Это означает:
|
||||
|
||||
* Переменная `prices` является `dict`:
|
||||
* Ключи этого `dict` имеют тип `str` (скажем, название каждого элемента).
|
||||
* Значения этого `dict` имеют тип `float` (скажем, цена каждой позиции).
|
||||
|
||||
#### `Optional`
|
||||
|
||||
Вы также можете использовать `Optional`, чтобы объявить, что переменная имеет тип, например, `str`, но это является «необязательным», что означает, что она также может быть `None`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
Использование `Optional[str]` вместо просто `str` позволит редактору помочь вам в обнаружении ошибок, в которых вы могли бы предположить, что значение всегда является `str`, хотя на самом деле это может быть и `None`.
|
||||
|
||||
#### Generic-типы
|
||||
|
||||
Эти типы принимают параметры в квадратных скобках:
|
||||
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Optional`
|
||||
* ...и др.
|
||||
|
||||
называются **Generic-типами** или **Generics**.
|
||||
|
||||
### Классы как типы
|
||||
|
||||
Вы также можете объявить класс как тип переменной.
|
||||
|
||||
Допустим, у вас есть класс `Person` с полем `name`:
|
||||
|
||||
```Python hl_lines="1-3"
|
||||
{!../../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
|
||||
Тогда вы можете объявить переменную типа `Person`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
|
||||
И снова вы получаете полную поддержку редактора:
|
||||
|
||||
<img src="/img/python-types/image06.png">
|
||||
|
||||
## Pydantic-модели
|
||||
|
||||
<a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> является Python-библиотекой для выполнения валидации данных.
|
||||
|
||||
Вы объявляете «форму» данных как классы с атрибутами.
|
||||
|
||||
И каждый атрибут имеет тип.
|
||||
|
||||
Затем вы создаете экземпляр этого класса с некоторыми значениями, и он проверяет значения, преобразует их в соответствующий тип (если все верно) и предоставляет вам объект со всеми данными.
|
||||
|
||||
И вы получаете полную поддержку редактора для этого итогового объекта.
|
||||
|
||||
Взято из официальной документации Pydantic:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
Чтобы узнать больше о <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic, читайте его документацию</a>.
|
||||
|
||||
**FastAPI** целиком основан на Pydantic.
|
||||
|
||||
Вы увидите намного больше всего этого на практике в [Руководстве пользователя](tutorial/index.md){.internal-link target=_blank}.
|
||||
|
||||
## Аннотации типов в **FastAPI**
|
||||
|
||||
**FastAPI** получает преимущества аннотаций типов для выполнения определённых задач.
|
||||
|
||||
С **FastAPI** вы объявляете параметры с аннотациями типов и получаете:
|
||||
|
||||
* **Поддержку редактора**.
|
||||
* **Проверки типов**.
|
||||
|
||||
...и **FastAPI** использует тот же механизм для:
|
||||
|
||||
* **Определения требований**: из параметров пути запроса, параметров запроса, заголовков, зависимостей и т.д.
|
||||
* **Преобразования данных**: от запроса к нужному типу.
|
||||
* **Валидации данных**: исходя из каждого запроса:
|
||||
* Генерации **автоматических ошибок**, возвращаемых клиенту, когда данные не являются корректными.
|
||||
* **Документирования** API с использованием OpenAPI:
|
||||
* который затем используется пользовательскими интерфейсами автоматической интерактивной документации.
|
||||
|
||||
Всё это может показаться абстрактным. Не волнуйтесь. Вы увидите всё это в действии в [Руководстве пользователя](tutorial/index.md){.internal-link target=_blank}.
|
||||
|
||||
Важно то, что при использовании стандартных типов Python в одном месте (вместо добавления дополнительных классов, декораторов и т.д.) **FastAPI** сделает за вас большую часть работы.
|
||||
|
||||
!!! info
|
||||
Если вы уже прошли всё руководство и вернулись, чтобы узнать больше о типах, хорошим ресурсом является <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">«шпаргалка» от `mypy`</a>.
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -57,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -66,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -75,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -87,6 +89,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -117,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -57,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -66,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -75,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -87,6 +89,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -117,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -57,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -66,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -75,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -87,6 +89,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -117,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -44,13 +44,16 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -57,7 +59,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -66,7 +68,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -75,7 +77,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -87,6 +89,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -117,6 +121,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
@@ -183,7 +183,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
|
||||
|
||||
包括许多与云存储,视频处理等交互的库。
|
||||
|
||||
```Python hl_lines="2 10 11"
|
||||
```Python hl_lines="2 10-12 14"
|
||||
{!../../../docs_src/custom_response/tutorial008.py!}
|
||||
```
|
||||
|
||||
|
||||
@@ -114,42 +114,51 @@ FastAPI 有一个非常棒的社区,它欢迎来自各个领域和背景的朋
|
||||
|
||||
他们主要通过<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>支持我在 **FastAPI** (和其他项目)的工作。
|
||||
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### 金牌赞助商
|
||||
|
||||
{% if sponsors %} {% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
{% endfor %} {% endif %}
|
||||
{% 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 %}
|
||||
|
||||
### 银牌赞助商
|
||||
|
||||
{% if sponsors %} {% for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
{% endfor %} {% endif %}
|
||||
{% 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 people %} {% if people.sponsors_50 %}
|
||||
{% if sponsors.bronze %}
|
||||
|
||||
### 铜牌赞助商
|
||||
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors_50 %}
|
||||
|
||||
<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>
|
||||
{% for sponsor in sponsors.bronze -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
{% endif %} {% endif %}
|
||||
{% endif %}
|
||||
|
||||
### 个人赞助
|
||||
|
||||
{% if people %}
|
||||
{% if github_sponsors %}
|
||||
{% for group in github_sponsors.sponsors %}
|
||||
|
||||
<div class="user-list user-list-center">
|
||||
{% for user in people.sponsors %}
|
||||
|
||||
{% 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 %}
|
||||
|
||||
## 关于数据 - 技术细节
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
编写带有类型标注的标准 Python:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -40,13 +40,16 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
|
||||
|
||||
<small>* 根据对某个构建线上应用的内部开发团队所进行的测试估算得出。</small>
|
||||
|
||||
## Gold Sponsors
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||
<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 %}
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# 路径操作装饰器依赖项
|
||||
|
||||
有时,我们并不需要在*路径操作函数*中使用依赖项的返回值。
|
||||
|
||||
或者说,有些依赖项不返回值。
|
||||
|
||||
但仍要执行或解析该依赖项。
|
||||
|
||||
对于这种情况,不必在声明*路径操作函数*的参数时使用 `Depends`,而是可以在*路径操作装饰器*中添加一个由 `dependencies` 组成的 `list`。
|
||||
|
||||
## 在*路径操作装饰器*中添加 `dependencies` 参数
|
||||
|
||||
*路径操作装饰器*支持可选参数 ~ `dependencies`。
|
||||
|
||||
该参数的值是由 `Depends()` 组成的 `list`:
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
路径操作装饰器依赖项(以下简称为**“路径装饰器依赖项”**)的执行或解析方式和普通依赖项一样,但就算这些依赖项会返回值,它们的值也不会传递给*路径操作函数*。
|
||||
|
||||
!!! tip "提示"
|
||||
|
||||
有些编辑器会检查代码中没使用过的函数参数,并显示错误提示。
|
||||
|
||||
在*路径操作装饰器*中使用 `dependencies` 参数,可以确保在执行依赖项的同时,避免编辑器显示错误提示。
|
||||
|
||||
使用路径装饰器依赖项还可以避免开发新人误会代码中包含无用的未使用参数。
|
||||
|
||||
!!! info "说明"
|
||||
|
||||
本例中,使用的是自定义响应头 `X-Key` 和 `X-Token`。
|
||||
|
||||
但实际开发中,尤其是在实现安全措施时,最好使用 FastAPI 内置的[安全工具](../security/index.md){.internal-link target=_blank}(详见下一章)。
|
||||
|
||||
## 依赖项错误和返回值
|
||||
|
||||
路径装饰器依赖项也可以使用普通的依赖项*函数*。
|
||||
|
||||
### 依赖项的需求项
|
||||
|
||||
路径装饰器依赖项可以声明请求的需求项(比如响应头)或其他子依赖项:
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
### 触发异常
|
||||
|
||||
路径装饰器依赖项与正常的依赖项一样,可以 `raise` 异常:
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
### 返回值
|
||||
|
||||
无论路径装饰器依赖项是否返回值,路径操作都不会使用这些值。
|
||||
|
||||
因此,可以复用在其他位置使用过的、(能返回值的)普通依赖项,即使没有使用这个值,也会执行该依赖项:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
{!../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
## 为一组路径操作定义依赖项
|
||||
|
||||
稍后,[大型应用 - 多文件](../../tutorial/bigger-applications.md){.internal-link target=\_blank}一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,您将了解到如何为一组*路径操作*声明单个 `dependencies` 参数。
|
||||
|
||||
## 全局依赖项
|
||||
|
||||
接下来,我们将学习如何为 `FastAPI` 应用程序添加全局依赖项,创建应用于每个*路径操作*的依赖项。
|
||||
18
docs/zh/docs/tutorial/dependencies/global-dependencies.md
Normal file
18
docs/zh/docs/tutorial/dependencies/global-dependencies.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# 全局依赖项
|
||||
|
||||
有时,我们要为整个应用添加依赖项。
|
||||
|
||||
通过与定义[*路径装饰器依赖项*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 类似的方式,可以把依赖项添加至整个 `FastAPI` 应用。
|
||||
|
||||
这样一来,就可以为所有*路径操作*应用该依赖项:
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!../../../docs_src/dependencies/tutorial012.py!}
|
||||
```
|
||||
|
||||
[*路径装饰器依赖项*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 一章的思路均适用于全局依赖项, 在本例中,这些依赖项可以用于应用中的所有*路径操作*。
|
||||
|
||||
## 为一组路径操作定义依赖项
|
||||
|
||||
稍后,[大型应用 - 多文件](../../tutorial/bigger-applications.md){.internal-link target=_blank}一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,您将了解到如何为一组*路径操作*声明单个 `dependencies` 参数。
|
||||
|
||||
212
docs/zh/docs/tutorial/dependencies/index.md
Normal file
212
docs/zh/docs/tutorial/dependencies/index.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# 依赖项 - 第一步
|
||||
|
||||
FastAPI 提供了简单易用,但功能强大的**<abbr title="也称为组件、资源、提供者、服务、可注入项">依赖注入</abbr>**系统。
|
||||
|
||||
这个依赖系统设计的简单易用,可以让开发人员轻松地把组件集成至 **FastAPI**。
|
||||
|
||||
## 什么是「依赖注入」
|
||||
|
||||
编程中的**「依赖注入」**是声明代码(本文中为*路径操作函数* )运行所需的,或要使用的「依赖」的一种方式。
|
||||
|
||||
然后,由系统(本文中为 **FastAPI**)负责执行任意需要的逻辑,为代码提供这些依赖(「注入」依赖项)。
|
||||
|
||||
依赖注入常用于以下场景:
|
||||
|
||||
* 共享业务逻辑(复用相同的代码逻辑)
|
||||
* 共享数据库连接
|
||||
* 实现安全、验证、角色权限
|
||||
* 等……
|
||||
|
||||
上述场景均可以使用**依赖注入**,将代码重复最小化。
|
||||
|
||||
## 第一步
|
||||
|
||||
接下来,我们学习一个非常简单的例子,尽管它过于简单,不是很实用。
|
||||
|
||||
但通过这个例子,您可以初步了解「依赖注入」的工作机制。
|
||||
|
||||
### 创建依赖项
|
||||
|
||||
首先,要关注的是依赖项。
|
||||
|
||||
依赖项就是一个函数,且可以使用与*路径操作函数*相同的参数:
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
大功告成。
|
||||
|
||||
只用了**2 行**代码。
|
||||
|
||||
依赖项函数的形式和结构与*路径操作函数*一样。
|
||||
|
||||
因此,可以把依赖项当作没有「装饰器」(即,没有 `@app.get("/some-path")` )的路径操作函数。
|
||||
|
||||
依赖项可以返回各种内容。
|
||||
|
||||
本例中的依赖项预期接收如下参数:
|
||||
|
||||
* 类型为 `str` 的可选查询参数 `q`
|
||||
* 类型为 `int` 的可选查询参数 `skip`,默认值是 `0`
|
||||
* 类型为 `int` 的可选查询参数 `limit`,默认值是 `100`
|
||||
|
||||
然后,依赖项函数返回包含这些值的 `dict`。
|
||||
|
||||
### 导入 `Depends`
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 声明依赖项
|
||||
|
||||
与在*路径操作函数*参数中使用 `Body`、`Query` 的方式相同,声明依赖项需要使用 `Depends` 和一个新的参数:
|
||||
|
||||
```Python hl_lines="13 18"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
虽然,在路径操作函数的参数中使用 `Depends` 的方式与 `Body`、`Query` 相同,但 `Depends` 的工作方式略有不同。
|
||||
|
||||
这里只能传给 Depends 一个参数。
|
||||
|
||||
且该参数必须是可调用对象,比如函数。
|
||||
|
||||
该函数接收的参数和*路径操作函数*的参数一样。
|
||||
|
||||
!!! tip "提示"
|
||||
|
||||
下一章介绍,除了函数还有哪些「对象」可以用作依赖项。
|
||||
|
||||
接收到新的请求时,**FastAPI** 执行如下操作:
|
||||
|
||||
* 用正确的参数调用依赖项函数(「可依赖项」)
|
||||
* 获取函数返回的结果
|
||||
* 把函数返回的结果赋值给*路径操作函数*的参数
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
|
||||
common_parameters(["common_parameters"])
|
||||
read_items["/items/"]
|
||||
read_users["/users/"]
|
||||
|
||||
common_parameters --> read_items
|
||||
common_parameters --> read_users
|
||||
```
|
||||
|
||||
这样,只编写一次代码,**FastAPI** 就可以为多个*路径操作*共享这段代码 。
|
||||
|
||||
!!! check "检查"
|
||||
|
||||
注意,无需创建专门的类,并将之传递给 **FastAPI** 以进行「注册」或执行类似的操作。
|
||||
|
||||
只要把它传递给 `Depends`,**FastAPI** 就知道该如何执行后续操作。
|
||||
|
||||
## 要不要使用 `async`?
|
||||
|
||||
**FastAPI** 调用依赖项的方式与*路径操作函数*一样,因此,定义依赖项函数,也要应用与路径操作函数相同的规则。
|
||||
|
||||
即,既可以使用异步的 `async def`,也可以使用普通的 `def` 定义依赖项。
|
||||
|
||||
在普通的 `def` *路径操作函数*中,可以声明异步的 `async def` 依赖项;也可以在异步的 `async def` *路径操作函数*中声明普通的 `def` 依赖项。
|
||||
|
||||
上述这些操作都是可行的,**FastAPI** 知道该怎么处理。
|
||||
|
||||
!!! note "笔记"
|
||||
|
||||
如里不了解异步,请参阅[异步:*“着急了?”*](../../async.md){.internal-link target=_blank} 一章中 `async` 和 `await` 的内容。
|
||||
|
||||
## 与 OpenAPI 集成
|
||||
|
||||
依赖项及子依赖项的所有请求声明、验证和需求都可以集成至同一个 OpenAPI 概图。
|
||||
|
||||
所以,交互文档里也会显示依赖项的所有信息:
|
||||
|
||||
<img src="/img/tutorial/dependencies/image01.png">
|
||||
|
||||
## 简单用法
|
||||
|
||||
观察一下就会发现,只要*路径* 和*操作*匹配,就可以使用声明的路径操作函数。然后,**FastAPI** 会用正确的参数调用函数,并提取请求中的数据。
|
||||
|
||||
实际上,所有(或大多数)网络框架的工作方式都是这样的。
|
||||
|
||||
开发人员永远都不需要直接调用这些函数,这些函数是由框架(在此为 **FastAPI** )调用的。
|
||||
|
||||
通过依赖注入系统,只要告诉 **FastAPI** *路径操作函数* 还要「依赖」其他在*路径操作函数*之前执行的内容,**FastAPI** 就会执行函数代码,并「注入」函数返回的结果。
|
||||
|
||||
其他与「依赖注入」概念相同的术语为:
|
||||
|
||||
* 资源(Resource)
|
||||
* 提供方(Provider)
|
||||
* 服务(Service)
|
||||
* 可注入(Injectable)
|
||||
* 组件(Component)
|
||||
|
||||
## **FastAPI** 插件
|
||||
|
||||
**依赖注入**系统支持构建集成和「插件」。但实际上,FastAPI 根本**不需要创建「插件」**,因为使用依赖项可以声明不限数量的、可用于*路径操作函数*的集成与交互。
|
||||
|
||||
创建依赖项非常简单、直观,并且还支持导入 Python 包。毫不夸张地说,只要几行代码就可以把需要的 Python 包与 API 函数集成在一起。
|
||||
|
||||
下一章将详细介绍在关系型数据库、NoSQL 数据库、安全等方面使用依赖项的例子。
|
||||
|
||||
## **FastAPI** 兼容性
|
||||
|
||||
依赖注入系统如此简洁的特性,让 **FastAPI** 可以与下列系统兼容:
|
||||
|
||||
* 关系型数据库
|
||||
* NoSQL 数据库
|
||||
* 外部支持库
|
||||
* 外部 API
|
||||
* 认证和鉴权系统
|
||||
* API 使用监控系统
|
||||
* 响应数据注入系统
|
||||
* 等等……
|
||||
|
||||
## 简单而强大
|
||||
|
||||
虽然,**层级式依赖注入系统**的定义与使用十分简单,但它却非常强大。
|
||||
|
||||
比如,可以定义依赖其他依赖项的依赖项。
|
||||
|
||||
最后,依赖项层级树构建后,**依赖注入系统**会处理所有依赖项及其子依赖项,并为每一步操作提供(注入)结果。
|
||||
|
||||
比如,下面有 4 个 API 路径操作(*端点*):
|
||||
|
||||
* `/items/public/`
|
||||
* `/items/private/`
|
||||
* `/users/{user_id}/activate`
|
||||
* `/items/pro/`
|
||||
|
||||
开发人员可以使用依赖项及其子依赖项为这些路径操作添加不同的权限:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
|
||||
current_user(["current_user"])
|
||||
active_user(["active_user"])
|
||||
admin_user(["admin_user"])
|
||||
paying_user(["paying_user"])
|
||||
|
||||
public["/items/public/"]
|
||||
private["/items/private/"]
|
||||
activate_user["/users/{user_id}/activate"]
|
||||
pro_items["/items/pro/"]
|
||||
|
||||
current_user --> active_user
|
||||
active_user --> admin_user
|
||||
active_user --> paying_user
|
||||
|
||||
current_user --> public
|
||||
active_user --> private
|
||||
admin_user --> activate_user
|
||||
paying_user --> pro_items
|
||||
```
|
||||
|
||||
## 与 **OpenAPI** 集成
|
||||
|
||||
在声明需求时,所有这些依赖项还会把参数、验证等功能添加至路径操作。
|
||||
|
||||
**FastAPI** 负责把上述内容全部添加到 OpenAPI 概图,并显示在交互文档中。
|
||||
88
docs/zh/docs/tutorial/dependencies/sub-dependencies.md
Normal file
88
docs/zh/docs/tutorial/dependencies/sub-dependencies.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# 子依赖项
|
||||
|
||||
FastAPI 支持创建含**子依赖项**的依赖项。
|
||||
|
||||
并且,可以按需声明任意**深度**的子依赖项嵌套层级。
|
||||
|
||||
**FastAPI** 负责处理解析不同深度的子依赖项。
|
||||
|
||||
### 第一层依赖项
|
||||
|
||||
下列代码创建了第一层依赖项:
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
这段代码声明了类型为 `str` 的可选查询参数 `q`,然后返回这个查询参数。
|
||||
|
||||
这个函数很简单(不过也没什么用),但却有助于让我们专注于了解子依赖项的工作方式。
|
||||
|
||||
### 第二层依赖项
|
||||
|
||||
接下来,创建另一个依赖项函数,并同时用该依赖项自身再声明一个依赖项(所以这也是一个「依赖项」):
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
这里重点说明一下声明的参数:
|
||||
|
||||
* 尽管该函数自身是依赖项,但还声明了另一个依赖项(它「依赖」于其他对象)
|
||||
* 该函数依赖 `query_extractor`, 并把 `query_extractor` 的返回值赋给参数 `q`
|
||||
* 同时,该函数还声明了类型是 `str` 的可选 cookie(`last_query`)
|
||||
* 用户未提供查询参数 `q` 时,则使用上次使用后保存在 cookie 中的查询
|
||||
|
||||
### 使用依赖项
|
||||
|
||||
接下来,就可以使用依赖项:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! info "信息"
|
||||
|
||||
注意,这里在*路径操作函数*中只声明了一个依赖项,即 `query_or_cookie_extractor` 。
|
||||
|
||||
但 **FastAPI** 必须先处理 `query_extractor`,以便在调用 `query_or_cookie_extractor` 时使用 `query_extractor` 返回的结果。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
|
||||
query_extractor(["query_extractor"])
|
||||
query_or_cookie_extractor(["query_or_cookie_extractor"])
|
||||
|
||||
read_query["/items/"]
|
||||
|
||||
query_extractor --> query_or_cookie_extractor --> read_query
|
||||
```
|
||||
|
||||
## 多次使用同一个依赖项
|
||||
|
||||
如果在同一个*路径操作* 多次声明了同一个依赖项,例如,多个依赖项共用一个子依赖项,**FastAPI** 在处理同一请求时,只调用一次该子依赖项。
|
||||
|
||||
FastAPI 不会为同一个请求多次调用同一个依赖项,而是把依赖项的返回值进行<abbr title="一个实用程序/系统来存储计算/生成的值,以便重用它们,而不是再次计算它们。">「缓存」</abbr>,并把它传递给同一请求中所有需要使用该返回值的「依赖项」。
|
||||
|
||||
在高级使用场景中,如果不想使用「缓存」值,而是为需要在同一请求的每一步操作(多次)中都实际调用依赖项,可以把 `Depends` 的参数 `use_cache` 的值设置为 `False` :
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
|
||||
return {"fresh_value": fresh_value}
|
||||
```
|
||||
|
||||
## 小结
|
||||
|
||||
千万别被本章里这些花里胡哨的词藻吓倒了,其实**依赖注入**系统非常简单。
|
||||
|
||||
依赖注入无非是与*路径操作函数*一样的函数罢了。
|
||||
|
||||
但它依然非常强大,能够声明任意嵌套深度的「图」或树状的依赖结构。
|
||||
|
||||
!!! tip "提示"
|
||||
|
||||
这些简单的例子现在看上去虽然没有什么实用价值,
|
||||
|
||||
但在**安全**一章中,您会了解到这些例子的用途,
|
||||
|
||||
以及这些例子所能节省的代码量。
|
||||
@@ -20,6 +20,7 @@ theme:
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
@@ -39,6 +40,7 @@ nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
@@ -79,6 +81,11 @@ nav:
|
||||
- tutorial/request-forms-and-files.md
|
||||
- tutorial/handling-errors.md
|
||||
- tutorial/body-updates.md
|
||||
- 依赖项:
|
||||
- tutorial/dependencies/index.md
|
||||
- tutorial/dependencies/sub-dependencies.md
|
||||
- tutorial/dependencies/dependencies-in-path-operation-decorators.md
|
||||
- tutorial/dependencies/global-dependencies.md
|
||||
- 安全性:
|
||||
- tutorial/security/index.md
|
||||
- tutorial/security/get-current-user.md
|
||||
@@ -103,7 +110,7 @@ markdown_extensions:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- markdown_include.include:
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
@@ -112,7 +119,7 @@ markdown_extensions:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_div_format ''
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
extra:
|
||||
social:
|
||||
@@ -121,7 +128,7 @@ extra:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/tiangolo
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
@@ -133,6 +140,8 @@ extra:
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fr/
|
||||
@@ -163,6 +172,5 @@ extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user