committed by
GitHub
493 changed files with 30665 additions and 2066 deletions
@ -1,181 +0,0 @@ |
|||||
name: Feature Request |
|
||||
description: Suggest an idea or ask for a feature that you would like to have in FastAPI |
|
||||
labels: [enhancement] |
|
||||
body: |
|
||||
- type: markdown |
|
||||
attributes: |
|
||||
value: | |
|
||||
Thanks for your interest in FastAPI! 🚀 |
|
||||
|
|
||||
Please follow these instructions, fill every question, and do every step. 🙏 |
|
||||
|
|
||||
I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the time. |
|
||||
|
|
||||
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling issues. |
|
||||
|
|
||||
All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others. |
|
||||
|
|
||||
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅). |
|
||||
|
|
||||
By asking questions in a structured way (following this) it will be much easier to help you. |
|
||||
|
|
||||
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎 |
|
||||
|
|
||||
As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓 |
|
||||
- type: checkboxes |
|
||||
id: checks |
|
||||
attributes: |
|
||||
label: First Check |
|
||||
description: Please confirm and check all the following options. |
|
||||
options: |
|
||||
- label: I added a very descriptive title to this issue. |
|
||||
required: true |
|
||||
- label: I used the GitHub search to find a similar issue and didn't find it. |
|
||||
required: true |
|
||||
- label: I searched the FastAPI documentation, with the integrated search. |
|
||||
required: true |
|
||||
- label: I already searched in Google "How to X in FastAPI" and didn't find any information. |
|
||||
required: true |
|
||||
- label: I already read and followed all the tutorial in the docs and didn't find an answer. |
|
||||
required: true |
|
||||
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic). |
|
||||
required: true |
|
||||
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui). |
|
||||
required: true |
|
||||
- label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc). |
|
||||
required: true |
|
||||
- type: checkboxes |
|
||||
id: help |
|
||||
attributes: |
|
||||
label: Commit to Help |
|
||||
description: | |
|
||||
After submitting this, I commit to one of: |
|
||||
|
|
||||
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there. |
|
||||
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future. |
|
||||
* Implement a Pull Request for a confirmed bug. |
|
||||
|
|
||||
options: |
|
||||
- label: I commit to help with one of those options 👆 |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: example |
|
||||
attributes: |
|
||||
label: Example Code |
|
||||
description: | |
|
||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case. |
|
||||
|
|
||||
If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you. |
|
||||
|
|
||||
placeholder: | |
|
||||
from fastapi import FastAPI |
|
||||
|
|
||||
app = FastAPI() |
|
||||
|
|
||||
|
|
||||
@app.get("/") |
|
||||
def read_root(): |
|
||||
return {"Hello": "World"} |
|
||||
render: python |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: description |
|
||||
attributes: |
|
||||
label: Description |
|
||||
description: | |
|
||||
What is your feature request? |
|
||||
|
|
||||
Write a short description telling me what you are trying to solve and what you are currently doing. |
|
||||
placeholder: | |
|
||||
* Open the browser and call the endpoint `/`. |
|
||||
* It returns a JSON with `{"Hello": "World"}`. |
|
||||
* I would like it to have an extra parameter to teleport me to the moon and back. |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: wanted-solution |
|
||||
attributes: |
|
||||
label: Wanted Solution |
|
||||
description: | |
|
||||
Tell me what's the solution you would like. |
|
||||
placeholder: | |
|
||||
I would like it to have a `teleport_to_moon` parameter that defaults to `False`, and can be set to `True` to teleport me. |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: wanted-code |
|
||||
attributes: |
|
||||
label: Wanted Code |
|
||||
description: Show me an example of how you would want the code to look like. |
|
||||
placeholder: | |
|
||||
from fastapi import FastAPI |
|
||||
|
|
||||
app = FastAPI() |
|
||||
|
|
||||
|
|
||||
@app.get("/", teleport_to_moon=True) |
|
||||
def read_root(): |
|
||||
return {"Hello": "World"} |
|
||||
render: python |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: alternatives |
|
||||
attributes: |
|
||||
label: Alternatives |
|
||||
description: | |
|
||||
Tell me about alternatives you've considered. |
|
||||
placeholder: | |
|
||||
To wait for Space X moon travel plans to drop down long after they release them. But I would rather teleport. |
|
||||
- type: dropdown |
|
||||
id: os |
|
||||
attributes: |
|
||||
label: Operating System |
|
||||
description: What operating system are you on? |
|
||||
multiple: true |
|
||||
options: |
|
||||
- Linux |
|
||||
- Windows |
|
||||
- macOS |
|
||||
- Other |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: os-details |
|
||||
attributes: |
|
||||
label: Operating System Details |
|
||||
description: You can add more details about your operating system here, in particular if you chose "Other". |
|
||||
- type: input |
|
||||
id: fastapi-version |
|
||||
attributes: |
|
||||
label: FastAPI Version |
|
||||
description: | |
|
||||
What FastAPI version are you using? |
|
||||
|
|
||||
You can find the FastAPI version with: |
|
||||
|
|
||||
```bash |
|
||||
python -c "import fastapi; print(fastapi.__version__)" |
|
||||
``` |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: input |
|
||||
id: python-version |
|
||||
attributes: |
|
||||
label: Python Version |
|
||||
description: | |
|
||||
What Python version are you using? |
|
||||
|
|
||||
You can find the Python version with: |
|
||||
|
|
||||
```bash |
|
||||
python --version |
|
||||
``` |
|
||||
validations: |
|
||||
required: true |
|
||||
- type: textarea |
|
||||
id: context |
|
||||
attributes: |
|
||||
label: Additional Context |
|
||||
description: Add any additional context information or screenshots you think are useful. |
|
@ -0,0 +1,22 @@ |
|||||
|
name: Privileged |
||||
|
description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. 👇 |
||||
|
body: |
||||
|
- type: markdown |
||||
|
attributes: |
||||
|
value: | |
||||
|
Thanks for your interest in FastAPI! 🚀 |
||||
|
|
||||
|
If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/tiangolo/fastapi/discussions/categories/questions) instead. |
||||
|
- type: checkboxes |
||||
|
id: privileged |
||||
|
attributes: |
||||
|
label: Privileged issue |
||||
|
description: Confirm that you are allowed to create an issue here. |
||||
|
options: |
||||
|
- label: I'm @tiangolo or he asked me directly to create an issue here. |
||||
|
required: true |
||||
|
- type: textarea |
||||
|
id: content |
||||
|
attributes: |
||||
|
label: Issue Content |
||||
|
description: Add the content of the issue here. |
@ -1,21 +0,0 @@ |
|||||
pt: 1211 |
|
||||
es: 1218 |
|
||||
zh: 1228 |
|
||||
ru: 1362 |
|
||||
it: 1556 |
|
||||
ja: 1572 |
|
||||
uk: 1748 |
|
||||
tr: 1892 |
|
||||
fr: 1972 |
|
||||
ko: 2017 |
|
||||
fa: 2041 |
|
||||
pl: 3169 |
|
||||
de: 3716 |
|
||||
id: 3717 |
|
||||
az: 3994 |
|
||||
nl: 4701 |
|
||||
uz: 4883 |
|
||||
sv: 5146 |
|
||||
he: 5157 |
|
||||
ta: 5434 |
|
||||
ar: 3349 |
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,168 @@ |
|||||
|
# Configuration avancée des paramètres de chemin |
||||
|
|
||||
|
## ID d'opération OpenAPI |
||||
|
|
||||
|
!!! Attention |
||||
|
Si vous n'êtes pas un "expert" en OpenAPI, vous n'en avez probablement pas besoin. |
||||
|
|
||||
|
Dans OpenAPI, les chemins sont des ressources, tels que /users/ ou /items/, exposées par votre API, et les opérations sont les méthodes HTTP utilisées pour manipuler ces chemins, telles que GET, POST ou DELETE. Les operationId sont des chaînes uniques facultatives utilisées pour identifier une opération d'un chemin. Vous pouvez définir l'OpenAPI `operationId` à utiliser dans votre *opération de chemin* avec le paramètre `operation_id`. |
||||
|
|
||||
|
Vous devez vous assurer qu'il est unique pour chaque opération. |
||||
|
|
||||
|
```Python hl_lines="6" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
### Utilisation du nom *path operation function* comme operationId |
||||
|
|
||||
|
Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`, vous pouvez les parcourir tous et remplacer chaque `operation_id` de l'*opération de chemin* en utilisant leur `APIRoute.name`. |
||||
|
|
||||
|
Vous devriez le faire après avoir ajouté toutes vos *paramètres de chemin*. |
||||
|
|
||||
|
```Python hl_lines="2 12-21 24" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! Astuce |
||||
|
Si vous appelez manuellement `app.openapi()`, vous devez mettre à jour les `operationId` avant. |
||||
|
|
||||
|
!!! Attention |
||||
|
Pour faire cela, vous devez vous assurer que chacun de vos *chemin* ait un nom unique. |
||||
|
|
||||
|
Même s'ils se trouvent dans des modules différents (fichiers Python). |
||||
|
|
||||
|
## Exclusion d'OpenAPI |
||||
|
|
||||
|
Pour exclure un *chemin* du schéma OpenAPI généré (et donc des systèmes de documentation automatiques), utilisez le paramètre `include_in_schema` et assignez-lui la valeur `False` : |
||||
|
|
||||
|
```Python hl_lines="6" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!} |
||||
|
``` |
||||
|
|
||||
|
## Description avancée de docstring |
||||
|
|
||||
|
Vous pouvez limiter le texte utilisé de la docstring d'une *fonction de chemin* qui sera affiché sur OpenAPI. |
||||
|
|
||||
|
L'ajout d'un `\f` (un caractère d'échappement "form feed") va permettre à **FastAPI** de tronquer la sortie utilisée pour OpenAPI à ce stade. |
||||
|
|
||||
|
Il n'apparaîtra pas dans la documentation, mais d'autres outils (tel que Sphinx) pourront utiliser le reste. |
||||
|
|
||||
|
```Python hl_lines="19-29" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!} |
||||
|
``` |
||||
|
|
||||
|
## Réponses supplémentaires |
||||
|
|
||||
|
Vous avez probablement vu comment déclarer le `response_model` et le `status_code` pour une *opération de chemin*. |
||||
|
|
||||
|
Cela définit les métadonnées sur la réponse principale d'une *opération de chemin*. |
||||
|
|
||||
|
Vous pouvez également déclarer des réponses supplémentaires avec leurs modèles, codes de statut, etc. |
||||
|
|
||||
|
Il y a un chapitre entier ici dans la documentation à ce sujet, vous pouvez le lire sur [Réponses supplémentaires dans OpenAPI](./additional-responses.md){.internal-link target=_blank}. |
||||
|
|
||||
|
## OpenAPI supplémentaire |
||||
|
|
||||
|
Lorsque vous déclarez un *chemin* dans votre application, **FastAPI** génère automatiquement les métadonnées concernant ce *chemin* à inclure dans le schéma OpenAPI. |
||||
|
|
||||
|
!!! note "Détails techniques" |
||||
|
La spécification OpenAPI appelle ces métaonnées des <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Objets d'opération</a>. |
||||
|
|
||||
|
Il contient toutes les informations sur le *chemin* et est utilisé pour générer automatiquement la documentation. |
||||
|
|
||||
|
Il inclut les `tags`, `parameters`, `requestBody`, `responses`, etc. |
||||
|
|
||||
|
Ce schéma OpenAPI spécifique aux *operations* est normalement généré automatiquement par **FastAPI**, mais vous pouvez également l'étendre. |
||||
|
|
||||
|
!!! Astuce |
||||
|
Si vous avez seulement besoin de déclarer des réponses supplémentaires, un moyen plus pratique de le faire est d'utiliser les [réponses supplémentaires dans OpenAPI](./additional-responses.md){.internal-link target=_blank}. |
||||
|
|
||||
|
Vous pouvez étendre le schéma OpenAPI pour une *opération de chemin* en utilisant le paramètre `openapi_extra`. |
||||
|
|
||||
|
### Extensions OpenAPI |
||||
|
|
||||
|
Cet `openapi_extra` peut être utile, par exemple, pour déclarer [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) : |
||||
|
|
||||
|
```Python hl_lines="6" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!} |
||||
|
``` |
||||
|
|
||||
|
Si vous ouvrez la documentation automatique de l'API, votre extension apparaîtra au bas du *chemin* spécifique. |
||||
|
|
||||
|
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png"> |
||||
|
|
||||
|
Et dans le fichier openapi généré (`/openapi.json`), vous verrez également votre extension dans le cadre du *chemin* spécifique : |
||||
|
|
||||
|
```JSON hl_lines="22" |
||||
|
{ |
||||
|
"openapi": "3.0.2", |
||||
|
"info": { |
||||
|
"title": "FastAPI", |
||||
|
"version": "0.1.0" |
||||
|
}, |
||||
|
"paths": { |
||||
|
"/items/": { |
||||
|
"get": { |
||||
|
"summary": "Read Items", |
||||
|
"operationId": "read_items_items__get", |
||||
|
"responses": { |
||||
|
"200": { |
||||
|
"description": "Successful Response", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": {} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"x-aperture-labs-portal": "blue" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Personnalisation du Schéma OpenAPI pour un chemin |
||||
|
|
||||
|
Le dictionnaire contenu dans la variable `openapi_extra` sera fusionné avec le schéma OpenAPI généré automatiquement pour l'*opération de chemin*. |
||||
|
|
||||
|
Ainsi, vous pouvez ajouter des données supplémentaires au schéma généré automatiquement. |
||||
|
|
||||
|
Par exemple, vous pouvez décider de lire et de valider la requête avec votre propre code, sans utiliser les fonctionnalités automatiques de validation proposée par Pydantic, mais vous pouvez toujours définir la requête dans le schéma OpenAPI. |
||||
|
|
||||
|
Vous pouvez le faire avec `openapi_extra` : |
||||
|
|
||||
|
```Python hl_lines="20-37 39-40" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py !} |
||||
|
``` |
||||
|
|
||||
|
Dans cet exemple, nous n'avons déclaré aucun modèle Pydantic. En fait, le corps de la requête n'est même pas <abbr title="converti d'un format simple, comme des octets, en objets Python">parsé</abbr> en tant que JSON, il est lu directement en tant que `bytes`, et la fonction `magic_data_reader()` serait chargé de l'analyser d'une manière ou d'une autre. |
||||
|
|
||||
|
Néanmoins, nous pouvons déclarer le schéma attendu pour le corps de la requête. |
||||
|
|
||||
|
### Type de contenu OpenAPI personnalisé |
||||
|
|
||||
|
En utilisant cette même astuce, vous pouvez utiliser un modèle Pydantic pour définir le schéma JSON qui est ensuite inclus dans la section de schéma OpenAPI personnalisée pour le *chemin* concerné. |
||||
|
|
||||
|
Et vous pouvez le faire même si le type de données dans la requête n'est pas au format JSON. |
||||
|
|
||||
|
Dans cet exemple, nous n'utilisons pas les fonctionnalités de FastAPI pour extraire le schéma JSON des modèles Pydantic ni la validation automatique pour JSON. En fait, nous déclarons le type de contenu de la requête en tant que YAML, et non JSON : |
||||
|
|
||||
|
```Python hl_lines="17-22 24" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!} |
||||
|
``` |
||||
|
|
||||
|
Néanmoins, bien que nous n'utilisions pas la fonctionnalité par défaut, nous utilisons toujours un modèle Pydantic pour générer manuellement le schéma JSON pour les données que nous souhaitons recevoir en YAML. |
||||
|
|
||||
|
Ensuite, nous utilisons directement la requête et extrayons son contenu en tant qu'octets. Cela signifie que FastAPI n'essaiera même pas d'analyser le payload de la requête en tant que JSON. |
||||
|
|
||||
|
Et nous analysons directement ce contenu YAML, puis nous utilisons à nouveau le même modèle Pydantic pour valider le contenu YAML : |
||||
|
|
||||
|
```Python hl_lines="26-33" |
||||
|
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! Astuce |
||||
|
Ici, nous réutilisons le même modèle Pydantic. |
||||
|
|
||||
|
Mais nous aurions pu tout aussi bien pu le valider d'une autre manière. |
@ -0,0 +1,153 @@ |
|||||
|
# Exécuter un serveur manuellement - Uvicorn |
||||
|
|
||||
|
La principale chose dont vous avez besoin pour exécuter une application **FastAPI** sur une machine serveur distante est un programme serveur ASGI tel que **Uvicorn**. |
||||
|
|
||||
|
Il existe 3 principales alternatives : |
||||
|
|
||||
|
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> : un serveur ASGI haute performance. |
||||
|
* <a href="https://pgjones.gitlab.io/hypercorn/" class="external-link" target="_blank">Hypercorn</a> : un serveur |
||||
|
ASGI compatible avec HTTP/2 et Trio entre autres fonctionnalités. |
||||
|
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a> : le serveur ASGI |
||||
|
conçu pour Django Channels. |
||||
|
|
||||
|
## Machine serveur et programme serveur |
||||
|
|
||||
|
Il y a un petit détail sur les noms à garder à l'esprit. 💡 |
||||
|
|
||||
|
Le mot "**serveur**" est couramment utilisé pour désigner à la fois l'ordinateur distant/cloud (la machine physique ou virtuelle) et également le programme qui s'exécute sur cette machine (par exemple, Uvicorn). |
||||
|
|
||||
|
Gardez cela à l'esprit lorsque vous lisez "serveur" en général, cela pourrait faire référence à l'une de ces deux choses. |
||||
|
|
||||
|
Lorsqu'on se réfère à la machine distante, il est courant de l'appeler **serveur**, mais aussi **machine**, **VM** (machine virtuelle), **nœud**. Tout cela fait référence à un type de machine distante, exécutant Linux, en règle générale, sur laquelle vous exécutez des programmes. |
||||
|
|
||||
|
|
||||
|
## Installer le programme serveur |
||||
|
|
||||
|
Vous pouvez installer un serveur compatible ASGI avec : |
||||
|
|
||||
|
=== "Uvicorn" |
||||
|
|
||||
|
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, un serveur ASGI rapide comme l'éclair, basé sur uvloop et httptools. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "uvicorn[standard]" |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
!!! tip "Astuce" |
||||
|
En ajoutant `standard`, Uvicorn va installer et utiliser quelques dépendances supplémentaires recommandées. |
||||
|
|
||||
|
Cela inclut `uvloop`, le remplaçant performant de `asyncio`, qui fournit le gros gain de performance en matière de concurrence. |
||||
|
|
||||
|
=== "Hypercorn" |
||||
|
|
||||
|
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, un serveur ASGI également compatible avec HTTP/2. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install hypercorn |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
...ou tout autre serveur ASGI. |
||||
|
|
||||
|
## Exécutez le programme serveur |
||||
|
|
||||
|
Vous pouvez ensuite exécuter votre application de la même manière que vous l'avez fait dans les tutoriels, mais sans l'option `--reload`, par exemple : |
||||
|
|
||||
|
=== "Uvicorn" |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --host 0.0.0.0 --port 80 |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
=== "Hypercorn" |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ hypercorn main:app --bind 0.0.0.0:80 |
||||
|
|
||||
|
Running on 0.0.0.0:8080 over http (CTRL + C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
!!! warning |
||||
|
N'oubliez pas de supprimer l'option `--reload` si vous l'utilisiez. |
||||
|
|
||||
|
L'option `--reload` consomme beaucoup plus de ressources, est plus instable, etc. |
||||
|
|
||||
|
Cela aide beaucoup pendant le **développement**, mais vous **ne devriez pas** l'utiliser en **production**. |
||||
|
|
||||
|
## Hypercorn avec Trio |
||||
|
|
||||
|
Starlette et **FastAPI** sont basés sur |
||||
|
<a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, qui les rend |
||||
|
compatibles avec <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a>, de la bibliothèque standard Python et |
||||
|
<a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>. |
||||
|
|
||||
|
Néanmoins, Uvicorn n'est actuellement compatible qu'avec asyncio, et il utilise normalement <a href="https://github. |
||||
|
com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a >, le remplaçant hautes performances de `asyncio`. |
||||
|
|
||||
|
Mais si vous souhaitez utiliser directement **Trio**, vous pouvez utiliser **Hypercorn** car il le prend en charge. ✨ |
||||
|
|
||||
|
### Installer Hypercorn avec Trio |
||||
|
|
||||
|
Vous devez d'abord installer Hypercorn avec le support Trio : |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "hypercorn[trio]" |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### Exécuter avec Trio |
||||
|
|
||||
|
Ensuite, vous pouvez passer l'option de ligne de commande `--worker-class` avec la valeur `trio` : |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ hypercorn main:app --worker-class trio |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Et cela démarrera Hypercorn avec votre application en utilisant Trio comme backend. |
||||
|
|
||||
|
Vous pouvez désormais utiliser Trio en interne dans votre application. Ou mieux encore, vous pouvez utiliser AnyIO pour que votre code reste compatible avec Trio et asyncio. 🎉 |
||||
|
|
||||
|
## Concepts de déploiement |
||||
|
|
||||
|
Ces exemples lancent le programme serveur (e.g. Uvicorn), démarrant **un seul processus**, sur toutes les IPs (`0.0. |
||||
|
0.0`) sur un port prédéfini (par example, `80`). |
||||
|
|
||||
|
C'est l'idée de base. Mais vous vous préoccuperez probablement de certains concepts supplémentaires, tels que ... : |
||||
|
|
||||
|
* la sécurité - HTTPS |
||||
|
* l'exécution au démarrage |
||||
|
* les redémarrages |
||||
|
* la réplication (le nombre de processus en cours d'exécution) |
||||
|
* la mémoire |
||||
|
* les étapes précédant le démarrage |
||||
|
|
||||
|
Je vous en dirai plus sur chacun de ces concepts, sur la façon de les aborder, et donnerai quelques exemples concrets avec des stratégies pour les traiter dans les prochains chapitres. 🚀 |
@ -0,0 +1,112 @@ |
|||||
|
# <abbr title="En anglais: Debugging">Débogage</abbr> |
||||
|
|
||||
|
Vous pouvez connecter le <abbr title="En anglais: debugger">débogueur</abbr> dans votre éditeur, par exemple avec Visual Studio Code ou PyCharm. |
||||
|
|
||||
|
## Faites appel à `uvicorn` |
||||
|
|
||||
|
Dans votre application FastAPI, importez et exécutez directement `uvicorn` : |
||||
|
|
||||
|
```Python hl_lines="1 15" |
||||
|
{!../../../docs_src/debugging/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
### À propos de `__name__ == "__main__"` |
||||
|
|
||||
|
Le but principal de `__name__ == "__main__"` est d'avoir du code qui est exécuté lorsque votre fichier est appelé avec : |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python myapp.py |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
mais qui n'est pas appelé lorsqu'un autre fichier l'importe, comme dans : |
||||
|
|
||||
|
```Python |
||||
|
from myapp import app |
||||
|
``` |
||||
|
|
||||
|
#### Pour davantage de détails |
||||
|
|
||||
|
Imaginons que votre fichier s'appelle `myapp.py`. |
||||
|
|
||||
|
Si vous l'exécutez avec : |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python myapp.py |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
alors la variable interne `__name__` de votre fichier, créée automatiquement par Python, aura pour valeur la chaîne de caractères `"__main__"`. |
||||
|
|
||||
|
Ainsi, la section : |
||||
|
|
||||
|
```Python |
||||
|
uvicorn.run(app, host="0.0.0.0", port=8000) |
||||
|
``` |
||||
|
|
||||
|
va s'exécuter. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Cela ne se produira pas si vous importez ce module (fichier). |
||||
|
|
||||
|
Par exemple, si vous avez un autre fichier `importer.py` qui contient : |
||||
|
|
||||
|
```Python |
||||
|
from myapp import app |
||||
|
|
||||
|
# Code supplémentaire |
||||
|
``` |
||||
|
|
||||
|
dans ce cas, la variable automatique `__name__` à l'intérieur de `myapp.py` n'aura pas la valeur `"__main__"`. |
||||
|
|
||||
|
Ainsi, la ligne : |
||||
|
|
||||
|
```Python |
||||
|
uvicorn.run(app, host="0.0.0.0", port=8000) |
||||
|
``` |
||||
|
|
||||
|
ne sera pas exécutée. |
||||
|
|
||||
|
!!! info |
||||
|
Pour plus d'informations, consultez <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">la documentation officielle de Python</a>. |
||||
|
|
||||
|
## Exécutez votre code avec votre <abbr title="En anglais: debugger">débogueur</abbr> |
||||
|
|
||||
|
Parce que vous exécutez le serveur Uvicorn directement depuis votre code, vous pouvez appeler votre programme Python (votre application FastAPI) directement depuis le <abbr title="En anglais: debugger">débogueur</abbr>. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Par exemple, dans Visual Studio Code, vous pouvez : |
||||
|
|
||||
|
- Cliquer sur l'onglet "Debug" de la barre d'activités de Visual Studio Code. |
||||
|
- "Add configuration...". |
||||
|
- Sélectionnez "Python". |
||||
|
- Lancez le <abbr title="En anglais: debugger">débogueur</abbr> avec l'option "`Python: Current File (Integrated Terminal)`". |
||||
|
|
||||
|
Il démarrera alors le serveur avec votre code **FastAPI**, s'arrêtera à vos points d'arrêt, etc. |
||||
|
|
||||
|
Voici à quoi cela pourrait ressembler : |
||||
|
|
||||
|
<img src="/img/tutorial/debugging/image01.png"> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Si vous utilisez Pycharm, vous pouvez : |
||||
|
|
||||
|
- Ouvrir le menu "Run". |
||||
|
- Sélectionnez l'option "Debug...". |
||||
|
- Un menu contextuel s'affiche alors. |
||||
|
- Sélectionnez le fichier à déboguer (dans ce cas, `main.py`). |
||||
|
|
||||
|
Il démarrera alors le serveur avec votre code **FastAPI**, s'arrêtera à vos points d'arrêt, etc. |
||||
|
|
||||
|
Voici à quoi cela pourrait ressembler : |
||||
|
|
||||
|
<img src="/img/tutorial/debugging/image02.png"> |
@ -0,0 +1,467 @@ |
|||||
|
|
||||
|
{!../../../docs/missing-translation.md!} |
||||
|
|
||||
|
|
||||
|
<p align="center"> |
||||
|
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a> |
||||
|
</p> |
||||
|
<p align="center"> |
||||
|
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em> |
||||
|
</p> |
||||
|
<p align="center"> |
||||
|
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank"> |
||||
|
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test"> |
||||
|
</a> |
||||
|
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi" target="_blank"> |
||||
|
<img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi.svg" alt="Coverage"> |
||||
|
</a> |
||||
|
<a href="https://pypi.org/project/fastapi" target="_blank"> |
||||
|
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version"> |
||||
|
</a> |
||||
|
<a href="https://pypi.org/project/fastapi" target="_blank"> |
||||
|
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions"> |
||||
|
</a> |
||||
|
</p> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a> |
||||
|
|
||||
|
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. |
||||
|
|
||||
|
The key features are: |
||||
|
|
||||
|
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance). |
||||
|
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. * |
||||
|
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. * |
||||
|
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging. |
||||
|
* **Easy**: Designed to be easy to use and learn. Less time reading docs. |
||||
|
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs. |
||||
|
* **Robust**: Get production-ready code. With automatic interactive documentation. |
||||
|
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>. |
||||
|
|
||||
|
<small>* estimation based on tests on an internal development team, building production applications.</small> |
||||
|
|
||||
|
## Sponsors |
||||
|
|
||||
|
<!-- sponsors --> |
||||
|
|
||||
|
{% if sponsors %} |
||||
|
{% for sponsor in sponsors.gold -%} |
||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor -%} |
||||
|
{%- for sponsor in sponsors.silver -%} |
||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor %} |
||||
|
{% endif %} |
||||
|
|
||||
|
<!-- /sponsors --> |
||||
|
|
||||
|
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a> |
||||
|
|
||||
|
## Opinions |
||||
|
|
||||
|
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_I’m over the moon excited about **FastAPI**. It’s so fun!_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_" |
||||
|
|
||||
|
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
## **Typer**, the FastAPI of CLIs |
||||
|
|
||||
|
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a> |
||||
|
|
||||
|
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>. |
||||
|
|
||||
|
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀 |
||||
|
|
||||
|
## Requirements |
||||
|
|
||||
|
Python 3.7+ |
||||
|
|
||||
|
FastAPI stands on the shoulders of giants: |
||||
|
|
||||
|
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts. |
||||
|
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install fastapi |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "uvicorn[standard]" |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## Example |
||||
|
|
||||
|
### Create it |
||||
|
|
||||
|
* Create a file `main.py` with: |
||||
|
|
||||
|
```Python |
||||
|
from typing import Union |
||||
|
|
||||
|
from fastapi import FastAPI |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
def read_item(item_id: int, q: Union[str, None] = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
``` |
||||
|
|
||||
|
<details markdown="1"> |
||||
|
<summary>Or use <code>async def</code>...</summary> |
||||
|
|
||||
|
If your code uses `async` / `await`, use `async def`: |
||||
|
|
||||
|
```Python hl_lines="9 14" |
||||
|
from typing import Union |
||||
|
|
||||
|
from fastapi import FastAPI |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
async def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
async def read_item(item_id: int, q: Union[str, None] = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
``` |
||||
|
|
||||
|
**Note**: |
||||
|
|
||||
|
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>. |
||||
|
|
||||
|
</details> |
||||
|
|
||||
|
### Run it |
||||
|
|
||||
|
Run the server with: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --reload |
||||
|
|
||||
|
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
INFO: Started reloader process [28720] |
||||
|
INFO: Started server process [28722] |
||||
|
INFO: Waiting for application startup. |
||||
|
INFO: Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<details markdown="1"> |
||||
|
<summary>About the command <code>uvicorn main:app --reload</code>...</summary> |
||||
|
|
||||
|
The command `uvicorn main:app` refers to: |
||||
|
|
||||
|
* `main`: the file `main.py` (the Python "module"). |
||||
|
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`. |
||||
|
* `--reload`: make the server restart after code changes. Only do this for development. |
||||
|
|
||||
|
</details> |
||||
|
|
||||
|
### Check it |
||||
|
|
||||
|
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>. |
||||
|
|
||||
|
You will see the JSON response as: |
||||
|
|
||||
|
```JSON |
||||
|
{"item_id": 5, "q": "somequery"} |
||||
|
``` |
||||
|
|
||||
|
You already created an API that: |
||||
|
|
||||
|
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`. |
||||
|
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_). |
||||
|
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`. |
||||
|
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`. |
||||
|
|
||||
|
### Interactive API docs |
||||
|
|
||||
|
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. |
||||
|
|
||||
|
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>): |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### 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 Union |
||||
|
|
||||
|
from fastapi import FastAPI |
||||
|
from pydantic import BaseModel |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
class Item(BaseModel): |
||||
|
name: str |
||||
|
price: float |
||||
|
is_offer: Union[bool, None] = None |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
def read_item(item_id: int, q: Union[str, None] = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
|
||||
|
|
||||
|
@app.put("/items/{item_id}") |
||||
|
def update_item(item_id: int, item: Item): |
||||
|
return {"item_name": item.name, "item_id": item_id} |
||||
|
``` |
||||
|
|
||||
|
The server should reload automatically (because you added `--reload` to the `uvicorn` command above). |
||||
|
|
||||
|
### Interactive API docs upgrade |
||||
|
|
||||
|
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. |
||||
|
|
||||
|
* The interactive API documentation will be automatically updated, including the new body: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* 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.7+**. |
||||
|
|
||||
|
For example, for an `int`: |
||||
|
|
||||
|
```Python |
||||
|
item_id: int |
||||
|
``` |
||||
|
|
||||
|
or for a more complex `Item` model: |
||||
|
|
||||
|
```Python |
||||
|
item: Item |
||||
|
``` |
||||
|
|
||||
|
...and with that single declaration you get: |
||||
|
|
||||
|
* Editor support, including: |
||||
|
* Completion. |
||||
|
* Type checks. |
||||
|
* Validation of data: |
||||
|
* Automatic and clear errors when the data is invalid. |
||||
|
* Validation even for deeply nested JSON objects. |
||||
|
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from: |
||||
|
* JSON. |
||||
|
* Path parameters. |
||||
|
* Query parameters. |
||||
|
* Cookies. |
||||
|
* Headers. |
||||
|
* Forms. |
||||
|
* Files. |
||||
|
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON): |
||||
|
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc). |
||||
|
* `datetime` objects. |
||||
|
* `UUID` objects. |
||||
|
* Database models. |
||||
|
* ...and many more. |
||||
|
* Automatic interactive API documentation, including 2 alternative user interfaces: |
||||
|
* Swagger UI. |
||||
|
* ReDoc. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Coming back to the previous code example, **FastAPI** will: |
||||
|
|
||||
|
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests. |
||||
|
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests. |
||||
|
* If it is not, the client will see a useful, clear error. |
||||
|
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests. |
||||
|
* As the `q` parameter is declared with `= None`, it is optional. |
||||
|
* Without the `None` it would be required (as is the body in the case with `PUT`). |
||||
|
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON: |
||||
|
* Check that it has a required attribute `name` that should be a `str`. |
||||
|
* Check that it has a required attribute `price` that has to be a `float`. |
||||
|
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present. |
||||
|
* All this would also work for deeply nested JSON objects. |
||||
|
* Convert from and to JSON automatically. |
||||
|
* Document everything with OpenAPI, that can be used by: |
||||
|
* Interactive documentation systems. |
||||
|
* Automatic client code generation systems, for many languages. |
||||
|
* Provide 2 interactive documentation web interfaces directly. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
We just scratched the surface, but you already get the idea of how it all works. |
||||
|
|
||||
|
Try changing the line with: |
||||
|
|
||||
|
```Python |
||||
|
return {"item_name": item.name, "item_id": item_id} |
||||
|
``` |
||||
|
|
||||
|
...from: |
||||
|
|
||||
|
```Python |
||||
|
... "item_name": item.name ... |
||||
|
``` |
||||
|
|
||||
|
...to: |
||||
|
|
||||
|
```Python |
||||
|
... "item_price": item.price ... |
||||
|
``` |
||||
|
|
||||
|
...and see how your editor will auto-complete the attributes and know their types: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>. |
||||
|
|
||||
|
**Spoiler alert**: the tutorial - user guide includes: |
||||
|
|
||||
|
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**. |
||||
|
* How to set **validation constraints** as `maximum_length` or `regex`. |
||||
|
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system. |
||||
|
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth. |
||||
|
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic). |
||||
|
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries. |
||||
|
* Many extra features (thanks to Starlette) as: |
||||
|
* **WebSockets** |
||||
|
* extremely easy tests based on HTTPX and `pytest` |
||||
|
* **CORS** |
||||
|
* **Cookie Sessions** |
||||
|
* ...and more. |
||||
|
|
||||
|
## Performance |
||||
|
|
||||
|
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*) |
||||
|
|
||||
|
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>. |
||||
|
|
||||
|
## Optional Dependencies |
||||
|
|
||||
|
Used by Pydantic: |
||||
|
|
||||
|
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>. |
||||
|
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation. |
||||
|
|
||||
|
Used by Starlette: |
||||
|
|
||||
|
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`. |
||||
|
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration. |
||||
|
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`. |
||||
|
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support. |
||||
|
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI). |
||||
|
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`. |
||||
|
|
||||
|
Used by FastAPI / Starlette: |
||||
|
|
||||
|
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application. |
||||
|
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`. |
||||
|
|
||||
|
You can install all of these with `pip install "fastapi[all]"`. |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
This project is licensed under the terms of the MIT license. |
@ -0,0 +1,148 @@ |
|||||
|
site_name: FastAPI |
||||
|
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production |
||||
|
site_url: https://fastapi.tiangolo.com/hy/ |
||||
|
theme: |
||||
|
name: material |
||||
|
custom_dir: overrides |
||||
|
palette: |
||||
|
- media: '(prefers-color-scheme: light)' |
||||
|
scheme: default |
||||
|
primary: teal |
||||
|
accent: amber |
||||
|
toggle: |
||||
|
icon: material/lightbulb |
||||
|
name: Switch to light mode |
||||
|
- media: '(prefers-color-scheme: dark)' |
||||
|
scheme: slate |
||||
|
primary: teal |
||||
|
accent: amber |
||||
|
toggle: |
||||
|
icon: material/lightbulb-outline |
||||
|
name: Switch to dark mode |
||||
|
features: |
||||
|
- search.suggest |
||||
|
- search.highlight |
||||
|
- content.tabs.link |
||||
|
icon: |
||||
|
repo: fontawesome/brands/github-alt |
||||
|
logo: https://fastapi.tiangolo.com/img/icon-white.svg |
||||
|
favicon: https://fastapi.tiangolo.com/img/favicon.png |
||||
|
language: hy |
||||
|
repo_name: tiangolo/fastapi |
||||
|
repo_url: https://github.com/tiangolo/fastapi |
||||
|
edit_uri: '' |
||||
|
plugins: |
||||
|
- search |
||||
|
- markdownextradata: |
||||
|
data: data |
||||
|
nav: |
||||
|
- FastAPI: index.md |
||||
|
- Languages: |
||||
|
- en: / |
||||
|
- az: /az/ |
||||
|
- de: /de/ |
||||
|
- es: /es/ |
||||
|
- fa: /fa/ |
||||
|
- fr: /fr/ |
||||
|
- he: /he/ |
||||
|
- hy: /hy/ |
||||
|
- id: /id/ |
||||
|
- it: /it/ |
||||
|
- ja: /ja/ |
||||
|
- ko: /ko/ |
||||
|
- nl: /nl/ |
||||
|
- pl: /pl/ |
||||
|
- pt: /pt/ |
||||
|
- ru: /ru/ |
||||
|
- sq: /sq/ |
||||
|
- sv: /sv/ |
||||
|
- tr: /tr/ |
||||
|
- uk: /uk/ |
||||
|
- zh: /zh/ |
||||
|
markdown_extensions: |
||||
|
- toc: |
||||
|
permalink: true |
||||
|
- markdown.extensions.codehilite: |
||||
|
guess_lang: false |
||||
|
- mdx_include: |
||||
|
base_path: docs |
||||
|
- admonition |
||||
|
- codehilite |
||||
|
- extra |
||||
|
- pymdownx.superfences: |
||||
|
custom_fences: |
||||
|
- name: mermaid |
||||
|
class: mermaid |
||||
|
format: !!python/name:pymdownx.superfences.fence_code_format '' |
||||
|
- pymdownx.tabbed: |
||||
|
alternate_style: true |
||||
|
- attr_list |
||||
|
- md_in_html |
||||
|
extra: |
||||
|
analytics: |
||||
|
provider: google |
||||
|
property: UA-133183413-1 |
||||
|
social: |
||||
|
- icon: fontawesome/brands/github-alt |
||||
|
link: https://github.com/tiangolo/fastapi |
||||
|
- icon: fontawesome/brands/discord |
||||
|
link: https://discord.gg/VQjSZaeJmf |
||||
|
- icon: fontawesome/brands/twitter |
||||
|
link: https://twitter.com/fastapi |
||||
|
- icon: fontawesome/brands/linkedin |
||||
|
link: https://www.linkedin.com/in/tiangolo |
||||
|
- icon: fontawesome/brands/dev |
||||
|
link: https://dev.to/tiangolo |
||||
|
- icon: fontawesome/brands/medium |
||||
|
link: https://medium.com/@tiangolo |
||||
|
- icon: fontawesome/solid/globe |
||||
|
link: https://tiangolo.com |
||||
|
alternate: |
||||
|
- link: / |
||||
|
name: en - English |
||||
|
- link: /az/ |
||||
|
name: az |
||||
|
- link: /de/ |
||||
|
name: de |
||||
|
- link: /es/ |
||||
|
name: es - español |
||||
|
- link: /fa/ |
||||
|
name: fa |
||||
|
- link: /fr/ |
||||
|
name: fr - français |
||||
|
- link: /he/ |
||||
|
name: he |
||||
|
- link: /hy/ |
||||
|
name: hy |
||||
|
- link: /id/ |
||||
|
name: id |
||||
|
- link: /it/ |
||||
|
name: it - italiano |
||||
|
- link: /ja/ |
||||
|
name: ja - 日本語 |
||||
|
- link: /ko/ |
||||
|
name: ko - 한국어 |
||||
|
- link: /nl/ |
||||
|
name: nl |
||||
|
- link: /pl/ |
||||
|
name: pl |
||||
|
- link: /pt/ |
||||
|
name: pt - português |
||||
|
- link: /ru/ |
||||
|
name: ru - русский язык |
||||
|
- link: /sq/ |
||||
|
name: sq - shqip |
||||
|
- link: /sv/ |
||||
|
name: sv - svenska |
||||
|
- link: /tr/ |
||||
|
name: tr - Türkçe |
||||
|
- link: /uk/ |
||||
|
name: uk - українська мова |
||||
|
- link: /zh/ |
||||
|
name: zh - 汉语 |
||||
|
extra_css: |
||||
|
- https://fastapi.tiangolo.com/css/termynal.css |
||||
|
- https://fastapi.tiangolo.com/css/custom.css |
||||
|
extra_javascript: |
||||
|
- https://fastapi.tiangolo.com/js/termynal.js |
||||
|
- https://fastapi.tiangolo.com/js/custom.js |
@ -0,0 +1,84 @@ |
|||||
|
# 교차 출처 리소스 공유 |
||||
|
|
||||
|
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS 또는 "교차-출처 리소스 공유"</a>란, 브라우저에서 동작하는 프론트엔드가 자바스크립트로 코드로 백엔드와 통신하고, 백엔드는 해당 프론트엔드와 다른 "출처"에 존재하는 상황을 의미합니다. |
||||
|
|
||||
|
## 출처 |
||||
|
|
||||
|
출처란 프로토콜(`http` , `https`), 도메인(`myapp.com`, `localhost`, `localhost.tiangolo.com` ), 그리고 포트(`80`, `443`, `8080` )의 조합을 의미합니다. |
||||
|
|
||||
|
따라서, 아래는 모두 상이한 출처입니다: |
||||
|
|
||||
|
* `http://localhost` |
||||
|
* `https://localhost` |
||||
|
* `http://localhost:8080` |
||||
|
|
||||
|
모두 `localhost` 에 있지만, 서로 다른 프로토콜과 포트를 사용하고 있으므로 다른 "출처"입니다. |
||||
|
|
||||
|
## 단계 |
||||
|
|
||||
|
브라우저 내 `http://localhost:8080`에서 동작하는 프론트엔드가 있고, 자바스크립트는 `http://localhost`를 통해 백엔드와 통신한다고 가정해봅시다(포트를 명시하지 않는 경우, 브라우저는 `80` 을 기본 포트로 간주합니다). |
||||
|
|
||||
|
그러면 브라우저는 백엔드에 HTTP `OPTIONS` 요청을 보내고, 백엔드에서 이 다른 출처(`http://localhost:8080`)와의 통신을 허가하는 적절한 헤더를 보내면, 브라우저는 프론트엔드의 자바스크립트가 백엔드에 요청을 보낼 수 있도록 합니다. |
||||
|
|
||||
|
이를 위해, 백엔드는 "허용된 출처(allowed origins)" 목록을 가지고 있어야만 합니다. |
||||
|
|
||||
|
이 경우, 프론트엔드가 제대로 동작하기 위해 `http://localhost:8080`을 목록에 포함해야 합니다. |
||||
|
|
||||
|
## 와일드카드 |
||||
|
|
||||
|
모든 출처를 허용하기 위해 목록을 `"*"` ("와일드카드")로 선언하는 것도 가능합니다. |
||||
|
|
||||
|
하지만 이것은 특정한 유형의 통신만을 허용하며, 쿠키 및 액세스 토큰과 사용되는 인증 헤더(Authoriztion header) 등이 포함된 경우와 같이 자격 증명(credentials)이 포함된 통신은 허용되지 않습니다. |
||||
|
|
||||
|
따라서 모든 작업을 의도한대로 실행하기 위해, 허용되는 출처를 명시적으로 지정하는 것이 좋습니다. |
||||
|
|
||||
|
## `CORSMiddleware` 사용 |
||||
|
|
||||
|
`CORSMiddleware` 을 사용하여 **FastAPI** 응용 프로그램의 교차 출처 리소스 공유 환경을 설정할 수 있습니다. |
||||
|
|
||||
|
* `CORSMiddleware` 임포트. |
||||
|
* 허용되는 출처(문자열 형식)의 리스트 생성. |
||||
|
* FastAPI 응용 프로그램에 "미들웨어(middleware)"로 추가. |
||||
|
|
||||
|
백엔드에서 다음의 사항을 허용할지에 대해 설정할 수도 있습니다: |
||||
|
|
||||
|
* 자격증명 (인증 헤더, 쿠키 등). |
||||
|
* 특정한 HTTP 메소드(`POST`, `PUT`) 또는 와일드카드 `"*"` 를 사용한 모든 HTTP 메소드. |
||||
|
* 특정한 HTTP 헤더 또는 와일드카드 `"*"` 를 사용한 모든 HTTP 헤더. |
||||
|
|
||||
|
```Python hl_lines="2 6-11 13-19" |
||||
|
{!../../../docs_src/cors/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
`CORSMiddleware` 에서 사용하는 기본 매개변수는 제한적이므로, 브라우저가 교차-도메인 상황에서 특정한 출처, 메소드, 헤더 등을 사용할 수 있도록 하려면 이들을 명시적으로 허용해야 합니다. |
||||
|
|
||||
|
다음의 인자들이 지원됩니다: |
||||
|
|
||||
|
* `allow_origins` - 교차-출처 요청을 보낼 수 있는 출처의 리스트입니다. 예) `['https://example.org', 'https://www.example.org']`. 모든 출처를 허용하기 위해 `['*']` 를 사용할 수 있습니다. |
||||
|
* `allow_origin_regex` - 교차-출처 요청을 보낼 수 있는 출처를 정규표현식 문자열로 나타냅니다. `'https://.*\.example\.org'`. |
||||
|
* `allow_methods` - 교차-출처 요청을 허용하는 HTTP 메소드의 리스트입니다. 기본값은 `['GET']` 입니다. `['*']` 을 사용하여 모든 표준 메소드들을 허용할 수 있습니다. |
||||
|
* `allow_headers` - 교차-출처를 지원하는 HTTP 요청 헤더의 리스트입니다. 기본값은 `[]` 입니다. 모든 헤더들을 허용하기 위해 `['*']` 를 사용할 수 있습니다. `Accept`, `Accept-Language`, `Content-Language` 그리고 `Content-Type` 헤더는 CORS 요청시 언제나 허용됩니다. |
||||
|
* `allow_credentials` - 교차-출처 요청시 쿠키 지원 여부를 설정합니다. 기본값은 `False` 입니다. 또한 해당 항목을 허용할 경우 `allow_origins` 는 `['*']` 로 설정할 수 없으며, 출처를 반드시 특정해야 합니다. |
||||
|
* `expose_headers` - 브라우저에 접근할 수 있어야 하는 모든 응답 헤더를 가리킵니다. 기본값은 `[]` 입니다. |
||||
|
* `max_age` - 브라우저가 CORS 응답을 캐시에 저장하는 최대 시간을 초 단위로 설정합니다. 기본값은 `600` 입니다. |
||||
|
|
||||
|
미들웨어는 두가지 특정한 종류의 HTTP 요청에 응답합니다... |
||||
|
|
||||
|
### CORS 사전 요청 |
||||
|
|
||||
|
`Origin` 및 `Access-Control-Request-Method` 헤더와 함께 전송하는 모든 `OPTIONS` 요청입니다. |
||||
|
|
||||
|
이 경우 미들웨어는 들어오는 요청을 가로채 적절한 CORS 헤더와, 정보 제공을 위한 `200` 또는 `400` 응답으로 응답합니다. |
||||
|
|
||||
|
### 단순한 요청 |
||||
|
|
||||
|
`Origin` 헤더를 가진 모든 요청. 이 경우 미들웨어는 요청을 정상적으로 전달하지만, 적절한 CORS 헤더를 응답에 포함시킵니다. |
||||
|
|
||||
|
## 더 많은 정보 |
||||
|
|
||||
|
<abbr title="교차-출처 리소스 공유">CORS</abbr>에 대한 더 많은 정보를 알고싶다면, <a href="https://developer.mozilla.org/ko/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS 문서</a>를 참고하기 바랍니다. |
||||
|
|
||||
|
!!! note "기술적 세부 사항" |
||||
|
`from starlette.middleware.cors import CORSMiddleware` 역시 사용할 수 있습니다. |
||||
|
|
||||
|
**FastAPI**는 개발자인 당신의 편의를 위해 `fastapi.middleware` 에서 몇가지의 미들웨어를 제공합니다. 하지만 대부분의 미들웨어가 Stralette으로부터 직접 제공됩니다. |
@ -0,0 +1,42 @@ |
|||||
|
# Codificador Compatível com JSON |
||||
|
|
||||
|
Existem alguns casos em que você pode precisar converter um tipo de dados (como um modelo Pydantic) para algo compatível com JSON (como um `dict`, `list`, etc). |
||||
|
|
||||
|
Por exemplo, se você precisar armazená-lo em um banco de dados. |
||||
|
|
||||
|
Para isso, **FastAPI** fornece uma função `jsonable_encoder()`. |
||||
|
|
||||
|
## Usando a função `jsonable_encoder` |
||||
|
|
||||
|
Vamos imaginar que você tenha um banco de dados `fake_db` que recebe apenas dados compatíveis com JSON. |
||||
|
|
||||
|
Por exemplo, ele não recebe objetos `datetime`, pois estes objetos não são compatíveis com JSON. |
||||
|
|
||||
|
Então, um objeto `datetime` teria que ser convertido em um `str` contendo os dados no formato <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO</a>. |
||||
|
|
||||
|
Da mesma forma, este banco de dados não receberia um modelo Pydantic (um objeto com atributos), apenas um `dict`. |
||||
|
|
||||
|
Você pode usar a função `jsonable_encoder` para resolver isso. |
||||
|
|
||||
|
A função recebe um objeto, como um modelo Pydantic e retorna uma versão compatível com JSON: |
||||
|
|
||||
|
=== "Python 3.10+" |
||||
|
|
||||
|
```Python hl_lines="4 21" |
||||
|
{!> ../../../docs_src/encoder/tutorial001_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
=== "Python 3.6+" |
||||
|
|
||||
|
```Python hl_lines="5 22" |
||||
|
{!> ../../../docs_src/encoder/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
Neste exemplo, ele converteria o modelo Pydantic em um `dict`, e o `datetime` em um `str`. |
||||
|
|
||||
|
O resultado de chamar a função é algo que pode ser codificado com o padrão do Python <a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a>. |
||||
|
|
||||
|
A função não retorna um grande `str` contendo os dados no formato JSON (como uma string). Mas sim, retorna uma estrutura de dados padrão do Python (por exemplo, um `dict`) com valores e subvalores compatíveis com JSON. |
||||
|
|
||||
|
!!! nota |
||||
|
`jsonable_encoder` é realmente usado pelo **FastAPI** internamente para converter dados. Mas também é útil em muitos outros cenários. |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue