@ -23,17 +23,14 @@ jobs: |
|||
with: |
|||
path: ${{ env.pythonLocation }} |
|||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03 |
|||
- name: Install Flit |
|||
if: steps.cache.outputs.cache-hit != 'true' |
|||
run: python3.7 -m pip install flit |
|||
- name: Install docs extras |
|||
if: steps.cache.outputs.cache-hit != 'true' |
|||
run: python3.7 -m flit install --deps production --extras doc |
|||
run: pip install .[doc] |
|||
- name: Install Material for MkDocs Insiders |
|||
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true' |
|||
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git |
|||
- name: Build Docs |
|||
run: python3.7 ./scripts/docs.py build-all |
|||
run: python ./scripts/docs.py build-all |
|||
- name: Zip docs |
|||
run: bash ./scripts/zip-docs.sh |
|||
- uses: actions/upload-artifact@v3 |
|||
@ -41,7 +38,7 @@ jobs: |
|||
name: docs-zip |
|||
path: ./docs.zip |
|||
- name: Deploy to Netlify |
|||
uses: nwtgck/[email protected].3 |
|||
uses: nwtgck/[email protected].4 |
|||
with: |
|||
publish-dir: './site' |
|||
production-branch: master |
|||
|
@ -12,7 +12,7 @@ jobs: |
|||
steps: |
|||
- uses: actions/checkout@v3 |
|||
- name: Download Artifact Docs |
|||
uses: dawidd6/[email protected]1.1 |
|||
uses: dawidd6/[email protected]4.0 |
|||
with: |
|||
github_token: ${{ secrets.GITHUB_TOKEN }} |
|||
workflow: build-docs.yml |
|||
@ -25,7 +25,7 @@ jobs: |
|||
rm -f docs.zip |
|||
- name: Deploy to Netlify |
|||
id: netlify |
|||
uses: nwtgck/[email protected].3 |
|||
uses: nwtgck/[email protected].4 |
|||
with: |
|||
publish-dir: './site' |
|||
production-deploy: false |
|||
|
@ -17,23 +17,21 @@ jobs: |
|||
- name: Set up Python |
|||
uses: actions/setup-python@v4 |
|||
with: |
|||
python-version: "3.6" |
|||
python-version: "3.7" |
|||
- uses: actions/cache@v3 |
|||
id: cache |
|||
with: |
|||
path: ${{ env.pythonLocation }} |
|||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish |
|||
- name: Install Flit |
|||
- name: Install build dependencies |
|||
if: steps.cache.outputs.cache-hit != 'true' |
|||
run: pip install flit |
|||
- name: Install Dependencies |
|||
if: steps.cache.outputs.cache-hit != 'true' |
|||
run: flit install --symlink |
|||
run: pip install build |
|||
- name: Build distribution |
|||
run: python -m build |
|||
- name: Publish |
|||
env: |
|||
FLIT_USERNAME: ${{ secrets.FLIT_USERNAME }} |
|||
FLIT_PASSWORD: ${{ secrets.FLIT_PASSWORD }} |
|||
run: bash scripts/publish.sh |
|||
uses: pypa/[email protected] |
|||
with: |
|||
password: ${{ secrets.PYPI_API_TOKEN }} |
|||
- name: Dump GitHub context |
|||
env: |
|||
GITHUB_CONTEXT: ${{ toJson(github) }} |
|||
|
@ -0,0 +1,35 @@ |
|||
name: Smokeshow |
|||
|
|||
on: |
|||
workflow_run: |
|||
workflows: [Test] |
|||
types: [completed] |
|||
|
|||
permissions: |
|||
statuses: write |
|||
|
|||
jobs: |
|||
smokeshow: |
|||
if: ${{ github.event.workflow_run.conclusion == 'success' }} |
|||
runs-on: ubuntu-latest |
|||
|
|||
steps: |
|||
- uses: actions/setup-python@v4 |
|||
with: |
|||
python-version: '3.9' |
|||
|
|||
- run: pip install smokeshow |
|||
|
|||
- uses: dawidd6/action-download-artifact@v2 |
|||
with: |
|||
workflow: test.yml |
|||
commit: ${{ github.event.workflow_run.head_sha }} |
|||
|
|||
- run: smokeshow upload coverage-html |
|||
env: |
|||
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage} |
|||
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100 |
|||
SMOKESHOW_GITHUB_CONTEXT: coverage |
|||
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
|||
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} |
|||
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }} |
@ -0,0 +1,466 @@ |
|||
|
|||
{!../../../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.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://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://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. |
After Width: | Height: | Size: 199 KiB |
After Width: | Height: | Size: 163 KiB |
After Width: | Height: | Size: 169 KiB |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 166 KiB |
After Width: | Height: | Size: 221 KiB |
After Width: | Height: | Size: 199 KiB |
After Width: | Height: | Size: 165 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 181 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 159 KiB |
After Width: | Height: | Size: 106 KiB |
@ -0,0 +1,245 @@ |
|||
# Déployer FastAPI sur Deta |
|||
|
|||
Dans cette section, vous apprendrez à déployer facilement une application **FastAPI** sur <a href="https://www.deta. |
|||
sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> en utilisant le plan tarifaire gratuit. 🎁 |
|||
|
|||
Cela vous prendra environ **10 minutes**. |
|||
|
|||
!!! info |
|||
<a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> sponsorise **FastAPI**. 🎉 |
|||
|
|||
## Une application **FastAPI** de base |
|||
|
|||
* Créez un répertoire pour votre application, par exemple `./fastapideta/` et déplacez-vous dedans. |
|||
|
|||
### Le code FastAPI |
|||
|
|||
* Créer un fichier `main.py` avec : |
|||
|
|||
```Python |
|||
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): |
|||
return {"item_id": item_id} |
|||
``` |
|||
|
|||
### Dépendances |
|||
|
|||
Maintenant, dans le même répertoire, créez un fichier `requirements.txt` avec : |
|||
|
|||
```text |
|||
fastapi |
|||
``` |
|||
|
|||
!!! tip "Astuce" |
|||
Il n'est pas nécessaire d'installer Uvicorn pour déployer sur Deta, bien qu'il soit probablement souhaitable de l'installer localement pour tester votre application. |
|||
|
|||
### Structure du répertoire |
|||
|
|||
Vous aurez maintenant un répertoire `./fastapideta/` avec deux fichiers : |
|||
|
|||
``` |
|||
. |
|||
└── main.py |
|||
└── requirements.txt |
|||
``` |
|||
|
|||
## Créer un compte gratuit sur Deta |
|||
|
|||
Créez maintenant un <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">compte gratuit |
|||
sur Deta</a>, vous avez juste besoin d'une adresse email et d'un mot de passe. |
|||
|
|||
Vous n'avez même pas besoin d'une carte de crédit. |
|||
|
|||
## Installer le CLI (Interface en Ligne de Commande) |
|||
|
|||
Une fois que vous avez votre compte, installez le <abbr title="Command Line Interface application">CLI</abbr> de Deta : |
|||
|
|||
=== "Linux, macOS" |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ curl -fsSL https://get.deta.dev/cli.sh | sh |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
=== "Windows PowerShell" |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ iwr https://get.deta.dev/cli.ps1 -useb | iex |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
Après l'avoir installé, ouvrez un nouveau terminal afin que la nouvelle installation soit détectée. |
|||
|
|||
Dans un nouveau terminal, confirmez qu'il a été correctement installé avec : |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ deta --help |
|||
|
|||
Deta command line interface for managing deta micros. |
|||
Complete documentation available at https://docs.deta.sh |
|||
|
|||
Usage: |
|||
deta [flags] |
|||
deta [command] |
|||
|
|||
Available Commands: |
|||
auth Change auth settings for a deta micro |
|||
|
|||
... |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
!!! tip "Astuce" |
|||
Si vous rencontrez des problèmes pour installer le CLI, consultez la <a href="https://docs.deta. sh/docs/micros/getting_started?ref=fastapi" class="external-link" target="_blank">documentation officielle de Deta (en anglais)</a>. |
|||
|
|||
## Connexion avec le CLI |
|||
|
|||
Maintenant, connectez-vous à Deta depuis le CLI avec : |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ deta login |
|||
|
|||
Please, log in from the web page. Waiting.. |
|||
Logged in successfully. |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
Cela ouvrira un navigateur web et permettra une authentification automatique. |
|||
|
|||
## Déployer avec Deta |
|||
|
|||
Ensuite, déployez votre application avec le CLI de Deta : |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ deta new |
|||
|
|||
Successfully created a new micro |
|||
|
|||
// Notice the "endpoint" 🔍 |
|||
|
|||
{ |
|||
"name": "fastapideta", |
|||
"runtime": "python3.7", |
|||
"endpoint": "https://qltnci.deta.dev", |
|||
"visor": "enabled", |
|||
"http_auth": "enabled" |
|||
} |
|||
|
|||
Adding dependencies... |
|||
|
|||
|
|||
---> 100% |
|||
|
|||
|
|||
Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
Vous verrez un message JSON similaire à : |
|||
|
|||
```JSON hl_lines="4" |
|||
{ |
|||
"name": "fastapideta", |
|||
"runtime": "python3.7", |
|||
"endpoint": "https://qltnci.deta.dev", |
|||
"visor": "enabled", |
|||
"http_auth": "enabled" |
|||
} |
|||
``` |
|||
|
|||
!!! tip "Astuce" |
|||
Votre déploiement aura une URL `"endpoint"` différente. |
|||
|
|||
## Vérifiez |
|||
|
|||
Maintenant, dans votre navigateur ouvrez votre URL `endpoint`. Dans l'exemple ci-dessus, c'était |
|||
`https://qltnci.deta.dev`, mais la vôtre sera différente. |
|||
|
|||
Vous verrez la réponse JSON de votre application FastAPI : |
|||
|
|||
```JSON |
|||
{ |
|||
"Hello": "World" |
|||
} |
|||
``` |
|||
|
|||
Et maintenant naviguez vers `/docs` dans votre API, dans l'exemple ci-dessus ce serait `https://qltnci.deta.dev/docs`. |
|||
|
|||
Vous verrez votre documentation comme suit : |
|||
|
|||
<img src="/img/deployment/deta/image01.png"> |
|||
|
|||
## Activer l'accès public |
|||
|
|||
Par défaut, Deta va gérer l'authentification en utilisant des cookies pour votre compte. |
|||
|
|||
Mais une fois que vous êtes prêt, vous pouvez le rendre public avec : |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ deta auth disable |
|||
|
|||
Successfully disabled http auth |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
Maintenant, vous pouvez partager cette URL avec n'importe qui et ils seront en mesure d'accéder à votre API. 🚀 |
|||
|
|||
## HTTPS |
|||
|
|||
Félicitations ! Vous avez déployé votre application FastAPI sur Deta ! 🎉 🍰 |
|||
|
|||
Remarquez également que Deta gère correctement HTTPS pour vous, vous n'avez donc pas à vous en occuper et pouvez être sûr que vos clients auront une connexion cryptée sécurisée. ✅ 🔒 |
|||
|
|||
## Vérifiez le Visor |
|||
|
|||
À partir de l'interface graphique de votre documentation (dans une URL telle que `https://qltnci.deta.dev/docs`) |
|||
envoyez une requête à votre *opération de chemin* `/items/{item_id}`. |
|||
|
|||
Par exemple avec l'ID `5`. |
|||
|
|||
Allez maintenant sur <a href="https://web.deta.sh/" class="external-link" target="_blank">https://web.deta.sh</a>. |
|||
|
|||
Vous verrez qu'il y a une section à gauche appelée <abbr title="ça vient de Micro(server)">"Micros"</abbr> avec chacune de vos applications. |
|||
|
|||
Vous verrez un onglet avec "Details", et aussi un onglet "Visor", allez à l'onglet "Visor". |
|||
|
|||
Vous pouvez y consulter les requêtes récentes envoyées à votre application. |
|||
|
|||
Vous pouvez également les modifier et les relancer. |
|||
|
|||
<img src="/img/deployment/deta/image02.png"> |
|||
|
|||
## En savoir plus |
|||
|
|||
À un moment donné, vous voudrez probablement stocker certaines données pour votre application d'une manière qui |
|||
persiste dans le temps. Pour cela, vous pouvez utiliser <a href="https://docs.deta.sh/docs/base/py_tutorial?ref=fastapi" class="external-link" target="_blank">Deta Base</a>, il dispose également d'un généreux **plan gratuit**. |
|||
|
|||
Vous pouvez également en lire plus dans la <a href="https://docs.deta.sh?ref=fastapi" class="external-link" target="_blank">documentation Deta</a>. |
@ -0,0 +1,53 @@ |
|||
# À propos de HTTPS |
|||
|
|||
Il est facile de penser que HTTPS peut simplement être "activé" ou non. |
|||
|
|||
Mais c'est beaucoup plus complexe que cela. |
|||
|
|||
!!! tip |
|||
Si vous êtes pressé ou si cela ne vous intéresse pas, passez aux sections suivantes pour obtenir des instructions étape par étape afin de tout configurer avec différentes techniques. |
|||
|
|||
Pour apprendre les bases du HTTPS, du point de vue d'un utilisateur, consultez <a href="https://howhttps.works/" |
|||
class="external-link" target="_blank">https://howhttps.works/</a>. |
|||
|
|||
Maintenant, du point de vue d'un développeur, voici plusieurs choses à avoir en tête en pensant au HTTPS : |
|||
|
|||
* Pour le HTTPS, le serveur a besoin de "certificats" générés par une tierce partie. |
|||
* Ces certificats sont en fait acquis auprès de la tierce partie, et non "générés". |
|||
* Les certificats ont une durée de vie. |
|||
* Ils expirent. |
|||
* Puis ils doivent être renouvelés et acquis à nouveau auprès de la tierce partie. |
|||
* Le cryptage de la connexion se fait au niveau du protocole TCP. |
|||
* C'est une couche en dessous de HTTP. |
|||
* Donc, le certificat et le traitement du cryptage sont faits avant HTTP. |
|||
* TCP ne connaît pas les "domaines", seulement les adresses IP. |
|||
* L'information sur le domaine spécifique demandé se trouve dans les données HTTP. |
|||
* Les certificats HTTPS "certifient" un certain domaine, mais le protocole et le cryptage se font au niveau TCP, avant de savoir quel domaine est traité. |
|||
* Par défaut, cela signifie que vous ne pouvez avoir qu'un seul certificat HTTPS par adresse IP. |
|||
* Quelle que soit la taille de votre serveur ou la taille de chacune des applications qu'il contient. |
|||
* Il existe cependant une solution à ce problème. |
|||
* Il existe une extension du protocole TLS (celui qui gère le cryptage au niveau TCP, avant HTTP) appelée <a |
|||
href="https://fr.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr |
|||
title="Server Name Indication (indication du nom du serveur)">SNI (indication du nom du serveur)</abbr></a>. |
|||
* Cette extension SNI permet à un seul serveur (avec une seule adresse IP) d'avoir plusieurs certificats HTTPS et de servir plusieurs domaines/applications HTTPS. |
|||
* Pour que cela fonctionne, un seul composant (programme) fonctionnant sur le serveur, écoutant sur l'adresse IP publique, doit avoir tous les certificats HTTPS du serveur. |
|||
* Après avoir obtenu une connexion sécurisée, le protocole de communication est toujours HTTP. |
|||
* Le contenu est crypté, même s'il est envoyé avec le protocole HTTP. |
|||
|
|||
Il est courant d'avoir un seul programme/serveur HTTP fonctionnant sur le serveur (la machine, l'hôte, etc.) et |
|||
gérant toutes les parties HTTPS : envoyer les requêtes HTTP décryptées à l'application HTTP réelle fonctionnant sur |
|||
le même serveur (dans ce cas, l'application **FastAPI**), prendre la réponse HTTP de l'application, la crypter en utilisant le certificat approprié et la renvoyer au client en utilisant HTTPS. Ce serveur est souvent appelé un <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">Proxy de terminaison TLS</a>. |
|||
|
|||
## Let's Encrypt |
|||
|
|||
Avant Let's Encrypt, ces certificats HTTPS étaient vendus par des tiers de confiance. |
|||
|
|||
Le processus d'acquisition d'un de ces certificats était auparavant lourd, nécessitait pas mal de paperasses et les certificats étaient assez chers. |
|||
|
|||
Mais ensuite, <a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a> a été créé. |
|||
|
|||
Il s'agit d'un projet de la Fondation Linux. Il fournit des certificats HTTPS gratuitement. De manière automatisée. Ces certificats utilisent toutes les sécurités cryptographiques standard et ont une durée de vie courte (environ 3 mois), de sorte que la sécurité est en fait meilleure en raison de leur durée de vie réduite. |
|||
|
|||
Les domaines sont vérifiés de manière sécurisée et les certificats sont générés automatiquement. Cela permet également d'automatiser le renouvellement de ces certificats. |
|||
|
|||
L'idée est d'automatiser l'acquisition et le renouvellement de ces certificats, afin que vous puissiez disposer d'un HTTPS sécurisé, gratuitement et pour toujours. |
@ -0,0 +1,28 @@ |
|||
# Déploiement - Intro |
|||
|
|||
Le déploiement d'une application **FastAPI** est relativement simple. |
|||
|
|||
## Que signifie le déploiement |
|||
|
|||
**Déployer** une application signifie effectuer les étapes nécessaires pour la rendre **disponible pour les |
|||
utilisateurs**. |
|||
|
|||
Pour une **API Web**, cela implique normalement de la placer sur une **machine distante**, avec un **programme serveur** |
|||
qui offre de bonnes performances, une bonne stabilité, _etc._, afin que vos **utilisateurs** puissent **accéder** à |
|||
l'application efficacement et sans interruption ni problème. |
|||
|
|||
Ceci contraste avec les étapes de **développement**, où vous êtes constamment en train de modifier le code, de le casser |
|||
et de le réparer, d'arrêter et de redémarrer le serveur de développement, _etc._ |
|||
|
|||
## Stratégies de déploiement |
|||
|
|||
Il existe plusieurs façons de procéder, en fonction de votre cas d'utilisation spécifique et des outils que vous |
|||
utilisez. |
|||
|
|||
Vous pouvez **déployer un serveur** vous-même en utilisant une combinaison d'outils, vous pouvez utiliser un **service |
|||
cloud** qui fait une partie du travail pour vous, ou encore d'autres options possibles. |
|||
|
|||
Je vais vous montrer certains des principaux concepts que vous devriez probablement avoir à l'esprit lors du déploiement |
|||
d'une application **FastAPI** (bien que la plupart de ces concepts s'appliquent à tout autre type d'application web). |
|||
|
|||
Vous verrez plus de détails à avoir en tête et certaines des techniques pour le faire dans les sections suivantes. ✨ |
@ -0,0 +1,95 @@ |
|||
# À propos des versions de FastAPI |
|||
|
|||
**FastAPI** est déjà utilisé en production dans de nombreuses applications et systèmes. Et la couverture de test est maintenue à 100 %. Mais son développement est toujours aussi rapide. |
|||
|
|||
De nouvelles fonctionnalités sont ajoutées fréquemment, des bogues sont corrigés régulièrement et le code est |
|||
amélioré continuellement. |
|||
|
|||
C'est pourquoi les versions actuelles sont toujours `0.x.x`, cela reflète que chaque version peut potentiellement |
|||
recevoir des changements non rétrocompatibles. Cela suit les conventions de <a href="https://semver.org/" class="external-link" |
|||
target="_blank">versionnage sémantique</a>. |
|||
|
|||
Vous pouvez créer des applications de production avec **FastAPI** dès maintenant (et vous le faites probablement depuis un certain temps), vous devez juste vous assurer que vous utilisez une version qui fonctionne correctement avec le reste de votre code. |
|||
|
|||
## Épinglez votre version de `fastapi` |
|||
|
|||
Tout d'abord il faut "épingler" la version de **FastAPI** que vous utilisez à la dernière version dont vous savez |
|||
qu'elle fonctionne correctement pour votre application. |
|||
|
|||
Par exemple, disons que vous utilisez la version `0.45.0` dans votre application. |
|||
|
|||
Si vous utilisez un fichier `requirements.txt`, vous pouvez spécifier la version avec : |
|||
|
|||
```txt |
|||
fastapi==0.45.0 |
|||
``` |
|||
|
|||
ce qui signifierait que vous utiliseriez exactement la version `0.45.0`. |
|||
|
|||
Ou vous pourriez aussi l'épingler avec : |
|||
|
|||
```txt |
|||
fastapi>=0.45.0,<0.46.0 |
|||
``` |
|||
|
|||
cela signifierait que vous utiliseriez les versions `0.45.0` ou supérieures, mais inférieures à `0.46.0`, par exemple, une version `0.45.2` serait toujours acceptée. |
|||
|
|||
Si vous utilisez un autre outil pour gérer vos installations, comme Poetry, Pipenv, ou autres, ils ont tous un moyen que vous pouvez utiliser pour définir des versions spécifiques pour vos paquets. |
|||
|
|||
## Versions disponibles |
|||
|
|||
Vous pouvez consulter les versions disponibles (par exemple, pour vérifier quelle est la dernière version en date) dans les [Notes de version](../release-notes.md){.internal-link target=_blank}. |
|||
|
|||
## À propos des versions |
|||
|
|||
Suivant les conventions de versionnage sémantique, toute version inférieure à `1.0.0` peut potentiellement ajouter |
|||
des changements non rétrocompatibles. |
|||
|
|||
FastAPI suit également la convention que tout changement de version "PATCH" est pour des corrections de bogues et |
|||
des changements rétrocompatibles. |
|||
|
|||
!!! tip "Astuce" |
|||
Le "PATCH" est le dernier chiffre, par exemple, dans `0.2.3`, la version PATCH est `3`. |
|||
|
|||
Donc, vous devriez être capable d'épingler une version comme suit : |
|||
|
|||
```txt |
|||
fastapi>=0.45.0,<0.46.0 |
|||
``` |
|||
|
|||
Les changements non rétrocompatibles et les nouvelles fonctionnalités sont ajoutés dans les versions "MINOR". |
|||
|
|||
!!! tip "Astuce" |
|||
Le "MINOR" est le numéro au milieu, par exemple, dans `0.2.3`, la version MINOR est `2`. |
|||
|
|||
## Mise à jour des versions FastAPI |
|||
|
|||
Vous devriez tester votre application. |
|||
|
|||
Avec **FastAPI** c'est très facile (merci à Starlette), consultez la documentation : [Testing](../tutorial/testing.md){.internal-link target=_blank} |
|||
|
|||
Après avoir effectué des tests, vous pouvez mettre à jour la version **FastAPI** vers une version plus récente, et vous assurer que tout votre code fonctionne correctement en exécutant vos tests. |
|||
|
|||
Si tout fonctionne, ou après avoir fait les changements nécessaires, et que tous vos tests passent, vous pouvez |
|||
épingler votre version de `fastapi` à cette nouvelle version récente. |
|||
|
|||
## À propos de Starlette |
|||
|
|||
Vous ne devriez pas épingler la version de `starlette`. |
|||
|
|||
Différentes versions de **FastAPI** utiliseront une version spécifique plus récente de Starlette. |
|||
|
|||
Ainsi, vous pouvez simplement laisser **FastAPI** utiliser la bonne version de Starlette. |
|||
|
|||
## À propos de Pydantic |
|||
|
|||
Pydantic inclut des tests pour **FastAPI** avec ses propres tests, ainsi les nouvelles versions de Pydantic (au-dessus |
|||
de `1.0.0`) sont toujours compatibles avec **FastAPI**. |
|||
|
|||
Vous pouvez épingler Pydantic à toute version supérieure à `1.0.0` qui fonctionne pour vous et inférieure à `2.0.0`. |
|||
|
|||
Par exemple : |
|||
|
|||
```txt |
|||
pydantic>=1.2.0,<2.0.0 |
|||
``` |
@ -0,0 +1,122 @@ |
|||
# Help FastAPI - Obtenir de l'aide |
|||
|
|||
Aimez-vous **FastAPI** ? |
|||
|
|||
Vous souhaitez aider FastAPI, les autres utilisateurs et l'auteur ? |
|||
|
|||
Ou souhaitez-vous obtenir de l'aide avec le **FastAPI** ? |
|||
|
|||
Il existe des moyens très simples d'aider (plusieurs ne nécessitent qu'un ou deux clics). |
|||
|
|||
Il existe également plusieurs façons d'obtenir de l'aide. |
|||
|
|||
## Star **FastAPI** sur GitHub |
|||
|
|||
Vous pouvez "star" FastAPI dans GitHub (en cliquant sur le bouton étoile en haut à droite) : <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. ⭐️ |
|||
|
|||
En ajoutant une étoile, les autres utilisateurs pourront la trouver plus facilement et constater qu'elle a déjà été utile à d'autres. |
|||
|
|||
## Watch le dépôt GitHub pour les releases |
|||
|
|||
Vous pouvez "watch" FastAPI dans GitHub (en cliquant sur le bouton "watch" en haut à droite) : <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀 |
|||
|
|||
Vous pouvez y sélectionner "Releases only". |
|||
|
|||
Ainsi, vous recevrez des notifications (dans votre courrier électronique) chaque fois qu'il y aura une nouvelle version de **FastAPI** avec des corrections de bugs et de nouvelles fonctionnalités. |
|||
|
|||
## Se rapprocher de l'auteur |
|||
|
|||
Vous pouvez vous rapprocher de <a href="https://tiangolo.com" class="external-link" target="_blank">moi (Sebastián Ramírez / `tiangolo`)</a>, l'auteur. |
|||
|
|||
Vous pouvez : |
|||
|
|||
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">Me suivre sur **GitHub**</a>. |
|||
* Voir d'autres projets Open Source que j'ai créés et qui pourraient vous aider. |
|||
* Suivez-moi pour voir quand je crée un nouveau projet Open Source. |
|||
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Me suivre sur **Twitter**</a>. |
|||
* Dites-moi comment vous utilisez FastAPI (j'adore entendre ça). |
|||
* Entendre quand je fais des annonces ou que je lance de nouveaux outils. |
|||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Vous connectez à moi sur **Linkedin**</a>. |
|||
* Etre notifié quand je fais des annonces ou que je lance de nouveaux outils (bien que j'utilise plus souvent Twitte 🤷♂). |
|||
* Lire ce que j’écris (ou me suivre) sur <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> ou <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>. |
|||
* Lire d'autres idées, articles, et sur les outils que j'ai créés. |
|||
* Suivez-moi pour lire quand je publie quelque chose de nouveau. |
|||
|
|||
## Tweeter sur **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">Tweetez à propos de **FastAPI**</a> et faites-moi savoir, ainsi qu'aux autres, pourquoi vous aimez ça. 🎉 |
|||
|
|||
J'aime entendre parler de l'utilisation du **FastAPI**, de ce que vous avez aimé dedans, dans quel projet/entreprise l'utilisez-vous, etc. |
|||
|
|||
## Voter pour FastAPI |
|||
|
|||
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Votez pour **FastAPI** sur Slant</a>. |
|||
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">Votez pour **FastAPI** sur AlternativeTo</a>. |
|||
* <a href="https://github.com/marmelab/awesome-rest/pull/93" class="external-link" target="_blank">Votez pour **FastAPI** sur awesome-rest</a>. |
|||
|
|||
## Aider les autres à résoudre les problèmes dans GitHub |
|||
|
|||
Vous pouvez voir <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">les problèmes existants</a> et essayer d'aider les autres, la plupart du temps il s'agit de questions dont vous connaissez peut-être déjà la réponse. 🤓 |
|||
|
|||
## Watch le dépôt GitHub |
|||
|
|||
Vous pouvez "watch" FastAPI dans GitHub (en cliquant sur le bouton "watch" en haut à droite) : <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀 |
|||
|
|||
Si vous sélectionnez "Watching" au lieu de "Releases only", vous recevrez des notifications lorsque quelqu'un crée une nouvelle Issue. |
|||
|
|||
Vous pouvez alors essayer de les aider à résoudre ces problèmes. |
|||
|
|||
## Créer une Issue |
|||
|
|||
Vous pouvez <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">créer une Issue</a> dans le dépôt GitHub, par exemple pour : |
|||
|
|||
* Poser une question ou s'informer sur un problème. |
|||
* Suggérer une nouvelle fonctionnalité. |
|||
|
|||
**Note** : si vous créez un problème, alors je vais vous demander d'aider aussi les autres. 😉 |
|||
|
|||
## Créer une Pull Request |
|||
|
|||
Vous pouvez <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">créer une Pull Request</a>, par exemple : |
|||
|
|||
* Pour corriger une faute de frappe que vous avez trouvée sur la documentation. |
|||
* Proposer de nouvelles sections de documentation. |
|||
* Pour corriger une Issue/Bug existant. |
|||
* Pour ajouter une nouvelle fonctionnalité. |
|||
|
|||
## Rejoindre le chat |
|||
|
|||
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank"> |
|||
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Rejoindre le chat à https://gitter.im/tiangolo/fastapi"> |
|||
</a> |
|||
|
|||
Rejoignez le chat sur Gitter: <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>. |
|||
|
|||
Vous pouvez y avoir des conversations rapides avec d'autres personnes, aider les autres, partager des idées, etc. |
|||
|
|||
Mais gardez à l'esprit que, comme il permet une "conversation plus libre", il est facile de poser des questions trop générales et plus difficiles à répondre, de sorte que vous risquez de ne pas recevoir de réponses. |
|||
|
|||
Dans les Issues de GitHub, le modèle vous guidera pour écrire la bonne question afin que vous puissiez plus facilement obtenir une bonne réponse, ou même résoudre le problème vous-même avant même de le poser. Et dans GitHub, je peux m'assurer que je réponds toujours à tout, même si cela prend du temps. Je ne peux pas faire cela personnellement avec le chat Gitter. 😅 |
|||
|
|||
Les conversations dans Gitter ne sont pas non plus aussi facilement consultables que dans GitHub, de sorte que les questions et les réponses peuvent se perdre dans la conversation. |
|||
|
|||
De l'autre côté, il y a plus de 1000 personnes dans le chat, il y a donc de fortes chances que vous y trouviez quelqu'un à qui parler, presque tout le temps. 😄 |
|||
|
|||
## Parrainer l'auteur |
|||
|
|||
Vous pouvez également soutenir financièrement l'auteur (moi) via <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>. |
|||
|
|||
Là, vous pourriez m'offrir un café ☕️ pour me remercier 😄. |
|||
|
|||
## Sponsoriser les outils qui font fonctionner FastAPI |
|||
|
|||
Comme vous l'avez vu dans la documentation, FastAPI se tient sur les épaules des géants, Starlette et Pydantic. |
|||
|
|||
Vous pouvez également parrainer : |
|||
|
|||
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a> |
|||
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a> |
|||
|
|||
--- |
|||
|
|||
Merci ! 🚀 |
@ -0,0 +1,79 @@ |
|||
# Histoire, conception et avenir |
|||
|
|||
Il y a quelque temps, <a href="https://github.com/tiangolo/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">un utilisateur de **FastAPI** a demandé</a> : |
|||
|
|||
> Quelle est l'histoire de ce projet ? Il semble être sorti de nulle part et est devenu génial en quelques semaines [...]. |
|||
|
|||
Voici un petit bout de cette histoire. |
|||
|
|||
## Alternatives |
|||
|
|||
Je crée des API avec des exigences complexes depuis plusieurs années (Machine Learning, systèmes distribués, jobs asynchrones, bases de données NoSQL, etc), en dirigeant plusieurs équipes de développeurs. |
|||
|
|||
Dans ce cadre, j'ai dû étudier, tester et utiliser de nombreuses alternatives. |
|||
|
|||
L'histoire de **FastAPI** est en grande partie l'histoire de ses prédécesseurs. |
|||
|
|||
Comme dit dans la section [Alternatives](alternatives.md){.internal-link target=\_blank} : |
|||
|
|||
<blockquote markdown="1"> |
|||
|
|||
**FastAPI** n'existerait pas sans le travail antérieur d'autres personnes. |
|||
|
|||
Il y a eu de nombreux outils créés auparavant qui ont contribué à inspirer sa création. |
|||
|
|||
J'ai évité la création d'un nouveau framework pendant plusieurs années. J'ai d'abord essayé de résoudre toutes les fonctionnalités couvertes par **FastAPI** en utilisant de nombreux frameworks, plug-ins et outils différents. |
|||
|
|||
Mais à un moment donné, il n'y avait pas d'autre option que de créer quelque chose qui offre toutes ces fonctionnalités, en prenant les meilleures idées des outils précédents, et en les combinant de la meilleure façon possible, en utilisant des fonctionnalités du langage qui n'étaient même pas disponibles auparavant (annotations de type pour Python 3.6+). |
|||
|
|||
</blockquote> |
|||
|
|||
## Recherche |
|||
|
|||
En utilisant toutes les alternatives précédentes, j'ai eu la chance d'apprendre de toutes, de prendre des idées, et de les combiner de la meilleure façon que j'ai pu trouver pour moi-même et les équipes de développeurs avec lesquelles j'ai travaillé. |
|||
|
|||
Par exemple, il était clair que l'idéal était de se baser sur les annotations de type Python standard. |
|||
|
|||
De plus, la meilleure approche était d'utiliser des normes déjà existantes. |
|||
|
|||
Ainsi, avant même de commencer à coder **FastAPI**, j'ai passé plusieurs mois à étudier les spécifications d'OpenAPI, JSON Schema, OAuth2, etc. Comprendre leurs relations, leurs similarités et leurs différences. |
|||
|
|||
## Conception |
|||
|
|||
Ensuite, j'ai passé du temps à concevoir l'"API" de développeur que je voulais avoir en tant qu'utilisateur (en tant que développeur utilisant FastAPI). |
|||
|
|||
J'ai testé plusieurs idées dans les éditeurs Python les plus populaires : PyCharm, VS Code, les éditeurs basés sur Jedi. |
|||
|
|||
D'après la dernière <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">Enquête Développeurs Python</a>, cela couvre environ 80% des utilisateurs. |
|||
|
|||
Cela signifie que **FastAPI** a été spécifiquement testé avec les éditeurs utilisés par 80% des développeurs Python. Et comme la plupart des autres éditeurs ont tendance à fonctionner de façon similaire, tous ses avantages devraient fonctionner pour pratiquement tous les éditeurs. |
|||
|
|||
Ainsi, j'ai pu trouver les meilleurs moyens de réduire autant que possible la duplication du code, d'avoir la complétion partout, les contrôles de type et d'erreur, etc. |
|||
|
|||
Le tout de manière à offrir la meilleure expérience de développement à tous les développeurs. |
|||
|
|||
## Exigences |
|||
|
|||
Après avoir testé plusieurs alternatives, j'ai décidé que j'allais utiliser <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">**Pydantic**</a> pour ses avantages. |
|||
|
|||
J'y ai ensuite contribué, pour le rendre entièrement compatible avec JSON Schema, pour supporter différentes manières de définir les déclarations de contraintes, et pour améliorer le support des éditeurs (vérifications de type, autocomplétion) sur la base des tests effectués dans plusieurs éditeurs. |
|||
|
|||
Pendant le développement, j'ai également contribué à <a href="https://www.starlette.io/" class="external-link" target="_blank">**Starlette**</a>, l'autre exigence clé. |
|||
|
|||
## Développement |
|||
|
|||
Au moment où j'ai commencé à créer **FastAPI** lui-même, la plupart des pièces étaient déjà en place, la conception était définie, les exigences et les outils étaient prêts, et la connaissance des normes et des spécifications était claire et fraîche. |
|||
|
|||
## Futur |
|||
|
|||
À ce stade, il est déjà clair que **FastAPI** et ses idées sont utiles pour de nombreuses personnes. |
|||
|
|||
Elle a été préférée aux solutions précédentes parce qu'elle convient mieux à de nombreux cas d'utilisation. |
|||
|
|||
De nombreux développeurs et équipes dépendent déjà de **FastAPI** pour leurs projets (y compris moi et mon équipe). |
|||
|
|||
Mais il y a encore de nombreuses améliorations et fonctionnalités à venir. |
|||
|
|||
**FastAPI** a un grand avenir devant lui. |
|||
|
|||
Et [votre aide](help-fastapi.md){.internal-link target=\_blank} est grandement appréciée. |
@ -0,0 +1,80 @@ |
|||
# Tutorial - Pedoman Pengguna - Pengenalan |
|||
|
|||
Tutorial ini menunjukan cara menggunakan ***FastAPI*** dengan semua fitur-fiturnya, tahap demi tahap. |
|||
|
|||
Setiap bagian dibangun secara bertahap dari bagian sebelumnya, tetapi terstruktur untuk memisahkan banyak topik, sehingga kamu bisa secara langsung menuju ke topik spesifik untuk menyelesaikan kebutuhan API tertentu. |
|||
|
|||
Ini juga dibangun untuk digunakan sebagai referensi yang akan datang. |
|||
|
|||
Sehingga kamu dapat kembali lagi dan mencari apa yang kamu butuhkan dengan tepat. |
|||
|
|||
## Jalankan kode |
|||
|
|||
Semua blok-blok kode dapat dicopy dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji). |
|||
|
|||
Untuk menjalankan setiap contoh, copy kode ke file `main.py`, dan jalankan `uvicorn` dengan: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uvicorn main:app --reload |
|||
|
|||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|||
<span style="color: green;">INFO</span>: Started reloader process [28720] |
|||
<span style="color: green;">INFO</span>: Started server process [28722] |
|||
<span style="color: green;">INFO</span>: Waiting for application startup. |
|||
<span style="color: green;">INFO</span>: Application startup complete. |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
**SANGAT disarankan** agar kamu menulis atau meng-copy kode, meng-editnya dan menjalankannya secara lokal. |
|||
|
|||
Dengan menggunakannya di dalam editor, benar-benar memperlihatkan manfaat dari FastAPI, melihat bagaimana sedikitnya kode yang harus kamu tulis, semua pengecekan tipe, pelengkapan otomatis, dll. |
|||
|
|||
--- |
|||
|
|||
## Install FastAPI |
|||
|
|||
Langkah pertama adalah dengan meng-install FastAPI. |
|||
|
|||
Untuk tutorial, kamu mungkin hendak meng-instalnya dengan semua pilihan fitur dan dependensinya: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "fastapi[all]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
...yang juga termasuk `uvicorn`, yang dapat kamu gunakan sebagai server yang menjalankan kodemu. |
|||
|
|||
!!! catatan |
|||
Kamu juga dapat meng-instalnya bagian demi bagian. |
|||
|
|||
Hal ini mungkin yang akan kamu lakukan ketika kamu hendak men-deploy aplikasimu ke tahap produksi: |
|||
|
|||
``` |
|||
pip install fastapi |
|||
``` |
|||
|
|||
Juga install `uvicorn` untk menjalankan server" |
|||
|
|||
``` |
|||
pip install "uvicorn[standard]" |
|||
``` |
|||
|
|||
Dan demikian juga untuk pilihan dependensi yang hendak kamu gunakan. |
|||
|
|||
## Pedoman Pengguna Lanjutan |
|||
|
|||
Tersedia juga **Pedoman Pengguna Lanjutan** yang dapat kamu baca nanti setelah **Tutorial - Pedoman Pengguna** ini. |
|||
|
|||
**Pedoman Pengguna Lanjutan**, dibangun atas hal ini, menggunakan konsep yang sama, dan mengajarkan kepadamu beberapa fitur tambahan. |
|||
|
|||
Tetapi kamu harus membaca terlebih dahulu **Tutorial - Pedoman Pengguna** (apa yang sedang kamu baca sekarang). |
|||
|
|||
Hal ini didesain sehingga kamu dapat membangun aplikasi lengkap dengan hanya **Tutorial - Pedoman Pengguna**, dan kemudian mengembangkannya ke banyak cara yang berbeda, tergantung dari kebutuhanmu, menggunakan beberapa ide-ide tambahan dari **Pedoman Pengguna Lanjutan**. |
@ -0,0 +1,156 @@ |
|||
# NoSQL (分散 / ビッグデータ) Databases |
|||
|
|||
**FastAPI** はあらゆる <abbr title="分散データベース (Big Data)や 'Not Only SQL'">NoSQL</abbr>と統合することもできます。 |
|||
|
|||
ここでは<abbr title="ここでのドキュメントとは、キーと値を持つJSONオブジェクト(ディクショナリー)をあらわし、これらの値は他のJSONオブジェクトや配列(リスト)、数値、文字列、真偽値などにすることができます。">ドキュメント</abbr>ベースのNoSQLデータベースである**<a href="https://www.couchbase.com/" class="external-link" target="_blank">Couchbase</a>**を使用した例を見てみましょう。 |
|||
|
|||
他にもこれらのNoSQLデータベースを利用することが出来ます: |
|||
|
|||
* **MongoDB** |
|||
* **Cassandra** |
|||
* **CouchDB** |
|||
* **ArangoDB** |
|||
* **ElasticSearch** など。 |
|||
|
|||
!!! tip "豆知識" |
|||
**FastAPI**と**Couchbase**を使った公式プロジェクト・ジェネレータがあります。すべて**Docker**ベースで、フロントエンドやその他のツールも含まれています: <a href="https://github.com/tiangolo/full-stack-fastapi-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-couchbase</a> |
|||
|
|||
## Couchbase コンポーネントの Import |
|||
|
|||
まずはImportしましょう。今はその他のソースコードに注意を払う必要はありません。 |
|||
|
|||
```Python hl_lines="3-5" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
## "document type" として利用する定数の定義 |
|||
|
|||
documentで利用する固定の`type`フィールドを用意しておきます。 |
|||
|
|||
これはCouchbaseで必須ではありませんが、後々の助けになるベストプラクティスです。 |
|||
|
|||
```Python hl_lines="9" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
## `Bucket` を取得する関数の追加 |
|||
|
|||
**Couchbase**では、bucketはdocumentのセットで、様々な種類のものがあります。 |
|||
|
|||
Bucketは通常、同一のアプリケーション内で互いに関係を持っています。 |
|||
|
|||
リレーショナルデータベースの世界でいう"database"(データベースサーバではなく特定のdatabase)と類似しています。 |
|||
|
|||
**MongoDB** で例えると"collection"と似た概念です。 |
|||
|
|||
次のコードでは主に `Bucket` を利用してCouchbaseを操作します。 |
|||
|
|||
この関数では以下の処理を行います: |
|||
|
|||
* **Couchbase** クラスタ(1台の場合もあるでしょう)に接続 |
|||
* タイムアウトのデフォルト値を設定 |
|||
* クラスタで認証を取得 |
|||
* `Bucket` インスタンスを取得 |
|||
* タイムアウトのデフォルト値を設定 |
|||
* 作成した`Bucket`インスタンスを返却 |
|||
|
|||
```Python hl_lines="12-21" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
## Pydantic モデルの作成 |
|||
|
|||
**Couchbase**のdocumentは実際には単にJSONオブジェクトなのでPydanticを利用してモデルに出来ます。 |
|||
|
|||
### `User` モデル |
|||
|
|||
まずは`User`モデルを作成してみましょう: |
|||
|
|||
```Python hl_lines="24-28" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
このモデルは*path operation*に使用するので`hashed_password`は含めません。 |
|||
|
|||
### `UserInDB` モデル |
|||
|
|||
それでは`UserInDB`モデルを作成しましょう。 |
|||
|
|||
こちらは実際にデータベースに保存されるデータを保持します。 |
|||
|
|||
`User`モデルの持つ全ての属性に加えていくつかの属性を追加するのでPydanticの`BaseModel`を継承せずに`User`のサブクラスとして定義します: |
|||
|
|||
```Python hl_lines="31-33" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! note "備考" |
|||
データベースに保存される`hashed_password`と`type`フィールドを`UserInDB`モデルに保持させていることに注意してください。 |
|||
|
|||
しかしこれらは(*path operation*で返却する)一般的な`User`モデルには含まれません |
|||
|
|||
## user の取得 |
|||
|
|||
それでは次の関数を作成しましょう: |
|||
|
|||
* username を取得する |
|||
* username を利用してdocumentのIDを生成する |
|||
* 作成したIDでdocumentを取得する |
|||
* documentの内容を`UserInDB`モデルに設定する |
|||
|
|||
*path operation関数*とは別に、`username`(またはその他のパラメータ)からuserを取得することだけに特化した関数を作成することで、より簡単に複数の部分で再利用したり<abbr title="コードで書かれた自動テストで、他のコードが正しく動作しているかどうかをチェックするもの。">ユニットテスト</abbr>を追加することができます。 |
|||
|
|||
```Python hl_lines="36-42" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
### f-strings |
|||
|
|||
`f"userprofile::{username}"` という記載に馴染みがありませんか?これは Python の"<a href="https://docs.python.org/3/glossary.html#term-f-string" class="external-link" target="_blank">f-string</a>"と呼ばれるものです。 |
|||
|
|||
f-stringの`{}`の中に入れられた変数は、文字列の中に展開/注入されます。 |
|||
|
|||
### `dict` アンパック |
|||
|
|||
`UserInDB(**result.value)`という記載に馴染みがありませんか?<a href="https://docs.python.org/3/glossary.html#term-argument" class="external-link" target="_blank">これは`dict`の"アンパック"</a>と呼ばれるものです。 |
|||
|
|||
これは`result.value`の`dict`からそのキーと値をそれぞれ取りキーワード引数として`UserInDB`に渡します。 |
|||
|
|||
例えば`dict`が下記のようになっていた場合: |
|||
|
|||
```Python |
|||
{ |
|||
"username": "johndoe", |
|||
"hashed_password": "some_hash", |
|||
} |
|||
``` |
|||
|
|||
`UserInDB`には次のように渡されます: |
|||
|
|||
```Python |
|||
UserInDB(username="johndoe", hashed_password="some_hash") |
|||
``` |
|||
|
|||
## **FastAPI** コードの実装 |
|||
|
|||
### `FastAPI` app の作成 |
|||
|
|||
```Python hl_lines="46" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
### *path operation関数*の作成 |
|||
|
|||
私たちのコードはCouchbaseを呼び出しており、<a href="https://docs.couchbase.com/python-sdk/2.5/async-programming.html#asyncio-python-3-5" class="external-link" target="_blank">実験的なPython <code>await</code></a>を使用していないので、私たちは`async def`ではなく通常の`def`で関数を宣言する必要があります。 |
|||
|
|||
また、Couchbaseは単一の`Bucket`オブジェクトを複数の<abbr title="プログラムによって実行される一連のコードのことで、同時に、または間隔をおいて他のコードも実行されることがあります。">スレッド</abbr>で使用しないことを推奨していますので、単に直接Bucketを取得して関数に渡すことが出来ます。 |
|||
|
|||
```Python hl_lines="49-53" |
|||
{!../../../docs_src/nosql_databases/tutorial001.py!} |
|||
``` |
|||
|
|||
## まとめ |
|||
|
|||
他のサードパーティ製のNoSQLデータベースを利用する場合でも、そのデータベースの標準ライブラリを利用するだけで利用できます。 |
|||
|
|||
他の外部ツール、システム、APIについても同じことが言えます。 |
@ -0,0 +1,213 @@ |
|||
# Corpo - Múltiplos parâmetros |
|||
|
|||
Agora que nós vimos como usar `Path` e `Query`, veremos usos mais avançados de declarações no corpo da requisição. |
|||
|
|||
## Misture `Path`, `Query` e parâmetros de corpo |
|||
|
|||
Primeiro, é claro, você pode misturar `Path`, `Query` e declarações de parâmetro no corpo da requisição livremente e o **FastAPI** saberá o que fazer. |
|||
|
|||
E você também pode declarar parâmetros de corpo como opcionais, definindo o valor padrão com `None`: |
|||
|
|||
=== "Python 3.6 e superiores" |
|||
|
|||
```Python hl_lines="19-21" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 e superiores" |
|||
|
|||
```Python hl_lines="17-19" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
!!! nota |
|||
Repare que, neste caso, o `item` que seria capturado a partir do corpo é opcional. Visto que ele possui `None` como valor padrão. |
|||
|
|||
## Múltiplos parâmetros de corpo |
|||
|
|||
No exemplo anterior, as *operações de rota* esperariam um JSON no corpo contendo os atributos de um `Item`, exemplo: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
} |
|||
``` |
|||
|
|||
Mas você pode também declarar múltiplos parâmetros de corpo, por exemplo, `item` e `user`: |
|||
|
|||
=== "Python 3.6 e superiores" |
|||
|
|||
```Python hl_lines="22" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial002.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 e superiores" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
Neste caso, o **FastAPI** perceberá que existe mais de um parâmetro de corpo na função (dois parâmetros que são modelos Pydantic). |
|||
|
|||
Então, ele usará o nome dos parâmetros como chaves (nome dos campos) no corpo, e espera um corpo como: |
|||
|
|||
```JSON |
|||
{ |
|||
"item": { |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
}, |
|||
"user": { |
|||
"username": "dave", |
|||
"full_name": "Dave Grohl" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
!!! nota |
|||
Repare que mesmo que o `item` esteja declarado da mesma maneira que antes, agora é esperado que ele esteja dentro do corpo com uma chave `item`. |
|||
|
|||
|
|||
O **FastAPI** fará a conversão automática a partir da requisição, assim esse parâmetro `item` receberá seu respectivo conteúdo e o mesmo ocorrerá com `user`. |
|||
|
|||
Ele executará a validação dos dados compostos e irá documentá-los de maneira compatível com o esquema OpenAPI e documentação automática. |
|||
|
|||
## Valores singulares no corpo |
|||
|
|||
Assim como existem uma `Query` e uma `Path` para definir dados adicionais para parâmetros de consulta e de rota, o **FastAPI** provê o equivalente para `Body`. |
|||
|
|||
Por exemplo, extendendo o modelo anterior, você poder decidir por ter uma outra chave `importance` no mesmo corpo, além de `item` e `user`. |
|||
|
|||
Se você declará-lo como é, porque é um valor singular, o **FastAPI** assumirá que se trata de um parâmetro de consulta. |
|||
|
|||
Mas você pode instruir o **FastAPI** para tratá-lo como outra chave do corpo usando `Body`: |
|||
|
|||
=== "Python 3.6 e superiores" |
|||
|
|||
```Python hl_lines="22" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 e superiores" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!} |
|||
``` |
|||
|
|||
Neste caso, o **FastAPI** esperará um corpo como: |
|||
|
|||
```JSON |
|||
{ |
|||
"item": { |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
}, |
|||
"user": { |
|||
"username": "dave", |
|||
"full_name": "Dave Grohl" |
|||
}, |
|||
"importance": 5 |
|||
} |
|||
``` |
|||
|
|||
Mais uma vez, ele converterá os tipos de dados, validar, documentar, etc. |
|||
|
|||
## Múltiplos parâmetros de corpo e consulta |
|||
|
|||
Obviamente, você também pode declarar parâmetros de consulta assim que você precisar, de modo adicional a quaisquer parâmetros de corpo. |
|||
|
|||
Dado que, por padrão, valores singulares são interpretados como parâmetros de consulta, você não precisa explicitamente adicionar uma `Query`, você pode somente: |
|||
|
|||
```Python |
|||
q: Union[str, None] = None |
|||
``` |
|||
|
|||
Ou como em Python 3.10 e versões superiores: |
|||
|
|||
```Python |
|||
q: str | None = None |
|||
``` |
|||
|
|||
Por exemplo: |
|||
|
|||
=== "Python 3.6 e superiores" |
|||
|
|||
```Python hl_lines="27" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 e superiores" |
|||
|
|||
```Python hl_lines="26" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!} |
|||
``` |
|||
|
|||
!!! info "Informação" |
|||
`Body` também possui todas as validações adicionais e metadados de parâmetros como em `Query`,`Path` e outras que você verá depois. |
|||
|
|||
## Declare um único parâmetro de corpo indicando sua chave |
|||
|
|||
Suponha que você tem um único parâmetro de corpo `item`, a partir de um modelo Pydantic `Item`. |
|||
|
|||
Por padrão, o **FastAPI** esperará que seu conteúdo venha no corpo diretamente. |
|||
|
|||
Mas se você quiser que ele espere por um JSON com uma chave `item` e dentro dele os conteúdos do modelo, como ocorre ao declarar vários parâmetros de corpo, você pode usar o parâmetro especial de `Body` chamado `embed`: |
|||
|
|||
```Python |
|||
item: Item = Body(embed=True) |
|||
``` |
|||
|
|||
como em: |
|||
|
|||
=== "Python 3.6 e superiores" |
|||
|
|||
```Python hl_lines="17" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 e superiores" |
|||
|
|||
```Python hl_lines="15" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!} |
|||
``` |
|||
|
|||
Neste caso o **FastAPI** esperará um corpo como: |
|||
|
|||
```JSON hl_lines="2" |
|||
{ |
|||
"item": { |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
} |
|||
} |
|||
``` |
|||
|
|||
ao invés de: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
} |
|||
``` |
|||
|
|||
## Recapitulando |
|||
|
|||
Você pode adicionar múltiplos parâmetros de corpo para sua *função de operação de rota*, mesmo que a requisição possa ter somente um único corpo. |
|||
|
|||
E o **FastAPI** vai manipulá-los, mandar para você os dados corretos na sua função, e validar e documentar o schema correto na *operação de rota*. |
|||
|
|||
Você também pode declarar valores singulares para serem recebidos como parte do corpo. |
|||
|
|||
E você pode instruir o **FastAPI** para requisitar no corpo a indicação de chave mesmo quando existe somente um único parâmetro declarado. |
@ -0,0 +1,251 @@ |
|||
# Manipulação de erros |
|||
|
|||
Há diversas situações em que você precisa notificar um erro a um cliente que está utilizando a sua API. |
|||
|
|||
Esse cliente pode ser um browser com um frontend, o código de outra pessoa, um dispositivo IoT, etc. |
|||
|
|||
Pode ser que você precise comunicar ao cliente que: |
|||
|
|||
* O cliente não tem direitos para realizar aquela operação. |
|||
* O cliente não tem acesso aquele recurso. |
|||
* O item que o cliente está tentando acessar não existe. |
|||
* etc. |
|||
|
|||
|
|||
Nesses casos, você normalmente retornaria um **HTTP status code** próximo ao status code na faixa do status code **400** (do 400 ao 499). |
|||
|
|||
Isso é bastante similar ao caso do HTTP status code 200 (do 200 ao 299). Esses "200" status codes significam que, de algum modo, houve sucesso na requisição. |
|||
|
|||
Os status codes na faixa dos 400 significam que houve um erro por parte do cliente. |
|||
|
|||
Você se lembra de todos aqueles erros (e piadas) a respeito do "**404 Not Found**"? |
|||
|
|||
## Use o `HTTPException` |
|||
|
|||
Para retornar ao cliente *responses* HTTP com erros, use o `HTTPException`. |
|||
|
|||
### Import `HTTPException` |
|||
|
|||
```Python hl_lines="1" |
|||
{!../../../docs_src/handling_errors/tutorial001.py!} |
|||
``` |
|||
|
|||
### Lance o `HTTPException` no seu código. |
|||
|
|||
`HTTPException`, ao fundo, nada mais é do que a conjunção entre uma exceção comum do Python e informações adicionais relevantes para APIs. |
|||
|
|||
E porque é uma exceção do Python, você não **retorna** (return) o `HTTPException`, você lança o (raise) no seu código. |
|||
|
|||
Isso também significa que, se você está escrevendo uma função de utilidade, a qual você está chamando dentro da sua função de operações de caminhos, e você lança o `HTTPException` dentro da função de utilidade, o resto do seu código não será executado dentro da função de operações de caminhos. Ao contrário, o `HTTPException` irá finalizar a requisição no mesmo instante e enviará o erro HTTP oriundo do `HTTPException` para o cliente. |
|||
|
|||
O benefício de lançar uma exceção em vez de retornar um valor ficará mais evidente na seção sobre Dependências e Segurança. |
|||
|
|||
Neste exemplo, quando o cliente pede, na requisição, por um item cujo ID não existe, a exceção com o status code `404` é lançada: |
|||
|
|||
```Python hl_lines="11" |
|||
{!../../../docs_src/handling_errors/tutorial001.py!} |
|||
``` |
|||
|
|||
### A response resultante |
|||
|
|||
|
|||
Se o cliente faz uma requisição para `http://example.com/items/foo` (um `item_id` `"foo"`), esse cliente receberá um HTTP status code 200, e uma resposta JSON: |
|||
|
|||
|
|||
``` |
|||
{ |
|||
"item": "The Foo Wrestlers" |
|||
} |
|||
``` |
|||
|
|||
Mas se o cliente faz uma requisição para `http://example.com/items/bar` (ou seja, um não existente `item_id "bar"`), esse cliente receberá um HTTP status code 404 (o erro "não encontrado" — *not found error*), e uma resposta JSON: |
|||
|
|||
```JSON |
|||
{ |
|||
"detail": "Item not found" |
|||
} |
|||
``` |
|||
|
|||
!!! tip "Dica" |
|||
Quando você lançar um `HTTPException`, você pode passar qualquer valor convertível em JSON como parâmetro de `detail`, e não apenas `str`. |
|||
|
|||
Você pode passar um `dict` ou um `list`, etc. |
|||
Esses tipos de dados são manipulados automaticamente pelo **FastAPI** e convertidos em JSON. |
|||
|
|||
|
|||
## Adicione headers customizados |
|||
|
|||
Há certas situações em que é bastante útil poder adicionar headers customizados no HTTP error. Exemplo disso seria adicionar headers customizados para tipos de segurança. |
|||
|
|||
Você provavelmente não precisará utilizar esses headers diretamente no seu código. |
|||
|
|||
Mas caso você precise, para um cenário mais complexo, você pode adicionar headers customizados: |
|||
|
|||
```Python hl_lines="14" |
|||
{!../../../docs_src/handling_errors/tutorial002.py!} |
|||
``` |
|||
|
|||
## Instalando manipuladores de exceções customizados |
|||
|
|||
Você pode adicionar manipuladores de exceção customizados com <a href="https://www.starlette.io/exceptions/" class="external-link" target="_blank">a mesma seção de utilidade de exceções presentes no Starlette</a> |
|||
|
|||
Digamos que você tenha uma exceção customizada `UnicornException` que você (ou uma biblioteca que você use) precise lançar (`raise`). |
|||
|
|||
Nesse cenário, se você precisa manipular essa exceção de modo global com o FastAPI, você pode adicionar um manipulador de exceção customizada com `@app.exception_handler()`. |
|||
|
|||
```Python hl_lines="5-7 13-18 24" |
|||
{!../../../docs_src/handling_errors/tutorial003.py!} |
|||
``` |
|||
|
|||
Nesse cenário, se você fizer uma requisição para `/unicorns/yolo`, a *operação de caminho* vai lançar (`raise`) o `UnicornException`. |
|||
|
|||
Essa exceção será manipulada, contudo, pelo `unicorn_exception_handler`. |
|||
|
|||
Dessa forma você receberá um erro "limpo", com o HTTP status code `418` e um JSON com o conteúdo: |
|||
|
|||
```JSON |
|||
{"message": "Oops! yolo did something. There goes a rainbow..."} |
|||
``` |
|||
|
|||
!!! note "Detalhes Técnicos" |
|||
Você também pode usar `from starlette.requests import Request` and `from starlette.responses import JSONResponse`. |
|||
|
|||
**FastAPI** disponibiliza o mesmo `starlette.responses` através do `fastapi.responses` por conveniência ao desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette. O mesmo acontece com o `Request`. |
|||
|
|||
## Sobrescreva o manipulador padrão de exceções |
|||
|
|||
**FastAPI** tem alguns manipuladores padrão de exceções. |
|||
|
|||
Esses manipuladores são os responsáveis por retornar o JSON padrão de respostas quando você lança (`raise`) o `HTTPException` e quando a requisição tem dados invalidos. |
|||
|
|||
Você pode sobrescrever esses manipuladores de exceção com os seus próprios manipuladores. |
|||
|
|||
## Sobrescreva exceções de validação da requisição |
|||
|
|||
Quando a requisição contém dados inválidos, **FastAPI** internamente lança para o `RequestValidationError`. |
|||
|
|||
Para sobrescrevê-lo, importe o `RequestValidationError` e use-o com o `@app.exception_handler(RequestValidationError)` para decorar o manipulador de exceções. |
|||
|
|||
```Python hl_lines="2 14-16" |
|||
{!../../../docs_src/handling_errors/tutorial004.py!} |
|||
``` |
|||
|
|||
Se você for ao `/items/foo`, em vez de receber o JSON padrão com o erro: |
|||
|
|||
```JSON |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"loc": [ |
|||
"path", |
|||
"item_id" |
|||
], |
|||
"msg": "value is not a valid integer", |
|||
"type": "type_error.integer" |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
você receberá a versão em texto: |
|||
|
|||
``` |
|||
1 validation error |
|||
path -> item_id |
|||
value is not a valid integer (type=type_error.integer) |
|||
``` |
|||
|
|||
### `RequestValidationError` vs `ValidationError` |
|||
|
|||
!!! warning "Aviso" |
|||
Você pode pular estes detalhes técnicos caso eles não sejam importantes para você neste momento. |
|||
|
|||
`RequestValidationError` é uma subclasse do <a href="https://pydantic-docs.helpmanual.io/#error-handling" class="external-link" target="_blank">`ValidationError`</a> existente no Pydantic. |
|||
|
|||
**FastAPI** faz uso dele para que você veja o erro no seu log, caso você utilize um modelo de Pydantic em `response_model`, e seus dados tenham erro. |
|||
|
|||
Contudo, o cliente ou usuário não terão acesso a ele. Ao contrário, o cliente receberá um "Internal Server Error" com o HTTP status code `500`. |
|||
|
|||
E assim deve ser porque seria um bug no seu código ter o `ValidationError` do Pydantic na sua *response*, ou em qualquer outro lugar do seu código (que não na requisição do cliente). |
|||
|
|||
E enquanto você conserta o bug, os clientes / usuários não deveriam ter acesso às informações internas do erro, porque, desse modo, haveria exposição de uma vulnerabilidade de segurança. |
|||
|
|||
Do mesmo modo, você pode sobreescrever o `HTTPException`. |
|||
|
|||
Por exemplo, você pode querer retornar uma *response* em *plain text* ao invés de um JSON para os seguintes erros: |
|||
|
|||
```Python hl_lines="3-4 9-11 22" |
|||
{!../../../docs_src/handling_errors/tutorial004.py!} |
|||
``` |
|||
|
|||
!!! note "Detalhes Técnicos" |
|||
Você pode usar `from starlette.responses import PlainTextResponse`. |
|||
|
|||
**FastAPI** disponibiliza o mesmo `starlette.responses` como `fastapi.responses`, como conveniência a você, desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette. |
|||
|
|||
|
|||
### Use o body do `RequestValidationError`. |
|||
|
|||
O `RequestValidationError` contém o `body` que ele recebeu de dados inválidos. |
|||
|
|||
Você pode utilizá-lo enquanto desenvolve seu app para conectar o *body* e debugá-lo, e assim retorná-lo ao usuário, etc. |
|||
|
|||
Tente enviar um item inválido como este: |
|||
|
|||
```JSON |
|||
{ |
|||
"title": "towel", |
|||
"size": "XL" |
|||
} |
|||
``` |
|||
|
|||
Você receberá uma *response* informando-o de que a data é inválida, e contendo o *body* recebido: |
|||
|
|||
```JSON hl_lines="12-15" |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"loc": [ |
|||
"body", |
|||
"size" |
|||
], |
|||
"msg": "value is not a valid integer", |
|||
"type": "type_error.integer" |
|||
} |
|||
], |
|||
"body": { |
|||
"title": "towel", |
|||
"size": "XL" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
#### O `HTTPException` do FastAPI vs o `HTTPException` do Starlette. |
|||
|
|||
O **FastAPI** tem o seu próprio `HTTPException`. |
|||
|
|||
E a classe de erro `HTTPException` do **FastAPI** herda da classe de erro do `HTTPException` do Starlette. |
|||
|
|||
A diferença entre os dois é a de que o `HTTPException` do **FastAPI** permite que você adicione *headers* que serão incluídos nas *responses*. |
|||
|
|||
Esses *headers* são necessários/utilizados internamente pelo OAuth 2.0 e também por outras utilidades de segurança. |
|||
|
|||
Portanto, você pode continuar lançando o `HTTPException` do **FastAPI** normalmente no seu código. |
|||
|
|||
Porém, quando você registrar um manipulador de exceção, você deve registrá-lo através do `HTTPException` do Starlette. |
|||
|
|||
Dessa forma, se qualquer parte do código interno, extensão ou plug-in do Starlette lançar o `HTTPException`, o seu manipulador de exceção poderá capturar esse lançamento e tratá-lo. |
|||
|
|||
```Python |
|||
from starlette.exceptions import HTTPException as StarletteHTTPException |
|||
``` |
|||
|
|||
### Re-use os manipulares de exceção do **FastAPI** |
|||
|
|||
Se você quer usar a exceção em conjunto com o mesmo manipulador de exceção *default* do **FastAPI**, você pode importar e re-usar esses manipuladores de exceção do `fastapi.exception_handlers`: |
|||
|
|||
```Python hl_lines="2-5 15 21" |
|||
{!../../../docs_src/handling_errors/tutorial006.py!} |
|||
``` |
|||
|
|||
Nesse exemplo você apenas imprime (`print`) o erro com uma mensagem expressiva. Mesmo assim, dá para pegar a ideia. Você pode usar a exceção e então apenas re-usar o manipulador de exceção *default*. |
@ -0,0 +1,128 @@ |
|||
# Parâmetros de Cabeçalho |
|||
|
|||
Você pode definir parâmetros de Cabeçalho da mesma maneira que define paramêtros com `Query`, `Path` e `Cookie`. |
|||
|
|||
## importe `Header` |
|||
|
|||
Primeiro importe `Header`: |
|||
|
|||
=== "Python 3.6 and above" |
|||
|
|||
```Python hl_lines="3" |
|||
{!> ../../../docs_src/header_params/tutorial001.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 and above" |
|||
|
|||
```Python hl_lines="1" |
|||
{!> ../../../docs_src/header_params/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
## Declare parâmetros de `Header` |
|||
|
|||
Então declare os paramêtros de cabeçalho usando a mesma estrutura que em `Path`, `Query` e `Cookie`. |
|||
|
|||
O primeiro valor é o valor padrão, você pode passar todas as validações adicionais ou parâmetros de anotação: |
|||
|
|||
=== "Python 3.6 and above" |
|||
|
|||
```Python hl_lines="9" |
|||
{!> ../../../docs_src/header_params/tutorial001.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 and above" |
|||
|
|||
```Python hl_lines="7" |
|||
{!> ../../../docs_src/header_params/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
!!! note "Detalhes Técnicos" |
|||
`Header` é uma classe "irmã" de `Path`, `Query` e `Cookie`. Ela também herda da mesma classe em comum `Param`. |
|||
|
|||
Mas lembre-se que quando você importa `Query`, `Path`, `Header`, e outras de `fastapi`, elas são na verdade funções que retornam classes especiais. |
|||
|
|||
!!! info |
|||
Para declarar headers, você precisa usar `Header`, caso contrário, os parâmetros seriam interpretados como parâmetros de consulta. |
|||
|
|||
## Conversão automática |
|||
|
|||
`Header` tem algumas funcionalidades a mais em relação a `Path`, `Query` e `Cookie`. |
|||
|
|||
A maioria dos cabeçalhos padrão são separados pelo caractere "hífen", também conhecido como "sinal de menos" (`-`). |
|||
|
|||
Mas uma variável como `user-agent` é inválida em Python. |
|||
|
|||
Portanto, por padrão, `Header` converterá os caracteres de nomes de parâmetros de sublinhado (`_`) para hífen (`-`) para extrair e documentar os cabeçalhos. |
|||
|
|||
Além disso, os cabeçalhos HTTP não diferenciam maiúsculas de minúsculas, portanto, você pode declará-los com o estilo padrão do Python (também conhecido como "snake_case"). |
|||
|
|||
Portanto, você pode usar `user_agent` como faria normalmente no código Python, em vez de precisar colocar as primeiras letras em maiúsculas como `User_Agent` ou algo semelhante. |
|||
|
|||
Se por algum motivo você precisar desabilitar a conversão automática de sublinhados para hífens, defina o parâmetro `convert_underscores` de `Header` para `False`: |
|||
|
|||
=== "Python 3.6 and above" |
|||
|
|||
```Python hl_lines="10" |
|||
{!> ../../../docs_src/header_params/tutorial002.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 and above" |
|||
|
|||
```Python hl_lines="8" |
|||
{!> ../../../docs_src/header_params/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
!!! warning "Aviso" |
|||
Antes de definir `convert_underscores` como `False`, lembre-se de que alguns proxies e servidores HTTP não permitem o uso de cabeçalhos com sublinhados. |
|||
|
|||
## Cabeçalhos duplicados |
|||
|
|||
É possível receber cabeçalhos duplicados. Isso significa, o mesmo cabeçalho com vários valores. |
|||
|
|||
Você pode definir esses casos usando uma lista na declaração de tipo. |
|||
|
|||
Você receberá todos os valores do cabeçalho duplicado como uma `list` Python. |
|||
|
|||
Por exemplo, para declarar um cabeçalho de `X-Token` que pode aparecer mais de uma vez, você pode escrever: |
|||
|
|||
=== "Python 3.6 and above" |
|||
|
|||
```Python hl_lines="9" |
|||
{!> ../../../docs_src/header_params/tutorial003.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9 and above" |
|||
|
|||
```Python hl_lines="9" |
|||
{!> ../../../docs_src/header_params/tutorial003_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10 and above" |
|||
|
|||
```Python hl_lines="7" |
|||
{!> ../../../docs_src/header_params/tutorial003_py310.py!} |
|||
``` |
|||
|
|||
Se você se comunicar com essa *operação de caminho* enviando dois cabeçalhos HTTP como: |
|||
|
|||
``` |
|||
X-Token: foo |
|||
X-Token: bar |
|||
``` |
|||
|
|||
A resposta seria como: |
|||
|
|||
```JSON |
|||
{ |
|||
"X-Token values": [ |
|||
"bar", |
|||
"foo" |
|||
] |
|||
} |
|||
``` |
|||
|
|||
## Recapitulando |
|||
|
|||
Declare cabeçalhos com `Header`, usando o mesmo padrão comum que utiliza-se em `Query`, `Path` e `Cookie`. |
|||
|
|||
E não se preocupe com sublinhados em suas variáveis, FastAPI cuidará da conversão deles. |