@ -1,5 +0,0 @@ |
|||||
[flake8] |
|
||||
max-line-length = 88 |
|
||||
select = C,E,F,W,B,B9 |
|
||||
ignore = E203, E501, W503 |
|
||||
exclude = __init__.py |
|
@ -11,21 +11,26 @@ jobs: |
|||||
runs-on: ubuntu-latest |
runs-on: ubuntu-latest |
||||
steps: |
steps: |
||||
- uses: actions/checkout@v3 |
- uses: actions/checkout@v3 |
||||
|
- name: Clean site |
||||
|
run: | |
||||
|
rm -rf ./site |
||||
|
mkdir ./site |
||||
- name: Download Artifact Docs |
- name: Download Artifact Docs |
||||
uses: dawidd6/[email protected] |
uses: dawidd6/[email protected]4.2 |
||||
with: |
with: |
||||
github_token: ${{ secrets.GITHUB_TOKEN }} |
github_token: ${{ secrets.GITHUB_TOKEN }} |
||||
workflow: build-docs.yml |
workflow: build-docs.yml |
||||
run_id: ${{ github.event.workflow_run.id }} |
run_id: ${{ github.event.workflow_run.id }} |
||||
name: docs-zip |
name: docs-zip |
||||
|
path: ./site/ |
||||
- name: Unzip docs |
- name: Unzip docs |
||||
run: | |
run: | |
||||
rm -rf ./site |
cd ./site |
||||
unzip docs.zip |
unzip docs.zip |
||||
rm -f docs.zip |
rm -f docs.zip |
||||
- name: Deploy to Netlify |
- name: Deploy to Netlify |
||||
id: netlify |
id: netlify |
||||
uses: nwtgck/actions-netlify@v1.2.3 |
uses: nwtgck/actions-netlify@v2.0.0 |
||||
with: |
with: |
||||
publish-dir: './site' |
publish-dir: './site' |
||||
production-deploy: false |
production-deploy: false |
||||
|
@ -17,23 +17,23 @@ jobs: |
|||||
- name: Set up Python |
- name: Set up Python |
||||
uses: actions/setup-python@v4 |
uses: actions/setup-python@v4 |
||||
with: |
with: |
||||
python-version: "3.6" |
python-version: "3.7" |
||||
|
cache: "pip" |
||||
|
cache-dependency-path: pyproject.toml |
||||
- uses: actions/cache@v3 |
- uses: actions/cache@v3 |
||||
id: cache |
id: cache |
||||
with: |
with: |
||||
path: ${{ env.pythonLocation }} |
path: ${{ env.pythonLocation }} |
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish |
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish |
||||
- name: Install Flit |
- name: Install build dependencies |
||||
if: steps.cache.outputs.cache-hit != 'true' |
if: steps.cache.outputs.cache-hit != 'true' |
||||
run: pip install flit |
run: pip install build |
||||
- name: Install Dependencies |
- name: Build distribution |
||||
if: steps.cache.outputs.cache-hit != 'true' |
run: python -m build |
||||
run: flit install --symlink |
|
||||
- name: Publish |
- name: Publish |
||||
env: |
uses: pypa/[email protected] |
||||
FLIT_USERNAME: ${{ secrets.FLIT_USERNAME }} |
with: |
||||
FLIT_PASSWORD: ${{ secrets.FLIT_PASSWORD }} |
password: ${{ secrets.PYPI_API_TOKEN }} |
||||
run: bash scripts/publish.sh |
|
||||
- name: Dump GitHub context |
- name: Dump GitHub context |
||||
env: |
env: |
||||
GITHUB_CONTEXT: ${{ toJson(github) }} |
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/[email protected] |
||||
|
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://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://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 |
After Width: | Height: | Size: 34 KiB |
@ -0,0 +1,240 @@ |
|||||
|
# Réponses supplémentaires dans OpenAPI |
||||
|
|
||||
|
!!! Attention |
||||
|
Ceci concerne un sujet plutôt avancé. |
||||
|
|
||||
|
Si vous débutez avec **FastAPI**, vous n'en aurez peut-être pas besoin. |
||||
|
|
||||
|
Vous pouvez déclarer des réponses supplémentaires, avec des codes HTTP, des types de médias, des descriptions, etc. |
||||
|
|
||||
|
Ces réponses supplémentaires seront incluses dans le schéma OpenAPI, elles apparaîtront donc également dans la documentation de l'API. |
||||
|
|
||||
|
Mais pour ces réponses supplémentaires, vous devez vous assurer de renvoyer directement une `Response` comme `JSONResponse`, avec votre code HTTP et votre contenu. |
||||
|
|
||||
|
## Réponse supplémentaire avec `model` |
||||
|
|
||||
|
Vous pouvez ajouter à votre décorateur de *paramètre de chemin* un paramètre `responses`. |
||||
|
|
||||
|
Il prend comme valeur un `dict` dont les clés sont des codes HTTP pour chaque réponse, comme `200`, et la valeur de ces clés sont d'autres `dict` avec des informations pour chacun d'eux. |
||||
|
|
||||
|
Chacun de ces `dict` de réponse peut avoir une clé `model`, contenant un modèle Pydantic, tout comme `response_model`. |
||||
|
|
||||
|
**FastAPI** prendra ce modèle, générera son schéma JSON et l'inclura au bon endroit dans OpenAPI. |
||||
|
|
||||
|
Par exemple, pour déclarer une autre réponse avec un code HTTP `404` et un modèle Pydantic `Message`, vous pouvez écrire : |
||||
|
|
||||
|
```Python hl_lines="18 22" |
||||
|
{!../../../docs_src/additional_responses/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! Remarque |
||||
|
Gardez à l'esprit que vous devez renvoyer directement `JSONResponse`. |
||||
|
|
||||
|
!!! Info |
||||
|
La clé `model` ne fait pas partie d'OpenAPI. |
||||
|
|
||||
|
**FastAPI** prendra le modèle Pydantic à partir de là, générera le `JSON Schema` et le placera au bon endroit. |
||||
|
|
||||
|
Le bon endroit est : |
||||
|
|
||||
|
* Dans la clé `content`, qui a pour valeur un autre objet JSON (`dict`) qui contient : |
||||
|
* Une clé avec le type de support, par ex. `application/json`, qui contient comme valeur un autre objet JSON, qui contient : |
||||
|
* Une clé `schema`, qui a pour valeur le schéma JSON du modèle, voici le bon endroit. |
||||
|
* **FastAPI** ajoute ici une référence aux schémas JSON globaux à un autre endroit de votre OpenAPI au lieu de l'inclure directement. De cette façon, d'autres applications et clients peuvent utiliser ces schémas JSON directement, fournir de meilleurs outils de génération de code, etc. |
||||
|
|
||||
|
Les réponses générées au format OpenAPI pour cette *opération de chemin* seront : |
||||
|
|
||||
|
```JSON hl_lines="3-12" |
||||
|
{ |
||||
|
"responses": { |
||||
|
"404": { |
||||
|
"description": "Additional Response", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/Message" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"200": { |
||||
|
"description": "Successful Response", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/Item" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"422": { |
||||
|
"description": "Validation Error", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/HTTPValidationError" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Les schémas sont référencés à un autre endroit du modèle OpenAPI : |
||||
|
|
||||
|
```JSON hl_lines="4-16" |
||||
|
{ |
||||
|
"components": { |
||||
|
"schemas": { |
||||
|
"Message": { |
||||
|
"title": "Message", |
||||
|
"required": [ |
||||
|
"message" |
||||
|
], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"message": { |
||||
|
"title": "Message", |
||||
|
"type": "string" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"Item": { |
||||
|
"title": "Item", |
||||
|
"required": [ |
||||
|
"id", |
||||
|
"value" |
||||
|
], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"id": { |
||||
|
"title": "Id", |
||||
|
"type": "string" |
||||
|
}, |
||||
|
"value": { |
||||
|
"title": "Value", |
||||
|
"type": "string" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"ValidationError": { |
||||
|
"title": "ValidationError", |
||||
|
"required": [ |
||||
|
"loc", |
||||
|
"msg", |
||||
|
"type" |
||||
|
], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"loc": { |
||||
|
"title": "Location", |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"type": "string" |
||||
|
} |
||||
|
}, |
||||
|
"msg": { |
||||
|
"title": "Message", |
||||
|
"type": "string" |
||||
|
}, |
||||
|
"type": { |
||||
|
"title": "Error Type", |
||||
|
"type": "string" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"HTTPValidationError": { |
||||
|
"title": "HTTPValidationError", |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"detail": { |
||||
|
"title": "Detail", |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"$ref": "#/components/schemas/ValidationError" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Types de médias supplémentaires pour la réponse principale |
||||
|
|
||||
|
Vous pouvez utiliser ce même paramètre `responses` pour ajouter différents types de médias pour la même réponse principale. |
||||
|
|
||||
|
Par exemple, vous pouvez ajouter un type de média supplémentaire `image/png`, en déclarant que votre *opération de chemin* peut renvoyer un objet JSON (avec le type de média `application/json`) ou une image PNG : |
||||
|
|
||||
|
```Python hl_lines="19-24 28" |
||||
|
{!../../../docs_src/additional_responses/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! Remarque |
||||
|
Notez que vous devez retourner l'image en utilisant directement un `FileResponse`. |
||||
|
|
||||
|
!!! Info |
||||
|
À moins que vous ne spécifiiez explicitement un type de média différent dans votre paramètre `responses`, FastAPI supposera que la réponse a le même type de média que la classe de réponse principale (par défaut `application/json`). |
||||
|
|
||||
|
Mais si vous avez spécifié une classe de réponse personnalisée avec `None` comme type de média, FastAPI utilisera `application/json` pour toute réponse supplémentaire associée à un modèle. |
||||
|
|
||||
|
## Combinaison d'informations |
||||
|
|
||||
|
Vous pouvez également combiner des informations de réponse provenant de plusieurs endroits, y compris les paramètres `response_model`, `status_code` et `responses`. |
||||
|
|
||||
|
Vous pouvez déclarer un `response_model`, en utilisant le code HTTP par défaut `200` (ou un code personnalisé si vous en avez besoin), puis déclarer des informations supplémentaires pour cette même réponse dans `responses`, directement dans le schéma OpenAPI. |
||||
|
|
||||
|
**FastAPI** conservera les informations supplémentaires des `responses` et les combinera avec le schéma JSON de votre modèle. |
||||
|
|
||||
|
Par exemple, vous pouvez déclarer une réponse avec un code HTTP `404` qui utilise un modèle Pydantic et a une `description` personnalisée. |
||||
|
|
||||
|
Et une réponse avec un code HTTP `200` qui utilise votre `response_model`, mais inclut un `example` personnalisé : |
||||
|
|
||||
|
```Python hl_lines="20-31" |
||||
|
{!../../../docs_src/additional_responses/tutorial003.py!} |
||||
|
``` |
||||
|
|
||||
|
Tout sera combiné et inclus dans votre OpenAPI, et affiché dans la documentation de l'API : |
||||
|
|
||||
|
<img src="/img/tutorial/additional-responses/image01.png"> |
||||
|
|
||||
|
## Combinez les réponses prédéfinies et les réponses personnalisées |
||||
|
|
||||
|
Vous voulez peut-être avoir des réponses prédéfinies qui s'appliquent à de nombreux *paramètre de chemin*, mais vous souhaitez les combiner avec des réponses personnalisées nécessaires à chaque *opération de chemin*. |
||||
|
|
||||
|
Dans ces cas, vous pouvez utiliser la technique Python "d'affection par décomposition" (appelé _unpacking_ en anglais) d'un `dict` avec `**dict_to_unpack` : |
||||
|
|
||||
|
``` Python |
||||
|
old_dict = { |
||||
|
"old key": "old value", |
||||
|
"second old key": "second old value", |
||||
|
} |
||||
|
new_dict = {**old_dict, "new key": "new value"} |
||||
|
``` |
||||
|
|
||||
|
Ici, `new_dict` contiendra toutes les paires clé-valeur de `old_dict` plus la nouvelle paire clé-valeur : |
||||
|
|
||||
|
``` Python |
||||
|
{ |
||||
|
"old key": "old value", |
||||
|
"second old key": "second old value", |
||||
|
"new key": "new value", |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Vous pouvez utiliser cette technique pour réutiliser certaines réponses prédéfinies dans vos *paramètres de chemin* et les combiner avec des réponses personnalisées supplémentaires. |
||||
|
|
||||
|
Par exemple: |
||||
|
|
||||
|
```Python hl_lines="13-17 26" |
||||
|
{!../../../docs_src/additional_responses/tutorial004.py!} |
||||
|
``` |
||||
|
|
||||
|
## Plus d'informations sur les réponses OpenAPI |
||||
|
|
||||
|
Pour voir exactement ce que vous pouvez inclure dans les réponses, vous pouvez consulter ces sections dans la spécification OpenAPI : |
||||
|
|
||||
|
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject" class="external-link" target="_blank">Objet Responses de OpenAPI </a>, il inclut le `Response Object`. |
||||
|
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject" class="external-link" target="_blank">Objet Response de OpenAPI </a>, vous pouvez inclure n'importe quoi directement dans chaque réponse à l'intérieur de votre paramètre `responses`. Y compris `description`, `headers`, `content` (à l'intérieur de cela, vous déclarez différents types de médias et schémas JSON) et `links`. |
@ -0,0 +1,37 @@ |
|||||
|
# Codes HTTP supplémentaires |
||||
|
|
||||
|
Par défaut, **FastAPI** renverra les réponses à l'aide d'une structure de données `JSONResponse`, en plaçant la réponse de votre *chemin d'accès* à l'intérieur de cette `JSONResponse`. |
||||
|
|
||||
|
Il utilisera le code HTTP par défaut ou celui que vous avez défini dans votre *chemin d'accès*. |
||||
|
|
||||
|
## Codes HTTP supplémentaires |
||||
|
|
||||
|
Si vous souhaitez renvoyer des codes HTTP supplémentaires en plus du code principal, vous pouvez le faire en renvoyant directement une `Response`, comme une `JSONResponse`, et en définissant directement le code HTTP supplémentaire. |
||||
|
|
||||
|
Par exemple, disons que vous voulez avoir un *chemin d'accès* qui permet de mettre à jour les éléments et renvoie les codes HTTP 200 "OK" en cas de succès. |
||||
|
|
||||
|
Mais vous voulez aussi qu'il accepte de nouveaux éléments. Et lorsque les éléments n'existaient pas auparavant, il les crée et renvoie un code HTTP de 201 "Créé". |
||||
|
|
||||
|
Pour y parvenir, importez `JSONResponse` et renvoyez-y directement votre contenu, en définissant le `status_code` que vous souhaitez : |
||||
|
|
||||
|
```Python hl_lines="4 25" |
||||
|
{!../../../docs_src/additional_status_codes/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! Attention |
||||
|
Lorsque vous renvoyez une `Response` directement, comme dans l'exemple ci-dessus, elle sera renvoyée directement. |
||||
|
|
||||
|
Elle ne sera pas sérialisée avec un modèle. |
||||
|
|
||||
|
Assurez-vous qu'il contient les données souhaitées et que les valeurs soient dans un format JSON valides (si vous utilisez une `JSONResponse`). |
||||
|
|
||||
|
!!! note "Détails techniques" |
||||
|
Vous pouvez également utiliser `from starlette.responses import JSONResponse`. |
||||
|
|
||||
|
Pour plus de commodités, **FastAPI** fournit les objets `starlette.responses` sous forme d'un alias accessible par `fastapi.responses`. Mais la plupart des réponses disponibles proviennent directement de Starlette. Il en est de même avec l'objet `statut`. |
||||
|
|
||||
|
## Documents OpenAPI et API |
||||
|
|
||||
|
Si vous renvoyez directement des codes HTTP et des réponses supplémentaires, ils ne seront pas inclus dans le schéma OpenAPI (la documentation de l'API), car FastAPI n'a aucun moyen de savoir à l'avance ce que vous allez renvoyer. |
||||
|
|
||||
|
Mais vous pouvez documenter cela dans votre code, en utilisant : [Réponses supplémentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}. |
@ -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,186 @@ |
|||||
|
# WebSocket |
||||
|
|
||||
|
**FastAPI**で<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSocket</a>が使用できます。 |
||||
|
|
||||
|
## `WebSockets`のインストール |
||||
|
|
||||
|
まず `WebSockets`のインストールが必要です。 |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install websockets |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## WebSocket クライアント |
||||
|
|
||||
|
### 本番環境 |
||||
|
|
||||
|
本番環境では、React、Vue.js、Angularなどの最新のフレームワークで作成されたフロントエンドを使用しているでしょう。 |
||||
|
|
||||
|
そして、バックエンドとWebSocketを使用して通信するために、おそらくフロントエンドのユーティリティを使用することになるでしょう。 |
||||
|
|
||||
|
または、ネイティブコードでWebSocketバックエンドと直接通信するネイティブモバイルアプリケーションがあるかもしれません。 |
||||
|
|
||||
|
他にも、WebSocketのエンドポイントと通信する方法があるかもしれません。 |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
ただし、この例では非常にシンプルなHTML文書といくつかのJavaScriptを、すべてソースコードの中に入れて使用することにします。 |
||||
|
|
||||
|
もちろん、これは最適な方法ではありませんし、本番環境で使うことはないでしょう。 |
||||
|
|
||||
|
本番環境では、上記の方法のいずれかの選択肢を採用することになるでしょう。 |
||||
|
|
||||
|
しかし、これはWebSocketのサーバーサイドに焦点を当て、実用的な例を示す最も簡単な方法です。 |
||||
|
|
||||
|
```Python hl_lines="2 6-38 41-43" |
||||
|
{!../../../docs_src/websockets/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
## `websocket` を作成する |
||||
|
|
||||
|
**FastAPI** アプリケーションで、`websocket` を作成します。 |
||||
|
|
||||
|
```Python hl_lines="1 46-47" |
||||
|
{!../../../docs_src/websockets/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! note "技術詳細" |
||||
|
`from starlette.websockets import WebSocket` を使用しても構いません. |
||||
|
|
||||
|
**FastAPI** は開発者の利便性のために、同じ `WebSocket` を提供します。しかし、こちらはStarletteから直接提供されるものです。 |
||||
|
|
||||
|
## メッセージの送受信 |
||||
|
|
||||
|
WebSocketルートでは、 `await` を使ってメッセージの送受信ができます。 |
||||
|
|
||||
|
```Python hl_lines="48-52" |
||||
|
{!../../../docs_src/websockets/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
バイナリやテキストデータ、JSONデータを送受信できます。 |
||||
|
|
||||
|
## 試してみる |
||||
|
|
||||
|
ファイル名が `main.py` である場合、以下の方法でアプリケーションを実行します。 |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --reload |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
ブラウザで <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> を開きます。 |
||||
|
|
||||
|
次のようなシンプルなページが表示されます。 |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image01.png"> |
||||
|
|
||||
|
入力ボックスにメッセージを入力して送信できます。 |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image02.png"> |
||||
|
|
||||
|
そして、 WebSocketを使用した**FastAPI**アプリケーションが応答します。 |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image03.png"> |
||||
|
|
||||
|
複数のメッセージを送信(および受信)できます。 |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image04.png"> |
||||
|
|
||||
|
そして、これらの通信はすべて同じWebSocket接続を使用します。 |
||||
|
|
||||
|
## 依存関係 |
||||
|
|
||||
|
WebSocketエンドポイントでは、`fastapi` から以下をインポートして使用できます。 |
||||
|
|
||||
|
* `Depends` |
||||
|
* `Security` |
||||
|
* `Cookie` |
||||
|
* `Header` |
||||
|
* `Path` |
||||
|
* `Query` |
||||
|
|
||||
|
これらは、他のFastAPI エンドポイント/*path operation* の場合と同じように機能します。 |
||||
|
|
||||
|
```Python hl_lines="58-65 68-83" |
||||
|
{!../../../docs_src/websockets/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! info "情報" |
||||
|
WebSocket で `HTTPException` を発生させることはあまり意味がありません。したがって、WebSocketの接続を直接閉じる方がよいでしょう。 |
||||
|
|
||||
|
クロージングコードは、<a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">仕様で定義された有効なコード</a>の中から使用することができます。 |
||||
|
|
||||
|
将来的には、どこからでも `raise` できる `WebSocketException` が用意され、専用の例外ハンドラを追加できるようになる予定です。これは、Starlette の <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> に依存するものです。 |
||||
|
|
||||
|
### 依存関係を用いてWebSocketsを試してみる |
||||
|
|
||||
|
ファイル名が `main.py` である場合、以下の方法でアプリケーションを実行します。 |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --reload |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
ブラウザで <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> を開きます。 |
||||
|
|
||||
|
クライアントが設定できる項目は以下の通りです。 |
||||
|
|
||||
|
* パスで使用される「Item ID」 |
||||
|
* クエリパラメータとして使用される「Token」 |
||||
|
|
||||
|
!!! tip "豆知識" |
||||
|
クエリ `token` は依存パッケージによって処理されることに注意してください。 |
||||
|
|
||||
|
これにより、WebSocketに接続してメッセージを送受信できます。 |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image05.png"> |
||||
|
|
||||
|
## 切断や複数クライアントへの対応 |
||||
|
|
||||
|
WebSocket接続が閉じられると、 `await websocket.receive_text()` は例外 `WebSocketDisconnect` を発生させ、この例のようにキャッチして処理することができます。 |
||||
|
|
||||
|
```Python hl_lines="81-83" |
||||
|
{!../../../docs_src/websockets/tutorial003.py!} |
||||
|
``` |
||||
|
|
||||
|
試してみるには、 |
||||
|
|
||||
|
* いくつかのブラウザタブでアプリを開きます。 |
||||
|
* それらのタブでメッセージを記入してください。 |
||||
|
* そして、タブのうち1つを閉じてください。 |
||||
|
|
||||
|
これにより例外 `WebSocketDisconnect` が発生し、他のすべてのクライアントは次のようなメッセージを受信します。 |
||||
|
|
||||
|
``` |
||||
|
Client #1596980209979 left the chat |
||||
|
``` |
||||
|
|
||||
|
!!! tip "豆知識" |
||||
|
上記のアプリは、複数の WebSocket 接続に対してメッセージを処理し、ブロードキャストする方法を示すための最小限のシンプルな例です。 |
||||
|
|
||||
|
しかし、すべての接続がメモリ内の単一のリストで処理されるため、プロセスの実行中にのみ機能し、単一のプロセスでのみ機能することに注意してください。 |
||||
|
|
||||
|
もしFastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、<a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a> を確認してください。 |
||||
|
|
||||
|
## その他のドキュメント |
||||
|
|
||||
|
オプションの詳細については、Starletteのドキュメントを確認してください。 |
||||
|
|
||||
|
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank"> `WebSocket` クラス</a> |
||||
|
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">クラスベースのWebSocket処理</a> |