@ -0,0 +1,4 @@ |
|||
PyGithub |
|||
pydantic>=2.5.3,<3.0.0 |
|||
pydantic-settings>=2.1.0,<3.0.0 |
|||
httpx |
@ -15,7 +15,7 @@ jobs: |
|||
run: echo "$GITHUB_CONTEXT" |
|||
- uses: actions/checkout@v4 |
|||
- name: Set up Python |
|||
uses: actions/setup-python@v4 |
|||
uses: actions/setup-python@v5 |
|||
with: |
|||
python-version: "3.10" |
|||
# Issue ref: https://github.com/actions/setup-python/issues/436 |
|||
@ -32,7 +32,7 @@ jobs: |
|||
- name: Build distribution |
|||
run: python -m build |
|||
- name: Publish |
|||
uses: pypa/[email protected]0 |
|||
uses: pypa/[email protected]1 |
|||
with: |
|||
password: ${{ secrets.PYPI_API_TOKEN }} |
|||
- name: Dump GitHub context |
|||
|
@ -0,0 +1,469 @@ |
|||
<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, yüksək məshuldarlı, öyrənməsi asan, çevik kodlama, istifadəyə hazırdır</em> |
|||
</p> |
|||
<p align="center"> |
|||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank"> |
|||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test"> |
|||
</a> |
|||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi" target="_blank"> |
|||
<img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi.svg" alt="Əhatə"> |
|||
</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="Paket versiyası"> |
|||
</a> |
|||
<a href="https://pypi.org/project/fastapi" target="_blank"> |
|||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Dəstəklənən Python versiyaları"> |
|||
</a> |
|||
</p> |
|||
|
|||
--- |
|||
|
|||
**Sənədlər**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a> |
|||
|
|||
**Qaynaq Kodu**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a> |
|||
|
|||
--- |
|||
|
|||
FastAPI Python 3.8+ ilə API yaratmaq üçün standart Python <abbr title="Tip Məsləhətləri: Type Hints">tip məsləhətlərinə</abbr> əsaslanan, müasir, sürətli (yüksək performanslı) framework-dür. |
|||
|
|||
Əsas xüsusiyyətləri bunlardır: |
|||
|
|||
* **Sürətli**: Çox yüksək performans, **NodeJS** və **Go** səviyyəsində (Starlette və Pydantic-ə təşəkkürlər). [Ən sürətli Python frameworklərindən biridir](#performans). |
|||
* **Çevik kodlama**: Funksiyanallıqları inkişaf etdirmək sürətini təxminən 200%-dən 300%-ə qədər artırın. * |
|||
* **Daha az xəta**: İnsan (developer) tərəfindən törədilən səhvlərin təxminən 40% -ni azaldın. * |
|||
* **İntuitiv**: Əla redaktor dəstəyi. Hər yerdə <abbr title="auto-complete, autocompletion, IntelliSense olaraq da bilinir">otomatik tamamlama</abbr>. Xətaları müəyyənləşdirməyə daha az vaxt sərf edəcəksiniz. |
|||
* **Asan**: İstifadəsi və öyrənilməsi asan olması üçün nəzərdə tutulmuşdur. Sənədləri oxumaq üçün daha az vaxt ayıracaqsınız. |
|||
* **Qısa**: Kod təkrarlanmasını minimuma endirin. Hər bir parametr tərifində birdən çox xüsusiyyət ilə və daha az səhvlə qarşılaşacaqsınız. |
|||
* **Güclü**: Avtomatik və interaktiv sənədlərlə birlikdə istifadəyə hazır kod əldə edə bilərsiniz. |
|||
* **Standartlara əsaslanan**: API-lar üçün açıq standartlara əsaslanır (və tam uyğun gəlir): <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (əvvəlki adı ilə Swagger) və <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>. |
|||
|
|||
<small>* Bu fikirlər daxili development komandasının hazırladıqları məhsulların sınaqlarına əsaslanır.</small> |
|||
|
|||
## Sponsorlar |
|||
|
|||
<!-- 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/az/fastapi-people/#sponsors" class="external-link" target="_blank">Digər sponsorlar</a> |
|||
|
|||
## Rəylər |
|||
|
|||
"_[...] Son günlərdə **FastAPI**-ı çox istifadə edirəm. [...] Əslində onu komandamın bütün **Microsoftda ML sevislərində** istifadə etməyi planlayıram. Onların bəziləri **windows**-un əsas məhsuluna və bəzi **Office** məhsullarına inteqrasiya olunurlar._" |
|||
|
|||
<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> |
|||
|
|||
--- |
|||
|
|||
"_**FastAPI** kitabxanasını **Proqnozlar** əldə etmək üçün sorğulana bilən **REST** serverini yaratmaqda istifadə etdik._" |
|||
|
|||
<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** **böhran idarəçiliyi** orkestrləşmə framework-nün açıq qaynaqlı buraxılışını elan etməkdən məmnundur: **Dispatch**! [**FastAPI** ilə quruldu]_" |
|||
|
|||
<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> |
|||
|
|||
--- |
|||
|
|||
"_**FastAPI** üçün həyəcanlıyam. Çox əyləncəlidir!_" |
|||
|
|||
<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> |
|||
|
|||
--- |
|||
|
|||
"_Düzünü desəm, sizin qurduğunuz şey həqiqətən möhkəm və peşəkar görünür. Bir çox cəhətdən **Hug**-un olmasını istədiyim kimdir - kiminsə belə bir şey qurduğunu görmək həqiqətən ruhlandırıcıdır._" |
|||
|
|||
<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> |
|||
|
|||
--- |
|||
|
|||
"_Əgər REST API-lər yaratmaq üçün **müasir framework** öyrənmək istəyirsinizsə, **FastAPI**-a baxın [...] Sürətli, istifadəsi və öyrənməsi asandır. [...]_" |
|||
|
|||
"_**API** xidmətlərimizi **FastAPI**-a köçürdük [...] Sizin də bəyənəcəyinizi düşünürük._" |
|||
|
|||
<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> |
|||
|
|||
--- |
|||
|
|||
"_Python ilə istifadəyə hazır API qurmaq istəyən hər kəsə **FastAPI**-ı tövsiyə edirəm. **Möhtəşəm şəkildə dizayn edilmiş**, **istifadəsi asan** və **yüksək dərəcədə genişlənə bilən**-dir, API əsaslı inkişaf strategiyamızın **əsas komponentinə** çevrilib və Virtual TAC Engineer kimi bir çox avtomatlaşdırma və servisləri idarə edir._" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div> |
|||
|
|||
--- |
|||
|
|||
## **Typer**, CLI-ların FastAPI-ı |
|||
|
|||
<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> |
|||
|
|||
Əgər siz veb API əvəzinə terminalda istifadə ediləcək <abbr title="Command Line Interface">CLI</abbr> proqramı qurursunuzsa, <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>-a baxa bilərsiniz. |
|||
|
|||
**Typer** FastAPI-ın kiçik qardaşıdır. Və o, CLI-lərin **FastAPI**-ı olmaq üçün nəzərdə tutulub. ⌨️ 🚀 |
|||
|
|||
## Tələblər |
|||
|
|||
Python 3.8+ |
|||
|
|||
FastAPI nəhənglərin çiyinlərində dayanır: |
|||
|
|||
* Web tərəfi üçün <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a>. |
|||
* Data tərəfi üçün <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>. |
|||
|
|||
## Quraşdırma |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install fastapi |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
Tətbiqimizi əlçatan etmək üçün bizə <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> və ya <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a> kimi ASGI server lazımdır. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "uvicorn[standard]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## Nümunə |
|||
|
|||
### Kodu yaradaq |
|||
|
|||
* `main.py` adlı fayl yaradaq və ona aşağıdakı kodu yerləşdirək: |
|||
|
|||
```Python |
|||
from typing import Union |
|||
|
|||
from fastapi import FastAPI |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/") |
|||
def read_root(): |
|||
return {"Hello": "World"} |
|||
|
|||
|
|||
@app.get("/items/{item_id}") |
|||
def read_item(item_id: int, q: Union[str, None] = None): |
|||
return {"item_id": item_id, "q": q} |
|||
``` |
|||
|
|||
<details markdown="1"> |
|||
<summary>Və ya <code>async def</code>...</summary> |
|||
|
|||
Əgər kodunuzda `async` və ya `await` vardırsa `async def` istifadə edə bilərik: |
|||
|
|||
```Python hl_lines="9 14" |
|||
from typing import Union |
|||
|
|||
from fastapi import FastAPI |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/") |
|||
async def read_root(): |
|||
return {"Hello": "World"} |
|||
|
|||
|
|||
@app.get("/items/{item_id}") |
|||
async def read_item(item_id: int, q: Union[str, None] = None): |
|||
return {"item_id": item_id, "q": q} |
|||
``` |
|||
|
|||
**Qeyd**: |
|||
|
|||
Əgər bu mövzu haqqında məlumatınız yoxdursa <a href="https://fastapi.tiangolo.com/az/async/#in-a-hurry" target="_blank">`async` və `await` sənədindəki</a> _"Tələsirsən?"_ bölməsinə baxa bilərsiniz. |
|||
|
|||
</details> |
|||
|
|||
### Kodu işə salaq |
|||
|
|||
Serveri aşağıdakı əmr ilə işə salaq: |
|||
|
|||
<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><code>uvicorn main:app --reload</code> əmri haqqında...</summary> |
|||
|
|||
`uvicorn main:app` əmri aşağıdakılara instinad edir: |
|||
|
|||
* `main`: `main.py` faylı (yəni Python "modulu"). |
|||
* `app`: `main.py` faylında `app = FastAPI()` sətrində yaratdığımız `FastAPI` obyektidir. |
|||
* `--reload`: kod dəyişikliyindən sonra avtomatik olaraq serveri yenidən işə salır. Bu parametrdən yalnız development mərhələsində istifadə etməliyik. |
|||
|
|||
</details> |
|||
|
|||
### İndi yoxlayaq |
|||
|
|||
Bu linki brauzerimizdə açaq <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>. |
|||
|
|||
Aşağıdakı kimi bir JSON cavabı görəcəksiniz: |
|||
|
|||
```JSON |
|||
{"item_id": 5, "q": "somequery"} |
|||
``` |
|||
|
|||
Siz artıq bir API yaratmısınız, hansı ki: |
|||
|
|||
* `/` və `/items/{item_id}` <abbr title="Yol: Path ">_yollarında_</abbr> HTTP sorğularını qəbul edir. |
|||
* Hər iki _yolda_ `GET` <em>əməliyyatlarını</em> (həmçinin HTTP _metodları_ kimi bilinir) aparır. |
|||
* `/items/{item_id}` _yolu_ `item_id` adlı `int` qiyməti almalı olan _yol parametrinə_ sahibdir. |
|||
* `/items/{item_id}` _yolunun_ `q` adlı yol parametri var və bu parametr istəyə bağlı olsa da, `str` qiymətini almalıdır. |
|||
|
|||
### İnteraktiv API Sənədləri |
|||
|
|||
İndi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> ünvanına daxil olun. |
|||
|
|||
Avtomatik interaktiv API sənədlərini görəcəksiniz (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tərəfindən təmin edilir): |
|||
|
|||
 |
|||
|
|||
### Alternativ API sənədləri |
|||
|
|||
İndi isə <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> ünvanına daxil olun. |
|||
|
|||
<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tərəfindən təqdim edilən avtomatik sənədləri görəcəksiniz: |
|||
|
|||
 |
|||
|
|||
## Nümunəni Yeniləyək |
|||
|
|||
İndi gəlin `main.py` faylını `PUT` sorğusu ilə birlikdə <abbr title="Gövdə: Body ">gövdə</abbr> qəbul edəcək şəkildə dəyişdirək. |
|||
|
|||
Pydantic sayəsində standart Python tiplərindən istifadə edərək <abbr title="Gövdə: Body ">gövdə</abbr>ni müəyyən edək. |
|||
|
|||
```Python hl_lines="4 9-12 25-27" |
|||
from typing import Union |
|||
|
|||
from fastapi import FastAPI |
|||
from pydantic import BaseModel |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
class Item(BaseModel): |
|||
name: str |
|||
price: float |
|||
is_offer: Union[bool, None] = None |
|||
|
|||
|
|||
@app.get("/") |
|||
def read_root(): |
|||
return {"Hello": "World"} |
|||
|
|||
|
|||
@app.get("/items/{item_id}") |
|||
def read_item(item_id: int, q: Union[str, None] = None): |
|||
return {"item_id": item_id, "q": q} |
|||
|
|||
|
|||
@app.put("/items/{item_id}") |
|||
def update_item(item_id: int, item: Item): |
|||
return {"item_name": item.name, "item_id": item_id} |
|||
``` |
|||
Server avtomatik olaraq yenidən işə salınmalı idi (çünki biz yuxarıda `uvicorn` əmri ilə `--reload` parametrindən istifadə etmişik). |
|||
|
|||
### İnteraktiv API sənədlərindəki dəyişikliyə baxaq |
|||
|
|||
Yenidən <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> ünvanına daxil olun. |
|||
|
|||
* İnteraktiv API sənədləri yeni gövdə də daxil olmaq ilə avtomatik olaraq yenilənəcək: |
|||
|
|||
 |
|||
|
|||
* "Try it out" düyməsini klikləyin, bu, parametrləri doldurmağa və API ilə birbaşa əlaqə saxlamağa imkan verir: |
|||
|
|||
 |
|||
|
|||
* Sonra "Execute" düyməsini klikləyin, istifadəçi interfeysi API ilə əlaqə quracaq, parametrləri göndərəcək, nəticələri əldə edəcək və onları ekranda göstərəcək: |
|||
|
|||
 |
|||
|
|||
### Alternativ API Sənədlərindəki Dəyişikliyə Baxaq |
|||
|
|||
İndi isə yenidən <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> ünvanına daxil olun. |
|||
|
|||
* Alternativ sənədlər həm də yeni sorğu parametri və gövdəsini əks etdirəcək: |
|||
|
|||
 |
|||
|
|||
### Xülasə |
|||
|
|||
Ümumiləşdirsək, parametrlər, gövdə və s. Biz məlumat növlərini **bir dəfə** funksiya parametrləri kimi təyin edirik. |
|||
|
|||
Bunu standart müasir Python tipləri ilə edirsiniz. |
|||
|
|||
Yeni sintaksis, müəyyən bir kitabxananın metodlarını və ya siniflərini və s. öyrənmək məcburiyyətində deyilsiniz. |
|||
|
|||
Sadəcə standart **Python 3.8+**. |
|||
|
|||
Məsələn, `int` üçün: |
|||
|
|||
```Python |
|||
item_id: int |
|||
``` |
|||
|
|||
və ya daha mürəkkəb `Item` modeli üçün: |
|||
|
|||
```Python |
|||
item: Item |
|||
``` |
|||
|
|||
...və yalnız parametr tipini təyin etməklə bunları əldə edirsiniz: |
|||
|
|||
* Redaktor dəstəyi ilə: |
|||
* Avtomatik tamamlama. |
|||
* Tip yoxlanması. |
|||
* Məlumatların Təsdiqlənməsi: |
|||
* Məlumat etibarsız olduqda avtomatik olaraq aydın xətalar göstərir. |
|||
* Hətta çox dərin JSON obyektlərində belə doğrulama aparır. |
|||
* Daxil olan məlumatları <abbr title="Çevrilmə: serialization, parsing, marshalling olaraq da bilinir">çevirmək</abbr> üçün aşağıdakı məlumat növlərindən istifadə edilir: |
|||
* JSON. |
|||
* <abbr title="Yol: Path">Yol</abbr> parametrləri. |
|||
* <abbr title="Sorğu: Query">Sorğu</abbr> parametrləri. |
|||
* <abbr title="Çərəz: Cookie">Çərəzlər</abbr>. |
|||
* <abbr title="Başlıq: Header">Başlıqlaq</abbr>. |
|||
* <abbr title="Forma: Form">Formalar</abbr>. |
|||
* Fayllar. |
|||
* Daxil olan məlumatları <abbr title="Çevrilmə: serialization, parsing, marshalling olaraq da bilinir">çevirmək</abbr> üçün aşağıdakı məlumat növlərindən istifadə edilir (JSON olaraq): |
|||
* Python tiplərinin (`str`, `int`, `float`, `bool`, `list`, və s) çevrilməsi. |
|||
* `datetime` obyektləri. |
|||
* `UUID` obyektləri. |
|||
* Verilənlər bazası modelləri. |
|||
* və daha çoxu... |
|||
* 2 alternativ istifadəçi interfeysi daxil olmaqla avtomatik interaktiv API sənədlərini təmin edir: |
|||
* Swagger UI. |
|||
* ReDoc. |
|||
|
|||
--- |
|||
|
|||
Gəlin əvvəlki nümunəyə qayıdaq və **FastAPI**-nin nələr edəcəyinə nəzər salaq: |
|||
|
|||
* `GET` və `PUT` sorğuları üçün `item_id`-nin <abbr title="Yol: Path">yolda</abbr> olub-olmadığını yoxlayacaq. |
|||
* `item_id`-nin `GET` və `PUT` sorğuları üçün növünün `int` olduğunu yoxlayacaq. |
|||
* Əgər `int` deyilsə, səbəbini göstərən bir xəta mesajı göstərəcəkdir. |
|||
* <abbr title="Məcburi olmayan: Optional">məcburi olmayan</abbr> `q` parametrinin `GET` (`http://127.0.0.1:8000/items/foo?q=somequery` burdakı kimi) sorğusu içərisində olub olmadığını yoxlayacaq. |
|||
* `q` parametrini `= None` ilə yaratdığımız üçün, <abbr title="Məcburi olmayan: Optional">məcburi olmayan</abbr> parametr olacaq. |
|||
* Əgər `None` olmasaydı, bu məcburi parametr olardı (`PUT` metodunun gövdəsində olduğu kimi). |
|||
* `PUT` sorğusu üçün, `/items/{item_id}` gövdəsini JSON olaraq oxuyacaq: |
|||
* `name` adında məcburi bir parametr olub olmadığını və əgər varsa, tipinin `str` olub olmadığını yoxlayacaq. |
|||
* `price` adında məcburi bir parametr olub olmadığını və əgər varsa, tipinin `float` olub olmadığını yoxlayacaq. |
|||
* `is_offer` adında <abbr title="Məcburi olmayan: Optional">məcburi olmayan</abbr> bir parametr olub olmadığını və əgər varsa, tipinin `float` olub olmadığını yoxlayacaq. |
|||
* Bütün bunlar ən dərin JSON obyektlərində belə işləyəcək. |
|||
* Məlumatların JSON-a və JSON-un Python obyektinə çevrilməsi avtomatik həyata keçiriləcək. |
|||
* Hər şeyi OpenAPI ilə uyğun olacaq şəkildə avtomatik olaraq sənədləşdirəcək və onları aşağıdakı kimi istifadə edə biləcək: |
|||
* İnteraktiv sənədləşmə sistemləri. |
|||
* Bir çox proqramlaşdırma dilləri üçün avtomatlaşdırılmış <abbr title="Müştəri: Client">müştəri</abbr> kodu yaratma sistemləri. |
|||
* 2 interaktiv sənədləşmə veb interfeysini birbaşa təmin edəcək. |
|||
|
|||
--- |
|||
|
|||
Yeni başlamışıq, amma siz artıq işin məntiqini başa düşmüsünüz. |
|||
|
|||
İndi aşağıdakı sətri dəyişdirməyə çalışın: |
|||
|
|||
```Python |
|||
return {"item_name": item.name, "item_id": item_id} |
|||
``` |
|||
|
|||
...bundan: |
|||
|
|||
```Python |
|||
... "item_name": item.name ... |
|||
``` |
|||
|
|||
...buna: |
|||
|
|||
```Python |
|||
... "item_price": item.price ... |
|||
``` |
|||
|
|||
...və redaktorun məlumat tiplərini bildiyini və avtomatik tamaladığını görəcəksiniz: |
|||
|
|||
 |
|||
|
|||
Daha çox funksiyaya malik daha dolğun nümunə üçün <a href="https://fastapi.tiangolo.com/az/tutorial/">Öyrədici - İstifadəçi Təlimatı</a> səhifəsinə baxa bilərsiniz. |
|||
|
|||
**Spoiler xəbərdarlığı**: Öyrədici - istifadəçi təlimatına bunlar daxildir: |
|||
|
|||
* **Parametrlərin**, <abbr title="Başlıq: Header">**başlıqlar**</abbr>, <abbr title="Çərəz: Cookie">çərəzlər</abbr>, **forma sahələri** və **fayllar** olaraq müəyyən edilməsi. |
|||
* `maximum_length` və ya `regex` kimi **doğrulama məhdudiyyətlərinin** necə təyin ediləcəyi. |
|||
* Çox güclü və istifadəsi asan **<abbr title="components, resources, providers, services, injectables olaraq da bilinir">Dependency Injection</abbr>** sistemi. |
|||
* Təhlükəsizlik və autentifikasiya, **JWT tokenləri** ilə **OAuth2** dəstəyi və **HTTP Basic** autentifikasiyası. |
|||
* **çox dərin JSON modellərini** müəyyən etmək üçün daha irəli səviyyə (lakin eyni dərəcədə asan) üsullar (Pydantic sayəsində). |
|||
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> və digər kitabxanalar ilə **GraphQL** inteqrasiyası. |
|||
* Digər əlavə xüsusiyyətlər (Starlette sayəsində): |
|||
* **WebSockets** |
|||
* HTTPX və `pytest` sayəsində çox asan testlər |
|||
* **CORS** |
|||
* **Cookie Sessions** |
|||
* ...və daha çoxu. |
|||
|
|||
## Performans |
|||
|
|||
Müstəqil TechEmpower meyarları göstərir ki, Uvicorn üzərində işləyən **FastAPI** proqramları <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">ən sürətli Python kitabxanalarından biridir</a>, yalnız Starlette və Uvicorn-un özündən yavaşdır, ki FastAPI bunların üzərinə qurulmuş bir framework-dür. (*) |
|||
|
|||
Ətraflı məlumat üçün bu bölməyə nəzər salın <a href="https://fastapi.tiangolo.com/az/benchmarks/" class="internal-link" target="_blank"><abbr title="Müqayisələr: Benchmarks">Müqayisələr</abbr></a>. |
|||
|
|||
## Məcburi Olmayan Tələblər |
|||
|
|||
Pydantic tərəfindən istifadə olunanlar: |
|||
|
|||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - e-poçtun yoxlanılması üçün. |
|||
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - parametrlərin idarə edilməsi üçün. |
|||
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - Pydantic ilə istifadə edilə bilən əlavə tiplər üçün. |
|||
|
|||
Starlette tərəfindən istifadə olunanlar: |
|||
|
|||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Əgər `TestClient` strukturundan istifadə edəcəksinizsə, tələb olunur. |
|||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Standart <abbr title="Şablon: Template">şablon</abbr> konfiqurasiyasından istifadə etmək istəyirsinizsə, tələb olunur. |
|||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - `request.form()` ilə forma <abbr title="HTTP sorğusu ilə alınan string məlumatın Python obyektinə çevrilməsi">"çevirmə"</abbr> dəstəyindən istifadə etmək istəyirsinizsə, tələb olunur. |
|||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` dəstəyi üçün tələb olunur. |
|||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - `SchemaGenerator` dəstəyi üçün tələb olunur (Çox güman ki, FastAPI istifadə edərkən buna ehtiyacınız olmayacaq). |
|||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse` istifadə etmək istəyirsinizsə, tələb olunur. |
|||
|
|||
Həm FastAPI, həm də Starlette tərəfindən istifadə olunur: |
|||
|
|||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - Yaratdığımız proqramı servis edəcək veb server kimi fəaliyyət göstərir. |
|||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse` istifadə edəcəksinizsə tələb olunur. |
|||
|
|||
Bütün bunları `pip install fastapi[all]` ilə quraşdıra bilərsiniz. |
|||
|
|||
## Lisenziya |
|||
|
|||
Bu layihə MIT lisenziyasının şərtlərinə əsasən lisenziyalaşdırılıb. |
@ -0,0 +1 @@ |
|||
INHERIT: ../en/mkdocs.yml |
@ -0,0 +1,464 @@ |
|||
<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 উচ্চক্ষমতা সম্পন্ন, সহজে শেখার এবং দ্রুত কোড করে প্রোডাকশনের জন্য ফ্রামওয়ার্ক।</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> |
|||
|
|||
--- |
|||
|
|||
**নির্দেশিকা নথি**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a> |
|||
|
|||
**সোর্স কোড**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a> |
|||
|
|||
--- |
|||
|
|||
FastAPI একটি আধুনিক, দ্রুত ( বেশি ক্ষমতা ) সম্পন্ন, Python 3.6+ দিয়ে API তৈরির জন্য স্ট্যান্ডার্ড পাইথন টাইপ ইঙ্গিত ভিত্তিক ওয়েব ফ্রেমওয়ার্ক। |
|||
|
|||
এর মূল বৈশিষ্ট্য গুলো হলঃ |
|||
|
|||
- **গতি**: এটি **NodeJS** এবং **Go** এর মত কার্যক্ষমতা সম্পন্ন (Starlette এবং Pydantic এর সাহায্যে)। [পাইথন এর দ্রুততম ফ্রেমওয়ার্ক গুলোর মধ্যে এটি একটি](#_11)। |
|||
- **দ্রুত কোড করা**:বৈশিষ্ট্য তৈরির গতি ২০০% থেকে ৩০০% বৃদ্ধি করে৷ \* |
|||
- **স্বল্প bugs**: মানুব (ডেভেলপার) সৃষ্ট ত্রুটির প্রায় ৪০% হ্রাস করে। \* |
|||
- **স্বজ্ঞাত**: দুর্দান্ত এডিটর সাহায্য <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> নামেও পরিচিত। দ্রুত ডিবাগ করা যায়। |
|||
|
|||
- **সহজ**: এটি এমন ভাবে সজানো হয়েছে যেন নির্দেশিকা নথি পড়ে সহজে শেখা এবং ব্যবহার করা যায়। |
|||
- **সংক্ষিপ্ত**: কোড পুনরাবৃত্তি কমানোর পাশাপাশি, bug কমায় এবং প্রতিটি প্যারামিটার ঘোষণা থেকে একাধিক ফিচার পাওয়া যায় । |
|||
- **জোরালো**: স্বয়ংক্রিয় ভাবে তৈরি ক্রিয়াশীল নির্দেশনা নথি (documentation) সহ উৎপাদন উপযোগি (Production-ready) কোড পাওয়া যায়। |
|||
- **মান-ভিত্তিক**: এর ভিত্তি <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (যা পুর্বে Swagger নামে পরিচিত ছিল) এবং <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a> এর আদর্শের মানের ওপর |
|||
|
|||
<small>\* উৎপাদনমুখি এপ্লিকেশন বানানোর এক দল ডেভেলপার এর মতামত ভিত্তিক ফলাফল।</small> |
|||
|
|||
## স্পনসর গণ |
|||
|
|||
<!-- 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">অন্যান্য স্পনসর গণ</a> |
|||
|
|||
## মতামত সমূহ |
|||
|
|||
"_আমি আজকাল **FastAPI** ব্যবহার করছি। [...] আমরা ভাবছি মাইক্রোসফ্টে **ML সার্ভিস** এ সকল দলের জন্য এটি ব্যবহার করব। যার মধ্যে কিছু পণ্য **Windows** এ সংযোযন হয় এবং কিছু **Office** এর সাথে সংযোযন হচ্ছে।_" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">কবির খান - <strong>মাইক্রোসফ্টে</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div> |
|||
|
|||
--- |
|||
|
|||
"_আমরা **FastAPI** লাইব্রেরি গ্রহণ করেছি একটি **REST** সার্ভার তৈরি করতে, যা **ভবিষ্যদ্বাণী** পাওয়ার জন্য কুয়েরি করা যেতে পারে। [লুডউইগের জন্য]_" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">পিয়েরো মোলিনো, ইয়ারোস্লাভ দুদিন, এবং সাই সুমন্থ মিরিয়ালা - <strong>উবার</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div> |
|||
|
|||
--- |
|||
|
|||
"_**Netflix** আমাদের **ক্রাইসিস ম্যানেজমেন্ট** অর্কেস্ট্রেশন ফ্রেমওয়ার্ক: **ডিসপ্যাচ** এর ওপেন সোর্স রিলিজ ঘোষণা করতে পেরে আনন্দিত! [যাকিনা **FastAPI** দিয়ে নির্মিত]_" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">কেভিন গ্লিসন, মার্ক ভিলানোভা, ফরেস্ট মনসেন - <strong>নেটফ্লিক্স</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div> |
|||
|
|||
--- |
|||
|
|||
"_আমি **FastAPI** নিয়ে চাঁদের সমান উৎসাহিত। এটি খুবই মজার!_" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">ব্রায়ান ওকেন - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">পাইথন বাইটস</a> পডকাস্ট হোস্ট</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div> |
|||
|
|||
--- |
|||
|
|||
"\_সত্যিই, আপনি যা তৈরি করেছেন তা খুব মজবুত এবং পরিপূর্ন৷ অনেক উপায়ে, আমি যা **Hug** এ করতে চেয়েছিলাম - তা কাউকে তৈরি করতে দেখে আমি সত্যিই অনুপ্রানিত৷\_" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">টিমোথি ক্রসলে - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> স্রষ্টা</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div> |
|||
|
|||
--- |
|||
|
|||
"আপনি যদি REST API তৈরির জন্য একটি **আধুনিক ফ্রেমওয়ার্ক** শিখতে চান, তাহলে **FastAPI** দেখুন [...] এটি দ্রুত, ব্যবহার করা সহজ এবং শিখতেও সহজ [...]\_" |
|||
|
|||
"_আমরা আমাদের **APIs** [...] এর জন্য **FastAPI**- তে এসেছি [...] আমি মনে করি আপনিও এটি পছন্দ করবেন [...]_" |
|||
|
|||
<div style="text-align: right; margin-right: 10%;">ইনেস মন্টানি - ম্যাথিউ হোনিবাল - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> প্রতিষ্ঠাতা - <a href="https://spacy.io" target="_blank">spaCy</a> স্রষ্টা</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**, CLI এর জন্য FastAPI |
|||
|
|||
<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> |
|||
|
|||
আপনি যদি <abbr title="Command Line Interface">CLI</abbr> অ্যাপ বানাতে চান, যা কিনা ওয়েব API এর পরিবর্তে টার্মিনালে ব্যবহার হবে, তাহলে দেখুন<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>. |
|||
|
|||
**টাইপার** হল FastAPI এর ছোট ভাইয়ের মত। এবং এটির উদ্দেশ্য ছিল **CLIs এর FastAPI** হওয়া। ⌨️ 🚀 |
|||
|
|||
## প্রয়োজনীয়তা গুলো |
|||
|
|||
Python 3.7+ |
|||
|
|||
FastAPI কিছু দানবেদের কাঁধে দাঁড়িয়ে আছে: |
|||
|
|||
- <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> ওয়েব অংশের জন্য. |
|||
- <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> ডেটা অংশগুলির জন্য. |
|||
|
|||
## ইনস্টলেশন প্রক্রিয়া |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install fastapi |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
আপনার একটি ASGI সার্ভারেরও প্রয়োজন হবে, প্রোডাকশনের জন্য <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> অথবা <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "uvicorn[standard]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## উদাহরণ |
|||
|
|||
### তৈরি |
|||
|
|||
- `main.py` নামে একটি ফাইল তৈরি করুন: |
|||
|
|||
```Python |
|||
from typing import Union |
|||
|
|||
from fastapi import FastAPI |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/") |
|||
def read_root(): |
|||
return {"Hello": "World"} |
|||
|
|||
|
|||
@app.get("/items/{item_id}") |
|||
def read_item(item_id: int, q: Union[str, None] = None): |
|||
return {"item_id": item_id, "q": q} |
|||
``` |
|||
|
|||
<details markdown="1"> |
|||
<summary>অথবা ব্যবহার করুন <code>async def</code>...</summary> |
|||
|
|||
যদি আপনার কোড `async` / `await`, ব্যবহার করে তাহলে `async def` ব্যবহার করুন: |
|||
|
|||
```Python hl_lines="9 14" |
|||
from typing import Union |
|||
|
|||
from fastapi import FastAPI |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/") |
|||
async def read_root(): |
|||
return {"Hello": "World"} |
|||
|
|||
|
|||
@app.get("/items/{item_id}") |
|||
async def read_item(item_id: int, q: Union[str, None] = None): |
|||
return {"item_id": item_id, "q": q} |
|||
``` |
|||
|
|||
**টীকা**: |
|||
|
|||
আপনি যদি না জানেন, _"তাড়াহুড়ো?"_ বিভাগটি দেখুন <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` এবং `await` নথির মধ্যে দেখুন </a>. |
|||
|
|||
</details> |
|||
|
|||
### এটি চালান |
|||
|
|||
সার্ভার চালু করুন: |
|||
|
|||
<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>নির্দেশনা সম্পর্কে <code>uvicorn main:app --reload</code>...</summary> |
|||
|
|||
`uvicorn main:app` নির্দেশনাটি দ্বারা বোঝায়: |
|||
|
|||
- `main`: ফাইল `main.py` (পাইথন "মডিউল")। |
|||
- `app`: `app = FastAPI()` লাইন দিয়ে `main.py` এর ভিতরে তৈরি করা অবজেক্ট। |
|||
- `--reload`: কোড পরিবর্তনের পরে সার্ভার পুনরায় চালু করুন। এটি শুধুমাত্র ডেভেলপমেন্ট এর সময় ব্যবহার করুন। |
|||
|
|||
</details> |
|||
|
|||
### এটা চেক করুন |
|||
|
|||
আপনার ব্রাউজার খুলুন <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> এ। |
|||
|
|||
আপনি JSON রেসপন্স দেখতে পাবেন: |
|||
|
|||
```JSON |
|||
{"item_id": 5, "q": "somequery"} |
|||
``` |
|||
|
|||
আপনি ইতিমধ্যে একটি API তৈরি করেছেন যা: |
|||
|
|||
- `/` এবং `/items/{item_id}` _paths_ এ HTTP অনুরোধ গ্রহণ করে। |
|||
- উভয় *path*ই `GET` <em>অপারেশন</em> নেয় ( যা HTTP _methods_ নামেও পরিচিত)। |
|||
- _path_ `/items/{item_id}`-এ একটি _path প্যারামিটার_ `item_id` আছে যা কিনা `int` হতে হবে। |
|||
- _path_ `/items/{item_id}`-এর একটি ঐচ্ছিক `str` _query প্যারামিটার_ `q` আছে। |
|||
|
|||
### ক্রিয়াশীল API নির্দেশিকা নথি |
|||
|
|||
এখন যান <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. |
|||
|
|||
আপনি স্বয়ংক্রিয় ভাবে প্রস্তুত ক্রিয়াশীল API নির্দেশিকা নথি দেখতে পাবেন (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> প্রদত্ত): |
|||
|
|||
 |
|||
|
|||
### বিকল্প API নির্দেশিকা নথি |
|||
|
|||
এবং এখন <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> এ যান. |
|||
|
|||
আপনি স্বয়ংক্রিয় ভাবে প্রস্তুত বিকল্প নির্দেশিকা নথি দেখতে পাবেন (<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> প্রদত্ত): |
|||
|
|||
 |
|||
|
|||
## উদাহরণস্বরূপ আপগ্রেড |
|||
|
|||
এখন `main.py` ফাইলটি পরিবর্তন করুন যেন এটি `PUT` রিকুয়েস্ট থেকে বডি পেতে পারে। |
|||
|
|||
Python স্ট্যান্ডার্ড লাইব্রেরি, Pydantic এর সাহায্যে বডি ঘোষণা করুন। |
|||
|
|||
```Python hl_lines="4 9-12 25-27" |
|||
from typing import Union |
|||
|
|||
from fastapi import FastAPI |
|||
from pydantic import BaseModel |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
class Item(BaseModel): |
|||
name: str |
|||
price: float |
|||
is_offer: Union[bool, None] = None |
|||
|
|||
|
|||
@app.get("/") |
|||
def read_root(): |
|||
return {"Hello": "World"} |
|||
|
|||
|
|||
@app.get("/items/{item_id}") |
|||
def read_item(item_id: int, q: Union[str, None] = None): |
|||
return {"item_id": item_id, "q": q} |
|||
|
|||
|
|||
@app.put("/items/{item_id}") |
|||
def update_item(item_id: int, item: Item): |
|||
return {"item_name": item.name, "item_id": item_id} |
|||
``` |
|||
|
|||
সার্ভারটি স্বয়ংক্রিয়ভাবে পুনরায় লোড হওয়া উচিত (কারণ আপনি উপরের `uvicorn` কমান্ডে `--reload` যোগ করেছেন)। |
|||
|
|||
### ক্রিয়াশীল API নির্দেশিকা নথি উন্নীতকরণ |
|||
|
|||
এখন <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> এডড্রেসে যান. |
|||
|
|||
- ক্রিয়াশীল API নির্দেশিকা নথিটি স্বয়ংক্রিয়ভাবে উন্নীত হযে যাবে, নতুন বডি সহ: |
|||
|
|||
 |
|||
|
|||
- "Try it out" বাটনে চাপুন, এটি আপনাকে পেরামিটারগুলো পূরণ করতে এবং API এর সাথে সরাসরি ক্রিয়া-কলাপ করতে দিবে: |
|||
|
|||
 |
|||
|
|||
- তারপরে "Execute" বাটনে চাপুন, ব্যবহারকারীর ইন্টারফেস আপনার API এর সাথে যোগাযোগ করবে, পেরামিটার পাঠাবে, ফলাফলগুলি পাবে এবং সেগুলি পর্রদায় দেখাবে: |
|||
|
|||
 |
|||
|
|||
### বিকল্প API নির্দেশিকা নথি আপগ্রেড |
|||
|
|||
এবং এখন <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> এ যান। |
|||
|
|||
- বিকল্প নির্দেশিকা নথিতেও নতুন কুয়েরি প্যারামিটার এবং বডি প্রতিফলিত হবে: |
|||
|
|||
 |
|||
|
|||
### সংক্ষিপ্তকরণ |
|||
|
|||
সংক্ষেপে, আপনি **শুধু একবার** প্যারামিটারের ধরন, বডি ইত্যাদি ফাংশন প্যারামিটার হিসেবে ঘোষণা করেন। |
|||
|
|||
আপনি সেটি আধুনিক পাইথনের সাথে করেন। |
|||
|
|||
আপনাকে নতুন করে নির্দিষ্ট কোন লাইব্রেরির বাক্য গঠন, ফাংশন বা ক্লাস কিছুই শিখতে হচ্ছে না। |
|||
|
|||
শুধুই আধুনিক **Python 3.6+** |
|||
|
|||
উদাহরণস্বরূপ, `int` এর জন্য: |
|||
|
|||
```Python |
|||
item_id: int |
|||
``` |
|||
|
|||
অথবা আরও জটিল `Item` মডেলের জন্য: |
|||
|
|||
```Python |
|||
item: Item |
|||
``` |
|||
|
|||
...এবং সেই একই ঘোষণার সাথে আপনি পাবেন: |
|||
|
|||
- এডিটর সাহায্য, যেমন |
|||
- সমাপ্তি। |
|||
- ধরণ যাচাই |
|||
- তথ্য যাচাইকরণ: |
|||
- ডেটা অবৈধ হলে স্বয়ংক্রিয় এবং পরিষ্কার ত্রুটির নির্দেশনা। |
|||
- এমনকি গভীরভাবে নেস্ট করা JSON অবজেক্টের জন্য বৈধতা। |
|||
- প্রেরিত তথ্য <abbr title="যা পরিচিত: serialization, parsing, marshalling">রূপান্তর</abbr>: যা নেটওয়ার্ক থেকে পাইথনের তথ্য এবং ধরনে আসে, এবং সেখান থেকে পড়া: |
|||
|
|||
- JSON। |
|||
- পাথ প্যারামিটার। |
|||
- কুয়েরি প্যারামিটার। |
|||
- কুকিজ |
|||
- হেডার |
|||
- ফর্ম |
|||
- ফাইল |
|||
|
|||
- আউটপুট ডেটার <abbr title="যা পরিচিত: serialization, parsing, marshalling">রূপান্তর</abbr>: পাইথন ডেটা এবং টাইপ থেকে নেটওয়ার্ক ডেটাতে রূপান্তর করা (JSON হিসাবে): |
|||
-পাইথন টাইপে রূপান্তর করুন (`str`, `int`, `float`, `bool`, `list`, ইত্যাদি)। |
|||
- `datetime` অবজেক্ট। |
|||
- `UUID` objeঅবজেক্টcts। |
|||
- ডাটাবেস মডেল। |
|||
- ...এবং আরো অনেক। |
|||
- স্বয়ংক্রিয় ক্রিয়াশীল API নির্দেশিকা নথি, 2টি বিকল্প ব্যবহারকারীর ইন্টারফেস সহ: |
|||
- সোয়াগার ইউ আই (Swagger UI)। |
|||
- রিডক (ReDoc)। |
|||
|
|||
--- |
|||
|
|||
পূর্ববর্তী কোড উদাহরণে ফিরে আসা যাক, **FastAPI** যা করবে: |
|||
|
|||
- `GET` এবং `PUT` অনুরোধের জন্য পথে `item_id` আছে কিনা তা যাচাই করবে। |
|||
- `GET` এবং `PUT` অনুরোধের জন্য `item_id` টাইপ `int` এর হতে হবে তা যাচাই করবে। |
|||
- যদি না হয় তবে ক্লায়েন্ট একটি উপযুক্ত, পরিষ্কার ত্রুটি দেখতে পাবেন। |
|||
- `GET` অনুরোধের জন্য একটি ঐচ্ছিক ক্যুয়েরি প্যারামিটার নামক `q` (যেমন `http://127.0.0.1:8000/items/foo?q=somequery`) আছে কি তা চেক করবে। |
|||
- যেহেতু `q` প্যারামিটারটি `= None` দিয়ে ঘোষণা করা হয়েছে, তাই এটি ঐচ্ছিক। |
|||
- `None` ছাড়া এটি প্রয়োজনীয় হতো (যেমন `PUT` এর ক্ষেত্রে হয়েছে)। |
|||
- `/items/{item_id}` এর জন্য `PUT` অনুরোধের বডি JSON হিসাবে পড়ুন: |
|||
- লক্ষ করুন, `name` একটি প্রয়োজনীয় অ্যাট্রিবিউট হিসাবে বিবেচনা করেছে এবং এটি `str` হতে হবে। |
|||
- লক্ষ করুন এখানে, `price` অ্যাট্রিবিউটটি আবশ্যক এবং এটি `float` হতে হবে। |
|||
- লক্ষ করুন `is_offer` একটি ঐচ্ছিক অ্যাট্রিবিউট এবং এটি `bool` হতে হবে যদি উপস্থিত থাকে। |
|||
- এই সবটি গভীরভাবে অবস্থানরত JSON অবজেক্টগুলিতেও কাজ করবে। |
|||
- স্বয়ংক্রিয়ভাবে JSON হতে এবং JSON থেকে কনভার্ট করুন। |
|||
- OpenAPI দিয়ে সবকিছু ডকুমেন্ট করুন, যা ব্যবহার করা যেতে পারে: |
|||
- ক্রিয়াশীল নির্দেশিকা নথি। |
|||
- অনেক ভাষার জন্য স্বয়ংক্রিয় ক্লায়েন্ট কোড তৈরির ব্যবস্থা। |
|||
- সরাসরি 2টি ক্রিয়াশীল নির্দেশিকা নথি ওয়েব পৃষ্ঠ প্রদান করা হয়েছে। |
|||
|
|||
--- |
|||
|
|||
আমরা এতক্ষন শুধু এর পৃষ্ঠ তৈরি করেছি, কিন্তু আপনি ইতমধ্যেই এটি কিভাবে কাজ করে তার ধারণাও পেয়ে গিয়েছেন। |
|||
|
|||
নিম্নোক্ত লাইন গুলো পরিবর্তন করার চেষ্টা করুন: |
|||
|
|||
```Python |
|||
return {"item_name": item.name, "item_id": item_id} |
|||
``` |
|||
|
|||
...পুর্বে: |
|||
|
|||
```Python |
|||
... "item_name": item.name ... |
|||
``` |
|||
|
|||
...পরবর্তীতে: |
|||
|
|||
```Python |
|||
... "item_price": item.price ... |
|||
``` |
|||
|
|||
...এবং দেখুন কিভাবে আপনার এডিটর উপাদানগুলোকে সয়ংক্রিয়ভাবে-সম্পন্ন করবে এবং তাদের ধরন জানতে পারবে: |
|||
|
|||
 |
|||
|
|||
আরও বৈশিষ্ট্য সম্পন্ন উদাহরণের জন্য, দেখুন <a href="https://fastapi.tiangolo.com/tutorial/">টিউটোরিয়াল - ব্যবহারকারীর গাইড</a>. |
|||
|
|||
**স্পয়লার সতর্কতা**: টিউটোরিয়াল - ব্যবহারকারীর গাইড নিম্নোক্ত বিষয়গুলি অন্তর্ভুক্ত করে: |
|||
|
|||
- **হেডার**, **কুকিজ**, **ফর্ম ফিল্ড** এবং **ফাইলগুলি** এমন অন্যান্য জায়গা থেকে প্যারামিটার ঘোষণা করা। |
|||
- `maximum_length` বা `regex` এর মতো **যাচাইকরণ বাধামুক্তি** সেট করা হয় কিভাবে, তা নিয়ে আলোচনা করা হবে। |
|||
- একটি খুব শক্তিশালী এবং ব্যবহার করা সহজ <abbr title="also known as components, resources, providers, services, injectables">ডিপেন্ডেন্সি ইনজেকশন</abbr> পদ্ধতি |
|||
- **OAuth2** এবং **JWT টোকেন** এবং **HTTP Basic** auth সহ নিরাপত্তা এবং অনুমোদনপ্রাপ্তি সম্পর্কিত বিষয়সমূহের উপর। |
|||
- **গভীরভাবে অবস্থানরত JSON মডেল** ঘোষণা করার জন্য আরও উন্নত (কিন্তু সমান সহজ) কৌশল (Pydantic কে ধন্যবাদ)। |
|||
- আরো অতিরিক্ত বৈশিষ্ট্য (স্টারলেটকে ধন্যবাদ) হিসাবে: |
|||
- **WebSockets** |
|||
- **GraphQL** |
|||
- HTTPX এবং `pytest` ভিত্তিক অত্যন্ত সহজ পরীক্ষা |
|||
- **CORS** |
|||
- **Cookie Sessions** |
|||
- ...এবং আরো। |
|||
|
|||
## কর্মক্ষমতা |
|||
|
|||
স্বাধীন TechEmpower Benchmarks দেখায় যে **FastAPI** অ্যাপ্লিকেশনগুলি Uvicorn-এর অধীনে চলমান দ্রুততম<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">পাইথন ফ্রেমওয়ার্কগুলির মধ্যে একটি,</a> শুধুমাত্র Starlette এবং Uvicorn-এর পর (FastAPI দ্বারা অভ্যন্তরীণভাবে ব্যবহৃত)। (\*) |
|||
|
|||
এটি সম্পর্কে আরও বুঝতে, দেখুন <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>. |
|||
|
|||
## ঐচ্ছিক নির্ভরশীলতা |
|||
|
|||
Pydantic দ্বারা ব্যবহৃত: |
|||
|
|||
- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - দ্রুত 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> - ইমেল যাচাইকরণের জন্য। |
|||
|
|||
স্টারলেট দ্বারা ব্যবহৃত: |
|||
|
|||
- <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - আপনি যদি `TestClient` ব্যবহার করতে চান তাহলে আবশ্যক। |
|||
- <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - আপনি যদি প্রদত্ত টেমপ্লেট রূপরেখা ব্যবহার করতে চান তাহলে প্রয়োজন। |
|||
- <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - আপনি যদি ফর্ম সহায়তা করতে চান তাহলে প্রয়োজন <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, `request.form()` সহ। |
|||
- <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` সহায়তার জন্য প্রয়োজন। |
|||
- <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - স্টারলেটের SchemaGenerator সাপোর্ট এর জন্য প্রয়োজন (আপনার সম্ভাবত FastAPI প্রয়োজন নেই)। |
|||
- <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - `GraphQLApp` সহায়তার জন্য প্রয়োজন। |
|||
- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - আপনি `UJSONResponse` ব্যবহার করতে চাইলে প্রয়োজন। |
|||
|
|||
FastAPI / Starlette দ্বারা ব্যবহৃত: |
|||
|
|||
- <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - সার্ভারের জন্য যা আপনার অ্যাপ্লিকেশন লোড করে এবং পরিবেশন করে। |
|||
- <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - আপনি `ORJSONResponse` ব্যবহার করতে চাইলে প্রয়োজন। |
|||
|
|||
আপনি এই সব ইনস্টল করতে পারেন `pip install fastapi[all]` দিয়ে. |
|||
|
|||
## লাইসেন্স |
|||
|
|||
এই প্রজেক্ট MIT লাইসেন্স নীতিমালার অধীনে শর্তায়িত। |
@ -0,0 +1 @@ |
|||
INHERIT: ../en/mkdocs.yml |
@ -0,0 +1,3 @@ |
|||
# Über |
|||
|
|||
Über FastAPI, sein Design, seine Inspiration und mehr. 🤓 |
@ -0,0 +1,69 @@ |
|||
# Zusätzliche Statuscodes |
|||
|
|||
Standardmäßig liefert **FastAPI** die Rückgabewerte (Responses) als `JSONResponse` zurück und fügt den Inhalt der jeweiligen *Pfadoperation* in das `JSONResponse` Objekt ein. |
|||
|
|||
Es wird der Default-Statuscode oder derjenige verwendet, den Sie in Ihrer *Pfadoperation* festgelegt haben. |
|||
|
|||
## Zusätzliche Statuscodes |
|||
|
|||
Wenn Sie neben dem Hauptstatuscode weitere Statuscodes zurückgeben möchten, können Sie dies tun, indem Sie direkt eine `Response` zurückgeben, wie etwa eine `JSONResponse`, und den zusätzlichen Statuscode direkt festlegen. |
|||
|
|||
Angenommen, Sie möchten eine *Pfadoperation* haben, die das Aktualisieren von Artikeln ermöglicht und bei Erfolg den HTTP-Statuscode 200 „OK“ zurückgibt. |
|||
|
|||
Sie möchten aber auch, dass sie neue Artikel akzeptiert. Und wenn die Elemente vorher nicht vorhanden waren, werden diese Elemente erstellt und der HTTP-Statuscode 201 „Created“ zurückgegeben. |
|||
|
|||
Um dies zu erreichen, importieren Sie `JSONResponse`, und geben Sie Ihren Inhalt direkt zurück, indem Sie den gewünschten `status_code` setzen: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="4 25" |
|||
{!> ../../../docs_src/additional_status_codes/tutorial001_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="4 25" |
|||
{!> ../../../docs_src/additional_status_codes/tutorial001_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="4 26" |
|||
{!> ../../../docs_src/additional_status_codes/tutorial001_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="2 23" |
|||
{!> ../../../docs_src/additional_status_codes/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="4 25" |
|||
{!> ../../../docs_src/additional_status_codes/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! warning "Achtung" |
|||
Wenn Sie eine `Response` direkt zurückgeben, wie im obigen Beispiel, wird sie direkt zurückgegeben. |
|||
|
|||
Sie wird nicht mit einem Modell usw. serialisiert. |
|||
|
|||
Stellen Sie sicher, dass sie die gewünschten Daten enthält und dass die Werte gültiges JSON sind (wenn Sie `JSONResponse` verwenden). |
|||
|
|||
!!! note "Technische Details" |
|||
Sie können auch `from starlette.responses import JSONResponse` verwenden. |
|||
|
|||
**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit für Sie, den Entwickler. Die meisten verfügbaren Responses kommen aber direkt von Starlette. Das Gleiche gilt für `status`. |
|||
|
|||
## OpenAPI- und API-Dokumentation |
|||
|
|||
Wenn Sie zusätzliche Statuscodes und Responses direkt zurückgeben, werden diese nicht in das OpenAPI-Schema (die API-Dokumentation) aufgenommen, da FastAPI keine Möglichkeit hat, im Voraus zu wissen, was Sie zurückgeben werden. |
|||
|
|||
Sie können das jedoch in Ihrem Code dokumentieren, indem Sie Folgendes verwenden: [Zusätzliche Responses](additional-responses.md){.internal-link target=_blank}. |
@ -0,0 +1,300 @@ |
|||
# Benutzerdefinierte Response – HTML, Stream, Datei, andere |
|||
|
|||
Standardmäßig gibt **FastAPI** die Responses mittels `JSONResponse` zurück. |
|||
|
|||
Sie können das überschreiben, indem Sie direkt eine `Response` zurückgeben, wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} gezeigt. |
|||
|
|||
Wenn Sie jedoch direkt eine `Response` zurückgeben, werden die Daten nicht automatisch konvertiert und die Dokumentation wird nicht automatisch generiert (zum Beispiel wird der spezifische „Medientyp“, der im HTTP-Header `Content-Type` angegeben ist, nicht Teil der generierten OpenAPI). |
|||
|
|||
Sie können aber auch die `Response`, die Sie verwenden möchten, im *Pfadoperation-Dekorator* deklarieren. |
|||
|
|||
Der Inhalt, den Sie von Ihrer *Pfadoperation-Funktion* zurückgeben, wird in diese `Response` eingefügt. |
|||
|
|||
Und wenn diese `Response` einen JSON-Medientyp (`application/json`) hat, wie es bei `JSONResponse` und `UJSONResponse` der Fall ist, werden die von Ihnen zurückgegebenen Daten automatisch mit jedem Pydantic `response_model` konvertiert (und gefiltert), das Sie im *Pfadoperation-Dekorator* deklariert haben. |
|||
|
|||
!!! note "Hinweis" |
|||
Wenn Sie eine Response-Klasse ohne Medientyp verwenden, erwartet FastAPI, dass Ihre Response keinen Inhalt hat, und dokumentiert daher das Format der Response nicht in deren generierter OpenAPI-Dokumentation. |
|||
|
|||
## `ORJSONResponse` verwenden |
|||
|
|||
Um beispielsweise noch etwas Leistung herauszuholen, können Sie <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> installieren und verwenden, und die Response als `ORJSONResponse` deklarieren. |
|||
|
|||
Importieren Sie die `Response`-Klasse (-Unterklasse), die Sie verwenden möchten, und deklarieren Sie sie im *Pfadoperation-Dekorator*. |
|||
|
|||
Bei umfangreichen Responses ist die direkte Rückgabe einer `Response` viel schneller als ein Dictionary zurückzugeben. |
|||
|
|||
Das liegt daran, dass FastAPI standardmäßig jedes enthaltene Element überprüft und sicherstellt, dass es als JSON serialisierbar ist, und zwar unter Verwendung desselben [JSON-kompatiblen Encoders](../tutorial/encoder.md){.internal-link target=_blank}, der im Tutorial erläutert wurde. Dadurch können Sie **beliebige Objekte** zurückgeben, zum Beispiel Datenbankmodelle. |
|||
|
|||
Wenn Sie jedoch sicher sind, dass der von Ihnen zurückgegebene Inhalt **mit JSON serialisierbar** ist, können Sie ihn direkt an die Response-Klasse übergeben und die zusätzliche Arbeit vermeiden, die FastAPI hätte, indem es Ihren zurückgegebenen Inhalt durch den `jsonable_encoder` leitet, bevor es ihn an die Response-Klasse übergibt. |
|||
|
|||
```Python hl_lines="2 7" |
|||
{!../../../docs_src/custom_response/tutorial001b.py!} |
|||
``` |
|||
|
|||
!!! info |
|||
Der Parameter `response_class` wird auch verwendet, um den „Medientyp“ der Response zu definieren. |
|||
|
|||
In diesem Fall wird der HTTP-Header `Content-Type` auf `application/json` gesetzt. |
|||
|
|||
Und er wird als solcher in OpenAPI dokumentiert. |
|||
|
|||
!!! tip "Tipp" |
|||
Die `ORJSONResponse` ist derzeit nur in FastAPI verfügbar, nicht in Starlette. |
|||
|
|||
## HTML-Response |
|||
|
|||
Um eine Response mit HTML direkt von **FastAPI** zurückzugeben, verwenden Sie `HTMLResponse`. |
|||
|
|||
* Importieren Sie `HTMLResponse`. |
|||
* Übergeben Sie `HTMLResponse` als den Parameter `response_class` Ihres *Pfadoperation-Dekorators*. |
|||
|
|||
```Python hl_lines="2 7" |
|||
{!../../../docs_src/custom_response/tutorial002.py!} |
|||
``` |
|||
|
|||
!!! info |
|||
Der Parameter `response_class` wird auch verwendet, um den „Medientyp“ der Response zu definieren. |
|||
|
|||
In diesem Fall wird der HTTP-Header `Content-Type` auf `text/html` gesetzt. |
|||
|
|||
Und er wird als solcher in OpenAPI dokumentiert. |
|||
|
|||
### Eine `Response` zurückgeben |
|||
|
|||
Wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} gezeigt, können Sie die Response auch direkt in Ihrer *Pfadoperation* überschreiben, indem Sie diese zurückgeben. |
|||
|
|||
Das gleiche Beispiel von oben, das eine `HTMLResponse` zurückgibt, könnte so aussehen: |
|||
|
|||
```Python hl_lines="2 7 19" |
|||
{!../../../docs_src/custom_response/tutorial003.py!} |
|||
``` |
|||
|
|||
!!! warning "Achtung" |
|||
Eine `Response`, die direkt von Ihrer *Pfadoperation-Funktion* zurückgegeben wird, wird in OpenAPI nicht dokumentiert (zum Beispiel wird der `Content-Type` nicht dokumentiert) und ist in der automatischen interaktiven Dokumentation nicht sichtbar. |
|||
|
|||
!!! info |
|||
Natürlich stammen der eigentliche `Content-Type`-Header, der Statuscode, usw., aus dem `Response`-Objekt, das Sie zurückgegeben haben. |
|||
|
|||
### In OpenAPI dokumentieren und `Response` überschreiben |
|||
|
|||
Wenn Sie die Response innerhalb der Funktion überschreiben und gleichzeitig den „Medientyp“ in OpenAPI dokumentieren möchten, können Sie den `response_class`-Parameter verwenden UND ein `Response`-Objekt zurückgeben. |
|||
|
|||
Die `response_class` wird dann nur zur Dokumentation der OpenAPI-Pfadoperation* verwendet, Ihre `Response` wird jedoch unverändert verwendet. |
|||
|
|||
#### Eine `HTMLResponse` direkt zurückgeben |
|||
|
|||
Es könnte zum Beispiel so etwas sein: |
|||
|
|||
```Python hl_lines="7 21 23" |
|||
{!../../../docs_src/custom_response/tutorial004.py!} |
|||
``` |
|||
|
|||
In diesem Beispiel generiert die Funktion `generate_html_response()` bereits eine `Response` und gibt sie zurück, anstatt das HTML in einem `str` zurückzugeben. |
|||
|
|||
Indem Sie das Ergebnis des Aufrufs von `generate_html_response()` zurückgeben, geben Sie bereits eine `Response` zurück, die das Standardverhalten von **FastAPI** überschreibt. |
|||
|
|||
Aber da Sie die `HTMLResponse` auch in der `response_class` übergeben haben, weiß **FastAPI**, dass sie in OpenAPI und der interaktiven Dokumentation als HTML mit `text/html` zu dokumentieren ist: |
|||
|
|||
<img src="/img/tutorial/custom-response/image01.png"> |
|||
|
|||
## Verfügbare Responses |
|||
|
|||
Hier sind einige der verfügbaren Responses. |
|||
|
|||
Bedenken Sie, dass Sie `Response` verwenden können, um alles andere zurückzugeben, oder sogar eine benutzerdefinierte Unterklasse zu erstellen. |
|||
|
|||
!!! note "Technische Details" |
|||
Sie können auch `from starlette.responses import HTMLResponse` verwenden. |
|||
|
|||
**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit für Sie, den Entwickler. Die meisten verfügbaren Responses kommen aber direkt von Starlette. |
|||
|
|||
### `Response` |
|||
|
|||
Die Hauptklasse `Response`, alle anderen Responses erben von ihr. |
|||
|
|||
Sie können sie direkt zurückgeben. |
|||
|
|||
Sie akzeptiert die folgenden Parameter: |
|||
|
|||
* `content` – Ein `str` oder `bytes`. |
|||
* `status_code` – Ein `int`-HTTP-Statuscode. |
|||
* `headers` – Ein `dict` von Strings. |
|||
* `media_type` – Ein `str`, der den Medientyp angibt. Z. B. `"text/html"`. |
|||
|
|||
FastAPI (eigentlich Starlette) fügt automatisch einen Content-Length-Header ein. Außerdem wird es einen Content-Type-Header einfügen, der auf dem media_type basiert, und für Texttypen einen Zeichensatz (charset) anfügen. |
|||
|
|||
```Python hl_lines="1 18" |
|||
{!../../../docs_src/response_directly/tutorial002.py!} |
|||
``` |
|||
|
|||
### `HTMLResponse` |
|||
|
|||
Nimmt Text oder Bytes entgegen und gibt eine HTML-Response zurück, wie Sie oben gelesen haben. |
|||
|
|||
### `PlainTextResponse` |
|||
|
|||
Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurück. |
|||
|
|||
```Python hl_lines="2 7 9" |
|||
{!../../../docs_src/custom_response/tutorial005.py!} |
|||
``` |
|||
|
|||
### `JSONResponse` |
|||
|
|||
Nimmt einige Daten entgegen und gibt eine `application/json`-codierte Response zurück. |
|||
|
|||
Dies ist die Standard-Response, die in **FastAPI** verwendet wird, wie Sie oben gelesen haben. |
|||
|
|||
### `ORJSONResponse` |
|||
|
|||
Eine schnelle alternative JSON-Response mit <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, wie Sie oben gelesen haben. |
|||
|
|||
### `UJSONResponse` |
|||
|
|||
Eine alternative JSON-Response mit <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>. |
|||
|
|||
!!! warning "Achtung" |
|||
`ujson` ist bei der Behandlung einiger Sonderfälle weniger sorgfältig als Pythons eingebaute Implementierung. |
|||
|
|||
```Python hl_lines="2 7" |
|||
{!../../../docs_src/custom_response/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! tip "Tipp" |
|||
Möglicherweise ist `ORJSONResponse` eine schnellere Alternative. |
|||
|
|||
### `RedirectResponse` |
|||
|
|||
Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurück. Verwendet standardmäßig den Statuscode 307 – Temporäre Weiterleitung (Temporary Redirect). |
|||
|
|||
Sie können eine `RedirectResponse` direkt zurückgeben: |
|||
|
|||
```Python hl_lines="2 9" |
|||
{!../../../docs_src/custom_response/tutorial006.py!} |
|||
``` |
|||
|
|||
--- |
|||
|
|||
Oder Sie können sie im Parameter `response_class` verwenden: |
|||
|
|||
|
|||
```Python hl_lines="2 7 9" |
|||
{!../../../docs_src/custom_response/tutorial006b.py!} |
|||
``` |
|||
|
|||
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben. |
|||
|
|||
In diesem Fall ist der verwendete `status_code` der Standardcode für die `RedirectResponse`, also `307`. |
|||
|
|||
--- |
|||
|
|||
Sie können den Parameter `status_code` auch in Kombination mit dem Parameter `response_class` verwenden: |
|||
|
|||
```Python hl_lines="2 7 9" |
|||
{!../../../docs_src/custom_response/tutorial006c.py!} |
|||
``` |
|||
|
|||
### `StreamingResponse` |
|||
|
|||
Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody. |
|||
|
|||
```Python hl_lines="2 14" |
|||
{!../../../docs_src/custom_response/tutorial007.py!} |
|||
``` |
|||
|
|||
#### Verwendung von `StreamingResponse` mit dateiähnlichen Objekten |
|||
|
|||
Wenn Sie ein dateiähnliches (file-like) Objekt haben (z. B. das von `open()` zurückgegebene Objekt), können Sie eine Generatorfunktion erstellen, um über dieses dateiähnliche Objekt zu iterieren. |
|||
|
|||
Auf diese Weise müssen Sie nicht alles zuerst in den Arbeitsspeicher lesen und können diese Generatorfunktion an `StreamingResponse` übergeben und zurückgeben. |
|||
|
|||
Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen. |
|||
|
|||
```{ .python .annotate hl_lines="2 10-12 14" } |
|||
{!../../../docs_src/custom_response/tutorial008.py!} |
|||
``` |
|||
|
|||
1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält. |
|||
2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiähnliche Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist. |
|||
3. Dieses `yield from` weist die Funktion an, über das Ding namens `file_like` zu iterieren. Und dann für jeden iterierten Teil, diesen Teil so zurückzugeben, als wenn er aus dieser Generatorfunktion (`iterfile`) stammen würde. |
|||
|
|||
Es handelt sich also hier um eine Generatorfunktion, die die „generierende“ Arbeit intern auf etwas anderes überträgt. |
|||
|
|||
Auf diese Weise können wir das Ganze in einen `with`-Block einfügen und so sicherstellen, dass das dateiartige Objekt nach Abschluss geschlossen wird. |
|||
|
|||
!!! tip "Tipp" |
|||
Beachten Sie, dass wir, da wir Standard-`open()` verwenden, welches `async` und `await` nicht unterstützt, hier die Pfadoperation mit normalen `def` deklarieren. |
|||
|
|||
### `FileResponse` |
|||
|
|||
Streamt eine Datei asynchron als Response. |
|||
|
|||
Nimmt zur Instanziierung einen anderen Satz von Argumenten entgegen als die anderen Response-Typen: |
|||
|
|||
* `path` – Der Dateipfad zur Datei, die gestreamt werden soll. |
|||
* `headers` – Alle benutzerdefinierten Header, die inkludiert werden sollen, als Dictionary. |
|||
* `media_type` – Ein String, der den Medientyp angibt. Wenn nicht gesetzt, wird der Dateiname oder Pfad verwendet, um auf einen Medientyp zu schließen. |
|||
* `filename` – Wenn gesetzt, wird das in der `Content-Disposition` der Response eingefügt. |
|||
|
|||
Datei-Responses enthalten die entsprechenden `Content-Length`-, `Last-Modified`- und `ETag`-Header. |
|||
|
|||
```Python hl_lines="2 10" |
|||
{!../../../docs_src/custom_response/tutorial009.py!} |
|||
``` |
|||
|
|||
Sie können auch den Parameter `response_class` verwenden: |
|||
|
|||
```Python hl_lines="2 8 10" |
|||
{!../../../docs_src/custom_response/tutorial009b.py!} |
|||
``` |
|||
|
|||
In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben. |
|||
|
|||
## Benutzerdefinierte Response-Klasse |
|||
|
|||
Sie können Ihre eigene benutzerdefinierte Response-Klasse erstellen, die von `Response` erbt und diese verwendet. |
|||
|
|||
Nehmen wir zum Beispiel an, dass Sie <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> verwenden möchten, aber mit einigen benutzerdefinierten Einstellungen, die in der enthaltenen `ORJSONResponse`-Klasse nicht verwendet werden. |
|||
|
|||
Sie möchten etwa, dass Ihre Response eingerücktes und formatiertes JSON zurückgibt. Dafür möchten Sie die orjson-Option `orjson.OPT_INDENT_2` verwenden. |
|||
|
|||
Sie könnten eine `CustomORJSONResponse` erstellen. Das Wichtigste, was Sie tun müssen, ist, eine `Response.render(content)`-Methode zu erstellen, die den Inhalt als `bytes` zurückgibt: |
|||
|
|||
```Python hl_lines="9-14 17" |
|||
{!../../../docs_src/custom_response/tutorial009c.py!} |
|||
``` |
|||
|
|||
Statt: |
|||
|
|||
```json |
|||
{"message": "Hello World"} |
|||
``` |
|||
|
|||
... wird die Response jetzt Folgendes zurückgeben: |
|||
|
|||
```json |
|||
{ |
|||
"message": "Hello World" |
|||
} |
|||
``` |
|||
|
|||
Natürlich werden Sie wahrscheinlich viel bessere Möglichkeiten finden, Vorteil daraus zu ziehen, als JSON zu formatieren. 😉 |
|||
|
|||
## Standard-Response-Klasse |
|||
|
|||
Beim Erstellen einer **FastAPI**-Klasseninstanz oder eines `APIRouter`s können Sie angeben, welche Response-Klasse standardmäßig verwendet werden soll. |
|||
|
|||
Der Parameter, der das definiert, ist `default_response_class`. |
|||
|
|||
Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`. |
|||
|
|||
```Python hl_lines="2 4" |
|||
{!../../../docs_src/custom_response/tutorial010.py!} |
|||
``` |
|||
|
|||
!!! tip "Tipp" |
|||
Sie können dennoch weiterhin `response_class` in *Pfadoperationen* überschreiben, wie bisher. |
|||
|
|||
## Zusätzliche Dokumentation |
|||
|
|||
Sie können auch den Medientyp und viele andere Details in OpenAPI mit `responses` deklarieren: [Zusätzliche Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}. |
@ -0,0 +1,286 @@ |
|||
# Clients generieren |
|||
|
|||
Da **FastAPI** auf der OpenAPI-Spezifikation basiert, erhalten Sie automatische Kompatibilität mit vielen Tools, einschließlich der automatischen API-Dokumentation (bereitgestellt von Swagger UI). |
|||
|
|||
Ein besonderer Vorteil, der nicht unbedingt offensichtlich ist, besteht darin, dass Sie für Ihre API **Clients generieren** können (manchmal auch <abbr title="Software Development Kits">**SDKs**</abbr> genannt), für viele verschiedene **Programmiersprachen**. |
|||
|
|||
## OpenAPI-Client-Generatoren |
|||
|
|||
Es gibt viele Tools zum Generieren von Clients aus **OpenAPI**. |
|||
|
|||
Ein gängiges Tool ist <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>. |
|||
|
|||
Wenn Sie ein **Frontend** erstellen, ist <a href="https://github.com/ferdikoomen/openapi-typescript-codegen" class="external-link" target="_blank">openapi-typescript-codegen</a> eine sehr interessante Alternative. |
|||
|
|||
## Client- und SDK-Generatoren – Sponsor |
|||
|
|||
Es gibt auch einige **vom Unternehmen entwickelte** Client- und SDK-Generatoren, die auf OpenAPI (FastAPI) basieren. In einigen Fällen können diese Ihnen **weitere Funktionalität** zusätzlich zu qualitativ hochwertigen generierten SDKs/Clients bieten. |
|||
|
|||
Einige von diesen ✨ [**sponsern FastAPI**](../help-fastapi.md#den-autor-sponsern){.internal-link target=_blank} ✨, das gewährleistet die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem**. |
|||
|
|||
Und es zeigt deren wahres Engagement für FastAPI und seine **Community** (Sie), da diese Ihnen nicht nur einen **guten Service** bieten möchten, sondern auch sicherstellen möchten, dass Sie über ein **gutes und gesundes Framework** verfügen, FastAPI. 🙇 |
|||
|
|||
Beispielsweise könnten Sie <a href="https://speakeasyapi.dev/?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a> ausprobieren. |
|||
|
|||
Es gibt auch mehrere andere Unternehmen, welche ähnliche Dienste anbieten und die Sie online suchen und finden können. 🤓 |
|||
|
|||
## Einen TypeScript-Frontend-Client generieren |
|||
|
|||
Beginnen wir mit einer einfachen FastAPI-Anwendung: |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="7-9 12-13 16-17 21" |
|||
{!> ../../../docs_src/generate_clients/tutorial001_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="9-11 14-15 18 19 23" |
|||
{!> ../../../docs_src/generate_clients/tutorial001.py!} |
|||
``` |
|||
|
|||
Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, welche diese für die Request- und Response-<abbr title="Die eigentlichen Nutzdaten, abzüglich der Metadaten">Payload</abbr> verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden. |
|||
|
|||
### API-Dokumentation |
|||
|
|||
Wenn Sie zur API-Dokumentation gehen, werden Sie sehen, dass diese die **Schemas** für die Daten enthält, welche in Requests gesendet und in Responses empfangen werden: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image01.png"> |
|||
|
|||
Sie können diese Schemas sehen, da sie mit den Modellen in der Anwendung deklariert wurden. |
|||
|
|||
Diese Informationen sind im **OpenAPI-Schema** der Anwendung verfügbar und werden dann in der API-Dokumentation angezeigt (von Swagger UI). |
|||
|
|||
Und dieselben Informationen aus den Modellen, die in OpenAPI enthalten sind, können zum **Generieren des Client-Codes** verwendet werden. |
|||
|
|||
### Einen TypeScript-Client generieren |
|||
|
|||
Nachdem wir nun die Anwendung mit den Modellen haben, können wir den Client-Code für das Frontend generieren. |
|||
|
|||
#### `openapi-typescript-codegen` installieren |
|||
|
|||
Sie können `openapi-typescript-codegen` in Ihrem Frontend-Code installieren mit: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ npm install openapi-typescript-codegen --save-dev |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
#### Client-Code generieren |
|||
|
|||
Um den Client-Code zu generieren, können Sie das Kommandozeilentool `openapi` verwenden, das soeben installiert wurde. |
|||
|
|||
Da es im lokalen Projekt installiert ist, könnten Sie diesen Befehl wahrscheinlich nicht direkt aufrufen, sondern würden ihn in Ihre Datei `package.json` einfügen. |
|||
|
|||
Diese könnte so aussehen: |
|||
|
|||
```JSON hl_lines="7" |
|||
{ |
|||
"name": "frontend-app", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes" |
|||
}, |
|||
"author": "", |
|||
"license": "", |
|||
"devDependencies": { |
|||
"openapi-typescript-codegen": "^0.20.1", |
|||
"typescript": "^4.6.2" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Nachdem Sie das NPM-Skript `generate-client` dort stehen haben, können Sie es ausführen mit: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ npm run generate-client |
|||
|
|||
[email protected] generate-client /home/user/code/frontend-app |
|||
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
Dieser Befehl generiert Code in `./src/client` und verwendet intern `axios` (die Frontend-HTTP-Bibliothek). |
|||
|
|||
### Den Client-Code ausprobieren |
|||
|
|||
Jetzt können Sie den Client-Code importieren und verwenden. Er könnte wie folgt aussehen, beachten Sie, dass Sie automatische Codevervollständigung für die Methoden erhalten: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image02.png"> |
|||
|
|||
Sie erhalten außerdem automatische Vervollständigung für die zu sendende Payload: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image03.png"> |
|||
|
|||
!!! tip "Tipp" |
|||
Beachten Sie die automatische Vervollständigung für `name` und `price`, welche in der FastAPI-Anwendung im `Item`-Modell definiert wurden. |
|||
|
|||
Sie erhalten Inline-Fehlerberichte für die von Ihnen gesendeten Daten: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image04.png"> |
|||
|
|||
Das Response-Objekt hat auch automatische Vervollständigung: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image05.png"> |
|||
|
|||
## FastAPI-Anwendung mit Tags |
|||
|
|||
In vielen Fällen wird Ihre FastAPI-Anwendung größer sein und Sie werden wahrscheinlich Tags verwenden, um verschiedene Gruppen von *Pfadoperationen* zu separieren. |
|||
|
|||
Beispielsweise könnten Sie einen Abschnitt für **Items (Artikel)** und einen weiteren Abschnitt für **Users (Benutzer)** haben, und diese könnten durch Tags getrennt sein: |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="21 26 34" |
|||
{!> ../../../docs_src/generate_clients/tutorial002_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="23 28 36" |
|||
{!> ../../../docs_src/generate_clients/tutorial002.py!} |
|||
``` |
|||
|
|||
### Einen TypeScript-Client mit Tags generieren |
|||
|
|||
Wenn Sie unter Verwendung von Tags einen Client für eine FastAPI-Anwendung generieren, wird normalerweise auch der Client-Code anhand der Tags getrennt. |
|||
|
|||
Auf diese Weise können Sie die Dinge für den Client-Code richtig ordnen und gruppieren: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image06.png"> |
|||
|
|||
In diesem Fall haben Sie: |
|||
|
|||
* `ItemsService` |
|||
* `UsersService` |
|||
|
|||
### Client-Methodennamen |
|||
|
|||
Im Moment sehen die generierten Methodennamen wie `createItemItemsPost` nicht sehr sauber aus: |
|||
|
|||
```TypeScript |
|||
ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) |
|||
``` |
|||
|
|||
... das liegt daran, dass der Client-Generator für jede *Pfadoperation* die OpenAPI-interne **Operation-ID** verwendet. |
|||
|
|||
OpenAPI erfordert, dass jede Operation-ID innerhalb aller *Pfadoperationen* eindeutig ist. Daher verwendet FastAPI den **Funktionsnamen**, den **Pfad** und die **HTTP-Methode/-Operation**, um diese Operation-ID zu generieren. Denn so kann sichergestellt werden, dass die Operation-IDs eindeutig sind. |
|||
|
|||
Aber ich zeige Ihnen als nächstes, wie Sie das verbessern können. 🤓 |
|||
|
|||
## Benutzerdefinierte Operation-IDs und bessere Methodennamen |
|||
|
|||
Sie können die Art und Weise, wie diese Operation-IDs **generiert** werden, **ändern**, um sie einfacher zu machen und **einfachere Methodennamen** in den Clients zu haben. |
|||
|
|||
In diesem Fall müssen Sie auf andere Weise sicherstellen, dass jede Operation-ID **eindeutig** ist. |
|||
|
|||
Sie könnten beispielsweise sicherstellen, dass jede *Pfadoperation* einen Tag hat, und dann die Operation-ID basierend auf dem **Tag** und dem **Namen** der *Pfadoperation* (dem Funktionsnamen) generieren. |
|||
|
|||
### Funktion zum Generieren einer eindeutigen ID erstellen |
|||
|
|||
FastAPI verwendet eine **eindeutige ID** für jede *Pfadoperation*, diese wird für die **Operation-ID** und auch für die Namen aller benötigten benutzerdefinierten Modelle für Requests oder Responses verwendet. |
|||
|
|||
Sie können diese Funktion anpassen. Sie nimmt eine `APIRoute` und gibt einen String zurück. |
|||
|
|||
Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur einen Tag haben) und den Namen der *Pfadoperation* (den Funktionsnamen). |
|||
|
|||
Anschließend können Sie diese benutzerdefinierte Funktion als Parameter `generate_unique_id_function` an **FastAPI** übergeben: |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="6-7 10" |
|||
{!> ../../../docs_src/generate_clients/tutorial003_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="8-9 12" |
|||
{!> ../../../docs_src/generate_clients/tutorial003.py!} |
|||
``` |
|||
|
|||
### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren |
|||
|
|||
Wenn Sie nun den Client erneut generieren, werden Sie feststellen, dass er über die verbesserten Methodennamen verfügt: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image07.png"> |
|||
|
|||
Wie Sie sehen, haben die Methodennamen jetzt den Tag und dann den Funktionsnamen, aber keine Informationen aus dem URL-Pfad und der HTTP-Operation. |
|||
|
|||
### Vorab-Modifikation der OpenAPI-Spezifikation für den Client-Generator |
|||
|
|||
Der generierte Code enthält immer noch etwas **verdoppelte Information**. |
|||
|
|||
Wir wissen bereits, dass diese Methode mit den **Items** zusammenhängt, da sich dieses Wort in `ItemsService` befindet (vom Tag übernommen), aber wir haben auch immer noch den Tagnamen im Methodennamen vorangestellt. 😕 |
|||
|
|||
Wir werden das wahrscheinlich weiterhin für OpenAPI im Allgemeinen beibehalten wollen, da dadurch sichergestellt wird, dass die Operation-IDs **eindeutig** sind. |
|||
|
|||
Aber für den generierten Client könnten wir die OpenAPI-Operation-IDs direkt vor der Generierung der Clients **modifizieren**, um diese Methodennamen schöner und **sauberer** zu machen. |
|||
|
|||
Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den vorangestellten Tag entfernen**: |
|||
|
|||
=== "Python" |
|||
|
|||
```Python |
|||
{!> ../../../docs_src/generate_clients/tutorial004.py!} |
|||
``` |
|||
|
|||
=== "Node.js" |
|||
|
|||
```Javascript |
|||
{!> ../../../docs_src/generate_clients/tutorial004.js!} |
|||
``` |
|||
|
|||
Damit würden die Operation-IDs von Dingen wie `items-get_items` in `get_items` umbenannt, sodass der Client-Generator einfachere Methodennamen generieren kann. |
|||
|
|||
### Einen TypeScript-Client mit der modifizierten OpenAPI generieren |
|||
|
|||
Da das Endergebnis nun in einer Datei `openapi.json` vorliegt, würden Sie die `package.json` ändern, um diese lokale Datei zu verwenden, zum Beispiel: |
|||
|
|||
```JSON hl_lines="7" |
|||
{ |
|||
"name": "frontend-app", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios --useOptions --useUnionTypes" |
|||
}, |
|||
"author": "", |
|||
"license": "", |
|||
"devDependencies": { |
|||
"openapi-typescript-codegen": "^0.20.1", |
|||
"typescript": "^4.6.2" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Nach der Generierung des neuen Clients hätten Sie nun **saubere Methodennamen** mit allen **Autovervollständigungen**, **Inline-Fehlerberichten**, usw.: |
|||
|
|||
<img src="/img/tutorial/generate-clients/image08.png"> |
|||
|
|||
## Vorteile |
|||
|
|||
Wenn Sie die automatisch generierten Clients verwenden, erhalten Sie **automatische Codevervollständigung** für: |
|||
|
|||
* Methoden. |
|||
* Request-Payloads im Body, Query-Parameter, usw. |
|||
* Response-Payloads. |
|||
|
|||
Außerdem erhalten Sie für alles **Inline-Fehlerberichte**. |
|||
|
|||
Und wann immer Sie den Backend-Code aktualisieren und das Frontend **neu generieren**, stehen alle neuen *Pfadoperationen* als Methoden zur Verfügung, die alten werden entfernt und alle anderen Änderungen werden im generierten Code reflektiert. 🤓 |
|||
|
|||
Das bedeutet auch, dass, wenn sich etwas ändert, dies automatisch im Client-Code **reflektiert** wird. Und wenn Sie den Client **erstellen**, kommt es zu einer Fehlermeldung, wenn die verwendeten Daten **nicht übereinstimmen**. |
|||
|
|||
Sie würden also sehr früh im Entwicklungszyklus **viele Fehler erkennen**, anstatt darauf warten zu müssen, dass die Fehler Ihren Endbenutzern in der Produktion angezeigt werden, und dann zu versuchen, zu debuggen, wo das Problem liegt. ✨ |
@ -0,0 +1,51 @@ |
|||
# OpenAPI-Webhooks |
|||
|
|||
Es gibt Fälle, in denen Sie Ihren API-Benutzern mitteilen möchten, dass Ihre Anwendung mit einigen Daten *deren* Anwendung aufrufen (ein Request senden) könnte, normalerweise um über ein bestimmtes **Event** zu **benachrichtigen**. |
|||
|
|||
Das bedeutet, dass anstelle des normalen Prozesses, bei dem Benutzer Requests an Ihre API senden, **Ihre API** (oder Ihre Anwendung) **Requests an deren System** (an deren API, deren Anwendung) senden könnte. |
|||
|
|||
Das wird normalerweise als **Webhook** bezeichnet. |
|||
|
|||
## Webhooks-Schritte |
|||
|
|||
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Body des Requests**. |
|||
|
|||
Sie definieren auch auf irgendeine Weise, zu welchen **Momenten** Ihre Anwendung diese Requests oder Events sendet. |
|||
|
|||
Und **Ihre Benutzer** definieren auf irgendeine Weise (zum Beispiel irgendwo in einem Web-Dashboard) die **URL**, an die Ihre Anwendung diese Requests senden soll. |
|||
|
|||
Die gesamte **Logik** zur Registrierung der URLs für Webhooks und der Code zum tatsächlichen Senden dieser Requests liegt bei Ihnen. Sie schreiben es so, wie Sie möchten, in **Ihrem eigenen Code**. |
|||
|
|||
## Webhooks mit **FastAPI** und OpenAPI dokumentieren |
|||
|
|||
Mit **FastAPI** können Sie mithilfe von OpenAPI die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre Anwendung senden kann (z. B. `POST`, `PUT`, usw.) und die Request**bodys** definieren, die Ihre Anwendung senden würde. |
|||
|
|||
Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. Möglicherweise können diese sogar einen Teil des eigenem API-Codes automatisch generieren. |
|||
|
|||
!!! info |
|||
Webhooks sind in OpenAPI 3.1.0 und höher verfügbar und werden von FastAPI `0.99.0` und höher unterstützt. |
|||
|
|||
## Eine Anwendung mit Webhooks |
|||
|
|||
Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, mit dem Sie *Webhooks* definieren können, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`. |
|||
|
|||
```Python hl_lines="9-13 36-53" |
|||
{!../../../docs_src/openapi_webhooks/tutorial001.py!} |
|||
``` |
|||
|
|||
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**. |
|||
|
|||
!!! info |
|||
Das `app.webhooks`-Objekt ist eigentlich nur ein `APIRouter`, derselbe Typ, den Sie verwenden würden, wenn Sie Ihre Anwendung mit mehreren Dateien strukturieren. |
|||
|
|||
Beachten Sie, dass Sie bei Webhooks tatsächlich keinen *Pfad* (wie `/items/`) deklarieren, sondern dass der Text, den Sie dort übergeben, lediglich eine **Kennzeichnung** des Webhooks (der Name des Events) ist. Zum Beispiel ist in `@app.webhooks.post("new-subscription")` der Webhook-Name `new-subscription`. |
|||
|
|||
Das liegt daran, dass erwartet wird, dass **Ihre Benutzer** den tatsächlichen **URL-Pfad**, an dem diese den Webhook-Request empfangen möchten, auf andere Weise definieren (z. B. über ein Web-Dashboard). |
|||
|
|||
### Es in der Dokumentation ansehen |
|||
|
|||
Jetzt können Sie Ihre Anwendung mit Uvicorn starten und auf <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> gehen. |
|||
|
|||
Sie werden sehen, dass Ihre Dokumentation die normalen *Pfadoperationen* und jetzt auch einige **Webhooks** enthält: |
|||
|
|||
<img src="/img/tutorial/openapi-webhooks/image01.png"> |
@ -0,0 +1,34 @@ |
|||
# Benchmarks |
|||
|
|||
Unabhängige TechEmpower-Benchmarks zeigen, **FastAPI**-Anwendungen, die unter Uvicorn ausgeführt werden, gehören zu <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">den schnellsten existierenden Python-Frameworks</a>, nur Starlette und Uvicorn selbst (intern von FastAPI verwendet) sind schneller. |
|||
|
|||
Beim Ansehen von Benchmarks und Vergleichen sollten Sie jedoch Folgende Punkte beachten. |
|||
|
|||
## Benchmarks und Geschwindigkeit |
|||
|
|||
Wenn Sie sich die Benchmarks ansehen, werden häufig mehrere Tools mit unterschiedlichen Eigenschaften als gleichwertig verglichen. |
|||
|
|||
Konkret geht es darum, Uvicorn, Starlette und FastAPI miteinander zu vergleichen (neben vielen anderen Tools). |
|||
|
|||
Je einfacher das Problem, welches durch das Tool gelöst wird, desto besser ist die Performanz. Und die meisten Benchmarks testen nicht die zusätzlichen Funktionen, welche das Tool bietet. |
|||
|
|||
Die Hierarchie ist wie folgt: |
|||
|
|||
* **Uvicorn**: ein ASGI-Server |
|||
* **Starlette**: (verwendet Uvicorn) ein Web-Mikroframework |
|||
* **FastAPI**: (verwendet Starlette) ein API-Mikroframework mit mehreren zusätzlichen Funktionen zum Erstellen von APIs, mit Datenvalidierung, usw. |
|||
|
|||
* **Uvicorn**: |
|||
* Bietet die beste Leistung, da außer dem Server selbst nicht viel zusätzlicher Code vorhanden ist. |
|||
* Sie würden eine Anwendung nicht direkt in Uvicorn schreiben. Das würde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten müsste. Und wenn Sie das täten, hätte Ihre endgültige Anwendung den gleichen Overhead wie die Verwendung eines Frameworks nebst Minimierung Ihres Anwendungscodes und der Fehler. |
|||
* Wenn Sie Uvicorn vergleichen, vergleichen Sie es mit Anwendungsservern wie Daphne, Hypercorn, uWSGI, usw. |
|||
* **Starlette**: |
|||
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich nutzt Starlette intern Uvicorn. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn sein, weil mehr Code ausgeführt wird. |
|||
* Aber es bietet Ihnen die Tools zum Erstellen einfacher Webanwendungen, mit Routing basierend auf Pfaden, usw. |
|||
* Wenn Sie Starlette vergleichen, vergleichen Sie es mit Webframeworks (oder Mikroframeworks) wie Sanic, Flask, Django, usw. |
|||
* **FastAPI**: |
|||
* So wie Starlette Uvicorn verwendet und nicht schneller als dieses sein kann, verwendet **FastAPI** Starlette, sodass es nicht schneller als dieses sein kann. |
|||
* FastAPI bietet zusätzlich zu Starlette weitere Funktionen. Funktionen, die Sie beim Erstellen von APIs fast immer benötigen, wie Datenvalidierung und Serialisierung. Und wenn Sie es verwenden, erhalten Sie kostenlos automatische Dokumentation (die automatische Dokumentation verursacht nicht einmal zusätzlichen Aufwand für laufende Anwendungen, sie wird beim Start generiert). |
|||
* Wenn Sie FastAPI nicht, und direkt Starlette (oder ein anderes Tool wie Sanic, Flask, Responder, usw.) verwenden würden, müssten Sie die gesamte Datenvalidierung und Serialisierung selbst implementieren. Ihre finale Anwendung hätte also immer noch den gleichen Overhead, als ob sie mit FastAPI erstellt worden wäre. Und in vielen Fällen ist diese Datenvalidierung und Serialisierung der größte Teil des in Anwendungen geschriebenen Codes. |
|||
* Durch die Verwendung von FastAPI sparen Sie also Entwicklungszeit, Fehler und Codezeilen und würden wahrscheinlich die gleiche Leistung (oder eine bessere) erzielen, die Sie hätten, wenn Sie es nicht verwenden würden (da Sie alles in Ihrem Code implementieren müssten). |
|||
* Wenn Sie FastAPI vergleichen, vergleichen Sie es mit einem Webanwendung-Framework (oder einer Reihe von Tools), welche Datenvalidierung, Serialisierung und Dokumentation bereitstellen, wie Flask-apispec, NestJS, Molten, usw. – Frameworks mit integrierter automatischer Datenvalidierung, Serialisierung und Dokumentation. |
@ -0,0 +1,3 @@ |
|||
# Hilfe |
|||
|
|||
Helfen und Hilfe erhalten, beitragen, mitmachen. 🤝 |
@ -0,0 +1,5 @@ |
|||
# Lernen |
|||
|
|||
Hier finden Sie die einführenden Kapitel und Tutorials zum Erlernen von **FastAPI**. |
|||
|
|||
Sie könnten dies als **Buch**, als **Kurs**, als **offizielle** und empfohlene Methode zum Erlernen von FastAPI betrachten. 😎 |
@ -0,0 +1,8 @@ |
|||
# Referenz – Code-API |
|||
|
|||
Hier ist die Referenz oder Code-API, die Klassen, Funktionen, Parameter, Attribute und alle FastAPI-Teile, die Sie in Ihren Anwendungen verwenden können. |
|||
|
|||
Wenn Sie **FastAPI** lernen möchten, ist es viel besser, das [FastAPI-Tutorial](https://fastapi.tiangolo.com/tutorial/) zu lesen. |
|||
|
|||
!!! note "Hinweis Deutsche Übersetzung" |
|||
Die nachfolgende API wird aus der Quelltext-Dokumentation erstellt, daher sind nur die Einleitungen auf Deutsch. |
@ -0,0 +1,3 @@ |
|||
# Ressourcen |
|||
|
|||
Zusätzliche Ressourcen, externe Links, Artikel und mehr. ✈️ |
@ -0,0 +1,126 @@ |
|||
# Hintergrundtasks |
|||
|
|||
Sie können Hintergrundtasks (Hintergrund-Aufgaben) definieren, die *nach* der Rückgabe einer Response ausgeführt werden sollen. |
|||
|
|||
Das ist nützlich für Vorgänge, die nach einem Request ausgeführt werden müssen, bei denen der Client jedoch nicht unbedingt auf den Abschluss des Vorgangs warten muss, bevor er die Response erhält. |
|||
|
|||
Hierzu zählen beispielsweise: |
|||
|
|||
* E-Mail-Benachrichtigungen, die nach dem Ausführen einer Aktion gesendet werden: |
|||
* Da die Verbindung zu einem E-Mail-Server und das Senden einer E-Mail in der Regel „langsam“ ist (einige Sekunden), können Sie die Response sofort zurücksenden und die E-Mail-Benachrichtigung im Hintergrund senden. |
|||
* Daten verarbeiten: |
|||
* Angenommen, Sie erhalten eine Datei, die einen langsamen Prozess durchlaufen muss. Sie können als Response „Accepted“ (HTTP 202) zurückgeben und die Datei im Hintergrund verarbeiten. |
|||
|
|||
## `BackgroundTasks` verwenden |
|||
|
|||
Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`: |
|||
|
|||
```Python hl_lines="1 13" |
|||
{!../../../docs_src/background_tasks/tutorial001.py!} |
|||
``` |
|||
|
|||
**FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter. |
|||
|
|||
## Eine Taskfunktion erstellen |
|||
|
|||
Erstellen Sie eine Funktion, die als Hintergrundtask ausgeführt werden soll. |
|||
|
|||
Es handelt sich schlicht um eine Standard-Funktion, die Parameter empfangen kann. |
|||
|
|||
Es kann sich um eine `async def`- oder normale `def`-Funktion handeln. **FastAPI** weiß, wie damit zu verfahren ist. |
|||
|
|||
In diesem Fall schreibt die Taskfunktion in eine Datei (den Versand einer E-Mail simulierend). |
|||
|
|||
Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir die Funktion mit normalem `def`: |
|||
|
|||
```Python hl_lines="6-9" |
|||
{!../../../docs_src/background_tasks/tutorial001.py!} |
|||
``` |
|||
|
|||
## Den Hintergrundtask hinzufügen |
|||
|
|||
Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt: |
|||
|
|||
```Python hl_lines="14" |
|||
{!../../../docs_src/background_tasks/tutorial001.py!} |
|||
``` |
|||
|
|||
`.add_task()` erhält als Argumente: |
|||
|
|||
* Eine Taskfunktion, die im Hintergrund ausgeführt wird (`write_notification`). |
|||
* Eine beliebige Folge von Argumenten, die der Reihe nach an die Taskfunktion übergeben werden sollen (`email`). |
|||
* Alle Schlüsselwort-Argumente, die an die Taskfunktion übergeben werden sollen (`message="some notification"`). |
|||
|
|||
## Dependency Injection |
|||
|
|||
Die Verwendung von `BackgroundTasks` funktioniert auch mit dem <abbr title="Einbringen von Abhängigkeiten">Dependency Injection</abbr> System. Sie können einen Parameter vom Typ `BackgroundTasks` auf mehreren Ebenen deklarieren: in einer *Pfadoperation-Funktion*, in einer Abhängigkeit (Dependable), in einer Unterabhängigkeit usw. |
|||
|
|||
**FastAPI** weiß, was jeweils zu tun ist und wie dasselbe Objekt wiederverwendet werden kann, sodass alle Hintergrundtasks zusammengeführt und anschließend im Hintergrund ausgeführt werden: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="13 15 22 25" |
|||
{!> ../../../docs_src/background_tasks/tutorial002_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="13 15 22 25" |
|||
{!> ../../../docs_src/background_tasks/tutorial002_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="14 16 23 26" |
|||
{!> ../../../docs_src/background_tasks/tutorial002_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="11 13 20 23" |
|||
{!> ../../../docs_src/background_tasks/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="13 15 22 25" |
|||
{!> ../../../docs_src/background_tasks/tutorial002.py!} |
|||
``` |
|||
|
|||
In obigem Beispiel werden die Nachrichten, *nachdem* die Response gesendet wurde, in die Datei `log.txt` geschrieben. |
|||
|
|||
Wenn im Request ein Query-Parameter enthalten war, wird dieser in einem Hintergrundtask in das Log geschrieben. |
|||
|
|||
Und dann schreibt ein weiterer Hintergrundtask, der in der *Pfadoperation-Funktion* erstellt wird, eine Nachricht unter Verwendung des Pfad-Parameters `email`. |
|||
|
|||
## Technische Details |
|||
|
|||
Die Klasse `BackgroundTasks` stammt direkt von <a href="https://www.starlette.io/background/" class="external-link" target="_blank">`starlette.background`</a>. |
|||
|
|||
Sie wird direkt in FastAPI importiert/inkludiert, sodass Sie sie von `fastapi` importieren können und vermeiden, versehentlich das alternative `BackgroundTask` (ohne das `s` am Ende) von `starlette.background` zu importieren. |
|||
|
|||
Indem Sie nur `BackgroundTasks` (und nicht `BackgroundTask`) verwenden, ist es dann möglich, es als *Pfadoperation-Funktion*-Parameter zu verwenden und **FastAPI** den Rest für Sie erledigen zu lassen, genau wie bei der direkten Verwendung des `Request`-Objekts. |
|||
|
|||
Es ist immer noch möglich, `BackgroundTask` allein in FastAPI zu verwenden, aber Sie müssen das Objekt in Ihrem Code erstellen und eine Starlette-`Response` zurückgeben, die es enthält. |
|||
|
|||
Weitere Details finden Sie in der <a href="https://www.starlette.io/background/" class="external-link" target="_blank">offiziellen Starlette-Dokumentation für Hintergrundtasks</a>. |
|||
|
|||
## Vorbehalt |
|||
|
|||
Wenn Sie umfangreiche Hintergrundberechnungen durchführen müssen und diese nicht unbedingt vom selben Prozess ausgeführt werden müssen (z. B. müssen Sie Speicher, Variablen, usw. nicht gemeinsam nutzen), könnte die Verwendung anderer größerer Tools wie z. B. <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a> von Vorteil sein. |
|||
|
|||
Sie erfordern in der Regel komplexere Konfigurationen und einen Nachrichten-/Job-Queue-Manager wie RabbitMQ oder Redis, ermöglichen Ihnen jedoch die Ausführung von Hintergrundtasks in mehreren Prozessen und insbesondere auf mehreren Servern. |
|||
|
|||
Um ein Beispiel zu sehen, sehen Sie sich die [Projektgeneratoren](../project-generation.md){.internal-link target=_blank} an. Sie alle enthalten Celery, bereits konfiguriert. |
|||
|
|||
Wenn Sie jedoch über dieselbe **FastAPI**-Anwendung auf Variablen und Objekte zugreifen oder kleine Hintergrundtasks ausführen müssen (z. B. das Senden einer E-Mail-Benachrichtigung), können Sie einfach `BackgroundTasks` verwenden. |
|||
|
|||
## Zusammenfassung |
|||
|
|||
Importieren und verwenden Sie `BackgroundTasks` mit Parametern in *Pfadoperation-Funktionen* und Abhängigkeiten, um Hintergrundtasks hinzuzufügen. |
@ -0,0 +1,115 @@ |
|||
# Body – Felder |
|||
|
|||
So wie Sie zusätzliche Validation und Metadaten in Parametern der **Pfadoperation-Funktion** mittels `Query`, `Path` und `Body` deklarieren, können Sie auch innerhalb von Pydantic-Modellen zusätzliche Validation und Metadaten deklarieren, mittels Pydantics `Field`. |
|||
|
|||
## `Field` importieren |
|||
|
|||
Importieren Sie es zuerst: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="4" |
|||
{!> ../../../docs_src/body_fields/tutorial001_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="4" |
|||
{!> ../../../docs_src/body_fields/tutorial001_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="4" |
|||
{!> ../../../docs_src/body_fields/tutorial001_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="2" |
|||
{!> ../../../docs_src/body_fields/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="4" |
|||
{!> ../../../docs_src/body_fields/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! warning "Achtung" |
|||
Beachten Sie, dass `Field` direkt von `pydantic` importiert wird, nicht von `fastapi`, wie die anderen (`Query`, `Path`, `Body`, usw.) |
|||
|
|||
## Modellattribute deklarieren |
|||
|
|||
Dann können Sie `Field` mit Modellattributen deklarieren: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="11-14" |
|||
{!> ../../../docs_src/body_fields/tutorial001_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="11-14" |
|||
{!> ../../../docs_src/body_fields/tutorial001_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="12-15" |
|||
{!> ../../../docs_src/body_fields/tutorial001_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="9-12" |
|||
{!> ../../../docs_src/body_fields/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="11-14" |
|||
{!> ../../../docs_src/body_fields/tutorial001.py!} |
|||
``` |
|||
|
|||
`Field` funktioniert genauso wie `Query`, `Path` und `Body`, es hat die gleichen Parameter, usw. |
|||
|
|||
!!! note "Technische Details" |
|||
Tatsächlich erstellen `Query`, `Path` und andere, die sie kennenlernen werden, Instanzen von Unterklassen einer allgemeinen Klasse `Param`, die ihrerseits eine Unterklasse von Pydantics `FieldInfo`-Klasse ist. |
|||
|
|||
Und Pydantics `Field` gibt ebenfalls eine Instanz von `FieldInfo` zurück. |
|||
|
|||
`Body` gibt auch Instanzen einer Unterklasse von `FieldInfo` zurück. Und später werden Sie andere sehen, die Unterklassen der `Body`-Klasse sind. |
|||
|
|||
Denken Sie daran, dass `Query`, `Path` und andere von `fastapi` tatsächlich Funktionen sind, die spezielle Klassen zurückgeben. |
|||
|
|||
!!! tip "Tipp" |
|||
Beachten Sie, dass jedes Modellattribut mit einem Typ, Defaultwert und `Field` die gleiche Struktur hat wie ein Parameter einer Pfadoperation-Funktion, nur mit `Field` statt `Path`, `Query`, `Body`. |
|||
|
|||
## Zusätzliche Information hinzufügen |
|||
|
|||
Sie können zusätzliche Information in `Field`, `Query`, `Body`, usw. deklarieren. Und es wird im generierten JSON-Schema untergebracht. |
|||
|
|||
Sie werden später mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren. |
|||
|
|||
!!! warning "Achtung" |
|||
Extra-Schlüssel, die `Field` überreicht werden, werden auch im resultierenden OpenAPI-Schema Ihrer Anwendung gelistet. Da diese Schlüssel nicht notwendigerweise Teil der OpenAPI-Spezifikation sind, könnten einige OpenAPI-Tools, wie etwa [der OpenAPI-Validator](https://validator.swagger.io/), nicht mit Ihrem generierten Schema funktionieren. |
|||
|
|||
## Zusammenfassung |
|||
|
|||
Sie können Pydantics `Field` verwenden, um zusätzliche Validierungen und Metadaten für Modellattribute zu deklarieren. |
|||
|
|||
Sie können auch Extra-Schlüssel verwenden, um zusätzliche JSON-Schema-Metadaten zu überreichen. |
@ -0,0 +1,308 @@ |
|||
# Body – Mehrere Parameter |
|||
|
|||
Jetzt, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von Requestbody-Deklarationen an. |
|||
|
|||
## `Path`-, `Query`- und Body-Parameter vermischen |
|||
|
|||
Zuerst einmal, Sie können `Path`-, `Query`- und Requestbody-Parameter-Deklarationen frei mischen und **FastAPI** wird wissen, was zu tun ist. |
|||
|
|||
Und Sie können auch Body-Parameter als optional kennzeichnen, indem Sie den Defaultwert auf `None` setzen: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="18-20" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="18-20" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="19-21" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="17-19" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="19-21" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! note "Hinweis" |
|||
Beachten Sie, dass in diesem Fall das `item`, welches vom Body genommen wird, optional ist. Da es `None` als Defaultwert hat. |
|||
|
|||
## Mehrere Body-Parameter |
|||
|
|||
Im vorherigen Beispiel erwartete die *Pfadoperation* einen JSON-Body mit den Attributen eines `Item`s, etwa: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
} |
|||
``` |
|||
|
|||
Aber Sie können auch mehrere Body-Parameter deklarieren, z. B. `item` und `user`: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="22" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial002.py!} |
|||
``` |
|||
|
|||
In diesem Fall wird **FastAPI** bemerken, dass es mehr als einen Body-Parameter in der Funktion gibt (zwei Parameter, die Pydantic-Modelle sind). |
|||
|
|||
Es wird deshalb die Parameternamen als Schlüssel (Feldnamen) im Body verwenden, und erwartet einen Body wie folgt: |
|||
|
|||
```JSON |
|||
{ |
|||
"item": { |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
}, |
|||
"user": { |
|||
"username": "dave", |
|||
"full_name": "Dave Grohl" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
!!! note "Hinweis" |
|||
Beachten Sie, dass, obwohl `item` wie zuvor deklariert wurde, es nun unter einem Schlüssel `item` im Body erwartet wird. |
|||
|
|||
**FastAPI** wird die automatische Konvertierung des Requests übernehmen, sodass der Parameter `item` seinen spezifischen Inhalt bekommt, genau so wie der Parameter `user`. |
|||
|
|||
Es wird die Validierung dieser zusammengesetzten Daten übernehmen, und sie im OpenAPI-Schema und der automatischen Dokumentation dokumentieren. |
|||
|
|||
## Einzelne Werte im Body |
|||
|
|||
So wie `Query` und `Path` für Query- und Pfad-Parameter, hat **FastAPI** auch das Äquivalent `Body`, um Extra-Daten für Body-Parameter zu definieren. |
|||
|
|||
Zum Beispiel, das vorherige Modell erweiternd, könnten Sie entscheiden, dass Sie einen weiteren Schlüssel <abbr title="Wichtigkeit">`importance`</abbr> haben möchten, im selben Body, Seite an Seite mit `item` und `user`. |
|||
|
|||
Wenn Sie diesen Parameter einfach so hinzufügen, wird **FastAPI** annehmen, dass es ein Query-Parameter ist. |
|||
|
|||
Aber Sie können **FastAPI** instruieren, ihn als weiteren Body-Schlüssel zu erkennen, indem Sie `Body` verwenden: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="23" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="23" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="24" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="22" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!} |
|||
``` |
|||
|
|||
In diesem Fall erwartet **FastAPI** einen Body wie: |
|||
|
|||
```JSON |
|||
{ |
|||
"item": { |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
}, |
|||
"user": { |
|||
"username": "dave", |
|||
"full_name": "Dave Grohl" |
|||
}, |
|||
"importance": 5 |
|||
} |
|||
``` |
|||
|
|||
Wiederum wird es die Daten konvertieren, validieren, dokumentieren, usw. |
|||
|
|||
## Mehrere Body-Parameter und Query-Parameter |
|||
|
|||
Natürlich können Sie auch, wann immer Sie das brauchen, weitere Query-Parameter hinzufügen, zusätzlich zu den Body-Parametern. |
|||
|
|||
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben: |
|||
|
|||
```Python |
|||
q: Union[str, None] = None |
|||
``` |
|||
|
|||
Oder in Python 3.10 und darüber: |
|||
|
|||
```Python |
|||
q: str | None = None |
|||
``` |
|||
|
|||
Zum Beispiel: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="27" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="27" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="28" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="25" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="27" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial004.py!} |
|||
``` |
|||
|
|||
!!! info |
|||
`Body` hat die gleichen zusätzlichen Validierungs- und Metadaten-Parameter wie `Query` und `Path` und andere, die Sie später kennenlernen. |
|||
|
|||
## Einen einzelnen Body-Parameter einbetten |
|||
|
|||
Nehmen wir an, Sie haben nur einen einzelnen `item`-Body-Parameter, ein Pydantic-Modell `Item`. |
|||
|
|||
Normalerweise wird **FastAPI** dann seinen JSON-Body direkt erwarten. |
|||
|
|||
Aber wenn Sie möchten, dass es einen JSON-Body erwartet, mit einem Schlüssel `item` und darin den Inhalt des Modells, so wie es das tut, wenn Sie mehrere Body-Parameter deklarieren, dann können Sie den speziellen `Body`-Parameter `embed` setzen: |
|||
|
|||
```Python |
|||
item: Item = Body(embed=True) |
|||
``` |
|||
|
|||
so wie in: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="17" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="17" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="18" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005_an.py!} |
|||
``` |
|||
|
|||
=== "Python 3.10+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="15" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+ nicht annotiert" |
|||
|
|||
!!! tip "Tipp" |
|||
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
|||
|
|||
```Python hl_lines="17" |
|||
{!> ../../../docs_src/body_multiple_params/tutorial005.py!} |
|||
``` |
|||
|
|||
In diesem Fall erwartet **FastAPI** einen Body wie: |
|||
|
|||
```JSON hl_lines="2" |
|||
{ |
|||
"item": { |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
} |
|||
} |
|||
``` |
|||
|
|||
statt: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2 |
|||
} |
|||
``` |
|||
|
|||
## Zusammenfassung |
|||
|
|||
Sie können mehrere Body-Parameter zu ihrer *Pfadoperation-Funktion* hinzufügen, obwohl ein Request nur einen einzigen Body enthalten kann. |
|||
|
|||
**FastAPI** wird sich darum kümmern, Ihnen korrekte Daten in Ihrer Funktion zu überreichen, und das korrekte Schema in der *Pfadoperation* zu validieren und zu dokumentieren. |
|||
|
|||
Sie können auch einzelne Werte deklarieren, die als Teil des Bodys empfangen werden. |
|||
|
|||
Und Sie können **FastAPI** instruieren, den Body in einem Schlüssel unterzubringen, selbst wenn nur ein einzelner Body-Parameter deklariert ist. |
@ -0,0 +1,382 @@ |
|||
# Body – Verschachtelte Modelle |
|||
|
|||
Mit **FastAPI** können Sie (dank Pydantic) beliebig tief verschachtelte Modelle definieren, validieren und dokumentieren. |
|||
|
|||
## Listen als Felder |
|||
|
|||
Sie können ein Attribut als Kindtyp definieren, zum Beispiel eine Python-`list`e. |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="12" |
|||
{!> ../../../docs_src/body_nested_models/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="14" |
|||
{!> ../../../docs_src/body_nested_models/tutorial001.py!} |
|||
``` |
|||
|
|||
Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts über den Typ der Elemente der Liste aussagt. |
|||
|
|||
## Listen mit Typ-Parametern als Felder |
|||
|
|||
Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren. |
|||
|
|||
### `List` von `typing` importieren |
|||
|
|||
In Python 3.9 oder darüber können Sie einfach `list` verwenden, um diese Typannotationen zu deklarieren, wie wir unten sehen werden. 💡 |
|||
|
|||
In Python-Versionen vor 3.9 (3.6 und darüber), müssen Sie zuerst `List` von Pythons Standardmodul `typing` importieren. |
|||
|
|||
```Python hl_lines="1" |
|||
{!> ../../../docs_src/body_nested_models/tutorial002.py!} |
|||
``` |
|||
|
|||
### Eine `list`e mit einem Typ-Parameter deklarieren |
|||
|
|||
Um Typen wie `list`, `dict`, `tuple` mit inneren Typ-Parametern (inneren Typen) zu deklarieren: |
|||
|
|||
* Wenn Sie eine Python-Version kleiner als 3.9 verwenden, importieren Sie das Äquivalent zum entsprechenden Typ vom `typing`-Modul |
|||
* Überreichen Sie den/die inneren Typ(en) von eckigen Klammern umschlossen, `[` und `]`, als „Typ-Parameter“ |
|||
|
|||
In Python 3.9 wäre das: |
|||
|
|||
```Python |
|||
my_list: list[str] |
|||
``` |
|||
|
|||
Und in Python-Versionen vor 3.9: |
|||
|
|||
```Python |
|||
from typing import List |
|||
|
|||
my_list: List[str] |
|||
``` |
|||
|
|||
Das ist alles Standard-Python-Syntax für Typdeklarationen. |
|||
|
|||
Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen. |
|||
|
|||
In unserem Beispiel können wir also bewirken, dass `tags` spezifisch eine „Liste von Strings“ ist: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="12" |
|||
{!> ../../../docs_src/body_nested_models/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="14" |
|||
{!> ../../../docs_src/body_nested_models/tutorial002_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="14" |
|||
{!> ../../../docs_src/body_nested_models/tutorial002.py!} |
|||
``` |
|||
|
|||
## Set-Typen |
|||
|
|||
Aber dann denken wir darüber nach und stellen fest, dass sich die Tags nicht wiederholen sollen, es sollen eindeutige Strings sein. |
|||
|
|||
Python hat einen Datentyp speziell für Mengen eindeutiger Dinge: das <abbr title="Menge">`set`</abbr>. |
|||
|
|||
Deklarieren wir also `tags` als Set von Strings. |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="12" |
|||
{!> ../../../docs_src/body_nested_models/tutorial003_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="14" |
|||
{!> ../../../docs_src/body_nested_models/tutorial003_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="1 14" |
|||
{!> ../../../docs_src/body_nested_models/tutorial003.py!} |
|||
``` |
|||
|
|||
Jetzt, selbst wenn Sie einen Request mit duplizierten Daten erhalten, werden diese zu einem Set eindeutiger Dinge konvertiert. |
|||
|
|||
Und wann immer Sie diese Daten ausgeben, selbst wenn die Quelle Duplikate hatte, wird es als Set von eindeutigen Dingen ausgegeben. |
|||
|
|||
Und es wird entsprechend annotiert/dokumentiert. |
|||
|
|||
## Verschachtelte Modelle |
|||
|
|||
Jedes Attribut eines Pydantic-Modells hat einen Typ. |
|||
|
|||
Aber dieser Typ kann selbst ein anderes Pydantic-Modell sein. |
|||
|
|||
Sie können also tief verschachtelte JSON-„Objekte“ deklarieren, mit spezifischen Attributnamen, -typen, und -validierungen. |
|||
|
|||
Alles das beliebig tief verschachtelt. |
|||
|
|||
### Ein Kindmodell definieren |
|||
|
|||
Wir können zum Beispiel ein `Image`-Modell definieren. |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="7-9" |
|||
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="9-11" |
|||
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="9-11" |
|||
{!> ../../../docs_src/body_nested_models/tutorial004.py!} |
|||
``` |
|||
|
|||
### Das Kindmodell als Typ verwenden |
|||
|
|||
Und dann können wir es als Typ eines Attributes verwenden. |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="18" |
|||
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_nested_models/tutorial004.py!} |
|||
``` |
|||
|
|||
Das würde bedeuten, dass **FastAPI** einen Body erwartet wie: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2, |
|||
"tags": ["rock", "metal", "bar"], |
|||
"image": { |
|||
"url": "http://example.com/baz.jpg", |
|||
"name": "The Foo live" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Wiederum, nur mit dieser Deklaration erhalten Sie von **FastAPI**: |
|||
|
|||
* Editor-Unterstützung (Codevervollständigung, usw.), selbst für verschachtelte Modelle |
|||
* Datenkonvertierung |
|||
* Datenvalidierung |
|||
* Automatische Dokumentation |
|||
|
|||
## Spezielle Typen und Validierungen |
|||
|
|||
Abgesehen von normalen einfachen Typen, wie `str`, `int`, `float`, usw. können Sie komplexere einfache Typen verwenden, die von `str` erben. |
|||
|
|||
Um alle Optionen kennenzulernen, die Sie haben, schauen Sie sich <a href="https://pydantic-docs.helpmanual.io/usage/types/" class="external-link" target="_blank">Pydantics Typübersicht</a> an. Sie werden im nächsten Kapitel ein paar Beispiele kennenlernen. |
|||
|
|||
Da wir zum Beispiel im `Image`-Modell ein Feld `url` haben, können wir deklarieren, dass das eine Instanz von Pydantics `HttpUrl` sein soll, anstelle eines `str`: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="2 8" |
|||
{!> ../../../docs_src/body_nested_models/tutorial005_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="4 10" |
|||
{!> ../../../docs_src/body_nested_models/tutorial005_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="4 10" |
|||
{!> ../../../docs_src/body_nested_models/tutorial005.py!} |
|||
``` |
|||
|
|||
Es wird getestet, ob der String eine gültige URL ist, und als solche wird er in JSON Schema / OpenAPI dokumentiert. |
|||
|
|||
## Attribute mit Listen von Kindmodellen |
|||
|
|||
Sie können Pydantic-Modelle auch als Typen innerhalb von `list`, `set`, usw. verwenden: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="18" |
|||
{!> ../../../docs_src/body_nested_models/tutorial006_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_nested_models/tutorial006_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="20" |
|||
{!> ../../../docs_src/body_nested_models/tutorial006.py!} |
|||
``` |
|||
|
|||
Das wird einen JSON-Body erwarten (konvertieren, validieren, dokumentieren), wie: |
|||
|
|||
```JSON hl_lines="11" |
|||
{ |
|||
"name": "Foo", |
|||
"description": "The pretender", |
|||
"price": 42.0, |
|||
"tax": 3.2, |
|||
"tags": [ |
|||
"rock", |
|||
"metal", |
|||
"bar" |
|||
], |
|||
"images": [ |
|||
{ |
|||
"url": "http://example.com/baz.jpg", |
|||
"name": "The Foo live" |
|||
}, |
|||
{ |
|||
"url": "http://example.com/dave.jpg", |
|||
"name": "The Baz" |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
!!! info |
|||
Beachten Sie, dass der `images`-Schlüssel jetzt eine Liste von Bild-Objekten hat. |
|||
|
|||
## Tief verschachtelte Modelle |
|||
|
|||
Sie können beliebig tief verschachtelte Modelle definieren: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="7 12 18 21 25" |
|||
{!> ../../../docs_src/body_nested_models/tutorial007_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="9 14 20 23 27" |
|||
{!> ../../../docs_src/body_nested_models/tutorial007_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="9 14 20 23 27" |
|||
{!> ../../../docs_src/body_nested_models/tutorial007.py!} |
|||
``` |
|||
|
|||
!!! info |
|||
Beachten Sie, wie `Offer` eine Liste von `Item`s hat, von denen jedes seinerseits eine optionale Liste von `Image`s hat. |
|||
|
|||
## Bodys aus reinen Listen |
|||
|
|||
Wenn Sie möchten, dass das äußerste Element des JSON-Bodys ein JSON-`array` (eine Python-`list`e) ist, können Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen: |
|||
|
|||
```Python |
|||
images: List[Image] |
|||
``` |
|||
|
|||
oder in Python 3.9 und darüber: |
|||
|
|||
```Python |
|||
images: list[Image] |
|||
``` |
|||
|
|||
so wie in: |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="13" |
|||
{!> ../../../docs_src/body_nested_models/tutorial008_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="15" |
|||
{!> ../../../docs_src/body_nested_models/tutorial008.py!} |
|||
``` |
|||
|
|||
## Editor-Unterstützung überall |
|||
|
|||
Und Sie erhalten Editor-Unterstützung überall. |
|||
|
|||
Selbst für Dinge in Listen: |
|||
|
|||
<img src="/img/tutorial/body-nested-models/image01.png"> |
|||
|
|||
Sie würden diese Editor-Unterstützung nicht erhalten, wenn Sie direkt mit `dict`, statt mit Pydantic-Modellen arbeiten würden. |
|||
|
|||
Aber Sie müssen sich auch nicht weiter um die Modelle kümmern, hereinkommende Dicts werden automatisch in sie konvertiert. Und was Sie zurückgeben, wird automatisch nach JSON konvertiert. |
|||
|
|||
## Bodys mit beliebigen `dict`s |
|||
|
|||
Sie können einen Body auch als `dict` deklarieren, mit Schlüsseln eines Typs und Werten eines anderen Typs. |
|||
|
|||
So brauchen Sie vorher nicht zu wissen, wie die Feld-/Attribut-Namen lauten (wie es bei Pydantic-Modellen der Fall wäre). |
|||
|
|||
Das ist nützlich, wenn Sie Schlüssel empfangen, deren Namen Sie nicht bereits kennen. |
|||
|
|||
--- |
|||
|
|||
Ein anderer nützlicher Anwendungsfall ist, wenn Sie Schlüssel eines anderen Typs haben wollen, z. B. `int`. |
|||
|
|||
Das schauen wir uns mal an. |
|||
|
|||
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat. |
|||
|
|||
=== "Python 3.9+" |
|||
|
|||
```Python hl_lines="7" |
|||
{!> ../../../docs_src/body_nested_models/tutorial009_py39.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="9" |
|||
{!> ../../../docs_src/body_nested_models/tutorial009.py!} |
|||
``` |
|||
|
|||
!!! tip "Tipp" |
|||
Bedenken Sie, dass JSON nur `str` als Schlüssel unterstützt. |
|||
|
|||
Aber Pydantic hat automatische Datenkonvertierung. |
|||
|
|||
Das bedeutet, dass Ihre API-Clients nur Strings senden können, aber solange diese Strings nur Zahlen enthalten, wird Pydantic sie konvertieren und validieren. |
|||
|
|||
Und das `dict` welches Sie als `weights` erhalten, wird `int`-Schlüssel und `float`-Werte haben. |
|||
|
|||
## Zusammenfassung |
|||
|
|||
Mit **FastAPI** haben Sie die maximale Flexibilität von Pydantic-Modellen, während Ihr Code einfach, kurz und elegant bleibt. |
|||
|
|||
Aber mit all den Vorzügen: |
|||
|
|||
* Editor-Unterstützung (Codevervollständigung überall) |
|||
* Datenkonvertierung (auch bekannt als Parsen, Serialisierung) |
|||
* Datenvalidierung |
|||
* Schema-Dokumentation |
|||
* Automatische Dokumentation |
@ -0,0 +1,213 @@ |
|||
# Requestbody |
|||
|
|||
Wenn Sie Daten von einem <abbr title="Client: Eine Software, die sich mit einem Server verbindet.">Client</abbr> (sagen wir, einem Browser) zu Ihrer API senden, dann senden Sie diese als einen **Requestbody** (Deutsch: Anfragekörper). |
|||
|
|||
Ein **Request**body sind Daten, die vom Client zu Ihrer API gesendet werden. Ein **Response**body (Deutsch: Antwortkörper) sind Daten, die Ihre API zum Client sendet. |
|||
|
|||
Ihre API sendet fast immer einen **Response**body. Aber Clients senden nicht unbedingt immer **Request**bodys (sondern nur Metadaten). |
|||
|
|||
Um einen **Request**body zu deklarieren, verwenden Sie <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>-Modelle mit allen deren Fähigkeiten und Vorzügen. |
|||
|
|||
!!! info |
|||
Um Daten zu versenden, sollten Sie eines von: `POST` (meistverwendet), `PUT`, `DELETE` oder `PATCH` verwenden. |
|||
|
|||
Senden Sie einen Body mit einem `GET`-Request, dann führt das laut Spezifikation zu undefiniertem Verhalten. Trotzdem wird es von FastAPI unterstützt, für sehr komplexe/extreme Anwendungsfälle. |
|||
|
|||
Da aber davon abgeraten wird, zeigt die interaktive Dokumentation mit Swagger-Benutzeroberfläche die Dokumentation für den Body auch nicht an, wenn `GET` verwendet wird. Dazwischengeschaltete Proxys unterstützen es möglicherweise auch nicht. |
|||
|
|||
## Importieren Sie Pydantics `BaseModel` |
|||
|
|||
Zuerst müssen Sie `BaseModel` von `pydantic` importieren: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="2" |
|||
{!> ../../../docs_src/body/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="4" |
|||
{!> ../../../docs_src/body/tutorial001.py!} |
|||
``` |
|||
|
|||
## Erstellen Sie Ihr Datenmodell |
|||
|
|||
Dann deklarieren Sie Ihr Datenmodell als eine Klasse, die von `BaseModel` erbt. |
|||
|
|||
Verwenden Sie Standard-Python-Typen für die Klassenattribute: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="5-9" |
|||
{!> ../../../docs_src/body/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="7-11" |
|||
{!> ../../../docs_src/body/tutorial001.py!} |
|||
``` |
|||
|
|||
Wie auch bei Query-Parametern gilt, wenn ein Modellattribut einen Defaultwert hat, ist das Attribut nicht erforderlich. Ansonsten ist es erforderlich. Verwenden Sie `None`, um es als optional zu kennzeichnen. |
|||
|
|||
Zum Beispiel deklariert das obige Modell ein JSON "`object`" (oder Python-`dict`) wie dieses: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"description": "An optional description", |
|||
"price": 45.2, |
|||
"tax": 3.5 |
|||
} |
|||
``` |
|||
|
|||
Da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre folgendes JSON "`object`" auch gültig: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"price": 45.2 |
|||
} |
|||
``` |
|||
|
|||
## Deklarieren Sie es als Parameter |
|||
|
|||
Um es zu Ihrer *Pfadoperation* hinzuzufügen, deklarieren Sie es auf die gleiche Weise, wie Sie Pfad- und Query-Parameter deklariert haben: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="16" |
|||
{!> ../../../docs_src/body/tutorial001_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="18" |
|||
{!> ../../../docs_src/body/tutorial001.py!} |
|||
``` |
|||
|
|||
... und deklarieren Sie seinen Typ als das Modell, welches Sie erstellt haben, `Item`. |
|||
|
|||
## Resultate |
|||
|
|||
Mit nur dieser Python-Typdeklaration, wird **FastAPI**: |
|||
|
|||
* Den Requestbody als JSON lesen. |
|||
* Die entsprechenden Typen konvertieren (falls nötig). |
|||
* Diese Daten validieren. |
|||
* Wenn die Daten ungültig sind, einen klar lesbaren Fehler zurückgeben, der anzeigt, wo und was die inkorrekten Daten waren. |
|||
* Ihnen die erhaltenen Daten im Parameter `item` übergeben. |
|||
* Da Sie diesen in der Funktion als vom Typ `Item` deklariert haben, erhalten Sie die ganze Editor-Unterstützung (Autovervollständigung, usw.) für alle Attribute und deren Typen. |
|||
* Eine <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> Definition für Ihr Modell generieren, welche Sie überall sonst verwenden können, wenn es für Ihr Projekt Sinn macht. |
|||
* Diese Schemas werden Teil des generierten OpenAPI-Schemas und werden von den <abbr title="User Interface – Benutzeroberfläche">UIs</abbr> der automatischen Dokumentation verwendet. |
|||
|
|||
## Automatische Dokumentation |
|||
|
|||
Die JSON-Schemas Ihrer Modelle werden Teil ihrer OpenAPI-generierten Schemas und werden in der interaktiven API Dokumentation angezeigt: |
|||
|
|||
<img src="/img/tutorial/body/image01.png"> |
|||
|
|||
Und werden auch verwendet in der API-Dokumentation innerhalb jeder *Pfadoperation*, welche sie braucht: |
|||
|
|||
<img src="/img/tutorial/body/image02.png"> |
|||
|
|||
## Editor Unterstützung |
|||
|
|||
In Ihrem Editor, innerhalb Ihrer Funktion, erhalten Sie Typhinweise und Code-Vervollständigung überall (was nicht der Fall wäre, wenn Sie ein `dict` anstelle eines Pydantic Modells erhalten hätten): |
|||
|
|||
<img src="/img/tutorial/body/image03.png"> |
|||
|
|||
Sie bekommen auch Fehler-Meldungen für inkorrekte Typoperationen: |
|||
|
|||
<img src="/img/tutorial/body/image04.png"> |
|||
|
|||
Das ist nicht zufällig so, das ganze Framework wurde um dieses Design herum aufgebaut. |
|||
|
|||
Und es wurde in der Designphase gründlich getestet, vor der Implementierung, um sicherzustellen, dass es mit jedem Editor funktioniert. |
|||
|
|||
Es gab sogar ein paar Änderungen an Pydantic selbst, um das zu unterstützen. |
|||
|
|||
Die vorherigen Screenshots zeigten <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>. |
|||
|
|||
Aber Sie bekommen die gleiche Editor-Unterstützung in <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> und in den meisten anderen Python-Editoren: |
|||
|
|||
<img src="/img/tutorial/body/image05.png"> |
|||
|
|||
!!! tip "Tipp" |
|||
Wenn Sie <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> als Ihren Editor verwenden, probieren Sie das <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a> aus. |
|||
|
|||
Es verbessert die Editor-Unterstützung für Pydantic-Modelle, mit: |
|||
|
|||
* Code-Vervollständigung |
|||
* Typüberprüfungen |
|||
* Refaktorisierung |
|||
* Suchen |
|||
* Inspektionen |
|||
|
|||
## Das Modell verwenden |
|||
|
|||
Innerhalb der Funktion können Sie alle Attribute des Modells direkt verwenden: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="19" |
|||
{!> ../../../docs_src/body/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="21" |
|||
{!> ../../../docs_src/body/tutorial002.py!} |
|||
``` |
|||
|
|||
## Requestbody- + Pfad-Parameter |
|||
|
|||
Sie können Pfad- und Requestbody-Parameter gleichzeitig deklarieren. |
|||
|
|||
**FastAPI** erkennt, dass Funktionsparameter, die mit Pfad-Parametern übereinstimmen, **vom Pfad genommen** werden sollen, und dass Funktionsparameter, welche Pydantic-Modelle sind, **vom Requestbody genommen** werden sollen. |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="15-16" |
|||
{!> ../../../docs_src/body/tutorial003_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="17-18" |
|||
{!> ../../../docs_src/body/tutorial003.py!} |
|||
``` |
|||
|
|||
## Requestbody- + Pfad- + Query-Parameter |
|||
|
|||
Sie können auch zur gleichen Zeit **Body-**, **Pfad-** und **Query-Parameter** deklarieren. |
|||
|
|||
**FastAPI** wird jeden Parameter korrekt erkennen und die Daten vom richtigen Ort holen. |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="16" |
|||
{!> ../../../docs_src/body/tutorial004_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="18" |
|||
{!> ../../../docs_src/body/tutorial004.py!} |
|||
``` |
|||
|
|||
Die Funktionsparameter werden wie folgt erkannt: |
|||
|
|||
* Wenn der Parameter auch im **Pfad** deklariert wurde, wird er als Pfad-Parameter interpretiert. |
|||
* Wenn der Parameter ein **einfacher Typ** ist (wie `int`, `float`, `str`, `bool`, usw.), wird er als **Query**-Parameter interpretiert. |
|||
* Wenn der Parameter vom Typ eines **Pydantic-Modells** ist, wird er als Request**body** interpretiert. |
|||
|
|||
!!! note "Hinweis" |
|||
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, wegen des definierten Defaultwertes `= None` |
|||
|
|||
Das `Union` in `Union[str, None]` wird von FastAPI nicht verwendet, aber es erlaubt Ihrem Editor, Sie besser zu unterstützen und Fehler zu erkennen. |
|||
|
|||
## Ohne Pydantic |
|||
|
|||
Wenn Sie keine Pydantic-Modelle verwenden wollen, können Sie auch **Body**-Parameter nehmen. Siehe die Dokumentation unter [Body – Mehrere Parameter: Einfache Werte im Body](body-multiple-params.md#einzelne-werte-im-body){.internal-link target=\_blank}. |
@ -0,0 +1,333 @@ |
|||
# Erste Schritte |
|||
|
|||
Die einfachste FastAPI-Datei könnte wie folgt aussehen: |
|||
|
|||
```Python |
|||
{!../../../docs_src/first_steps/tutorial001.py!} |
|||
``` |
|||
|
|||
Kopieren Sie dies in eine Datei `main.py`. |
|||
|
|||
Starten Sie den Live-Server: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uvicorn main:app --reload |
|||
|
|||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|||
<span style="color: green;">INFO</span>: Started reloader process [28720] |
|||
<span style="color: green;">INFO</span>: Started server process [28722] |
|||
<span style="color: green;">INFO</span>: Waiting for application startup. |
|||
<span style="color: green;">INFO</span>: Application startup complete. |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
!!! note "Hinweis" |
|||
Der Befehl `uvicorn main:app` bezieht sich auf: |
|||
|
|||
* `main`: die Datei `main.py` (das sogenannte Python-„Modul“). |
|||
* `app`: das Objekt, welches in der Datei `main.py` mit der Zeile `app = FastAPI()` erzeugt wurde. |
|||
* `--reload`: lässt den Server nach Codeänderungen neu starten. Verwenden Sie das nur während der Entwicklung. |
|||
|
|||
In der Konsolenausgabe sollte es eine Zeile geben, die ungefähr so aussieht: |
|||
|
|||
```hl_lines="4" |
|||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|||
``` |
|||
|
|||
Diese Zeile zeigt die URL, unter der Ihre Anwendung auf Ihrem lokalen Computer bereitgestellt wird. |
|||
|
|||
### Testen Sie es |
|||
|
|||
Öffnen Sie Ihren Browser unter <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000.</a> |
|||
|
|||
Sie werden folgende JSON-Response sehen: |
|||
|
|||
```JSON |
|||
{"message": "Hello World"} |
|||
``` |
|||
|
|||
### Interaktive API-Dokumentation |
|||
|
|||
Gehen Sie als Nächstes auf <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs </a>. |
|||
|
|||
Sie werden die automatisch erzeugte, interaktive API-Dokumentation sehen (bereitgestellt durch <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>): |
|||
|
|||
 |
|||
|
|||
### Alternative API-Dokumentation |
|||
|
|||
Gehen Sie nun auf <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>. |
|||
|
|||
Dort sehen Sie die alternative, automatische Dokumentation (bereitgestellt durch <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>): |
|||
|
|||
 |
|||
|
|||
### OpenAPI |
|||
|
|||
**FastAPI** generiert ein „Schema“ mit all Ihren APIs unter Verwendung des **OpenAPI**-Standards zur Definition von APIs. |
|||
|
|||
#### „Schema“ |
|||
|
|||
Ein „Schema“ ist eine Definition oder Beschreibung von etwas. Nicht der eigentliche Code, der es implementiert, sondern lediglich eine abstrakte Beschreibung. |
|||
|
|||
#### API-„Schema“ |
|||
|
|||
In diesem Fall ist <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> eine Spezifikation, die vorschreibt, wie ein Schema für Ihre API zu definieren ist. |
|||
|
|||
Diese Schemadefinition enthält Ihre API-Pfade, die möglichen Parameter, welche diese entgegennehmen, usw. |
|||
|
|||
#### Daten-„Schema“ |
|||
|
|||
Der Begriff „Schema“ kann sich auch auf die Form von Daten beziehen, wie z. B. einen JSON-Inhalt. |
|||
|
|||
In diesem Fall sind die JSON-Attribute und deren Datentypen, usw. gemeint. |
|||
|
|||
#### OpenAPI und JSON Schema |
|||
|
|||
OpenAPI definiert ein API-Schema für Ihre API. Dieses Schema enthält Definitionen (oder „Schemas“) der Daten, die von Ihrer API unter Verwendung von **JSON Schema**, dem Standard für JSON-Datenschemata, gesendet und empfangen werden. |
|||
|
|||
#### Überprüfen Sie die `openapi.json` |
|||
|
|||
Falls Sie wissen möchten, wie das rohe OpenAPI-Schema aussieht: FastAPI generiert automatisch ein JSON (Schema) mit den Beschreibungen Ihrer gesamten API. |
|||
|
|||
Sie können es direkt einsehen unter: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>. |
|||
|
|||
Es wird ein JSON angezeigt, welches ungefähr so aussieht: |
|||
|
|||
```JSON |
|||
{ |
|||
"openapi": "3.1.0", |
|||
"info": { |
|||
"title": "FastAPI", |
|||
"version": "0.1.0" |
|||
}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": { |
|||
"application/json": { |
|||
|
|||
|
|||
|
|||
... |
|||
``` |
|||
|
|||
#### Wofür OpenAPI gedacht ist |
|||
|
|||
Das OpenAPI-Schema ist die Grundlage für die beiden enthaltenen interaktiven Dokumentationssysteme. |
|||
|
|||
Es gibt dutzende Alternativen, die alle auf OpenAPI basieren. Sie können jede dieser Alternativen problemlos zu Ihrer mit **FastAPI** erstellten Anwendung hinzufügen. |
|||
|
|||
Ebenfalls können Sie es verwenden, um automatisch Code für Clients zu generieren, die mit Ihrer API kommunizieren. Zum Beispiel für Frontend-, Mobile- oder IoT-Anwendungen. |
|||
|
|||
## Rückblick, Schritt für Schritt |
|||
|
|||
### Schritt 1: Importieren von `FastAPI` |
|||
|
|||
```Python hl_lines="1" |
|||
{!../../../docs_src/first_steps/tutorial001.py!} |
|||
``` |
|||
|
|||
`FastAPI` ist eine Python-Klasse, die die gesamte Funktionalität für Ihre API bereitstellt. |
|||
|
|||
!!! note "Technische Details" |
|||
`FastAPI` ist eine Klasse, die direkt von `Starlette` erbt. |
|||
|
|||
Sie können alle <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a>-Funktionalitäten auch mit `FastAPI` nutzen. |
|||
|
|||
### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ |
|||
|
|||
```Python hl_lines="3" |
|||
{!../../../docs_src/first_steps/tutorial001.py!} |
|||
``` |
|||
|
|||
In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI`. |
|||
|
|||
Dies wird der Hauptinteraktionspunkt für die Erstellung all Ihrer APIs sein. |
|||
|
|||
Die Variable `app` ist dieselbe, auf die sich der Befehl `uvicorn` bezieht: |
|||
|
|||
<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> |
|||
|
|||
Wenn Sie Ihre Anwendung wie folgt erstellen: |
|||
|
|||
```Python hl_lines="3" |
|||
{!../../../docs_src/first_steps/tutorial002.py!} |
|||
``` |
|||
|
|||
Und in eine Datei `main.py` einfügen, dann würden Sie `uvicorn` wie folgt aufrufen: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uvicorn main:my_awesome_api --reload |
|||
|
|||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
### Schritt 3: Erstellen einer *Pfadoperation* |
|||
|
|||
#### Pfad |
|||
|
|||
„Pfad“ bezieht sich hier auf den letzten Teil der URL, beginnend mit dem ersten `/`. |
|||
|
|||
In einer URL wie: |
|||
|
|||
``` |
|||
https://example.com/items/foo |
|||
``` |
|||
|
|||
... wäre der Pfad folglich: |
|||
|
|||
``` |
|||
/items/foo |
|||
``` |
|||
|
|||
!!! info |
|||
Ein „Pfad“ wird häufig auch als „Endpunkt“ oder „Route“ bezeichnet. |
|||
|
|||
Bei der Erstellung einer API ist der „Pfad“ die wichtigste Möglichkeit zur Trennung von „Anliegen“ und „Ressourcen“. |
|||
|
|||
#### Operation |
|||
|
|||
„Operation“ bezieht sich hier auf eine der HTTP-„Methoden“. |
|||
|
|||
Eine von diesen: |
|||
|
|||
* `POST` |
|||
* `GET` |
|||
* `PUT` |
|||
* `DELETE` |
|||
|
|||
... und die etwas Exotischeren: |
|||
|
|||
* `OPTIONS` |
|||
* `HEAD` |
|||
* `PATCH` |
|||
* `TRACE` |
|||
|
|||
Im HTTP-Protokoll können Sie mit jedem Pfad über eine (oder mehrere) dieser „Methoden“ kommunizieren. |
|||
|
|||
--- |
|||
|
|||
Bei der Erstellung von APIs verwenden Sie normalerweise diese spezifischen HTTP-Methoden, um eine bestimmte Aktion durchzuführen. |
|||
|
|||
Normalerweise verwenden Sie: |
|||
|
|||
* `POST`: um Daten zu erzeugen (create). |
|||
* `GET`: um Daten zu lesen (read). |
|||
* `PUT`: um Daten zu aktualisieren (update). |
|||
* `DELETE`: um Daten zu löschen (delete). |
|||
|
|||
In OpenAPI wird folglich jede dieser HTTP-Methoden als „Operation“ bezeichnet. |
|||
|
|||
Wir werden sie auch „**Operationen**“ nennen. |
|||
|
|||
#### Definieren eines *Pfadoperation-Dekorators* |
|||
|
|||
```Python hl_lines="6" |
|||
{!../../../docs_src/first_steps/tutorial001.py!} |
|||
``` |
|||
|
|||
Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die Bearbeitung von Anfragen zuständig ist, die an: |
|||
|
|||
* den Pfad `/` |
|||
* unter der Verwendung der <abbr title="eine HTTP GET Methode"><code>get</code>-Operation</abbr> gehen |
|||
|
|||
!!! info "`@decorator` Information" |
|||
Diese `@something`-Syntax wird in Python „Dekorator“ genannt. |
|||
|
|||
Sie platzieren ihn über einer Funktion. Wie ein hübscher, dekorativer Hut (daher kommt wohl der Begriff). |
|||
|
|||
Ein „Dekorator“ nimmt die darunter stehende Funktion und macht etwas damit. |
|||
|
|||
In unserem Fall teilt dieser Dekorator **FastAPI** mit, dass die folgende Funktion mit dem **Pfad** `/` und der **Operation** `get` zusammenhängt. |
|||
|
|||
Dies ist der „**Pfadoperation-Dekorator**“. |
|||
|
|||
Sie können auch die anderen Operationen verwenden: |
|||
|
|||
* `@app.post()` |
|||
* `@app.put()` |
|||
* `@app.delete()` |
|||
|
|||
Oder die exotischeren: |
|||
|
|||
* `@app.options()` |
|||
* `@app.head()` |
|||
* `@app.patch()` |
|||
* `@app.trace()` |
|||
|
|||
!!! tip "Tipp" |
|||
Es steht Ihnen frei, jede Operation (HTTP-Methode) so zu verwenden, wie Sie es möchten. |
|||
|
|||
**FastAPI** erzwingt keine bestimmte Bedeutung. |
|||
|
|||
Die hier aufgeführten Informationen dienen als Leitfaden und sind nicht verbindlich. |
|||
|
|||
Wenn Sie beispielsweise GraphQL verwenden, führen Sie normalerweise alle Aktionen nur mit „POST“-Operationen durch. |
|||
|
|||
### Schritt 4: Definieren der **Pfadoperation-Funktion** |
|||
|
|||
Das ist unsere „**Pfadoperation-Funktion**“: |
|||
|
|||
* **Pfad**: ist `/`. |
|||
* **Operation**: ist `get`. |
|||
* **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`). |
|||
|
|||
```Python hl_lines="7" |
|||
{!../../../docs_src/first_steps/tutorial001.py!} |
|||
``` |
|||
|
|||
Dies ist eine Python-Funktion. |
|||
|
|||
Sie wird von **FastAPI** immer dann aufgerufen, wenn sie eine Anfrage an die URL "`/`" mittels einer `GET`-Operation erhält. |
|||
|
|||
In diesem Fall handelt es sich um eine `async`-Funktion. |
|||
|
|||
--- |
|||
|
|||
Sie könnten sie auch als normale Funktion anstelle von `async def` definieren: |
|||
|
|||
```Python hl_lines="7" |
|||
{!../../../docs_src/first_steps/tutorial003.py!} |
|||
``` |
|||
|
|||
!!! note "Hinweis" |
|||
Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../async.md#in-eile){.internal-link target=_blank}. |
|||
|
|||
### Schritt 5: den Inhalt zurückgeben |
|||
|
|||
```Python hl_lines="8" |
|||
{!../../../docs_src/first_steps/tutorial001.py!} |
|||
``` |
|||
|
|||
Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben. |
|||
|
|||
Sie können auch Pydantic-Modelle zurückgeben (dazu später mehr). |
|||
|
|||
Es gibt viele andere Objekte und Modelle, die automatisch zu JSON konvertiert werden (einschließlich ORMs usw.). Versuchen Sie, Ihre Lieblingsobjekte zu verwenden. Es ist sehr wahrscheinlich, dass sie bereits unterstützt werden. |
|||
|
|||
## Zusammenfassung |
|||
|
|||
* Importieren Sie `FastAPI`. |
|||
* Erstellen Sie eine `app` Instanz. |
|||
* Schreiben Sie einen **Pfadoperation-Dekorator** (wie z. B. `@app.get("/")`). |
|||
* Schreiben Sie eine **Pfadoperation-Funktion** (wie z. B. oben `def root(): ...`). |
|||
* Starten Sie den Entwicklungsserver (z. B. `uvicorn main:app --reload`). |
@ -0,0 +1,80 @@ |
|||
# Tutorial – Benutzerhandbuch |
|||
|
|||
Dieses Tutorial zeigt Ihnen Schritt für Schritt, wie Sie **FastAPI** und die meisten seiner Funktionen verwenden können. |
|||
|
|||
Jeder Abschnitt baut schrittweise auf den vorhergehenden auf. Diese Abschnitte sind aber nach einzelnen Themen gegliedert, sodass Sie direkt zu einem bestimmten Thema übergehen können, um Ihre speziellen API-Anforderungen zu lösen. |
|||
|
|||
Außerdem dienen diese als zukünftige Referenz. |
|||
|
|||
Dadurch können Sie jederzeit zurückkommen und sehen genau das, was Sie benötigen. |
|||
|
|||
## Den Code ausführen |
|||
|
|||
Alle Codeblöcke können kopiert und direkt verwendet werden (da es sich um getestete Python-Dateien handelt). |
|||
|
|||
Um eines der Beispiele auszuführen, kopieren Sie den Code in eine Datei `main.py`, und starten Sie `uvicorn` mit: |
|||
|
|||
<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> |
|||
|
|||
Es wird **ausdrücklich empfohlen**, dass Sie den Code schreiben oder kopieren, ihn bearbeiten und lokal ausführen. |
|||
|
|||
Die Verwendung in Ihrem eigenen Editor zeigt Ihnen die Vorteile von FastAPI am besten, wenn Sie sehen, wie wenig Code Sie schreiben müssen, all die Typprüfungen, die automatische Vervollständigung usw. |
|||
|
|||
--- |
|||
|
|||
## FastAPI installieren |
|||
|
|||
Der erste Schritt besteht aus der Installation von FastAPI. |
|||
|
|||
Für dieses Tutorial empfiehlt es sich, FastAPI mit allen optionalen Abhängigkeiten und Funktionen zu installieren: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "fastapi[all]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
... das beinhaltet auch `uvicorn`, welchen Sie als Server verwenden können, der ihren Code ausführt. |
|||
|
|||
!!! note "Hinweis" |
|||
Sie können die einzelnen Teile auch separat installieren. |
|||
|
|||
Das folgende würden Sie wahrscheinlich tun, wenn Sie Ihre Anwendung in der Produktion einsetzen: |
|||
|
|||
``` |
|||
pip install fastapi |
|||
``` |
|||
|
|||
Installieren Sie auch `uvicorn` als Server: |
|||
|
|||
``` |
|||
pip install "uvicorn[standard]" |
|||
``` |
|||
|
|||
Das gleiche gilt für jede der optionalen Abhängigkeiten, die Sie verwenden möchten. |
|||
|
|||
## Handbuch für fortgeschrittene Benutzer |
|||
|
|||
Es gibt auch ein **Handbuch für fortgeschrittene Benutzer**, welches Sie später nach diesem **Tutorial – Benutzerhandbuch** lesen können. |
|||
|
|||
Das **Handbuch für fortgeschrittene Benutzer** baut auf diesem Tutorial auf, verwendet dieselben Konzepte und bringt Ihnen einige zusätzliche Funktionen bei. |
|||
|
|||
Allerdings sollten Sie zuerst das **Tutorial – Benutzerhandbuch** lesen (was Sie hier gerade tun). |
|||
|
|||
Die Dokumentation ist so konzipiert, dass Sie mit dem **Tutorial – Benutzerhandbuch** eine vollständige Anwendung erstellen können und diese dann je nach Bedarf mit einigen der zusätzlichen Ideen aus dem **Handbuch für fortgeschrittene Benutzer** vervollständigen können. |
@ -0,0 +1,61 @@ |
|||
# Middleware |
|||
|
|||
Sie können Middleware zu **FastAPI**-Anwendungen hinzufügen. |
|||
|
|||
Eine „Middleware“ ist eine Funktion, die mit jedem **Request** arbeitet, bevor er von einer bestimmten *Pfadoperation* verarbeitet wird. Und auch mit jeder **Response**, bevor sie zurückgegeben wird. |
|||
|
|||
* Sie nimmt jeden **Request** entgegen, der an Ihre Anwendung gesendet wird. |
|||
* Sie kann dann etwas mit diesem **Request** tun oder beliebigen Code ausführen. |
|||
* Dann gibt sie den **Request** zur Verarbeitung durch den Rest der Anwendung weiter (durch eine bestimmte *Pfadoperation*). |
|||
* Sie nimmt dann die **Response** entgegen, die von der Anwendung generiert wurde (durch eine bestimmte *Pfadoperation*). |
|||
* Sie kann etwas mit dieser **Response** tun oder beliebigen Code ausführen. |
|||
* Dann gibt sie die **Response** zurück. |
|||
|
|||
!!! note "Technische Details" |
|||
Wenn Sie Abhängigkeiten mit `yield` haben, wird der Exit-Code *nach* der Middleware ausgeführt. |
|||
|
|||
Wenn es Hintergrundaufgaben gab (später dokumentiert), werden sie *nach* allen Middlewares ausgeführt. |
|||
|
|||
## Erstellung einer Middleware |
|||
|
|||
Um eine Middleware zu erstellen, verwenden Sie den Dekorator `@app.middleware("http")` über einer Funktion. |
|||
|
|||
Die Middleware-Funktion erhält: |
|||
|
|||
* Den `request`. |
|||
* Eine Funktion `call_next`, die den `request` als Parameter erhält. |
|||
* Diese Funktion gibt den `request` an die entsprechende *Pfadoperation* weiter. |
|||
* Dann gibt es die von der entsprechenden *Pfadoperation* generierte `response` zurück. |
|||
* Sie können die `response` dann weiter modifizieren, bevor Sie sie zurückgeben. |
|||
|
|||
```Python hl_lines="8-9 11 14" |
|||
{!../../../docs_src/middleware/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! tip "Tipp" |
|||
Beachten Sie, dass benutzerdefinierte proprietäre Header hinzugefügt werden können. <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">Verwenden Sie dafür das Präfix 'X-'</a>. |
|||
|
|||
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen soll, müssen Sie sie zu Ihrer CORS-Konfigurationen ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) hinzufügen, indem Sie den Parameter `expose_headers` verwenden, der in der <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette-CORS-Dokumentation</a> dokumentiert ist. |
|||
|
|||
!!! note "Technische Details" |
|||
Sie könnten auch `from starlette.requests import Request` verwenden. |
|||
|
|||
**FastAPI** bietet es als Komfort für Sie, den Entwickler, an. Aber es stammt direkt von Starlette. |
|||
|
|||
### Vor und nach der `response` |
|||
|
|||
Sie können Code hinzufügen, der mit dem `request` ausgeführt wird, bevor dieser von einer beliebigen *Pfadoperation* empfangen wird. |
|||
|
|||
Und auch nachdem die `response` generiert wurde, bevor sie zurückgegeben wird. |
|||
|
|||
Sie könnten beispielsweise einen benutzerdefinierten Header `X-Process-Time` hinzufügen, der die Zeit in Sekunden enthält, die benötigt wurde, um den Request zu verarbeiten und eine Response zu generieren: |
|||
|
|||
```Python hl_lines="10 12-13" |
|||
{!../../../docs_src/middleware/tutorial001.py!} |
|||
``` |
|||
|
|||
## Andere Middlewares |
|||
|
|||
Sie können später mehr über andere Middlewares in [Handbuch für fortgeschrittene Benutzer: Fortgeschrittene Middleware](../advanced/middleware.md){.internal-link target=_blank} lesen. |
|||
|
|||
In der nächsten Sektion erfahren Sie, wie Sie <abbr title="Cross-Origin Resource Sharing">CORS</abbr> mit einer Middleware behandeln können. |
@ -0,0 +1,226 @@ |
|||
# Query-Parameter |
|||
|
|||
Wenn Sie in ihrer Funktion Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert. |
|||
|
|||
```Python hl_lines="9" |
|||
{!../../../docs_src/query_params/tutorial001.py!} |
|||
``` |
|||
|
|||
Query-Parameter (Deutsch: Abfrage-Parameter) sind die Schlüssel-Wert-Paare, die nach dem `?` in einer URL aufgelistet sind, getrennt durch `&`-Zeichen. |
|||
|
|||
Zum Beispiel sind in der URL: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/?skip=0&limit=10 |
|||
``` |
|||
|
|||
... die Query-Parameter: |
|||
|
|||
* `skip`: mit dem Wert `0` |
|||
* `limit`: mit dem Wert `10` |
|||
|
|||
Da sie Teil der URL sind, sind sie „naturgemäß“ Strings. |
|||
|
|||
Aber wenn Sie sie mit Python-Typen deklarieren (im obigen Beispiel als `int`), werden sie zu diesem Typ konvertiert, und gegen diesen validiert. |
|||
|
|||
Die gleichen Prozesse, die für Pfad-Parameter stattfinden, werden auch auf Query-Parameter angewendet: |
|||
|
|||
* Editor Unterstützung (natürlich) |
|||
* <abbr title="Konvertieren des Strings, der von einer HTTP-Anfrage kommt, in Python-Daten">„Parsen“</abbr> der Daten |
|||
* Datenvalidierung |
|||
* Automatische Dokumentation |
|||
|
|||
## Defaultwerte |
|||
|
|||
Da Query-Parameter nicht ein festgelegter Teil des Pfades sind, können sie optional sein und Defaultwerte haben. |
|||
|
|||
Im obigen Beispiel haben sie die Defaultwerte `skip=0` und `limit=10`. |
|||
|
|||
Wenn Sie also zur URL: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/ |
|||
``` |
|||
|
|||
gehen, so ist das das gleiche wie die URL: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/?skip=0&limit=10 |
|||
``` |
|||
|
|||
Aber wenn Sie zum Beispiel zu: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/?skip=20 |
|||
``` |
|||
|
|||
gehen, werden die Parameter-Werte Ihrer Funktion sein: |
|||
|
|||
* `skip=20`: da Sie das in der URL gesetzt haben |
|||
* `limit=10`: weil das der Defaultwert ist |
|||
|
|||
## Optionale Parameter |
|||
|
|||
Auf die gleiche Weise können Sie optionale Query-Parameter deklarieren, indem Sie deren Defaultwert auf `None` setzen: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="7" |
|||
{!> ../../../docs_src/query_params/tutorial002_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="9" |
|||
{!> ../../../docs_src/query_params/tutorial002.py!} |
|||
``` |
|||
|
|||
In diesem Fall wird der Funktionsparameter `q` optional, und standardmäßig `None` sein. |
|||
|
|||
!!! check |
|||
Beachten Sie auch, dass **FastAPI** intelligent genug ist, um zu erkennen, dass `item_id` ein Pfad-Parameter ist und `q` keiner, daher muss letzteres ein Query-Parameter sein. |
|||
|
|||
## Query-Parameter Typkonvertierung |
|||
|
|||
Sie können auch `bool`-Typen deklarieren und sie werden konvertiert: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="7" |
|||
{!> ../../../docs_src/query_params/tutorial003_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="9" |
|||
{!> ../../../docs_src/query_params/tutorial003.py!} |
|||
``` |
|||
|
|||
Wenn Sie nun zu: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo?short=1 |
|||
``` |
|||
|
|||
oder |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo?short=True |
|||
``` |
|||
|
|||
oder |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo?short=true |
|||
``` |
|||
|
|||
oder |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo?short=on |
|||
``` |
|||
|
|||
oder |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo?short=yes |
|||
``` |
|||
|
|||
gehen, oder zu irgendeiner anderen Variante der Groß-/Kleinschreibung (Alles groß, Anfangsbuchstabe groß, usw.), dann wird Ihre Funktion den Parameter `short` mit dem `bool`-Wert `True` sehen, ansonsten mit dem Wert `False`. |
|||
|
|||
## Mehrere Pfad- und Query-Parameter |
|||
|
|||
Sie können mehrere Pfad-Parameter und Query-Parameter gleichzeitig deklarieren, **FastAPI** weiß, was welches ist. |
|||
|
|||
Und Sie müssen sie auch nicht in einer spezifischen Reihenfolge deklarieren. |
|||
|
|||
Parameter werden anhand ihres Namens erkannt: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="6 8" |
|||
{!> ../../../docs_src/query_params/tutorial004_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="8 10" |
|||
{!> ../../../docs_src/query_params/tutorial004.py!} |
|||
``` |
|||
|
|||
## Erforderliche Query-Parameter |
|||
|
|||
Wenn Sie einen Defaultwert für Nicht-Pfad-Parameter deklarieren (Bis jetzt haben wir nur Query-Parameter gesehen), dann ist der Parameter nicht erforderlich. |
|||
|
|||
Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach optional sein soll, dann setzen Sie den Defaultwert auf `None`. |
|||
|
|||
Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert: |
|||
|
|||
```Python hl_lines="6-7" |
|||
{!../../../docs_src/query_params/tutorial005.py!} |
|||
``` |
|||
|
|||
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`. |
|||
|
|||
Wenn Sie in Ihrem Browser eine URL wie: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo-item |
|||
``` |
|||
|
|||
... öffnen, ohne den benötigten Parameter `needy`, dann erhalten Sie einen Fehler wie den folgenden: |
|||
|
|||
```JSON |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"type": "missing", |
|||
"loc": [ |
|||
"query", |
|||
"needy" |
|||
], |
|||
"msg": "Field required", |
|||
"input": null, |
|||
"url": "https://errors.pydantic.dev/2.1/v/missing" |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
Da `needy` ein erforderlicher Parameter ist, müssen Sie ihn in der URL setzen: |
|||
|
|||
``` |
|||
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy |
|||
``` |
|||
|
|||
... Das funktioniert: |
|||
|
|||
```JSON |
|||
{ |
|||
"item_id": "foo-item", |
|||
"needy": "sooooneedy" |
|||
} |
|||
``` |
|||
|
|||
Und natürlich können Sie einige Parameter als erforderlich, einige mit Defaultwert, und einige als vollständig optional definieren: |
|||
|
|||
=== "Python 3.10+" |
|||
|
|||
```Python hl_lines="8" |
|||
{!> ../../../docs_src/query_params/tutorial006_py310.py!} |
|||
``` |
|||
|
|||
=== "Python 3.8+" |
|||
|
|||
```Python hl_lines="10" |
|||
{!> ../../../docs_src/query_params/tutorial006.py!} |
|||
``` |
|||
|
|||
In diesem Fall gibt es drei Query-Parameter: |
|||
|
|||
* `needy`, ein erforderlicher `str`. |
|||
* `skip`, ein `int` mit einem Defaultwert `0`. |
|||
* `limit`, ein optionales `int`. |
|||
|
|||
!!! tip "Tipp" |
|||
Sie können auch `Enum`s verwenden, auf die gleiche Weise wie mit [Pfad-Parametern](path-params.md#vordefinierte-parameterwerte){.internal-link target=_blank}. |
@ -20,10 +20,9 @@ Some of them also ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-autho |
|||
|
|||
And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇 |
|||
|
|||
You might want to try their services and follow their guides: |
|||
For example, you might want to try <a href="https://speakeasyapi.dev/?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>. |
|||
|
|||
* <a href="https://www.buildwithfern.com/?utm_source=tiangolo&utm_medium=website&utm_campaign=docs-generate-clients" class="external-link" target="_blank">Fern</a> |
|||
* <a href="https://speakeasyapi.dev/?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a> |
|||
There are also several other companies offering similar services that you can search and find online. 🤓 |
|||
|
|||
## Generate a TypeScript Frontend Client |
|||
|
|||
@ -88,7 +87,7 @@ It could look like this: |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios" |
|||
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes" |
|||
}, |
|||
"author": "", |
|||
"license": "", |
|||
@ -107,7 +106,7 @@ After having that NPM `generate-client` script there, you can run it with: |
|||
$ npm run generate-client |
|||
|
|||
[email protected] generate-client /home/user/code/frontend-app |
|||
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios |
|||
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes |
|||
``` |
|||
|
|||
</div> |
|||
@ -230,9 +229,17 @@ But for the generated client we could **modify** the OpenAPI operation IDs right |
|||
|
|||
We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this: |
|||
|
|||
```Python |
|||
{!../../../docs_src/generate_clients/tutorial004.py!} |
|||
``` |
|||
=== "Python" |
|||
|
|||
```Python |
|||
{!> ../../../docs_src/generate_clients/tutorial004.py!} |
|||
``` |
|||
|
|||
=== "Node.js" |
|||
|
|||
```Python |
|||
{!> ../../../docs_src/generate_clients/tutorial004.js!} |
|||
``` |
|||
|
|||
With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names. |
|||
|
|||
@ -247,7 +254,7 @@ Now as the end result is in a file `openapi.json`, you would modify the `package |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios" |
|||
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios --useOptions --useUnionTypes" |
|||
}, |
|||
"author": "", |
|||
"license": "", |
|||
|
Before Width: | Height: | Size: 412 B After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 9.5 KiB |