mirror of
https://github.com/fastapi/fastapi.git
synced 2026-01-23 05:19:46 -05:00
Compare commits
2 Commits
Update-emb
...
translate-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
462a387115 | ||
|
|
6bf1331692 |
18
README.md
18
README.md
@@ -164,6 +164,8 @@ $ pip install "fastapi[standard]"
|
|||||||
Create a file `main.py` with:
|
Create a file `main.py` with:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -175,7 +177,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -184,7 +186,9 @@ def read_item(item_id: int, q: str | None = None):
|
|||||||
|
|
||||||
If your code uses `async` / `await`, use `async def`:
|
If your code uses `async` / `await`, use `async def`:
|
||||||
|
|
||||||
```Python hl_lines="7 12"
|
```Python hl_lines="9 14"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -196,7 +200,7 @@ async def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
async def read_item(item_id: int, q: str | None = None):
|
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -287,7 +291,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
|
|||||||
|
|
||||||
Declare the body using standard Python types, thanks to Pydantic.
|
Declare the body using standard Python types, thanks to Pydantic.
|
||||||
|
|
||||||
```Python hl_lines="2 7-10 23-25"
|
```Python hl_lines="4 9-12 25-27"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@@ -297,7 +303,7 @@ app = FastAPI()
|
|||||||
class Item(BaseModel):
|
class Item(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
price: float
|
price: float
|
||||||
is_offer: bool | None = None
|
is_offer: Union[bool, None] = None
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -306,7 +312,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ Siehe Abschnitt `### Links` im allgemeinen Prompt in `scripts/translate.py`.
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
## HTML-„abbr“-Elemente { #html-abbr-elements }
|
## HTML „abbr“-Elemente { #html-abbr-elements }
|
||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
|
|
||||||
|
|||||||
@@ -56,19 +56,19 @@ from app.routers import items
|
|||||||
|
|
||||||
Die gleiche Dateistruktur mit Kommentaren:
|
Die gleiche Dateistruktur mit Kommentaren:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
.
|
.
|
||||||
├── app # "app" ist ein Python-Package
|
├── app # „app“ ist ein Python-Package
|
||||||
│ ├── __init__.py # diese Datei macht "app" zu einem "Python-Package"
|
│ ├── __init__.py # diese Datei macht „app“ zu einem „Python-Package“
|
||||||
│ ├── main.py # "main"-Modul, z. B. import app.main
|
│ ├── main.py # „main“-Modul, z. B. import app.main
|
||||||
│ ├── dependencies.py # "dependencies"-Modul, z. B. import app.dependencies
|
│ ├── dependencies.py # „dependencies“-Modul, z. B. import app.dependencies
|
||||||
│ └── routers # "routers" ist ein "Python-Subpackage"
|
│ └── routers # „routers“ ist ein „Python-Subpackage“
|
||||||
│ │ ├── __init__.py # macht "routers" zu einem "Python-Subpackage"
|
│ │ ├── __init__.py # macht „routers“ zu einem „Python-Subpackage“
|
||||||
│ │ ├── items.py # "items"-Submodul, z. B. import app.routers.items
|
│ │ ├── items.py # „items“-Submodul, z. B. import app.routers.items
|
||||||
│ │ └── users.py # "users"-Submodul, z. B. import app.routers.users
|
│ │ └── users.py # „users“-Submodul, z. B. import app.routers.users
|
||||||
│ └── internal # "internal" ist ein "Python-Subpackage"
|
│ └── internal # „internal“ ist ein „Python-Subpackage“
|
||||||
│ ├── __init__.py # macht "internal" zu einem "Python-Subpackage"
|
│ ├── __init__.py # macht „internal“ zu einem „Python-Subpackage“
|
||||||
│ └── admin.py # "admin"-Submodul, z. B. import app.internal.admin
|
│ └── admin.py # „admin“-Submodul, z. B. import app.internal.admin
|
||||||
```
|
```
|
||||||
|
|
||||||
## `APIRouter` { #apirouter }
|
## `APIRouter` { #apirouter }
|
||||||
@@ -479,7 +479,7 @@ $ fastapi dev app/main.py
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||||
|
|
||||||
Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Submodule, mit den richtigen Pfaden (und Präfixen) und den richtigen Tags:
|
Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Submodule, mit den richtigen Pfaden (und Präfixen) und den richtigen Tags:
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ There are other formats and tools to define and install package dependencies.
|
|||||||
* Create a `main.py` file with:
|
* Create a `main.py` file with:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -156,7 +158,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ $ pip install "fastapi[standard]"
|
|||||||
Create a file `main.py` with:
|
Create a file `main.py` with:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -172,7 +174,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -181,7 +183,9 @@ def read_item(item_id: int, q: str | None = None):
|
|||||||
|
|
||||||
If your code uses `async` / `await`, use `async def`:
|
If your code uses `async` / `await`, use `async def`:
|
||||||
|
|
||||||
```Python hl_lines="7 12"
|
```Python hl_lines="9 14"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -193,7 +197,7 @@ async def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
async def read_item(item_id: int, q: str | None = None):
|
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -284,7 +288,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
|
|||||||
|
|
||||||
Declare the body using standard Python types, thanks to Pydantic.
|
Declare the body using standard Python types, thanks to Pydantic.
|
||||||
|
|
||||||
```Python hl_lines="2 7-10 23-25"
|
```Python hl_lines="4 9-12 25-27"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@@ -294,7 +300,7 @@ app = FastAPI()
|
|||||||
class Item(BaseModel):
|
class Item(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
price: float
|
price: float
|
||||||
is_offer: bool | None = None
|
is_offer: Union[bool, None] = None
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -303,7 +309,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ hide:
|
|||||||
|
|
||||||
### Translations
|
### Translations
|
||||||
|
|
||||||
* 🌐 Update translations for de (update-outdated). PR [#14690](https://github.com/fastapi/fastapi/pull/14690) by [@tiangolo](https://github.com/tiangolo).
|
|
||||||
* 🌐 Update LLM prompt for Russian translations. PR [#14733](https://github.com/fastapi/fastapi/pull/14733) by [@YuriiMotov](https://github.com/YuriiMotov).
|
|
||||||
* 🌐 Update translations for ru (update-outdated). PR [#14693](https://github.com/fastapi/fastapi/pull/14693) by [@tiangolo](https://github.com/tiangolo).
|
|
||||||
* 🌐 Update translations for pt (update-outdated). PR [#14724](https://github.com/fastapi/fastapi/pull/14724) by [@tiangolo](https://github.com/tiangolo).
|
|
||||||
* 🌐 Update Korean LLM prompt. PR [#14740](https://github.com/fastapi/fastapi/pull/14740) by [@hard-coders](https://github.com/hard-coders).
|
|
||||||
* 🌐 Improve LLM prompt for Turkish translations. PR [#14728](https://github.com/fastapi/fastapi/pull/14728) by [@Kadermiyanyedi](https://github.com/Kadermiyanyedi).
|
|
||||||
* 🌐 Update portuguese llm-prompt.md. PR [#14702](https://github.com/fastapi/fastapi/pull/14702) by [@ceb10n](https://github.com/ceb10n).
|
* 🌐 Update portuguese llm-prompt.md. PR [#14702](https://github.com/fastapi/fastapi/pull/14702) by [@ceb10n](https://github.com/ceb10n).
|
||||||
* 🌐 Update LLM prompt instructions file for French. PR [#14618](https://github.com/fastapi/fastapi/pull/14618) by [@tiangolo](https://github.com/tiangolo).
|
* 🌐 Update LLM prompt instructions file for French. PR [#14618](https://github.com/fastapi/fastapi/pull/14618) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* 🌐 Update translations for ko (add-missing). PR [#14699](https://github.com/fastapi/fastapi/pull/14699) by [@tiangolo](https://github.com/tiangolo).
|
* 🌐 Update translations for ko (add-missing). PR [#14699](https://github.com/fastapi/fastapi/pull/14699) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
|||||||
@@ -102,16 +102,15 @@ Of course, you can also declare additional query parameters whenever you need, a
|
|||||||
|
|
||||||
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
|
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
|
||||||
|
|
||||||
```Python
|
|
||||||
q: str | None = None
|
|
||||||
```
|
|
||||||
|
|
||||||
Or in Python 3.9:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
q: Union[str, None] = None
|
q: Union[str, None] = None
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or in Python 3.10 and above:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
q: str | None = None
|
||||||
|
```
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ Language code: ko.
|
|||||||
|
|
||||||
- Use polite, instructional Korean (e.g. 합니다/하세요 style).
|
- Use polite, instructional Korean (e.g. 합니다/하세요 style).
|
||||||
- Keep the tone consistent with the existing Korean FastAPI docs.
|
- Keep the tone consistent with the existing Korean FastAPI docs.
|
||||||
- Do not translate “You” literally as “당신”. Use “여러분” where appropriate, or omit the subject if it sounds more natural in Korean.
|
|
||||||
|
|
||||||
### Headings
|
### Headings
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Arquivo de teste de LLM { #llm-test-file }
|
# Arquivo de teste de LLM { #llm-test-file }
|
||||||
|
|
||||||
Este documento testa se o <abbr title="Large Language Model - Modelo de Linguagem de Grande Porte">LLM</abbr>, que traduz a documentação, entende o `general_prompt` em `scripts/translate.py` e o prompt específico do idioma em `docs/{language code}/llm-prompt.md`. O prompt específico do idioma é anexado ao `general_prompt`.
|
Este documento testa se o <abbr title="Large Language Model – Modelo de Linguagem de Grande Porte">LLM</abbr>, que traduz a documentação, entende o `general_prompt` em `scripts/translate.py` e o prompt específico do idioma em `docs/{language code}/llm-prompt.md`. O prompt específico do idioma é anexado ao `general_prompt`.
|
||||||
|
|
||||||
Os testes adicionados aqui serão vistos por todos os designers dos prompts específicos de idioma.
|
Os testes adicionados aqui serão vistos por todos os autores dos prompts específicos de idioma.
|
||||||
|
|
||||||
Use da seguinte forma:
|
Use da seguinte forma:
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ Este é um trecho de código: `foo`. E este é outro trecho de código: `bar`. E
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
O conteúdo dos trechos de código deve ser deixado como está.
|
O conteúdo dos trechos de código deve ser deixado como está.
|
||||||
|
|
||||||
@@ -45,9 +45,9 @@ O LLM provavelmente vai traduzir isso errado. O interessante é apenas se ele ma
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
O designer do prompt pode escolher se quer converter aspas neutras em aspas tipográficas. Também é aceitável deixá-las como estão.
|
O autor do prompt pode escolher se deseja converter aspas neutras em aspas tipográficas. Também é aceitável deixá-las como estão.
|
||||||
|
|
||||||
Veja, por exemplo, a seção `### Quotes` em `docs/de/llm-prompt.md`.
|
Veja, por exemplo, a seção `### Quotes` em `docs/de/llm-prompt.md`.
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ Pesado: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you ha
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
... No entanto, as aspas dentro de trechos de código devem permanecer como estão.
|
... No entanto, as aspas dentro de trechos de código devem permanecer como estão.
|
||||||
|
|
||||||
@@ -95,24 +95,24 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
|
|||||||
...e outro exemplo de código de console...
|
...e outro exemplo de código de console...
|
||||||
|
|
||||||
```console
|
```console
|
||||||
// Criar um diretório "Code"
|
// Crie um diretório "Code"
|
||||||
$ mkdir code
|
$ mkdir code
|
||||||
// Mudar para esse diretório
|
// Entre nesse diretório
|
||||||
$ cd code
|
$ cd code
|
||||||
```
|
```
|
||||||
|
|
||||||
...e um exemplo de código Python...
|
...e um exemplo de código Python...
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
wont_work() # This won't work 😱
|
wont_work() # Isto não vai funcionar 😱
|
||||||
works(foo="bar") # This works 🎉
|
works(foo="bar") # Isto funciona 🎉
|
||||||
```
|
```
|
||||||
|
|
||||||
...e é isso.
|
...e é isso.
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
O código em blocos de código não deve ser modificado, com exceção dos comentários.
|
O código em blocos de código não deve ser modificado, com exceção dos comentários.
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ Algum texto
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
Abas e blocos `Info`/`Note`/`Warning`/etc. devem ter a tradução do seu título adicionada após uma barra vertical (`|`).
|
Abas e blocos `Info`/`Note`/`Warning`/etc. devem ter a tradução do seu título adicionada após uma barra vertical (`|`).
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ O texto do link deve ser traduzido, o endereço do link deve apontar para a trad
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
Os links devem ser traduzidos, mas seus endereços devem permanecer inalterados. Uma exceção são links absolutos para páginas da documentação do FastAPI. Nesse caso, devem apontar para a tradução.
|
Os links devem ser traduzidos, mas seus endereços devem permanecer inalterados. Uma exceção são links absolutos para páginas da documentação do FastAPI. Nesse caso, devem apontar para a tradução.
|
||||||
|
|
||||||
@@ -197,10 +197,10 @@ Aqui estão algumas coisas envolvidas em elementos HTML "abbr" (algumas são inv
|
|||||||
|
|
||||||
### O abbr fornece uma frase completa { #the-abbr-gives-a-full-phrase }
|
### O abbr fornece uma frase completa { #the-abbr-gives-a-full-phrase }
|
||||||
|
|
||||||
* <abbr title="Getting Things Done">GTD</abbr>
|
* <abbr title="Getting Things Done – Fazer as Coisas">GTD</abbr>
|
||||||
* <abbr title="less than - menos que"><code>lt</code></abbr>
|
* <abbr title="menos que"><code>lt</code></abbr>
|
||||||
* <abbr title="XML Web Token">XWT</abbr>
|
* <abbr title="XML Web Token – Token Web XML">XWT</abbr>
|
||||||
* <abbr title="Parallel Server Gateway Interface - Interface de Gateway de Servidor Paralelo">PSGI</abbr>
|
* <abbr title="Parallel Server Gateway Interface – Interface de Gateway de Servidor Paralelo">PSGI</abbr>
|
||||||
|
|
||||||
### O abbr fornece uma explicação { #the-abbr-gives-an-explanation }
|
### O abbr fornece uma explicação { #the-abbr-gives-an-explanation }
|
||||||
|
|
||||||
@@ -209,12 +209,12 @@ Aqui estão algumas coisas envolvidas em elementos HTML "abbr" (algumas são inv
|
|||||||
|
|
||||||
### O abbr fornece uma frase completa e uma explicação { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
### O abbr fornece uma frase completa e uma explicação { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
||||||
|
|
||||||
* <abbr title="Mozilla Developer Network: documentação para desenvolvedores, escrita pelo pessoal do Firefox">MDN</abbr>
|
* <abbr title="Mozilla Developer Network – Rede de Desenvolvedores da Mozilla: documentação para desenvolvedores, escrita pelo pessoal do Firefox">MDN</abbr>
|
||||||
* <abbr title="Input/Output: leitura ou escrita em disco, comunicações de rede.">I/O</abbr>.
|
* <abbr title="Input/Output – Entrada/Saída: leitura ou escrita em disco, comunicações de rede.">I/O</abbr>.
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
Os atributos "title" dos elementos "abbr" são traduzidos seguindo algumas instruções específicas.
|
Os atributos "title" dos elementos "abbr" são traduzidos seguindo algumas instruções específicas.
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ Veja a seção `### HTML abbr elements` no prompt geral em `scripts/translate.py
|
|||||||
|
|
||||||
//// tab | Teste
|
//// tab | Teste
|
||||||
|
|
||||||
### Desenvolver uma webapp - um tutorial { #develop-a-webapp-a-tutorial }
|
### Desenvolver uma aplicação web - um tutorial { #develop-a-webapp-a-tutorial }
|
||||||
|
|
||||||
Olá.
|
Olá.
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ Olá novamente.
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
A única regra rígida para títulos é que o LLM deixe a parte do hash dentro de chaves inalterada, o que garante que os links não quebrem.
|
A única regra rígida para títulos é que o LLM deixe a parte do hash dentro de chaves inalterada, o que garante que os links não quebrem.
|
||||||
|
|
||||||
@@ -494,9 +494,9 @@ Para algumas instruções específicas do idioma, veja, por exemplo, a seção `
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Informação
|
//// tab | Informações
|
||||||
|
|
||||||
Esta é uma lista não completa e não normativa de termos (principalmente) técnicos vistos na documentação. Pode ser útil para o designer do prompt descobrir para quais termos o LLM precisa de uma ajudinha. Por exemplo, quando ele continua revertendo uma boa tradução para uma tradução subótima. Ou quando tem problemas para conjugar/declinar um termo no seu idioma.
|
Esta é uma lista não completa e não normativa de termos (principalmente) técnicos vistos na documentação. Pode ser útil para o autor do prompt descobrir para quais termos o LLM precisa de uma ajudinha. Por exemplo, quando ele continua revertendo uma boa tradução para uma tradução subótima. Ou quando tem problemas para conjugar/declinar um termo no seu idioma.
|
||||||
|
|
||||||
Veja, por exemplo, a seção `### List of English terms and their preferred German translations` em `docs/de/llm-prompt.md`.
|
Veja, por exemplo, a seção `### List of English terms and their preferred German translations` em `docs/de/llm-prompt.md`.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Se você não é um "especialista" no OpenAPI, você provavelmente não precisa
|
|||||||
|
|
||||||
Você pode definir o `operationId` do OpenAPI que será utilizado na sua *operação de rota* com o parâmetro `operation_id`.
|
Você pode definir o `operationId` do OpenAPI que será utilizado na sua *operação de rota* com o parâmetro `operation_id`.
|
||||||
|
|
||||||
Você deveria ter certeza que ele é único para cada operação.
|
Você precisa ter certeza que ele é único para cada operação.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
@@ -18,13 +18,13 @@ Você deveria ter certeza que ele é único para cada operação.
|
|||||||
|
|
||||||
Se você quiser utilizar o nome das funções da sua API como `operationId`s, você pode iterar sobre todos esses nomes e sobrescrever o `operation_id` em cada *operação de rota* utilizando o `APIRoute.name` dela.
|
Se você quiser utilizar o nome das funções da sua API como `operationId`s, você pode iterar sobre todos esses nomes e sobrescrever o `operation_id` em cada *operação de rota* utilizando o `APIRoute.name` dela.
|
||||||
|
|
||||||
Você deveria fazer isso depois de adicionar todas as suas *operações de rota*.
|
Você deve fazer isso depois de adicionar todas as suas *operações de rota*.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Se você chamar `app.openapi()` manualmente, você deveria atualizar os `operationId`s antes dessa chamada.
|
Se você chamar `app.openapi()` manualmente, os `operationId`s devem ser atualizados antes dessa chamada.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -44,11 +44,11 @@ Para excluir uma *operação de rota* do esquema OpenAPI gerado (e por consequê
|
|||||||
|
|
||||||
## Descrição avançada a partir de docstring { #advanced-description-from-docstring }
|
## Descrição avançada a partir de docstring { #advanced-description-from-docstring }
|
||||||
|
|
||||||
Você pode limitar as linhas utilizadas a partir da docstring de uma *função de operação de rota* para o OpenAPI.
|
Você pode limitar as linhas utilizadas a partir de uma docstring de uma *função de operação de rota* para o OpenAPI.
|
||||||
|
|
||||||
Adicionar um `\f` (um caractere de escape para "form feed") faz com que o **FastAPI** trunque a saída usada para o OpenAPI até esse ponto.
|
Adicionar um `\f` (um caractere de escape para alimentação de formulário) faz com que o **FastAPI** restrinja a saída utilizada pelo OpenAPI até esse ponto.
|
||||||
|
|
||||||
Ele não será mostrado na documentação, mas outras ferramentas (como o Sphinx) serão capazes de utilizar o resto.
|
Ele não será mostrado na documentação, mas outras ferramentas (como o Sphinx) serão capazes de utilizar o resto do texto.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
|
||||||
|
|
||||||
@@ -131,38 +131,70 @@ E se você olhar o esquema OpenAPI resultante (na rota `/openapi.json` da sua AP
|
|||||||
|
|
||||||
### Esquema de *operação de rota* do OpenAPI personalizado { #custom-openapi-path-operation-schema }
|
### Esquema de *operação de rota* do OpenAPI personalizado { #custom-openapi-path-operation-schema }
|
||||||
|
|
||||||
O dicionário em `openapi_extra` vai ser mesclado profundamente com o esquema OpenAPI gerado automaticamente para a *operação de rota*.
|
O dicionário em `openapi_extra` vai ter todos os seus níveis mesclados dentro do esquema OpenAPI gerado automaticamente para a *operação de rota*.
|
||||||
|
|
||||||
Então, você pode adicionar dados extras ao esquema gerado automaticamente.
|
Então, você pode adicionar dados extras para o esquema gerado automaticamente.
|
||||||
|
|
||||||
Por exemplo, você poderia decidir ler e validar a requisição com seu próprio código, sem usar as funcionalidades automáticas do FastAPI com o Pydantic, mas ainda assim querer definir a requisição no esquema OpenAPI.
|
Por exemplo, você poderia optar por ler e validar a requisição com seu próprio código, sem utilizar funcionalidades automatizadas do FastAPI com o Pydantic, mas você ainda pode quere definir a requisição no esquema OpenAPI.
|
||||||
|
|
||||||
Você pode fazer isso com `openapi_extra`:
|
Você pode fazer isso com `openapi_extra`:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
|
||||||
|
|
||||||
Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo <abbr title="converted from some plain format, like bytes, into Python objects - convertido de algum formato simples, como bytes, em objetos Python">analisado</abbr> como JSON, ele é lido diretamente como `bytes`, e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma.
|
Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo <abbr title="convertido de um formato plano, como bytes, para objetos Python">analisado</abbr> como JSON, ele é lido diretamente como `bytes` e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma.
|
||||||
|
|
||||||
De toda forma, nós podemos declarar o esquema esperado para o corpo da requisição.
|
De toda forma, nós podemos declarar o esquema esperado para o corpo da requisição.
|
||||||
|
|
||||||
### Tipo de conteúdo do OpenAPI personalizado { #custom-openapi-content-type }
|
### Tipo de conteúdo do OpenAPI personalizado { #custom-openapi-content-type }
|
||||||
|
|
||||||
Utilizando esse mesmo truque, você pode usar um modelo Pydantic para definir o JSON Schema que é então incluído na seção do esquema personalizado do OpenAPI na *operação de rota*.
|
Utilizando esse mesmo truque, você pode utilizar um modelo Pydantic para definir o JSON Schema que é então incluído na seção do esquema personalizado do OpenAPI na *operação de rota*.
|
||||||
|
|
||||||
E você pode fazer isso até mesmo quando o tipo de dados na requisição não é JSON.
|
E você pode fazer isso até mesmo quando os dados da requisição não seguem o formato JSON.
|
||||||
|
|
||||||
Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao FastAPI de extrair o JSON Schema dos modelos Pydantic nem a validação automática para JSON. Na verdade, estamos declarando o tipo de conteúdo da requisição como YAML, em vez de JSON:
|
Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao FastAPI de extrair o JSON Schema dos modelos Pydantic nem a validação automática do JSON. Na verdade, estamos declarando o tipo do conteúdo da requisição como YAML, em vez de JSON:
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
|
||||||
|
|
||||||
Entretanto, mesmo que não utilizemos a funcionalidade integrada por padrão, ainda estamos usando um modelo Pydantic para gerar um JSON Schema manualmente para os dados que queremos receber em YAML.
|
////
|
||||||
|
|
||||||
Então utilizamos a requisição diretamente e extraímos o corpo como `bytes`. Isso significa que o FastAPI não vai sequer tentar analisar o payload da requisição como JSON.
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
E então no nosso código, nós analisamos o conteúdo YAML diretamente e, em seguida, estamos usando novamente o mesmo modelo Pydantic para validar o conteúdo YAML:
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
Na versão 1 do Pydantic, o método para obter o JSON Schema de um modelo é `Item.schema()`, na versão 2 do Pydantic, o método é `Item.model_json_schema()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Entretanto, mesmo que não utilizemos a funcionalidade integrada por padrão, ainda estamos usando um modelo Pydantic para gerar um JSON Schema manualmente para os dados que queremos receber no formato YAML.
|
||||||
|
|
||||||
|
Então utilizamos a requisição diretamente, e extraímos o corpo como `bytes`. Isso significa que o FastAPI não vai sequer tentar analisar o corpo da requisição como JSON.
|
||||||
|
|
||||||
|
E então no nosso código, nós analisamos o conteúdo YAML diretamente, e estamos utilizando o mesmo modelo Pydantic para validar o conteúdo YAML:
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
Na versão 1 do Pydantic, o método para analisar e validar um objeto era `Item.parse_obj()`, na versão 2 do Pydantic, o método é chamado de `Item.model_validate()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Aqui reutilizamos o mesmo modelo do Pydantic.
|
Aqui reutilizamos o mesmo modelo do Pydantic.
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ $ pip install "fastapi[all]"
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
No Pydantic v1 ele vinha incluído no pacote principal. Agora é distribuído como um pacote independente para que você possa optar por instalá-lo ou não, caso não precise dessa funcionalidade.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
### Criar o objeto `Settings` { #create-the-settings-object }
|
### Criar o objeto `Settings` { #create-the-settings-object }
|
||||||
|
|
||||||
Importe `BaseSettings` do Pydantic e crie uma subclasse, muito parecido com um modelo do Pydantic.
|
Importe `BaseSettings` do Pydantic e crie uma subclasse, muito parecido com um modelo do Pydantic.
|
||||||
@@ -54,8 +60,24 @@ Da mesma forma que com modelos do Pydantic, você declara atributos de classe co
|
|||||||
|
|
||||||
Você pode usar as mesmas funcionalidades e ferramentas de validação que usa em modelos do Pydantic, como diferentes tipos de dados e validações adicionais com `Field()`.
|
Você pode usar as mesmas funcionalidades e ferramentas de validação que usa em modelos do Pydantic, como diferentes tipos de dados e validações adicionais com `Field()`.
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
|
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
No Pydantic v1 você importaria `BaseSettings` diretamente de `pydantic` em vez de `pydantic_settings`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Se você quer algo rápido para copiar e colar, não use este exemplo, use o último abaixo.
|
Se você quer algo rápido para copiar e colar, não use este exemplo, use o último abaixo.
|
||||||
@@ -193,6 +215,8 @@ APP_NAME="ChimichangApp"
|
|||||||
|
|
||||||
E então atualizar seu `config.py` com:
|
E então atualizar seu `config.py` com:
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
|
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
@@ -201,6 +225,26 @@ O atributo `model_config` é usado apenas para configuração do Pydantic. Você
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
|
||||||
|
|
||||||
|
/// tip | Dica
|
||||||
|
|
||||||
|
A classe `Config` é usada apenas para configuração do Pydantic. Você pode ler mais em <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
Na versão 1 do Pydantic a configuração era feita em uma classe interna `Config`, na versão 2 do Pydantic é feita em um atributo `model_config`. Esse atributo recebe um `dict`, e para ter autocompletar e erros inline você pode importar e usar `SettingsConfigDict` para definir esse `dict`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
Aqui definimos a configuração `env_file` dentro da sua classe `Settings` do Pydantic e definimos o valor como o nome do arquivo dotenv que queremos usar.
|
Aqui definimos a configuração `env_file` dentro da sua classe `Settings` do Pydantic e definimos o valor como o nome do arquivo dotenv que queremos usar.
|
||||||
|
|
||||||
### Criando o `Settings` apenas uma vez com `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
### Criando o `Settings` apenas uma vez com `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
||||||
|
|||||||
@@ -2,23 +2,21 @@
|
|||||||
|
|
||||||
Se você tem uma aplicação FastAPI antiga, pode estar usando o Pydantic versão 1.
|
Se você tem uma aplicação FastAPI antiga, pode estar usando o Pydantic versão 1.
|
||||||
|
|
||||||
O FastAPI versão 0.100.0 tinha suporte ao Pydantic v1 ou v2. Ele usaria aquele que você tivesse instalado.
|
O FastAPI tem suporte ao Pydantic v1 ou v2 desde a versão 0.100.0.
|
||||||
|
|
||||||
O FastAPI versão 0.119.0 introduziu suporte parcial ao Pydantic v1 a partir de dentro do Pydantic v2 (como `pydantic.v1`), para facilitar a migração para o v2.
|
Se você tiver o Pydantic v2 instalado, ele será utilizado. Se, em vez disso, tiver o Pydantic v1, será ele que será utilizado.
|
||||||
|
|
||||||
O FastAPI 0.126.0 removeu o suporte ao Pydantic v1, enquanto ainda oferece suporte a `pydantic.v1` por mais algum tempo.
|
O Pydantic v1 está agora descontinuado e o suporte a ele será removido nas próximas versões do FastAPI, você deveria migrar para o Pydantic v2. Assim, você terá as funcionalidades, melhorias e correções mais recentes.
|
||||||
|
|
||||||
/// warning | Atenção
|
/// warning | Atenção
|
||||||
|
|
||||||
A equipe do Pydantic interrompeu o suporte ao Pydantic v1 para as versões mais recentes do Python, a partir do **Python 3.14**.
|
Além disso, a equipe do Pydantic interrompeu o suporte ao Pydantic v1 para as versões mais recentes do Python, a partir do **Python 3.14**.
|
||||||
|
|
||||||
Isso inclui `pydantic.v1`, que não é mais suportado no Python 3.14 e superiores.
|
|
||||||
|
|
||||||
Se quiser usar as funcionalidades mais recentes do Python, você precisará garantir que usa o Pydantic v2.
|
Se quiser usar as funcionalidades mais recentes do Python, você precisará garantir que usa o Pydantic v2.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Se você tem uma aplicação FastAPI antiga com Pydantic v1, aqui vou mostrar como migrá-la para o Pydantic v2, e as **funcionalidades no FastAPI 0.119.0** para ajudar em uma migração gradual.
|
Se você tem uma aplicação FastAPI antiga com Pydantic v1, aqui vou mostrar como migrá-la para o Pydantic v2 e as **novas funcionalidades no FastAPI 0.119.0** para ajudar em uma migração gradual.
|
||||||
|
|
||||||
## Guia oficial { #official-guide }
|
## Guia oficial { #official-guide }
|
||||||
|
|
||||||
@@ -46,7 +44,7 @@ Depois disso, você pode rodar os testes e verificar se tudo funciona. Se funcio
|
|||||||
|
|
||||||
## Pydantic v1 no v2 { #pydantic-v1-in-v2 }
|
## Pydantic v1 no v2 { #pydantic-v1-in-v2 }
|
||||||
|
|
||||||
O Pydantic v2 inclui tudo do Pydantic v1 como um submódulo `pydantic.v1`. Mas isso não é mais suportado em versões acima do Python 3.13.
|
O Pydantic v2 inclui tudo do Pydantic v1 como um submódulo `pydantic.v1`.
|
||||||
|
|
||||||
Isso significa que você pode instalar a versão mais recente do Pydantic v2 e importar e usar os componentes antigos do Pydantic v1 a partir desse submódulo, como se tivesse o Pydantic v1 antigo instalado.
|
Isso significa que você pode instalar a versão mais recente do Pydantic v2 e importar e usar os componentes antigos do Pydantic v1 a partir desse submódulo, como se tivesse o Pydantic v1 antigo instalado.
|
||||||
|
|
||||||
@@ -68,7 +66,7 @@ Tenha em mente que, como a equipe do Pydantic não oferece mais suporte ao Pydan
|
|||||||
|
|
||||||
### Pydantic v1 e v2 na mesma aplicação { #pydantic-v1-and-v2-on-the-same-app }
|
### Pydantic v1 e v2 na mesma aplicação { #pydantic-v1-and-v2-on-the-same-app }
|
||||||
|
|
||||||
Não é **suportado** pelo Pydantic ter um modelo do Pydantic v2 com campos próprios definidos como modelos do Pydantic v1, ou vice-versa.
|
Não é suportado pelo Pydantic ter um modelo do Pydantic v2 com campos próprios definidos como modelos do Pydantic v1, ou vice-versa.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TB
|
graph TB
|
||||||
@@ -88,7 +86,7 @@ graph TB
|
|||||||
style V2Field fill:#f9fff3
|
style V2Field fill:#f9fff3
|
||||||
```
|
```
|
||||||
|
|
||||||
...mas, você pode ter modelos separados usando Pydantic v1 e v2 na mesma aplicação.
|
...but, you can have separated models using Pydantic v1 and v2 in the same app.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TB
|
graph TB
|
||||||
@@ -108,7 +106,7 @@ graph TB
|
|||||||
style V2Field fill:#f9fff3
|
style V2Field fill:#f9fff3
|
||||||
```
|
```
|
||||||
|
|
||||||
Em alguns casos, é até possível ter modelos Pydantic v1 e v2 na mesma **operação de rota** na sua aplicação FastAPI:
|
Em alguns casos, é até possível ter modelos Pydantic v1 e v2 na mesma operação de rota na sua aplicação FastAPI:
|
||||||
|
|
||||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
|
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
|
||||||
|
|
||||||
@@ -124,7 +122,7 @@ Se você precisar usar algumas das ferramentas específicas do FastAPI para par
|
|||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Primeiro tente com o `bump-pydantic`, se seus testes passarem e isso funcionar, então você concluiu tudo com um único comando. ✨
|
Primeiro tente com o `bump-pydantic`; se seus testes passarem e isso funcionar, então você concluiu tudo com um único comando. ✨
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Esquemas OpenAPI Separados para Entrada e Saída ou Não { #separate-openapi-schemas-for-input-and-output-or-not }
|
# Esquemas OpenAPI Separados para Entrada e Saída ou Não { #separate-openapi-schemas-for-input-and-output-or-not }
|
||||||
|
|
||||||
Desde que o **Pydantic v2** foi lançado, o OpenAPI gerado é um pouco mais exato e **correto** do que antes. 😎
|
Ao usar **Pydantic v2**, o OpenAPI gerado é um pouco mais exato e **correto** do que antes. 😎
|
||||||
|
|
||||||
De fato, em alguns casos, ele terá até **dois JSON Schemas** no OpenAPI para o mesmo modelo Pydantic, para entrada e saída, dependendo se eles possuem **valores padrão**.
|
Inclusive, em alguns casos, ele terá até **dois JSON Schemas** no OpenAPI para o mesmo modelo Pydantic, para entrada e saída, dependendo se eles possuem **valores padrão**.
|
||||||
|
|
||||||
Vamos ver como isso funciona e como alterar se for necessário.
|
Vamos ver como isso funciona e como alterar se for necessário.
|
||||||
|
|
||||||
@@ -95,8 +95,10 @@ O suporte para `separate_input_output_schemas` foi adicionado no FastAPI `0.102.
|
|||||||
|
|
||||||
### Mesmo Esquema para Modelos de Entrada e Saída na Documentação { #same-schema-for-input-and-output-models-in-docs }
|
### Mesmo Esquema para Modelos de Entrada e Saída na Documentação { #same-schema-for-input-and-output-models-in-docs }
|
||||||
|
|
||||||
E agora haverá um único esquema para entrada e saída para o modelo, apenas `Item`, e ele terá `description` como **não obrigatório**:
|
E agora haverá um único esquema para entrada e saída para o modelo, apenas `Item`, e `description` **não será obrigatório**:
|
||||||
|
|
||||||
<div class="screenshot">
|
<div class="screenshot">
|
||||||
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Esse é o mesmo comportamento do Pydantic v1. 🤓
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ Os recursos chave são:
|
|||||||
* **Rápido**: alta performance, equivalente a **NodeJS** e **Go** (graças ao Starlette e Pydantic). [Um dos frameworks mais rápidos disponíveis](#performance).
|
* **Rápido**: alta performance, equivalente a **NodeJS** e **Go** (graças ao Starlette e Pydantic). [Um dos frameworks mais rápidos disponíveis](#performance).
|
||||||
* **Rápido para codar**: Aumenta a velocidade para desenvolver recursos entre 200% a 300%. *
|
* **Rápido para codar**: Aumenta a velocidade para desenvolver recursos entre 200% a 300%. *
|
||||||
* **Poucos bugs**: Reduz cerca de 40% de erros induzidos por humanos (desenvolvedores). *
|
* **Poucos bugs**: Reduz cerca de 40% de erros induzidos por humanos (desenvolvedores). *
|
||||||
* **Intuitivo**: Grande suporte a editores. <abbr title="também conhecido como auto-complete, autocompletion, IntelliSense">Completação</abbr> em todos os lugares. Menos tempo debugando.
|
* **Intuitivo**: Grande suporte a _IDEs_. <abbr title="também conhecido como autocompletar, preenchimento automático, IntelliSense">Preenchimento automático</abbr> em todos os lugares. Menos tempo debugando.
|
||||||
* **Fácil**: Projetado para ser fácil de aprender e usar. Menos tempo lendo docs.
|
* **Fácil**: Projetado para ser fácil de aprender e usar. Menos tempo lendo documentação.
|
||||||
* **Enxuto**: Minimize duplicação de código. Múltiplas funcionalidades para cada declaração de parâmetro. Menos bugs.
|
* **Enxuto**: Minimize duplicação de código. Múltiplas funcionalidades para cada declaração de parâmetro. Menos bugs.
|
||||||
* **Robusto**: Tenha código pronto para produção. E com documentação interativa automática.
|
* **Robusto**: Tenha código pronto para produção. E com documentação interativa automática.
|
||||||
* **Baseado em padrões**: Baseado em (e totalmente compatível com) os padrões abertos para APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (anteriormente conhecido como Swagger) e <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
* **Baseado em padrões**: Baseado em (e totalmente compatível com) os padrões abertos para APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (anteriormente conhecido como Swagger) e <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||||
@@ -73,7 +73,7 @@ Os recursos chave são:
|
|||||||
|
|
||||||
## Opiniões { #opinions }
|
## Opiniões { #opinions }
|
||||||
|
|
||||||
"_[...] Estou usando **FastAPI** muito esses dias. [...] Estou na verdade planejando utilizar ele em todos os times de **serviços ML na Microsoft**. Alguns deles estão sendo integrados no _core_ do produto **Windows** e alguns produtos **Office**._"
|
"*[...] Estou usando **FastAPI** muito esses dias. [...] Estou na verdade planejando utilizar ele em todos os times de **serviços _Machine Learning_ na Microsoft**. Alguns deles estão sendo integrados no _core_ do produto **Windows** e alguns produtos **Office**.*"
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
@@ -91,45 +91,39 @@ Os recursos chave são:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Estou muito entusiasmado com o **FastAPI**. É tão divertido!_"
|
"*Estou extremamente entusiasmado com o **FastAPI**. É tão divertido!*"
|
||||||
|
|
||||||
<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> apresentador do podcast</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
<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> podcaster</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Honestamente, o que você construiu parece super sólido e refinado. De muitas formas, é o que eu queria que o **Hug** fosse - é realmente inspirador ver alguém construir isso._"
|
"*Honestamente, o que você construiu parece super sólido e rebuscado. De muitas formas, eu queria que o **Hug** fosse assim - é realmente inspirador ver alguém que construiu ele.*"
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>criador do<a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>criador do<a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Se você está procurando aprender um **framework moderno** para construir APIs REST, dê uma olhada no **FastAPI** [...] É rápido, fácil de usar e fácil de aprender [...]_"
|
"*Se você está procurando aprender um **_framework_ moderno** para construir aplicações _REST_, dê uma olhada no **FastAPI** [...] É rápido, fácil de usar e fácil de aprender [...]*"
|
||||||
|
|
||||||
"_Nós trocamos nossas **APIs** por **FastAPI** [...] Acredito que você gostará dele [...]_"
|
"*Nós trocamos nossas **APIs** por **FastAPI** [...] Acredito que vocês gostarão dele [...]*"
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>fundadores da <a href="https://explosion.ai" target="_blank">Explosion AI</a> - criadores da <a href="https://spacy.io" target="_blank">spaCy</a></strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>fundadores da <a href="https://explosion.ai" target="_blank">Explosion AI</a> - criadores da <a href="https://spacy.io" target="_blank">spaCy</a></strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Se alguém estiver procurando construir uma API Python para produção, eu recomendaria fortemente o **FastAPI**. Ele é **lindamente projetado**, **simples de usar** e **altamente escalável**, e se tornou um **componente chave** para a nossa estratégia de desenvolvimento API first, impulsionando diversas automações e serviços, como o nosso Virtual TAC Engineer._"
|
"_Se alguém estiver procurando construir uma API Python para produção, eu recomendaria fortemente o **FastAPI**. Ele é **lindamente projetado**, **simples de usar** e **altamente escalável**. Ele se tornou um **componente chave** para a nossa estratégia API first de desenvolvimento e está impulsionando diversas automações e serviços, como o nosso Virtual TAC Engineer._"
|
||||||
|
|
||||||
<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>
|
<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>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Mini documentário do FastAPI { #fastapi-mini-documentary }
|
|
||||||
|
|
||||||
Há um <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">mini documentário do FastAPI</a> lançado no fim de 2025, você pode assisti-lo online:
|
|
||||||
|
|
||||||
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
|
||||||
|
|
||||||
## **Typer**, o FastAPI das interfaces de linhas de comando { #typer-the-fastapi-of-clis }
|
## **Typer**, o FastAPI das interfaces de linhas de comando { #typer-the-fastapi-of-clis }
|
||||||
|
|
||||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
<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>
|
||||||
|
|
||||||
Se você estiver construindo uma aplicação <abbr title="Command Line Interface - Interface de Linha de Comando">CLI</abbr> para ser utilizada no terminal ao invés de uma API web, dê uma olhada no <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
Se você estiver construindo uma aplicação <abbr title="Command Line Interface – Interface de Linha de Comando">CLI</abbr> para ser utilizada em um terminal ao invés de uma aplicação web, dê uma olhada no <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||||
|
|
||||||
**Typer** é o irmão menor do FastAPI. E seu propósito é ser o **FastAPI das CLIs**. ⌨️ 🚀
|
**Typer** é o irmão menor do FastAPI. E seu propósito é ser o **FastAPI das _CLIs_**. ⌨️ 🚀
|
||||||
|
|
||||||
## Requisitos { #requirements }
|
## Requisitos { #requirements }
|
||||||
|
|
||||||
@@ -261,10 +255,10 @@ Você verá a resposta JSON como:
|
|||||||
|
|
||||||
Você acabou de criar uma API que:
|
Você acabou de criar uma API que:
|
||||||
|
|
||||||
* Recebe requisições HTTP nos _paths_ `/` e `/items/{item_id}`.
|
* Recebe requisições HTTP nas _rotas_ `/` e `/items/{item_id}`.
|
||||||
* Ambos _paths_ fazem <em>operações</em> `GET` (também conhecido como _métodos_ HTTP).
|
* Ambas _rotas_ fazem <em>operações</em> `GET` (também conhecido como _métodos_ HTTP).
|
||||||
* O _path_ `/items/{item_id}` tem um _parâmetro de path_ `item_id` que deve ser um `int`.
|
* A _rota_ `/items/{item_id}` tem um _parâmetro de rota_ `item_id` que deve ser um `int`.
|
||||||
* O _path_ `/items/{item_id}` tem um _parâmetro query_ `q` `str` opcional.
|
* A _rota_ `/items/{item_id}` tem um _parâmetro query_ `q` `str` opcional.
|
||||||
|
|
||||||
### Documentação Interativa da API { #interactive-api-docs }
|
### Documentação Interativa da API { #interactive-api-docs }
|
||||||
|
|
||||||
@@ -284,7 +278,7 @@ Você verá a documentação automática alternativa (fornecida por <a href="htt
|
|||||||
|
|
||||||
## Evoluindo o Exemplo { #example-upgrade }
|
## Evoluindo o Exemplo { #example-upgrade }
|
||||||
|
|
||||||
Agora modifique o arquivo `main.py` para receber um corpo de uma requisição `PUT`.
|
Agora modifique o arquivo `main.py` para receber um corpo para uma requisição `PUT`.
|
||||||
|
|
||||||
Declare o corpo utilizando tipos padrão Python, graças ao Pydantic.
|
Declare o corpo utilizando tipos padrão Python, graças ao Pydantic.
|
||||||
|
|
||||||
@@ -340,7 +334,7 @@ Agora vá para <a href="http://127.0.0.1:8000/docs" class="external-link" target
|
|||||||
|
|
||||||
E agora, vá para <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
E agora, vá para <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||||
|
|
||||||
* A documentação alternativa também irá refletir o novo parâmetro query e o corpo:
|
* A documentação alternativa também irá refletir o novo parâmetro da _query_ e o corpo:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -374,15 +368,15 @@ item: Item
|
|||||||
* Validação de dados:
|
* Validação de dados:
|
||||||
* Erros automáticos e claros quando o dado é inválido.
|
* Erros automáticos e claros quando o dado é inválido.
|
||||||
* Validação até para objetos JSON profundamente aninhados.
|
* Validação até para objetos JSON profundamente aninhados.
|
||||||
* <abbr title="também conhecido como: serialization, parsing, marshalling">Conversão</abbr> de dados de entrada: vindo da rede para dados e tipos Python. Consegue ler:
|
* <abbr title="também conhecido como: serialização, parsing, marshalling">Conversão</abbr> de dados de entrada: vindo da rede para dados e tipos Python. Consegue ler:
|
||||||
* JSON.
|
* JSON.
|
||||||
* Parâmetros de path.
|
* Parâmetros de rota.
|
||||||
* Parâmetros query.
|
* Parâmetros de _query_ .
|
||||||
* Cookies.
|
* _Cookies_.
|
||||||
* Cabeçalhos.
|
* Cabeçalhos.
|
||||||
* Formulários.
|
* Formulários.
|
||||||
* Arquivos.
|
* Arquivos.
|
||||||
* <abbr title="também conhecido como: serialization, parsing, marshalling">Conversão</abbr> de dados de saída: convertendo de tipos e dados Python para dados de rede (como JSON):
|
* <abbr title="também conhecido como: serialização, parsing, marshalling">Conversão</abbr> de dados de saída de tipos e dados Python para dados de rede (como JSON):
|
||||||
* Converte tipos Python (`str`, `int`, `float`, `bool`, `list` etc).
|
* Converte tipos Python (`str`, `int`, `float`, `bool`, `list` etc).
|
||||||
* Objetos `datetime`.
|
* Objetos `datetime`.
|
||||||
* Objetos `UUID`.
|
* Objetos `UUID`.
|
||||||
@@ -396,17 +390,17 @@ item: Item
|
|||||||
|
|
||||||
Voltando ao código do exemplo anterior, **FastAPI** irá:
|
Voltando ao código do exemplo anterior, **FastAPI** irá:
|
||||||
|
|
||||||
* Validar que existe um `item_id` no path para requisições `GET` e `PUT`.
|
* Validar que existe um `item_id` na rota para requisições `GET` e `PUT`.
|
||||||
* Validar que `item_id` é do tipo `int` para requisições `GET` e `PUT`.
|
* Validar que `item_id` é do tipo `int` para requisições `GET` e `PUT`.
|
||||||
* Se não for, o cliente verá um erro útil e claro.
|
* Se não é validado, o cliente verá um útil, claro erro.
|
||||||
* Verificar se existe um parâmetro query opcional nomeado como `q` (como em `http://127.0.0.1:8000/items/foo?q=somequery`) para requisições `GET`.
|
* Verificar se existe um parâmetro de _query_ opcional nomeado como `q` (como em `http://127.0.0.1:8000/items/foo?q=somequery`) para requisições `GET`.
|
||||||
* Como o parâmetro `q` é declarado com `= None`, ele é opcional.
|
* Como o parâmetro `q` é declarado com `= None`, ele é opcional.
|
||||||
* Sem o `None` ele seria obrigatório (como o corpo no caso de `PUT`).
|
* Sem o `None` ele poderia ser obrigatório (como o corpo no caso de `PUT`).
|
||||||
* Para requisições `PUT` para `/items/{item_id}`, lerá o corpo como JSON:
|
* Para requisições `PUT` para `/items/{item_id}`, lerá o corpo como JSON:
|
||||||
* Verifica que tem um atributo obrigatório `name` que deve ser `str`.
|
* Verifica que tem um atributo obrigatório `name` que deve ser `str`.
|
||||||
* Verifica que tem um atributo obrigatório `price` que tem que ser um `float`.
|
* Verifica que tem um atributo obrigatório `price` que deve ser `float`.
|
||||||
* Verifica que tem um atributo opcional `is_offer`, que deve ser um `bool`, se presente.
|
* Verifica que tem an atributo opcional `is_offer`, que deve ser `bool`, se presente.
|
||||||
* Tudo isso também funcionaria para objetos JSON profundamente aninhados.
|
* Tudo isso também funciona para objetos JSON profundamente aninhados.
|
||||||
* Converter de e para JSON automaticamente.
|
* Converter de e para JSON automaticamente.
|
||||||
* Documentar tudo com OpenAPI, que poderá ser usado por:
|
* Documentar tudo com OpenAPI, que poderá ser usado por:
|
||||||
* Sistemas de documentação interativos.
|
* Sistemas de documentação interativos.
|
||||||
@@ -415,7 +409,7 @@ Voltando ao código do exemplo anterior, **FastAPI** irá:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Nós apenas arranhamos a superfície, mas você já tem ideia de como tudo funciona.
|
Nós apenas arranhamos a superfície, mas você já tem idéia de como tudo funciona.
|
||||||
|
|
||||||
Experimente mudar a seguinte linha:
|
Experimente mudar a seguinte linha:
|
||||||
|
|
||||||
@@ -443,22 +437,22 @@ Para um exemplo mais completo incluindo mais recursos, veja <a href="https://fas
|
|||||||
|
|
||||||
**Alerta de Spoiler**: o tutorial - guia do usuário inclui:
|
**Alerta de Spoiler**: o tutorial - guia do usuário inclui:
|
||||||
|
|
||||||
* Declaração de **parâmetros** de diferentes lugares como: **cabeçalhos**, **cookies**, **campos de formulários** e **arquivos**.
|
* Declaração de **parâmetetros** de diferentes lugares como: **cabeçalhos**, **cookies**, **campos de formulários** e **arquivos**.
|
||||||
* Como configurar **limitações de validação** como `maximum_length` ou `regex`.
|
* Como configurar **Limitações de Validação** como `maximum_length` ou `regex`.
|
||||||
* Um poderoso e fácil de usar sistema de **<abbr title="também conhecido como components, resources, providers, services, injectables">Injeção de Dependência</abbr>**.
|
* Um poderoso e fácil de usar sistema de **<abbr title="também conhecido como componentes, recursos, fornecedores, serviços, injetáveis">Injeção de Dependência</abbr>**.
|
||||||
* Segurança e autenticação, incluindo suporte para **OAuth2** com autenticação com **JWT tokens** e **HTTP Basic**.
|
* Segurança e autenticação, incluindo suporte para **OAuth2** com autenticação **JWT tokens** e **HTTP Basic**.
|
||||||
* Técnicas mais avançadas (mas igualmente fáceis) para declaração de **modelos JSON profundamente aninhados** (graças ao Pydantic).
|
* Técnicas mais avançadas (mas igualmente fáceis) para declaração de **modelos JSON profundamente aninhados** (graças ao Pydantic).
|
||||||
* Integrações **GraphQL** com o <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> e outras bibliotecas.
|
* Integrações **GraphQL** com o <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> e outras bibliotecas.
|
||||||
* Muitos recursos extras (graças ao Starlette) como:
|
* Muitos recursos extras (graças ao Starlette) como:
|
||||||
* **WebSockets**
|
* **WebSockets**
|
||||||
* testes extremamente fáceis baseados em HTTPX e `pytest`
|
* testes extrememamente fáceis baseados em HTTPX e `pytest`
|
||||||
* **CORS**
|
* **CORS**
|
||||||
* **Cookie Sessions**
|
* **Cookie Sessions**
|
||||||
* ...e mais.
|
* ...e mais.
|
||||||
|
|
||||||
### Implemente sua aplicação (opcional) { #deploy-your-app-optional }
|
### Implemente sua aplicação (opcional) { #deploy-your-app-optional }
|
||||||
|
|
||||||
Você pode opcionalmente implantar sua aplicação FastAPI na <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, vá e entre na lista de espera se ainda não o fez. 🚀
|
Você pode opcionalmente implantar sua aplicação FastAPI na <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, inscreva-se na lista de espera se ainda não o fez. 🚀
|
||||||
|
|
||||||
Se você já tem uma conta na **FastAPI Cloud** (nós convidamos você da lista de espera 😉), pode implantar sua aplicação com um único comando.
|
Se você já tem uma conta na **FastAPI Cloud** (nós convidamos você da lista de espera 😉), pode implantar sua aplicação com um único comando.
|
||||||
|
|
||||||
@@ -512,7 +506,7 @@ Siga os tutoriais do seu provedor de nuvem para implantar aplicações FastAPI c
|
|||||||
|
|
||||||
Testes de performance da _Independent TechEmpower_ mostram aplicações **FastAPI** rodando sob Uvicorn como <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">um dos _frameworks_ Python mais rápidos disponíveis</a>, somente atrás de Starlette e Uvicorn (utilizados internamente pelo FastAPI). (*)
|
Testes de performance da _Independent TechEmpower_ mostram aplicações **FastAPI** rodando sob Uvicorn como <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">um dos _frameworks_ Python mais rápidos disponíveis</a>, somente atrás de Starlette e Uvicorn (utilizados internamente pelo FastAPI). (*)
|
||||||
|
|
||||||
Para entender mais sobre isso, veja a seção <a href="https://fastapi.tiangolo.com/pt/benchmarks/" class="internal-link" target="_blank">Comparações</a>.
|
Para entender mais sobre performance, veja a seção <a href="https://fastapi.tiangolo.com/pt/benchmarks/" class="internal-link" target="_blank">Comparações</a>.
|
||||||
|
|
||||||
## Dependências { #dependencies }
|
## Dependências { #dependencies }
|
||||||
|
|
||||||
@@ -520,7 +514,7 @@ O FastAPI depende do Pydantic e do Starlette.
|
|||||||
|
|
||||||
### Dependências `standard` { #standard-dependencies }
|
### Dependências `standard` { #standard-dependencies }
|
||||||
|
|
||||||
Quando você instala o FastAPI com `pip install "fastapi[standard]"`, ele vem com o grupo `standard` de dependências opcionais:
|
Quando você instala o FastAPI com `pip install "fastapi[standard]"`, ele vêm com o grupo `standard` (padrão) de dependências opcionais:
|
||||||
|
|
||||||
Utilizado pelo Pydantic:
|
Utilizado pelo Pydantic:
|
||||||
|
|
||||||
@@ -530,7 +524,7 @@ Utilizado pelo Starlette:
|
|||||||
|
|
||||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Obrigatório caso você queira utilizar o `TestClient`.
|
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Obrigatório caso você queira utilizar o `TestClient`.
|
||||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Obrigatório se você quer utilizar a configuração padrão de templates.
|
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Obrigatório se você quer utilizar a configuração padrão de templates.
|
||||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Obrigatório se você deseja suporte a <abbr title="converting the string that comes from an HTTP request into Python data - convertendo a string que vem de uma requisição HTTP em dados Python">"parsing"</abbr> de formulário, com `request.form()`.
|
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Obrigatório se você deseja suporte a <abbr title="convertendo a string que vem de uma requisição HTTP em dados Python">"parsing"</abbr> de formulário, com `request.form()`.
|
||||||
|
|
||||||
Utilizado pelo FastAPI:
|
Utilizado pelo FastAPI:
|
||||||
|
|
||||||
@@ -553,7 +547,7 @@ Existem algumas dependências adicionais que você pode querer instalar.
|
|||||||
Dependências opcionais adicionais do Pydantic:
|
Dependências opcionais adicionais do Pydantic:
|
||||||
|
|
||||||
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - para gerenciamento de configurações.
|
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - para gerenciamento de configurações.
|
||||||
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - para tipos extras a serem utilizados com o Pydantic.
|
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - tipos extras para serem utilizados com o Pydantic.
|
||||||
|
|
||||||
Dependências opcionais adicionais do FastAPI:
|
Dependências opcionais adicionais do FastAPI:
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Digamos que você tenha uma estrutura de arquivos como esta:
|
|||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Existem vários arquivos `__init__.py`: um em cada diretório ou subdiretório.
|
Existem vários arquivos `__init__.py` presentes em cada diretório ou subdiretório.
|
||||||
|
|
||||||
Isso permite a importação de código de um arquivo para outro.
|
Isso permite a importação de código de um arquivo para outro.
|
||||||
|
|
||||||
@@ -43,32 +43,32 @@ from app.routers import items
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
* O diretório `app` contém tudo. E possui um arquivo vazio `app/__init__.py`, então ele é um "pacote Python" (uma coleção de "módulos Python"): `app`.
|
* O diretório `app` contém todo o código da aplicação. Ele possui um arquivo `app/__init__.py` vazio, o que o torna um "pacote Python" (uma coleção de "módulos Python"): `app`.
|
||||||
* Ele contém um arquivo `app/main.py`. Como está dentro de um pacote Python (um diretório com um arquivo `__init__.py`), ele é um "módulo" desse pacote: `app.main`.
|
* Dentro dele, o arquivo `app/main.py` está localizado em um pacote Python (diretório com `__init__.py`). Portanto, ele é um "módulo" desse pacote: `app.main`.
|
||||||
* Existe também um arquivo `app/dependencies.py`, assim como `app/main.py`, ele é um "módulo": `app.dependencies`.
|
* Existem também um arquivo `app/dependencies.py`, assim como o `app/main.py`, ele é um "módulo": `app.dependencies`.
|
||||||
* Há um subdiretório `app/routers/` com outro arquivo `__init__.py`, então ele é um "subpacote Python": `app.routers`.
|
* Há um subdiretório `app/routers/` com outro arquivo `__init__.py`, então ele é um "subpacote Python": `app.routers`.
|
||||||
* O arquivo `app/routers/items.py` está dentro de um pacote, `app/routers/`, portanto é um submódulo: `app.routers.items`.
|
* O arquivo `app/routers/items.py` está dentro de um pacote, `app/routers/`, portanto, é um "submódulo": `app.routers.items`.
|
||||||
* O mesmo com `app/routers/users.py`, ele é outro submódulo: `app.routers.users`.
|
* O mesmo com `app/routers/users.py`, ele é outro submódulo: `app.routers.users`.
|
||||||
* Há também um subdiretório `app/internal/` com outro arquivo `__init__.py`, então ele é outro "subpacote Python": `app.internal`.
|
* Há também um subdiretório `app/internal/` com outro arquivo `__init__.py`, então ele é outro "subpacote Python":`app.internal`.
|
||||||
* E o arquivo `app/internal/admin.py` é outro submódulo: `app.internal.admin`.
|
* E o arquivo `app/internal/admin.py` é outro submódulo: `app.internal.admin`.
|
||||||
|
|
||||||
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
||||||
|
|
||||||
A mesma estrutura de arquivos com comentários:
|
A mesma estrutura de arquivos com comentários:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
.
|
.
|
||||||
├── app # "app" is a Python package
|
├── app # "app" é um pacote Python
|
||||||
│ ├── __init__.py # this file makes "app" a "Python package"
|
│ ├── __init__.py # este arquivo torna "app" um "pacote Python"
|
||||||
│ ├── main.py # "main" module, e.g. import app.main
|
│ ├── main.py # "main" módulo, e.g. import app.main
|
||||||
│ ├── dependencies.py # "dependencies" module, e.g. import app.dependencies
|
│ ├── dependencies.py # "dependencies" módulo, e.g. import app.dependencies
|
||||||
│ └── routers # "routers" is a "Python subpackage"
|
│ └── routers # "routers" é um "subpacote Python"
|
||||||
│ │ ├── __init__.py # makes "routers" a "Python subpackage"
|
│ │ ├── __init__.py # torna "routers" um "subpacote Python"
|
||||||
│ │ ├── items.py # "items" submodule, e.g. import app.routers.items
|
│ │ ├── items.py # "items" submódulo, e.g. import app.routers.items
|
||||||
│ │ └── users.py # "users" submodule, e.g. import app.routers.users
|
│ │ └── users.py # "users" submódulo, e.g. import app.routers.users
|
||||||
│ └── internal # "internal" is a "Python subpackage"
|
│ └── internal # "internal" é um "subpacote Python"
|
||||||
│ ├── __init__.py # makes "internal" a "Python subpackage"
|
│ ├── __init__.py # torna "internal" um "subpacote Python"
|
||||||
│ └── admin.py # "admin" submodule, e.g. import app.internal.admin
|
│ └── admin.py # "admin" submódulo, e.g. import app.internal.admin
|
||||||
```
|
```
|
||||||
|
|
||||||
## `APIRouter` { #apirouter }
|
## `APIRouter` { #apirouter }
|
||||||
@@ -79,11 +79,11 @@ Você quer manter as *operações de rota* relacionadas aos seus usuários separ
|
|||||||
|
|
||||||
Mas ele ainda faz parte da mesma aplicação/web API **FastAPI** (faz parte do mesmo "pacote Python").
|
Mas ele ainda faz parte da mesma aplicação/web API **FastAPI** (faz parte do mesmo "pacote Python").
|
||||||
|
|
||||||
Você pode criar as *operações de rota* para esse módulo usando o `APIRouter`.
|
Você pode criar as *operações de rotas* para esse módulo usando o `APIRouter`.
|
||||||
|
|
||||||
### Importe `APIRouter` { #import-apirouter }
|
### Importe `APIRouter` { #import-apirouter }
|
||||||
|
|
||||||
Você o importa e cria uma "instância" da mesma maneira que faria com a classe `FastAPI`:
|
você o importa e cria uma "instância" da mesma maneira que faria com a classe `FastAPI`:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ Você o importa e cria uma "instância" da mesma maneira que faria com a classe
|
|||||||
|
|
||||||
E então você o utiliza para declarar suas *operações de rota*.
|
E então você o utiliza para declarar suas *operações de rota*.
|
||||||
|
|
||||||
Utilize-o da mesma maneira que utilizaria a classe `FastAPI`:
|
Utilize-o da mesma maneira que utilizaria a classe `FastAPI`:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ Então, em vez de adicionar tudo isso a cada *operação de rota*, podemos adici
|
|||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
||||||
|
|
||||||
Como o path de cada *operação de rota* tem que começar com `/`, como em:
|
Como o caminho de cada *operação de rota* deve começar com `/`, como em:
|
||||||
|
|
||||||
```Python hl_lines="1"
|
```Python hl_lines="1"
|
||||||
@router.get("/{item_id}")
|
@router.get("/{item_id}")
|
||||||
@@ -163,9 +163,9 @@ async def read_item(item_id: str):
|
|||||||
|
|
||||||
Então, o prefixo neste caso é `/items`.
|
Então, o prefixo neste caso é `/items`.
|
||||||
|
|
||||||
Também podemos adicionar uma list de `tags` e `responses` extras que serão aplicadas a todas as *operações de rota* incluídas neste router.
|
Também podemos adicionar uma lista de `tags` e `responses` extras que serão aplicadas a todas as *operações de rota* incluídas neste roteador.
|
||||||
|
|
||||||
E podemos adicionar uma list de `dependencies` que serão adicionadas a todas as *operações de rota* no router e serão executadas/resolvidas para cada request feita a elas.
|
E podemos adicionar uma lista de `dependencies` que serão adicionadas a todas as *operações de rota* no roteador e serão executadas/resolvidas para cada request feita a elas.
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ Observe que, assim como [dependências em *decoradores de operação de rota*](d
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
O resultado final é que os paths dos itens agora são:
|
O resultado final é que os caminhos dos itens agora são:
|
||||||
|
|
||||||
* `/items/`
|
* `/items/`
|
||||||
* `/items/{item_id}`
|
* `/items/{item_id}`
|
||||||
@@ -183,9 +183,9 @@ O resultado final é que os paths dos itens agora são:
|
|||||||
* Elas serão marcadas com uma lista de tags que contêm uma única string `"items"`.
|
* Elas serão marcadas com uma lista de tags que contêm uma única string `"items"`.
|
||||||
* Essas "tags" são especialmente úteis para os sistemas de documentação interativa automática (usando OpenAPI).
|
* Essas "tags" são especialmente úteis para os sistemas de documentação interativa automática (usando OpenAPI).
|
||||||
* Todas elas incluirão as `responses` predefinidas.
|
* Todas elas incluirão as `responses` predefinidas.
|
||||||
* Todas essas *operações de rota* terão a list de `dependencies` avaliada/executada antes delas.
|
* Todas essas *operações de rota* terão a lista de `dependencies` avaliada/executada antes delas.
|
||||||
* Se você também declarar dependências em uma *operação de rota* específica, **elas também serão executadas**.
|
* Se você também declarar dependências em uma *operação de rota* específica, **elas também serão executadas**.
|
||||||
* As dependências do router são executadas primeiro, depois as [`dependencies` no decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} e, em seguida, as dependências de parâmetros normais.
|
* As dependências do roteador são executadas primeiro, depois as [`dependencies` no decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} e, em seguida, as dependências de parâmetros normais.
|
||||||
* Você também pode adicionar [dependências de `Segurança` com `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
|
* Você também pode adicionar [dependências de `Segurança` com `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
@@ -246,7 +246,7 @@ from ..dependencies import get_token_header
|
|||||||
|
|
||||||
significa:
|
significa:
|
||||||
|
|
||||||
* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) vive (o diretório `app/routers/`)...
|
* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) reside (o diretório `app/routers/`)...
|
||||||
* vá para o pacote pai (o diretório `app/`)...
|
* vá para o pacote pai (o diretório `app/`)...
|
||||||
* e lá, encontre o módulo `dependencies` (o arquivo em `app/dependencies.py`)...
|
* e lá, encontre o módulo `dependencies` (o arquivo em `app/dependencies.py`)...
|
||||||
* e dele, importe a função `get_token_header`.
|
* e dele, importe a função `get_token_header`.
|
||||||
@@ -283,9 +283,9 @@ Mas ainda podemos adicionar _mais_ `tags` que serão aplicadas a uma *operação
|
|||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Esta última operação de rota terá a combinação de tags: `["items", "custom"]`.
|
Esta última operação de caminho terá a combinação de tags: `["items", "custom"]`.
|
||||||
|
|
||||||
E também terá ambas as responses na documentação, uma para `404` e uma para `403`.
|
E também terá ambas as respostas na documentação, uma para `404` e uma para `403`.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ from .routers import items, users
|
|||||||
|
|
||||||
significa:
|
significa:
|
||||||
|
|
||||||
* Começando no mesmo pacote em que este módulo (o arquivo `app/main.py`) vive (o diretório `app/`)...
|
* Começando no mesmo pacote em que este módulo (o arquivo `app/main.py`) reside (o diretório `app/`)...
|
||||||
* procure o subpacote `routers` (o diretório em `app/routers/`)...
|
* procure o subpacote `routers` (o diretório em `app/routers/`)...
|
||||||
* e dele, importe o submódulo `items` (o arquivo em `app/routers/items.py`) e `users` (o arquivo em `app/routers/users.py`)...
|
* e dele, importe o submódulo `items` (o arquivo em `app/routers/items.py`) e `users` (o arquivo em `app/routers/users.py`)...
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ Então, para poder usar ambos no mesmo arquivo, importamos os submódulos direta
|
|||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
|
||||||
|
|
||||||
### Inclua os `APIRouter`s para `users` e `items` { #include-the-apirouters-for-users-and-items }
|
### Inclua os `APIRouter`s para `usuários` e `itens` { #include-the-apirouters-for-users-and-items }
|
||||||
|
|
||||||
Agora, vamos incluir os `router`s dos submódulos `users` e `items`:
|
Agora, vamos incluir os `router`s dos submódulos `users` e `items`:
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ E `items.router` contém o `APIRouter` dentro do arquivo `app/routers/items.py`.
|
|||||||
|
|
||||||
Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo principal `FastAPI`.
|
Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo principal `FastAPI`.
|
||||||
|
|
||||||
Ele incluirá todas as rotas daquele router como parte dele.
|
Ele incluirá todas as rotas daquele roteador como parte dele.
|
||||||
|
|
||||||
/// note | Detalhes Técnicos
|
/// note | Detalhes Técnicos
|
||||||
|
|
||||||
@@ -404,7 +404,7 @@ Então, nos bastidores, ele realmente funcionará como se tudo fosse o mesmo apl
|
|||||||
|
|
||||||
/// check | Verifique
|
/// check | Verifique
|
||||||
|
|
||||||
Você não precisa se preocupar com desempenho ao incluir routers.
|
Você não precisa se preocupar com desempenho ao incluir roteadores.
|
||||||
|
|
||||||
Isso levará microssegundos e só acontecerá na inicialização.
|
Isso levará microssegundos e só acontecerá na inicialização.
|
||||||
|
|
||||||
@@ -453,7 +453,7 @@ e funcionará corretamente, junto com todas as outras *operações de rota* adic
|
|||||||
|
|
||||||
/// note | Detalhes Técnicos Avançados
|
/// note | Detalhes Técnicos Avançados
|
||||||
|
|
||||||
**Nota**: este é um detalhe muito técnico que você provavelmente pode **simplesmente pular**.
|
**Observação**: este é um detalhe muito técnico que você provavelmente pode **simplesmente pular**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -479,15 +479,15 @@ $ fastapi dev app/main.py
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
E abra a documentação em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
E abra os documentos em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||||
|
|
||||||
Você verá a documentação automática da API, incluindo os paths de todos os submódulos, usando os paths (e prefixos) corretos e as tags corretas:
|
Você verá a documentação automática da API, incluindo os caminhos de todos os submódulos, usando os caminhos (e prefixos) corretos e as tags corretas:
|
||||||
|
|
||||||
<img src="/img/tutorial/bigger-applications/image01.png">
|
<img src="/img/tutorial/bigger-applications/image01.png">
|
||||||
|
|
||||||
## Inclua o mesmo router várias vezes com `prefix` diferentes { #include-the-same-router-multiple-times-with-different-prefix }
|
## Inclua o mesmo roteador várias vezes com `prefix` diferentes { #include-the-same-router-multiple-times-with-different-prefix }
|
||||||
|
|
||||||
Você também pode usar `.include_router()` várias vezes com o *mesmo* router usando prefixos diferentes.
|
Você também pode usar `.include_router()` várias vezes com o *mesmo* roteador usando prefixos diferentes.
|
||||||
|
|
||||||
Isso pode ser útil, por exemplo, para expor a mesma API sob prefixos diferentes, por exemplo, `/api/v1` e `/api/latest`.
|
Isso pode ser útil, por exemplo, para expor a mesma API sob prefixos diferentes, por exemplo, `/api/v1` e `/api/latest`.
|
||||||
|
|
||||||
@@ -495,10 +495,10 @@ Esse é um uso avançado que você pode não precisar, mas está lá caso precis
|
|||||||
|
|
||||||
## Inclua um `APIRouter` em outro { #include-an-apirouter-in-another }
|
## Inclua um `APIRouter` em outro { #include-an-apirouter-in-another }
|
||||||
|
|
||||||
Da mesma forma que você pode incluir um `APIRouter` em uma aplicação `FastAPI`, você pode incluir um `APIRouter` em outro `APIRouter` usando:
|
Da mesma forma que você pode incluir um `APIRouter` em um aplicativo `FastAPI`, você pode incluir um `APIRouter` em outro `APIRouter` usando:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
router.include_router(other_router)
|
router.include_router(other_router)
|
||||||
```
|
```
|
||||||
|
|
||||||
Certifique-se de fazer isso antes de incluir `router` na aplicação `FastAPI`, para que as *operações de rota* de `other_router` também sejam incluídas.
|
Certifique-se de fazer isso antes de incluir `router` no aplicativo `FastAPI`, para que as *operações de rota* de `other_router` também sejam incluídas.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Corpo - Atualizações { #body-updates }
|
# Corpo - Atualizações { #body-updates }
|
||||||
|
|
||||||
## Atualização substituindo com `PUT` { #update-replacing-with-put }
|
## Atualização de dados existentes com `PUT` { #update-replacing-with-put }
|
||||||
|
|
||||||
Para atualizar um item, você pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
|
Para atualizar um item, você pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
|
||||||
|
|
||||||
@@ -22,13 +22,13 @@ Isso significa que, se você quiser atualizar o item `bar` usando `PUT` com um c
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`.
|
Como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`.
|
||||||
|
|
||||||
E os dados seriam salvos com esse "novo" `tax` de `10.5`.
|
E os dados seriam salvos com esse "novo" `tax` de `10.5`.
|
||||||
|
|
||||||
## Atualizações parciais com `PATCH` { #partial-updates-with-patch }
|
## Atualizações parciais com `PATCH` { #partial-updates-with-patch }
|
||||||
|
|
||||||
Você também pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> para atualizar dados *parcialmente*.
|
Você também pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> para atualizar parcialmente os dados.
|
||||||
|
|
||||||
Isso significa que você pode enviar apenas os dados que deseja atualizar, deixando o restante intacto.
|
Isso significa que você pode enviar apenas os dados que deseja atualizar, deixando o restante intacto.
|
||||||
|
|
||||||
@@ -40,17 +40,25 @@ E muitas equipes usam apenas `PUT`, mesmo para atualizações parciais.
|
|||||||
|
|
||||||
Você é **livre** para usá-los como preferir, **FastAPI** não impõe restrições.
|
Você é **livre** para usá-los como preferir, **FastAPI** não impõe restrições.
|
||||||
|
|
||||||
Mas este guia mostra, mais ou menos, como eles são destinados a serem usados.
|
Mas este guia te dá uma ideia de como eles são destinados a serem usados.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Usando o parâmetro `exclude_unset` do Pydantic { #using-pydantics-exclude-unset-parameter }
|
### Usando o parâmetro `exclude_unset` do Pydantic { #using-pydantics-exclude-unset-parameter }
|
||||||
|
|
||||||
Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no `.model_dump()` do modelo do Pydantic.
|
Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no método `.model_dump()` do modelo do Pydantic.
|
||||||
|
|
||||||
Como `item.model_dump(exclude_unset=True)`.
|
Como `item.model_dump(exclude_unset=True)`.
|
||||||
|
|
||||||
Isso geraria um `dict` com apenas os dados que foram definidos ao criar o modelo `item`, excluindo os valores padrão.
|
/// info | Informação
|
||||||
|
|
||||||
|
No Pydantic v1, o método que era chamado `.dict()` e foi descontinuado (mas ainda suportado) no Pydantic v2. Agora, deve-se usar o método `.model_dump()`.
|
||||||
|
|
||||||
|
Os exemplos aqui usam `.dict()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` a partir do Pydantic v2.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Isso gera um `dict` com apenas os dados definidos ao criar o modelo `item`, excluindo os valores padrão.
|
||||||
|
|
||||||
Então, você pode usar isso para gerar um `dict` com apenas os dados definidos (enviados na solicitação), omitindo valores padrão:
|
Então, você pode usar isso para gerar um `dict` com apenas os dados definidos (enviados na solicitação), omitindo valores padrão:
|
||||||
|
|
||||||
@@ -60,23 +68,31 @@ Então, você pode usar isso para gerar um `dict` com apenas os dados definidos
|
|||||||
|
|
||||||
Agora, você pode criar uma cópia do modelo existente usando `.model_copy()`, e passar o parâmetro `update` com um `dict` contendo os dados para atualizar.
|
Agora, você pode criar uma cópia do modelo existente usando `.model_copy()`, e passar o parâmetro `update` com um `dict` contendo os dados para atualizar.
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
No Pydantic v1, o método era chamado `.copy()`, ele foi descontinuado (mas ainda suportado) no Pydantic v2, e renomeado para `.model_copy()`.
|
||||||
|
|
||||||
|
Os exemplos aqui usam `.copy()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_copy()` com o Pydantic v2.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
Como `stored_item_model.model_copy(update=update_data)`:
|
Como `stored_item_model.model_copy(update=update_data)`:
|
||||||
|
|
||||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
||||||
|
|
||||||
### Recapitulando as atualizações parciais { #partial-updates-recap }
|
### Recapitulando as atualizações parciais { #partial-updates-recap }
|
||||||
|
|
||||||
Resumindo, para aplicar atualizações parciais você deveria:
|
Resumindo, para aplicar atualizações parciais você pode:
|
||||||
|
|
||||||
* (Opcionalmente) usar `PATCH` em vez de `PUT`.
|
* (Opcionalmente) usar `PATCH` em vez de `PUT`.
|
||||||
* Recuperar os dados armazenados.
|
* Recuperar os dados armazenados.
|
||||||
* Colocar esses dados em um modelo do Pydantic.
|
* Colocar esses dados em um modelo do Pydantic.
|
||||||
* Gerar um `dict` sem valores padrão a partir do modelo de entrada (usando `exclude_unset`).
|
* Gerar um `dict` sem valores padrão a partir do modelo de entrada (usando `exclude_unset`).
|
||||||
* Dessa forma, você pode atualizar apenas os valores realmente definidos pelo usuário, em vez de substituir valores já armazenados por valores padrão do modelo.
|
* Dessa forma, você pode atualizar apenas os valores definidos pelo usuário, em vez de substituir os valores já armazenados com valores padrão em seu modelo.
|
||||||
* Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`).
|
* Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`).
|
||||||
* Converter o modelo copiado em algo que possa ser armazenado no seu BD (por exemplo, usando o `jsonable_encoder`).
|
* Converter o modelo copiado em algo que possa ser armazenado no seu banco de dados (por exemplo, usando o `jsonable_encoder`).
|
||||||
* Isso é comparável a usar o método `.model_dump()` do modelo novamente, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`.
|
* Isso é comparável ao uso do método `.model_dump()`, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`.
|
||||||
* Salvar os dados no seu BD.
|
* Salvar os dados no seu banco de dados.
|
||||||
* Retornar o modelo atualizado.
|
* Retornar o modelo atualizado.
|
||||||
|
|
||||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
|
{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
|
||||||
@@ -93,8 +109,8 @@ Mas o exemplo aqui usa `PATCH` porque foi criado para esses casos de uso.
|
|||||||
|
|
||||||
Observe que o modelo de entrada ainda é validado.
|
Observe que o modelo de entrada ainda é validado.
|
||||||
|
|
||||||
Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, você precisa ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`).
|
Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, precisará ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`).
|
||||||
|
|
||||||
Para distinguir entre os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}.
|
Para distinguir os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ Para declarar um corpo da **requisição**, você utiliza os modelos do <a href=
|
|||||||
|
|
||||||
/// info | Informação
|
/// info | Informação
|
||||||
|
|
||||||
Para enviar dados, você deveria usar um dos: `POST` (o mais comum), `PUT`, `DELETE` ou `PATCH`.
|
Para enviar dados, você deve usar um dos: `POST` (o mais comum), `PUT`, `DELETE` ou `PATCH`.
|
||||||
|
|
||||||
Enviar um corpo em uma requisição `GET` não tem um comportamento definido nas especificações, porém é suportado pelo FastAPI, apenas para casos de uso bem complexos/extremos.
|
Enviar um corpo em uma requisição `GET` não tem um comportamento definido nas especificações, porém é suportado pelo FastAPI, apenas para casos de uso bem complexos/extremos.
|
||||||
|
|
||||||
Como é desencorajado, a documentação interativa com Swagger UI não irá mostrar a documentação para o corpo da requisição ao usar `GET`, e proxies intermediários podem não suportá-lo.
|
Como é desencorajado, a documentação interativa com Swagger UI não irá mostrar a documentação para o corpo da requisição para um `GET`, e proxies que intermediarem podem não suportar o corpo da requisição.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -32,8 +32,7 @@ Utilize os tipos Python padrão para todos os atributos:
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
|
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
|
||||||
|
|
||||||
|
Assim como quando declaramos parâmetros de consulta, quando um atributo do modelo possui um valor padrão, ele se torna opcional. Caso contrário, se torna obrigatório. Use `None` para torná-lo opcional.
|
||||||
Assim como quando declaramos parâmetros de consulta, quando um atributo do modelo possui um valor padrão, ele não é obrigatório. Caso contrário, é obrigatório. Use `None` para torná-lo apenas opcional.
|
|
||||||
|
|
||||||
Por exemplo, o modelo acima declara um JSON "`object`" (ou `dict` no Python) como esse:
|
Por exemplo, o modelo acima declara um JSON "`object`" (ou `dict` no Python) como esse:
|
||||||
|
|
||||||
@@ -67,7 +66,7 @@ Para adicioná-lo à sua *operação de rota*, declare-o da mesma maneira que vo
|
|||||||
|
|
||||||
Apenas com essa declaração de tipos do Python, o **FastAPI** irá:
|
Apenas com essa declaração de tipos do Python, o **FastAPI** irá:
|
||||||
|
|
||||||
* Ler o corpo da requisição como JSON.
|
* Ler o corpo da requisição como um JSON.
|
||||||
* Converter os tipos correspondentes (se necessário).
|
* Converter os tipos correspondentes (se necessário).
|
||||||
* Validar os dados.
|
* Validar os dados.
|
||||||
* Se algum dado for inválido, irá retornar um erro bem claro, indicando exatamente onde e o que estava incorreto.
|
* Se algum dado for inválido, irá retornar um erro bem claro, indicando exatamente onde e o que estava incorreto.
|
||||||
@@ -128,6 +127,14 @@ Dentro da função, você pode acessar todos os atributos do objeto do modelo di
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial002_py310.py *}
|
{* ../../docs_src/body/tutorial002_py310.py *}
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
No Pydantic v1 o método se chamava `.dict()`, ele foi descontinuado (mas ainda é suportado) no Pydantic v2, e renomeado para `.model_dump()`.
|
||||||
|
|
||||||
|
Os exemplos aqui usam `.dict()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` se puder usar o Pydantic v2.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
## Corpo da requisição + parâmetros de rota { #request-body-path-parameters }
|
## Corpo da requisição + parâmetros de rota { #request-body-path-parameters }
|
||||||
|
|
||||||
Você pode declarar parâmetros de rota e corpo da requisição ao mesmo tempo.
|
Você pode declarar parâmetros de rota e corpo da requisição ao mesmo tempo.
|
||||||
@@ -136,7 +143,6 @@ O **FastAPI** irá reconhecer que os parâmetros da função que combinam com pa
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
|
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
|
||||||
|
|
||||||
|
|
||||||
## Corpo da requisição + parâmetros de rota + parâmetros de consulta { #request-body-path-query-parameters }
|
## Corpo da requisição + parâmetros de rota + parâmetros de consulta { #request-body-path-query-parameters }
|
||||||
|
|
||||||
Você também pode declarar parâmetros de **corpo**, **rota** e **consulta**, ao mesmo tempo.
|
Você também pode declarar parâmetros de **corpo**, **rota** e **consulta**, ao mesmo tempo.
|
||||||
|
|||||||
@@ -22,13 +22,21 @@ Aqui está uma ideia geral de como os modelos poderiam parecer com seus campos d
|
|||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
||||||
|
|
||||||
### Sobre `**user_in.model_dump()` { #about-user-in-model-dump }
|
/// info | Informação
|
||||||
|
|
||||||
#### O `.model_dump()` do Pydantic { #pydantics-model-dump }
|
No Pydantic v1 o método se chamava `.dict()`, ele foi descontinuado (mas ainda é suportado) no Pydantic v2 e renomeado para `.model_dump()`.
|
||||||
|
|
||||||
|
Os exemplos aqui usam `.dict()` por compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` se puder usar o Pydantic v2.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
### Sobre `**user_in.dict()` { #about-user-in-dict }
|
||||||
|
|
||||||
|
#### O `.dict()` do Pydantic { #pydantics-dict }
|
||||||
|
|
||||||
`user_in` é um modelo Pydantic da classe `UserIn`.
|
`user_in` é um modelo Pydantic da classe `UserIn`.
|
||||||
|
|
||||||
Os modelos Pydantic possuem um método `.model_dump()` que retorna um `dict` com os dados do modelo.
|
Os modelos Pydantic possuem um método `.dict()` que retorna um `dict` com os dados do modelo.
|
||||||
|
|
||||||
Então, se criarmos um objeto Pydantic `user_in` como:
|
Então, se criarmos um objeto Pydantic `user_in` como:
|
||||||
|
|
||||||
@@ -39,7 +47,7 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
|
|||||||
e depois chamarmos:
|
e depois chamarmos:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
user_dict = user_in.model_dump()
|
user_dict = user_in.dict()
|
||||||
```
|
```
|
||||||
|
|
||||||
agora temos um `dict` com os dados na variável `user_dict` (é um `dict` em vez de um objeto de modelo Pydantic).
|
agora temos um `dict` com os dados na variável `user_dict` (é um `dict` em vez de um objeto de modelo Pydantic).
|
||||||
@@ -95,20 +103,20 @@ UserInDB(
|
|||||||
|
|
||||||
#### Um modelo Pydantic a partir do conteúdo de outro { #a-pydantic-model-from-the-contents-of-another }
|
#### Um modelo Pydantic a partir do conteúdo de outro { #a-pydantic-model-from-the-contents-of-another }
|
||||||
|
|
||||||
Como no exemplo acima, obtivemos o `user_dict` a partir do `user_in.model_dump()`, este código:
|
Como no exemplo acima, obtivemos o `user_dict` a partir do `user_in.dict()`, este código:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
user_dict = user_in.model_dump()
|
user_dict = user_in.dict()
|
||||||
UserInDB(**user_dict)
|
UserInDB(**user_dict)
|
||||||
```
|
```
|
||||||
|
|
||||||
seria equivalente a:
|
seria equivalente a:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(**user_in.model_dump())
|
UserInDB(**user_in.dict())
|
||||||
```
|
```
|
||||||
|
|
||||||
...porque `user_in.model_dump()` é um `dict`, e depois fazemos o Python "desembrulhá-lo" passando-o para `UserInDB` precedido por `**`.
|
...porque `user_in.dict()` é um `dict`, e depois fazemos o Python "desembrulhá-lo" passando-o para `UserInDB` precedido por `**`.
|
||||||
|
|
||||||
Então, obtemos um modelo Pydantic a partir dos dados em outro modelo Pydantic.
|
Então, obtemos um modelo Pydantic a partir dos dados em outro modelo Pydantic.
|
||||||
|
|
||||||
@@ -117,7 +125,7 @@ Então, obtemos um modelo Pydantic a partir dos dados em outro modelo Pydantic.
|
|||||||
E, então, adicionando o argumento de palavra-chave extra `hashed_password=hashed_password`, como em:
|
E, então, adicionando o argumento de palavra-chave extra `hashed_password=hashed_password`, como em:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
|
UserInDB(**user_in.dict(), hashed_password=hashed_password)
|
||||||
```
|
```
|
||||||
|
|
||||||
...acaba sendo como:
|
...acaba sendo como:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Para isso, primeiro importe:
|
|||||||
|
|
||||||
O FastAPI adicionou suporte a `Annotated` (e passou a recomendá-lo) na versão 0.95.0.
|
O FastAPI adicionou suporte a `Annotated` (e passou a recomendá-lo) na versão 0.95.0.
|
||||||
|
|
||||||
Se você tiver uma versão mais antiga, teria erros ao tentar usar `Annotated`.
|
Se você tiver uma versão mais antiga, terá erros ao tentar usar `Annotated`.
|
||||||
|
|
||||||
Certifique-se de [Atualizar a versão do FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
|
Certifique-se de [Atualizar a versão do FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ Agora o FastAPI vai:
|
|||||||
|
|
||||||
## Alternativa (antiga): `Query` como valor padrão { #alternative-old-query-as-the-default-value }
|
## Alternativa (antiga): `Query` como valor padrão { #alternative-old-query-as-the-default-value }
|
||||||
|
|
||||||
Versões anteriores do FastAPI (antes de <abbr title="before 2023-03 - antes de 2023-03">0.95.0</abbr>) exigiam que você usasse `Query` como valor padrão do seu parâmetro, em vez de colocá-lo em `Annotated`, há uma grande chance de você ver código usando isso por aí, então vou explicar.
|
Versões anteriores do FastAPI (antes de <abbr title="antes de 2023-03">0.95.0</abbr>) exigiam que você usasse `Query` como valor padrão do seu parâmetro, em vez de colocá-lo em `Annotated`. É muito provável que você veja código assim por aí, então vou te explicar.
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ Você também pode adicionar um parâmetro `min_length`:
|
|||||||
|
|
||||||
## Adicione expressões regulares { #add-regular-expressions }
|
## Adicione expressões regulares { #add-regular-expressions }
|
||||||
|
|
||||||
Você pode definir um `pattern` de <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings. - Uma expressão regular, regex ou regexp é uma sequência de caracteres que define um padrão de busca para strings.">expressão regular</abbr> que o parâmetro deve corresponder:
|
Você pode definir um `pattern` de <abbr title="Uma expressão regular, regex ou regexp é uma sequência de caracteres que define um padrão de busca para strings.">expressão regular</abbr> que o parâmetro deve corresponder:
|
||||||
|
|
||||||
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
||||||
|
|
||||||
@@ -206,6 +206,20 @@ Se você se sentir perdido com essas ideias de **"expressão regular"**, não se
|
|||||||
|
|
||||||
Agora você sabe que, sempre que precisar delas, pode usá-las no **FastAPI**.
|
Agora você sabe que, sempre que precisar delas, pode usá-las no **FastAPI**.
|
||||||
|
|
||||||
|
### Pydantic v1 `regex` em vez de `pattern` { #pydantic-v1-regex-instead-of-pattern }
|
||||||
|
|
||||||
|
Antes da versão 2 do Pydantic e antes do FastAPI 0.100.0, o parâmetro se chamava `regex` em vez de `pattern`, mas agora está descontinuado.
|
||||||
|
|
||||||
|
Você ainda pode ver algum código usando isso:
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
Mas saiba que isso está descontinuado e deve ser atualizado para usar o novo parâmetro `pattern`. 🤓
|
||||||
|
|
||||||
## Valores padrão { #default-values }
|
## Valores padrão { #default-values }
|
||||||
|
|
||||||
Você pode, claro, usar valores padrão diferentes de `None`.
|
Você pode, claro, usar valores padrão diferentes de `None`.
|
||||||
@@ -266,7 +280,7 @@ Então, com uma URL como:
|
|||||||
http://localhost:8000/items/?q=foo&q=bar
|
http://localhost:8000/items/?q=foo&q=bar
|
||||||
```
|
```
|
||||||
|
|
||||||
você receberia os múltiplos valores dos *parâmetros de consulta* `q` (`foo` e `bar`) em uma `list` Python dentro da sua *função de operação de rota*, no *parâmetro da função* `q`.
|
você receberá os múltiplos valores do *parâmetro de consulta* `q` (`foo` e `bar`) em uma `list` Python dentro da sua *função de operação de rota*, no *parâmetro da função* `q`.
|
||||||
|
|
||||||
Assim, a resposta para essa URL seria:
|
Assim, a resposta para essa URL seria:
|
||||||
|
|
||||||
@@ -336,7 +350,7 @@ Essas informações serão incluídas no OpenAPI gerado e usadas pelas interface
|
|||||||
|
|
||||||
Tenha em mente que ferramentas diferentes podem ter níveis diferentes de suporte ao OpenAPI.
|
Tenha em mente que ferramentas diferentes podem ter níveis diferentes de suporte ao OpenAPI.
|
||||||
|
|
||||||
Algumas delas podem ainda não mostrar todas as informações extras declaradas, embora na maioria dos casos a funcionalidade ausente já esteja planejada para desenvolvimento.
|
Algumas delas podem ainda não mostrar todas as informações extras declaradas, embora na maioria dos casos o recurso ausente já esteja planejado para desenvolvimento.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -372,7 +386,7 @@ Então você pode declarar um `alias`, e esse alias será usado para encontrar o
|
|||||||
|
|
||||||
Agora digamos que você não gosta mais desse parâmetro.
|
Agora digamos que você não gosta mais desse parâmetro.
|
||||||
|
|
||||||
Você tem que deixá-lo por um tempo, pois há clientes usando-o, mas quer que a documentação mostre claramente que ele está <abbr title="obsolete, recommended not to use it - obsoleto, recomenda-se não usá-lo">deprecated</abbr>.
|
Você tem que deixá-lo por um tempo, pois há clientes usando-o, mas quer que a documentação mostre claramente que ele está <abbr title="obsoleto, recomenda-se não usá-lo">descontinuado</abbr>.
|
||||||
|
|
||||||
Então passe o parâmetro `deprecated=True` para `Query`:
|
Então passe o parâmetro `deprecated=True` para `Query`:
|
||||||
|
|
||||||
@@ -402,7 +416,7 @@ O Pydantic também tem <a href="https://docs.pydantic.dev/latest/concepts/valida
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Por exemplo, este validador personalizado verifica se o ID do item começa com `isbn-` para um número de livro <abbr title="ISBN means International Standard Book Number - ISBN significa Número Padrão Internacional de Livro">ISBN</abbr> ou com `imdb-` para um ID de URL de filme <abbr title="IMDB (Internet Movie Database) is a website with information about movies - IMDB (Internet Movie Database) é um site com informações sobre filmes">IMDB</abbr>:
|
Por exemplo, este validador personalizado verifica se o ID do item começa com `isbn-` para um número de livro <abbr title="ISBN significa Número Padrão Internacional de Livro">ISBN</abbr> ou com `imdb-` para um ID de URL de filme <abbr title="IMDB (Internet Movie Database) é um site com informações sobre filmes">IMDB</abbr>:
|
||||||
|
|
||||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
||||||
|
|
||||||
@@ -414,7 +428,7 @@ Isso está disponível com a versão 2 do Pydantic ou superior. 😎
|
|||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Se você precisar fazer qualquer tipo de validação que exija comunicação com algum **componente externo**, como um banco de dados ou outra API, você deveria usar **Dependências do FastAPI** em vez disso; você aprenderá sobre elas mais adiante.
|
Se você precisar fazer qualquer tipo de validação que exija comunicação com algum **componente externo**, como um banco de dados ou outra API, você deve usar **Dependências do FastAPI** em vez disso; você aprenderá sobre elas mais adiante.
|
||||||
|
|
||||||
Esses validadores personalizados são para coisas que podem ser verificadas **apenas** com os **mesmos dados** fornecidos na requisição.
|
Esses validadores personalizados são para coisas que podem ser verificadas **apenas** com os **mesmos dados** fornecidos na requisição.
|
||||||
|
|
||||||
@@ -426,7 +440,7 @@ O ponto importante é apenas usar **`AfterValidator` com uma função dentro de
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Mas se você estiver curioso sobre este exemplo de código específico e ainda entretido, aqui vão alguns detalhes extras.
|
Mas se você está curioso sobre este exemplo específico e ainda entretido, aqui vão alguns detalhes extras.
|
||||||
|
|
||||||
#### String com `value.startswith()` { #string-with-value-startswith }
|
#### String com `value.startswith()` { #string-with-value-startswith }
|
||||||
|
|
||||||
@@ -436,7 +450,7 @@ Percebeu? Uma string usando `value.startswith()` pode receber uma tupla, e verif
|
|||||||
|
|
||||||
#### Um item aleatório { #a-random-item }
|
#### Um item aleatório { #a-random-item }
|
||||||
|
|
||||||
Com `data.items()` obtemos um <abbr title="Something we can iterate on with a for loop, like a list, set, etc. - Algo que podemos iterar com um laço for, como uma list, set, etc.">objeto iterável</abbr> com tuplas contendo a chave e o valor de cada item do dicionário.
|
Com `data.items()` obtemos um <abbr title="Algo que podemos iterar com um laço for, como uma list, set, etc.">objeto iterável</abbr> com tuplas contendo a chave e o valor de cada item do dicionário.
|
||||||
|
|
||||||
Convertimos esse objeto iterável em uma `list` adequada com `list(data.items())`.
|
Convertimos esse objeto iterável em uma `list` adequada com `list(data.items())`.
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,20 @@ Então, se você enviar uma solicitação para essa *operação de rota* para o
|
|||||||
|
|
||||||
/// info | Informação
|
/// info | Informação
|
||||||
|
|
||||||
|
No Pydantic v1, o método era chamado `.dict()`, ele foi descontinuado (mas ainda suportado) no Pydantic v2 e renomeado para `.model_dump()`.
|
||||||
|
|
||||||
|
Os exemplos aqui usam `.dict()` para compatibilidade com Pydantic v1, mas você deve usar `.model_dump()` em vez disso se puder usar Pydantic v2.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
|
O FastAPI usa `.dict()` do modelo Pydantic com <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">seu parâmetro `exclude_unset`</a> para chegar a isso.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/// info | Informação
|
||||||
|
|
||||||
Você também pode usar:
|
Você também pode usar:
|
||||||
|
|
||||||
* `response_model_exclude_defaults=True`
|
* `response_model_exclude_defaults=True`
|
||||||
|
|||||||
@@ -8,17 +8,39 @@ Aqui estão várias maneiras de fazer isso.
|
|||||||
|
|
||||||
Você pode declarar `examples` para um modelo Pydantic que serão adicionados ao JSON Schema gerado.
|
Você pode declarar `examples` para um modelo Pydantic que serão adicionados ao JSON Schema gerado.
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
|
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
Essas informações extras serão adicionadas como estão ao **JSON Schema** de saída para esse modelo e serão usadas na documentação da API.
|
Essas informações extras serão adicionadas como estão ao **JSON Schema** de saída para esse modelo e serão usadas na documentação da API.
|
||||||
|
|
||||||
Você pode usar o atributo `model_config`, que recebe um `dict`, conforme descrito na <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">documentação do Pydantic: Configuration</a>.
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
|
Na versão 2 do Pydantic, você usaria o atributo `model_config`, que recebe um `dict`, conforme descrito na <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">documentação do Pydantic: Configuration</a>.
|
||||||
|
|
||||||
Você pode definir `"json_schema_extra"` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`.
|
Você pode definir `"json_schema_extra"` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`.
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
Na versão 1 do Pydantic, você usaria uma classe interna `Config` e `schema_extra`, conforme descrito na <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">documentação do Pydantic: Schema customization</a>.
|
||||||
|
|
||||||
|
Você pode definir `schema_extra` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`.
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
Você poderia usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras personalizadas.
|
Você pode usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras personalizadas.
|
||||||
|
|
||||||
Por exemplo, você poderia usá-la para adicionar metadados para uma interface de usuário de front-end, etc.
|
Por exemplo, você poderia usá-la para adicionar metadados para uma interface de usuário de front-end, etc.
|
||||||
|
|
||||||
@@ -28,7 +50,7 @@ Por exemplo, você poderia usá-la para adicionar metadados para uma interface d
|
|||||||
|
|
||||||
O OpenAPI 3.1.0 (usado desde o FastAPI 0.99.0) adicionou suporte a `examples`, que faz parte do padrão **JSON Schema**.
|
O OpenAPI 3.1.0 (usado desde o FastAPI 0.99.0) adicionou suporte a `examples`, que faz parte do padrão **JSON Schema**.
|
||||||
|
|
||||||
Antes disso, ele suportava apenas a palavra‑chave `example` com um único exemplo. Isso ainda é suportado pelo OpenAPI 3.1.0, mas é descontinuado e não faz parte do padrão JSON Schema. Portanto, você é incentivado a migrar de `example` para `examples`. 🤓
|
Antes disso, ele suportava apenas a palavra‑chave `example` com um único exemplo. Isso ainda é suportado pelo OpenAPI 3.1.0, mas é descontinuado e não faz parte do padrão JSON Schema. Portanto, é recomendado migrar de `example` para `examples`. 🤓
|
||||||
|
|
||||||
Você pode ler mais no final desta página.
|
Você pode ler mais no final desta página.
|
||||||
|
|
||||||
@@ -80,7 +102,7 @@ No entanto, <abbr title="2023-08-26">no momento em que isto foi escrito</abbr>,
|
|||||||
|
|
||||||
Antes do **JSON Schema** suportar `examples`, o OpenAPI já tinha suporte para um campo diferente também chamado `examples`.
|
Antes do **JSON Schema** suportar `examples`, o OpenAPI já tinha suporte para um campo diferente também chamado `examples`.
|
||||||
|
|
||||||
Esse `examples` **específico do OpenAPI** vai em outra seção da especificação OpenAPI. Ele fica nos **detalhes de cada *operação de rota***, não dentro de cada JSON Schema.
|
Esse `examples` específico do OpenAPI vai em outra seção da especificação. Ele fica nos **detalhes de cada função de operação de rota**, não dentro de cada JSON Schema.
|
||||||
|
|
||||||
E o Swagger UI tem suportado esse campo `examples` particular há algum tempo. Então, você pode usá-lo para **mostrar** diferentes **exemplos na UI da documentação**.
|
E o Swagger UI tem suportado esse campo `examples` particular há algum tempo. Então, você pode usá-lo para **mostrar** diferentes **exemplos na UI da documentação**.
|
||||||
|
|
||||||
@@ -167,9 +189,9 @@ Depois, o JSON Schema adicionou um campo <a href="https://json-schema.org/draft/
|
|||||||
|
|
||||||
E então o novo OpenAPI 3.1.0 passou a se basear na versão mais recente (JSON Schema 2020-12), que incluiu esse novo campo `examples`.
|
E então o novo OpenAPI 3.1.0 passou a se basear na versão mais recente (JSON Schema 2020-12), que incluiu esse novo campo `examples`.
|
||||||
|
|
||||||
E agora esse novo campo `examples` tem precedência sobre o antigo campo único (e customizado) `example`, que agora está descontinuado.
|
Agora, esse novo campo `examples` tem precedência sobre o antigo (e customizado) campo único `example`, que agora está descontinuado.
|
||||||
|
|
||||||
Esse novo campo `examples` no JSON Schema é **apenas uma `list`** de exemplos, não um dict com metadados extras como nos outros lugares do OpenAPI (descritos acima).
|
Esse novo campo `examples` no JSON Schema é **apenas uma `list`** de exemplos, não um `dict` com metadados extras como nos outros lugares do OpenAPI (descritos acima).
|
||||||
|
|
||||||
/// info | Informação
|
/// info | Informação
|
||||||
|
|
||||||
@@ -191,7 +213,7 @@ Mas agora que o FastAPI 0.99.0 e superiores usam o OpenAPI 3.1.0, que usa o JSON
|
|||||||
|
|
||||||
### Swagger UI e `examples` específicos do OpenAPI { #swagger-ui-and-openapi-specific-examples }
|
### Swagger UI e `examples` específicos do OpenAPI { #swagger-ui-and-openapi-specific-examples }
|
||||||
|
|
||||||
Agora, como o Swagger UI não suportava vários exemplos no JSON Schema (em 2023-08-26), os usuários não tinham uma forma de mostrar vários exemplos na documentação.
|
Como o Swagger UI não suportava vários exemplos no JSON Schema (em 2023-08-26), os usuários não tinham uma forma de mostrar vários exemplos na documentação.
|
||||||
|
|
||||||
Para resolver isso, o FastAPI `0.103.0` **adicionou suporte** para declarar o mesmo antigo campo **específico do OpenAPI** `examples` com o novo parâmetro `openapi_examples`. 🤓
|
Para resolver isso, o FastAPI `0.103.0` **adicionou suporte** para declarar o mesmo antigo campo **específico do OpenAPI** `examples` com o novo parâmetro `openapi_examples`. 🤓
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Тестовый файл LLM { #llm-test-file }
|
# Тестовый файл LLM { #llm-test-file }
|
||||||
|
|
||||||
Этот документ проверяет, понимает ли <abbr title="Large Language Model - Большая языковая модель">LLM</abbr>, переводящая документацию, `general_prompt` в `scripts/translate.py` и языковой специфичный промпт в `docs/{language code}/llm-prompt.md`. Языковой специфичный промпт добавляется к `general_prompt`.
|
Этот документ проверяет, понимает ли <abbr title="Large Language Model – Большая языковая модель">LLM</abbr>, переводящая документацию, `general_prompt` в `scripts/translate.py` и языковой специфичный промпт в `docs/{language code}/llm-prompt.md`. Языковой специфичный промпт добавляется к `general_prompt`.
|
||||||
|
|
||||||
Тесты, добавленные здесь, увидят все создатели языковых специфичных промптов.
|
Тесты, добавленные здесь, увидят все создатели языковых промптов.
|
||||||
|
|
||||||
Использование:
|
Использование:
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
* Проверьте, всё ли в порядке в переводе.
|
* Проверьте, всё ли в порядке в переводе.
|
||||||
* При необходимости улучшите ваш языковой специфичный промпт, общий промпт или английский документ.
|
* При необходимости улучшите ваш языковой специфичный промпт, общий промпт или английский документ.
|
||||||
* Затем вручную исправьте оставшиеся проблемы в переводе, чтобы он был хорошим.
|
* Затем вручную исправьте оставшиеся проблемы в переводе, чтобы он был хорошим.
|
||||||
* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт настолько хороши, насколько это возможно (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">LLM — недетерминированные алгоритмы</a>).
|
* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт максимально хороши (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">LLM — недетерминированные алгоритмы</a>).
|
||||||
|
|
||||||
Тесты:
|
Тесты:
|
||||||
|
|
||||||
@@ -197,10 +197,10 @@ works(foo="bar") # Это работает 🎉
|
|||||||
|
|
||||||
### abbr даёт полную расшифровку { #the-abbr-gives-a-full-phrase }
|
### abbr даёт полную расшифровку { #the-abbr-gives-a-full-phrase }
|
||||||
|
|
||||||
* <abbr title="Getting Things Done - Как привести дела в порядок">GTD</abbr>
|
* <abbr title="Getting Things Done – Как привести дела в порядок">GTD</abbr>
|
||||||
* <abbr title="less than - меньше чем"><code>lt</code></abbr>
|
* <abbr title="less than – меньше чем"><code>lt</code></abbr>
|
||||||
* <abbr title="XML Web Token - XML веб‑токен">XWT</abbr>
|
* <abbr title="XML Web Token – XML веб‑токен">XWT</abbr>
|
||||||
* <abbr title="Parallel Server Gateway Interface - Параллельный серверный интерфейс шлюза">PSGI</abbr>
|
* <abbr title="Parallel Server Gateway Interface – Параллельный серверный интерфейс шлюза">PSGI</abbr>
|
||||||
|
|
||||||
### abbr даёт объяснение { #the-abbr-gives-an-explanation }
|
### abbr даёт объяснение { #the-abbr-gives-an-explanation }
|
||||||
|
|
||||||
@@ -209,8 +209,8 @@ works(foo="bar") # Это работает 🎉
|
|||||||
|
|
||||||
### abbr даёт полную расшифровку и объяснение { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
### abbr даёт полную расшифровку и объяснение { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
||||||
|
|
||||||
* <abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla: документация для разработчиков, созданная командой Firefox">MDN</abbr>
|
* <abbr title="Mozilla Developer Network – Сеть разработчиков Mozilla: документация для разработчиков, созданная командой Firefox">MDN</abbr>
|
||||||
* <abbr title="Input/Output - Ввод/Вывод: чтение или запись на диск, сетевое взаимодействие.">I/O</abbr>.
|
* <abbr title="Input/Output – Ввод/Вывод: чтение или запись на диск, сетевое взаимодействие.">I/O</abbr>.
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
### Использование имени *функции-обработчика пути* как operationId { #using-the-path-operation-function-name-as-the-operationid }
|
### Использование имени функции-обработчика пути как operationId { #using-the-path-operation-function-name-as-the-operationid }
|
||||||
|
|
||||||
Если вы хотите использовать имена функций ваших API в качестве `operationId`, вы можете пройти по всем из них и переопределить `operation_id` каждой *операции пути* с помощью их `APIRoute.name`.
|
Если вы хотите использовать имена функций ваших API в качестве `operationId`, вы можете пройти по всем из них и переопределить `operation_id` каждой *операции пути* с помощью их `APIRoute.name`.
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
## Исключить из OpenAPI { #exclude-from-openapi }
|
## Исключить из OpenAPI { #exclude-from-openapi }
|
||||||
|
|
||||||
Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматических систем документации), используйте параметр `include_in_schema` и установите его в `False`:
|
Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматической документации), используйте параметр `include_in_schema` и установите его в `False`:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
Добавление `\f` (экранированного символа «form feed») заставит **FastAPI** обрезать текст, используемый для OpenAPI, в этой точке.
|
Добавление `\f` (экранированного символа «form feed») заставит **FastAPI** обрезать текст, используемый для OpenAPI, в этой точке.
|
||||||
|
|
||||||
Это не отобразится в документации, но другие инструменты (например, Sphinx) смогут использовать остальное.
|
Эта часть не попадёт в документацию, но другие инструменты (например, Sphinx) смогут использовать остальное.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
Вы, вероятно, уже видели, как объявлять `response_model` и `status_code` для *операции пути*.
|
Вы, вероятно, уже видели, как объявлять `response_model` и `status_code` для *операции пути*.
|
||||||
|
|
||||||
Это определяет метаданные об основном HTTP-ответе *операции пути*.
|
Это определяет метаданные об основном ответе *операции пути*.
|
||||||
|
|
||||||
Также можно объявлять дополнительные ответы с их моделями, статус-кодами и т.д.
|
Также можно объявлять дополнительные ответы с их моделями, статус-кодами и т.д.
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
|
|
||||||
Там есть `tags`, `parameters`, `requestBody`, `responses` и т.д.
|
Там есть `tags`, `parameters`, `requestBody`, `responses` и т.д.
|
||||||
|
|
||||||
Эта специфичная для *операции пути* схема OpenAPI обычно генерируется автоматически **FastAPI**, но вы также можете её расширить.
|
Эта спецификация OpenAPI, специфичная для *операции пути*, обычно генерируется автоматически **FastAPI**, но вы также можете её расширить.
|
||||||
|
|
||||||
/// tip | Совет
|
/// tip | Совет
|
||||||
|
|
||||||
@@ -129,13 +129,13 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пользовательская схема OpenAPI для *операции пути* { #custom-openapi-path-operation-schema }
|
### Пользовательская схема OpenAPI для операции пути { #custom-openapi-path-operation-schema }
|
||||||
|
|
||||||
Словарь в `openapi_extra` будет глубоко объединён с автоматически сгенерированной схемой OpenAPI для *операции пути*.
|
Словарь в `openapi_extra` будет объединён с автоматически сгенерированной схемой OpenAPI для *операции пути*.
|
||||||
|
|
||||||
Таким образом, вы можете добавить дополнительные данные к автоматически сгенерированной схеме.
|
Таким образом, вы можете добавить дополнительные данные к автоматически сгенерированной схеме.
|
||||||
|
|
||||||
Например, вы можете решить читать и валидировать HTTP-запрос своим кодом, не используя автоматические возможности FastAPI и Pydantic, но при этом захотите описать HTTP-запрос в схеме OpenAPI.
|
Например, вы можете решить читать и валидировать запрос своим кодом, не используя автоматические возможности FastAPI и Pydantic, но при этом захотите описать запрос в схеме OpenAPI.
|
||||||
|
|
||||||
Это можно сделать с помощью `openapi_extra`:
|
Это можно сделать с помощью `openapi_extra`:
|
||||||
|
|
||||||
@@ -149,20 +149,52 @@
|
|||||||
|
|
||||||
Используя тот же приём, вы можете воспользоваться Pydantic-моделью, чтобы определить JSON Schema, которая затем будет включена в пользовательский раздел схемы OpenAPI для *операции пути*.
|
Используя тот же приём, вы можете воспользоваться Pydantic-моделью, чтобы определить JSON Schema, которая затем будет включена в пользовательский раздел схемы OpenAPI для *операции пути*.
|
||||||
|
|
||||||
И вы можете сделать это, даже если тип данных в HTTP-запросе — не JSON.
|
И вы можете сделать это, даже если тип данных в запросе — не JSON.
|
||||||
|
|
||||||
Например, в этом приложении мы не используем встроенную функциональность FastAPI для извлечения JSON Schema из моделей Pydantic, равно как и автоматическую валидацию JSON. Мы объявляем тип содержимого HTTP-запроса как YAML, а не JSON:
|
Например, в этом приложении мы не используем встроенную функциональность FastAPI для извлечения JSON Schema из моделей Pydantic, равно как и автоматическую валидацию JSON. Мы объявляем тип содержимого запроса как YAML, а не JSON:
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic версии 1 метод для получения JSON Schema модели назывался `Item.schema()`, в Pydantic версии 2 метод называется `Item.model_json_schema()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
Тем не менее, хотя мы не используем встроенную функциональность по умолчанию, мы всё равно используем Pydantic-модель, чтобы вручную сгенерировать JSON Schema для данных, которые мы хотим получить в YAML.
|
Тем не менее, хотя мы не используем встроенную функциональность по умолчанию, мы всё равно используем Pydantic-модель, чтобы вручную сгенерировать JSON Schema для данных, которые мы хотим получить в YAML.
|
||||||
|
|
||||||
Затем мы работаем с HTTP-запросом напрямую и извлекаем тело как `bytes`. Это означает, что FastAPI даже не попытается распарсить полезную нагрузку HTTP-запроса как JSON.
|
Затем мы работаем с запросом напрямую и извлекаем тело как `bytes`. Это означает, что FastAPI даже не попытается распарсить полезную нагрузку запроса как JSON.
|
||||||
|
|
||||||
А затем в нашем коде мы напрямую парсим это содержимое YAML и снова используем ту же Pydantic-модель, чтобы валидировать YAML-содержимое:
|
А затем в нашем коде мы напрямую парсим этот YAML и снова используем ту же Pydantic-модель для валидации YAML-содержимого:
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic версии 1 метод для парсинга и валидации объекта назывался `Item.parse_obj()`, в Pydantic версии 2 метод называется `Item.model_validate()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
/// tip | Совет
|
/// tip | Совет
|
||||||
|
|
||||||
Здесь мы переиспользуем ту же Pydantic-модель.
|
Здесь мы переиспользуем ту же Pydantic-модель.
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ $ pip install "fastapi[all]"
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic v1 он входил в основной пакет. Теперь он распространяется как отдельный пакет, чтобы вы могли установить его только при необходимости.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
### Создание объекта `Settings` { #create-the-settings-object }
|
### Создание объекта `Settings` { #create-the-settings-object }
|
||||||
|
|
||||||
Импортируйте `BaseSettings` из Pydantic и создайте подкласс, очень похожий на Pydantic‑модель.
|
Импортируйте `BaseSettings` из Pydantic и создайте подкласс, очень похожий на Pydantic‑модель.
|
||||||
@@ -54,8 +60,24 @@ $ pip install "fastapi[all]"
|
|||||||
|
|
||||||
Вы можете использовать все те же возможности валидации и инструменты, что и для Pydantic‑моделей, например разные типы данных и дополнительную валидацию через `Field()`.
|
Вы можете использовать все те же возможности валидации и инструменты, что и для Pydantic‑моделей, например разные типы данных и дополнительную валидацию через `Field()`.
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
|
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic v1 вы бы импортировали `BaseSettings` напрямую из `pydantic`, а не из `pydantic_settings`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
/// tip | Совет
|
/// tip | Совет
|
||||||
|
|
||||||
Если вам нужно что-то быстро скопировать и вставить, не используйте этот пример — воспользуйтесь последним ниже.
|
Если вам нужно что-то быстро скопировать и вставить, не используйте этот пример — воспользуйтесь последним ниже.
|
||||||
@@ -193,6 +215,8 @@ APP_NAME="ChimichangApp"
|
|||||||
|
|
||||||
Затем обновите ваш `config.py` так:
|
Затем обновите ваш `config.py` так:
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
|
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
|
||||||
|
|
||||||
/// tip | Совет
|
/// tip | Совет
|
||||||
@@ -201,6 +225,26 @@ APP_NAME="ChimichangApp"
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
|
||||||
|
|
||||||
|
/// tip | Совет
|
||||||
|
|
||||||
|
Класс `Config` используется только для конфигурации Pydantic. Подробнее см. <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic версии 1 конфигурация задавалась во внутреннем классе `Config`, в Pydantic версии 2 — в атрибуте `model_config`. Этот атрибут принимает `dict`, и чтобы получить автозавершение и ошибки «на лету», вы можете импортировать и использовать `SettingsConfigDict` для описания этого `dict`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
Здесь мы задаем параметр конфигурации `env_file` внутри вашего класса Pydantic `Settings` и устанавливаем значение равным имени файла dotenv, который хотим использовать.
|
Здесь мы задаем параметр конфигурации `env_file` внутри вашего класса Pydantic `Settings` и устанавливаем значение равным имени файла dotenv, который хотим использовать.
|
||||||
|
|
||||||
### Создание `Settings` только один раз с помощью `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
### Создание `Settings` только один раз с помощью `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
||||||
|
|||||||
@@ -2,23 +2,21 @@
|
|||||||
|
|
||||||
Если у вас старое приложение FastAPI, возможно, вы используете Pydantic версии 1.
|
Если у вас старое приложение FastAPI, возможно, вы используете Pydantic версии 1.
|
||||||
|
|
||||||
FastAPI версии 0.100.0 поддерживал либо Pydantic v1, либо v2. Он использовал ту версию, которая была установлена.
|
FastAPI поддерживает и Pydantic v1, и v2 начиная с версии 0.100.0.
|
||||||
|
|
||||||
FastAPI версии 0.119.0 добавил частичную поддержку Pydantic v1 изнутри Pydantic v2 (как `pydantic.v1`), чтобы упростить миграцию на v2.
|
Если у вас был установлен Pydantic v2, использовался он. Если вместо этого был установлен Pydantic v1 — использовался он.
|
||||||
|
|
||||||
FastAPI 0.126.0 убрал поддержку Pydantic v1, при этом ещё некоторое время продолжал поддерживать `pydantic.v1`.
|
Сейчас Pydantic v1 объявлен устаревшим, и поддержка его будет удалена в следующих версиях FastAPI, поэтому вам следует **перейти на Pydantic v2**. Так вы получите последние возможности, улучшения и исправления.
|
||||||
|
|
||||||
/// warning | Предупреждение
|
/// warning | Предупреждение
|
||||||
|
|
||||||
Команда Pydantic прекратила поддержку Pydantic v1 для последних версий Python, начиная с **Python 3.14**.
|
Кроме того, команда Pydantic прекратила поддержку Pydantic v1 для последних версий Python, начиная с **Python 3.14**.
|
||||||
|
|
||||||
Это включает `pydantic.v1`, который больше не поддерживается в Python 3.14 и выше.
|
|
||||||
|
|
||||||
Если вы хотите использовать последние возможности Python, вам нужно убедиться, что вы используете Pydantic v2.
|
Если вы хотите использовать последние возможности Python, вам нужно убедиться, что вы используете Pydantic v2.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Если у вас старое приложение FastAPI с Pydantic v1, здесь я покажу, как мигрировать на Pydantic v2, и **возможности FastAPI 0.119.0**, которые помогут выполнить постепенную миграцию.
|
Если у вас старое приложение FastAPI с Pydantic v1, здесь я покажу, как мигрировать на Pydantic v2, и **новые возможности в FastAPI 0.119.0**, которые помогут выполнить постепенную миграцию.
|
||||||
|
|
||||||
## Официальное руководство { #official-guide }
|
## Официальное руководство { #official-guide }
|
||||||
|
|
||||||
@@ -40,13 +38,13 @@ FastAPI 0.126.0 убрал поддержку Pydantic v1, при этом ещ
|
|||||||
|
|
||||||
Вы можете использовать <a href="https://github.com/pydantic/bump-pydantic" class="external-link" target="_blank">`bump-pydantic`</a> от той же команды Pydantic.
|
Вы можете использовать <a href="https://github.com/pydantic/bump-pydantic" class="external-link" target="_blank">`bump-pydantic`</a> от той же команды Pydantic.
|
||||||
|
|
||||||
Этот инструмент поможет автоматически изменить большую часть кода, который нужно изменить.
|
Этот инструмент поможет автоматически внести большую часть необходимых изменений в код.
|
||||||
|
|
||||||
После этого вы можете запустить тесты и проверить, что всё работает. Если да — на этом всё. 😎
|
После этого запустите тесты и проверьте, что всё работает. Если да — на этом всё. 😎
|
||||||
|
|
||||||
## Pydantic v1 в v2 { #pydantic-v1-in-v2 }
|
## Pydantic v1 в v2 { #pydantic-v1-in-v2 }
|
||||||
|
|
||||||
Pydantic v2 включает всё из Pydantic v1 как подмодуль `pydantic.v1`. Но это больше не поддерживается в версиях Python выше 3.13.
|
Pydantic v2 включает всё из Pydantic v1 как подмодуль `pydantic.v1`.
|
||||||
|
|
||||||
Это означает, что вы можете установить последнюю версию Pydantic v2 и импортировать и использовать старые компоненты Pydantic v1 из этого подмодуля так, как если бы у вас был установлен старый Pydantic v1.
|
Это означает, что вы можете установить последнюю версию Pydantic v2 и импортировать и использовать старые компоненты Pydantic v1 из этого подмодуля так, как если бы у вас был установлен старый Pydantic v1.
|
||||||
|
|
||||||
@@ -54,7 +52,7 @@ Pydantic v2 включает всё из Pydantic v1 как подмодуль `
|
|||||||
|
|
||||||
### Поддержка FastAPI для Pydantic v1 внутри v2 { #fastapi-support-for-pydantic-v1-in-v2 }
|
### Поддержка FastAPI для Pydantic v1 внутри v2 { #fastapi-support-for-pydantic-v1-in-v2 }
|
||||||
|
|
||||||
Начиная с FastAPI 0.119.0, есть также частичная поддержка Pydantic v1 изнутри Pydantic v2, чтобы упростить миграцию на v2.
|
Начиная с FastAPI 0.119.0, есть также частичная поддержка Pydantic v1 в составе Pydantic v2, чтобы упростить миграцию на v2.
|
||||||
|
|
||||||
Таким образом, вы можете обновить Pydantic до последней версии 2 и сменить импорты на подмодуль `pydantic.v1` — во многих случаях всё просто заработает.
|
Таким образом, вы можете обновить Pydantic до последней версии 2 и сменить импорты на подмодуль `pydantic.v1` — во многих случаях всё просто заработает.
|
||||||
|
|
||||||
@@ -108,7 +106,7 @@ graph TB
|
|||||||
style V2Field fill:#f9fff3
|
style V2Field fill:#f9fff3
|
||||||
```
|
```
|
||||||
|
|
||||||
В некоторых случаях можно использовать и модели Pydantic v1, и v2 в одной и той же **операции пути** (обработчике пути) вашего приложения FastAPI:
|
В некоторых случаях можно использовать и модели Pydantic v1, и v2 в одной и той же операции пути (обработчике пути) вашего приложения FastAPI:
|
||||||
|
|
||||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
|
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
|
||||||
|
|
||||||
@@ -124,12 +122,12 @@ graph TB
|
|||||||
|
|
||||||
/// tip | Совет
|
/// tip | Совет
|
||||||
|
|
||||||
Сначала попробуйте `bump-pydantic`: если тесты проходят и всё работает, вы справились одной командой. ✨
|
Сначала попробуйте `bump-pydantic`. Если тесты проходят и всё работает, вы справились одной командой. ✨
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Если `bump-pydantic` не подходит для вашего случая, вы можете использовать поддержку одновременной работы моделей Pydantic v1 и v2 в одном приложении, чтобы мигрировать на Pydantic v2 постепенно.
|
Если `bump-pydantic` не подходит для вашего случая, вы можете использовать поддержку одновременной работы моделей Pydantic v1 и v2 в одном приложении, чтобы мигрировать на Pydantic v2 постепенно.
|
||||||
|
|
||||||
Сначала вы можете обновить Pydantic до последней 2-й версии и изменить импорты так, чтобы все ваши модели использовали `pydantic.v1`.
|
Сначала обновите Pydantic до последней 2-й версии и измените импорты так, чтобы все ваши модели использовали `pydantic.v1`.
|
||||||
|
|
||||||
Затем вы можете начать мигрировать ваши модели с Pydantic v1 на v2 группами, поэтапно. 🚶
|
Затем начните мигрировать ваши модели с Pydantic v1 на v2 группами, поэтапно. 🚶
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
При использовании **Pydantic v2** сгенерированный OpenAPI становится чуть более точным и **корректным**, чем раньше. 😎
|
При использовании **Pydantic v2** сгенерированный OpenAPI становится чуть более точным и **корректным**, чем раньше. 😎
|
||||||
|
|
||||||
На самом деле, в некоторых случаях в OpenAPI будет даже **две JSON-схемы** для одной и той же Pydantic‑модели: для входа и для выхода — в зависимости от наличия **значений по умолчанию**.
|
На самом деле, в некоторых случаях в OpenAPI будет даже **две JSON схемы** для одной и той же Pydantic‑модели: для входа и для выхода — в зависимости от наличия **значений по умолчанию**.
|
||||||
|
|
||||||
Посмотрим, как это работает, и как это изменить при необходимости.
|
Посмотрим, как это работает, и как это изменить при необходимости.
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
|
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
|
||||||
|
|
||||||
…то, поскольку у `description` есть значение по умолчанию, если вы **ничего не вернёте** для этого поля, оно всё равно будет иметь это **значение по умолчанию**.
|
…то, поскольку у `description` есть значение по умолчанию, даже если вы **ничего не вернёте** для этого поля, оно всё равно будет иметь это **значение по умолчанию**.
|
||||||
|
|
||||||
### Модель для данных ответа { #model-for-output-response-data }
|
### Модель для данных ответа { #model-for-output-response-data }
|
||||||
|
|
||||||
@@ -46,13 +46,13 @@
|
|||||||
|
|
||||||
Это означает, что у него **всегда будет какое‑то значение**, просто иногда это значение может быть `None` (или `null` в JSON).
|
Это означает, что у него **всегда будет какое‑то значение**, просто иногда это значение может быть `None` (или `null` в JSON).
|
||||||
|
|
||||||
Это означает, что клиентам, использующим ваш API, не нужно проверять, существует ли это значение или нет: они могут **исходить из того, что поле всегда присутствует**, но в некоторых случаях оно будет иметь значение по умолчанию `None`.
|
Следовательно, клиентам, использующим ваш API, не нужно проверять наличие этого значения: они могут **исходить из того, что поле всегда присутствует**, а в некоторых случаях имеет значение по умолчанию `None`.
|
||||||
|
|
||||||
В OpenAPI это описывается тем, что поле помечается как **обязательное**, поскольку оно всегда присутствует.
|
В OpenAPI это описывается тем, что поле помечается как **обязательное**, поскольку оно всегда присутствует.
|
||||||
|
|
||||||
Из‑за этого JSON Schema для модели может отличаться в зависимости от использования для **входа** или **выхода**:
|
Из‑за этого JSON Schema для модели может отличаться в зависимости от использования для **входа** или **выхода**:
|
||||||
|
|
||||||
* для **входа** `description` **не будет обязательным**
|
* для **входа** `description` не будет обязательным
|
||||||
* для **выхода** оно будет **обязательным** (и при этом может быть `None`, или, в терминах JSON, `null`)
|
* для **выхода** оно будет **обязательным** (и при этом может быть `None`, или, в терминах JSON, `null`)
|
||||||
|
|
||||||
### Выходная модель в документации { #model-for-output-in-docs }
|
### Выходная модель в документации { #model-for-output-in-docs }
|
||||||
@@ -81,9 +81,9 @@
|
|||||||
|
|
||||||
Однако бывают случаи, когда вы хотите иметь **одну и ту же схему для входа и выхода**.
|
Однако бывают случаи, когда вы хотите иметь **одну и ту же схему для входа и выхода**.
|
||||||
|
|
||||||
Главный сценарий — когда у вас уже есть сгенерированный клиентский код/SDK, и вы пока не хотите обновлять весь этот автогенерируемый клиентский код/SDK, вероятно, вы захотите сделать это в какой-то момент, но, возможно, не прямо сейчас.
|
Главный сценарий — когда у вас уже есть сгенерированный клиентский код/SDK, и вы пока не хотите обновлять весь этот автогенерируемый код/SDK (рано или поздно вы это сделаете, но не сейчас).
|
||||||
|
|
||||||
В таком случае вы можете отключить эту функциональность в **FastAPI** с помощью параметра `separate_input_output_schemas=False`.
|
В таком случае вы можете отключить эту функциональность в FastAPI с помощью параметра `separate_input_output_schemas=False`.
|
||||||
|
|
||||||
/// info | Информация
|
/// info | Информация
|
||||||
|
|
||||||
@@ -95,8 +95,10 @@
|
|||||||
|
|
||||||
### Одна и та же схема для входной и выходной моделей в документации { #same-schema-for-input-and-output-models-in-docs }
|
### Одна и та же схема для входной и выходной моделей в документации { #same-schema-for-input-and-output-models-in-docs }
|
||||||
|
|
||||||
И теперь для модели будет одна общая схема и для входа, и для выхода — только `Item`, и в ней `description` будет **не обязательным**:
|
Теперь для этой модели будет одна общая схема и для входа, и для выхода — только `Item`, и в ней `description` будет **не обязательным**:
|
||||||
|
|
||||||
<div class="screenshot">
|
<div class="screenshot">
|
||||||
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Это то же поведение, что и в Pydantic v1. 🤓
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://fastapi.tiangolo.com/ru"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<em>Фреймворк FastAPI: высокая производительность, прост в изучении, позволяет быстро писать код, готов к продакшн</em>
|
<em>Фреймворк FastAPI: высокая производительность, прост в изучении, быстрый в разработке, готов к продакшн</em>
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||||
@@ -40,7 +40,7 @@ FastAPI — это современный, быстрый (высокопрои
|
|||||||
* **Скорость**: Очень высокая производительность, на уровне **NodeJS** и **Go** (благодаря Starlette и Pydantic). [Один из самых быстрых доступных фреймворков Python](#performance).
|
* **Скорость**: Очень высокая производительность, на уровне **NodeJS** и **Go** (благодаря Starlette и Pydantic). [Один из самых быстрых доступных фреймворков Python](#performance).
|
||||||
* **Быстрота разработки**: Увеличьте скорость разработки фич примерно на 200–300%. *
|
* **Быстрота разработки**: Увеличьте скорость разработки фич примерно на 200–300%. *
|
||||||
* **Меньше ошибок**: Сократите примерно на 40% количество ошибок, вызванных человеком (разработчиком). *
|
* **Меньше ошибок**: Сократите примерно на 40% количество ошибок, вызванных человеком (разработчиком). *
|
||||||
* **Интуитивность**: Отличная поддержка редактора кода. <abbr title="также известное как: автодополнение, автозавершение, IntelliSense">Автозавершение</abbr> везде. Меньше времени на отладку.
|
* **Интуитивность**: Отличная поддержка редактора кода. <abbr title="также известное как: автодополнение, IntelliSense">Автозавершение</abbr> везде. Меньше времени на отладку.
|
||||||
* **Простота**: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации.
|
* **Простота**: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации.
|
||||||
* **Краткость**: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок.
|
* **Краткость**: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок.
|
||||||
* **Надежность**: Получите код, готовый к продакшн. С автоматической интерактивной документацией.
|
* **Надежность**: Получите код, готовый к продакшн. С автоматической интерактивной документацией.
|
||||||
@@ -117,12 +117,6 @@ FastAPI — это современный, быстрый (высокопрои
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Мини-документальный фильм о FastAPI { #fastapi-mini-documentary }
|
|
||||||
|
|
||||||
В конце 2025 года вышел <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">мини-документальный фильм о FastAPI</a>, вы можете посмотреть его онлайн:
|
|
||||||
|
|
||||||
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
|
||||||
|
|
||||||
## **Typer**, FastAPI для CLI { #typer-the-fastapi-of-clis }
|
## **Typer**, FastAPI для CLI { #typer-the-fastapi-of-clis }
|
||||||
|
|
||||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
<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>
|
||||||
@@ -263,7 +257,7 @@ INFO: Application startup complete.
|
|||||||
|
|
||||||
* Получает HTTP-запросы по _путям_ `/` и `/items/{item_id}`.
|
* Получает HTTP-запросы по _путям_ `/` и `/items/{item_id}`.
|
||||||
* Оба _пути_ используют `GET` <em>операции</em> (также известные как HTTP _методы_).
|
* Оба _пути_ используют `GET` <em>операции</em> (также известные как HTTP _методы_).
|
||||||
* _Путь_ `/items/{item_id}` имеет _path-параметр_ `item_id`, который должен быть `int`.
|
* _Путь_ `/items/{item_id}` имеет _параметр пути_ `item_id`, который должен быть `int`.
|
||||||
* _Путь_ `/items/{item_id}` имеет необязательный `str` _параметр запроса_ `q`.
|
* _Путь_ `/items/{item_id}` имеет необязательный `str` _параметр запроса_ `q`.
|
||||||
|
|
||||||
### Интерактивная документация API { #interactive-api-docs }
|
### Интерактивная документация API { #interactive-api-docs }
|
||||||
@@ -284,9 +278,9 @@ INFO: Application startup complete.
|
|||||||
|
|
||||||
## Пример обновления { #example-upgrade }
|
## Пример обновления { #example-upgrade }
|
||||||
|
|
||||||
Теперь измените файл `main.py`, чтобы принимать тело запроса из `PUT` HTTP-запроса.
|
Теперь измените файл `main.py`, чтобы принимать тело запроса из `PUT` запроса.
|
||||||
|
|
||||||
Объявите тело запроса, используя стандартные типы Python, спасибо Pydantic.
|
Объявите тело, используя стандартные типы Python, спасибо Pydantic.
|
||||||
|
|
||||||
```Python hl_lines="4 9-12 25-27"
|
```Python hl_lines="4 9-12 25-27"
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@@ -324,7 +318,7 @@ def update_item(item_id: int, item: Item):
|
|||||||
|
|
||||||
Перейдите на <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
Перейдите на <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||||
|
|
||||||
* Интерактивная документация API будет автоматически обновлена, включая новое тело запроса:
|
* Интерактивная документация API будет автоматически обновлена, включая новое тело:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -340,13 +334,13 @@ def update_item(item_id: int, item: Item):
|
|||||||
|
|
||||||
Теперь откройте <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
Теперь откройте <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||||
|
|
||||||
* Альтернативная документация также отразит новый параметр запроса и тело запроса:
|
* Альтернативная документация также отразит новый параметр запроса и тело:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Подведём итоги { #recap }
|
### Подведём итоги { #recap }
|
||||||
|
|
||||||
Итак, вы объявляете **один раз** типы параметров, тело запроса и т.д. как параметры функции.
|
Итак, вы объявляете **один раз** типы параметров, тела запроса и т.д. как параметры функции.
|
||||||
|
|
||||||
Вы делаете это с помощью стандартных современных типов Python.
|
Вы делаете это с помощью стандартных современных типов Python.
|
||||||
|
|
||||||
@@ -396,13 +390,13 @@ item: Item
|
|||||||
|
|
||||||
Возвращаясь к предыдущему примеру кода, **FastAPI** будет:
|
Возвращаясь к предыдущему примеру кода, **FastAPI** будет:
|
||||||
|
|
||||||
* Валидировать наличие `item_id` в пути для `GET` и `PUT` HTTP-запросов.
|
* Валидировать наличие `item_id` в пути для `GET` и `PUT` запросов.
|
||||||
* Валидировать, что `item_id` имеет тип `int` для `GET` и `PUT` HTTP-запросов.
|
* Валидировать, что `item_id` имеет тип `int` для `GET` и `PUT` запросов.
|
||||||
* Если это не так, клиент увидит полезную понятную ошибку.
|
* Если это не так, клиент увидит полезную понятную ошибку.
|
||||||
* Проверять, есть ли необязательный параметр запроса с именем `q` (например, `http://127.0.0.1:8000/items/foo?q=somequery`) для `GET` HTTP-запросов.
|
* Проверять, есть ли необязательный параметр запроса с именем `q` (например, `http://127.0.0.1:8000/items/foo?q=somequery`) для `GET` запросов.
|
||||||
* Поскольку параметр `q` объявлен с `= None`, он необязателен.
|
* Поскольку параметр `q` объявлен с `= None`, он необязателен.
|
||||||
* Без `None` он был бы обязательным (как тело запроса в случае с `PUT`).
|
* Без `None` он был бы обязательным (как тело запроса в случае с `PUT`).
|
||||||
* Для `PUT` HTTP-запросов к `/items/{item_id}` читать тело запроса как JSON:
|
* Для `PUT` запросов к `/items/{item_id}` читать тело запроса как JSON:
|
||||||
* Проверять, что есть обязательный атрибут `name`, который должен быть `str`.
|
* Проверять, что есть обязательный атрибут `name`, который должен быть `str`.
|
||||||
* Проверять, что есть обязательный атрибут `price`, который должен быть `float`.
|
* Проверять, что есть обязательный атрибут `price`, который должен быть `float`.
|
||||||
* Проверять, что есть необязательный атрибут `is_offer`, который должен быть `bool`, если он присутствует.
|
* Проверять, что есть необязательный атрибут `is_offer`, который должен быть `bool`, если он присутствует.
|
||||||
@@ -441,11 +435,11 @@ item: Item
|
|||||||
|
|
||||||
Более полный пример с дополнительными возможностями см. в <a href="https://fastapi.tiangolo.com/ru/tutorial/">Учебник - Руководство пользователя</a>.
|
Более полный пример с дополнительными возможностями см. в <a href="https://fastapi.tiangolo.com/ru/tutorial/">Учебник - Руководство пользователя</a>.
|
||||||
|
|
||||||
**Осторожно, спойлер**: учебник - руководство пользователя включает:
|
**Осторожно, спойлер**: учебник - руководство включает:
|
||||||
|
|
||||||
* Объявление **параметров** из других источников: **HTTP-заголовки**, **cookies**, **поля формы** и **файлы**.
|
* Объявление **параметров** из других источников: **HTTP-заголовки**, **cookies**, **поля формы** и **файлы**.
|
||||||
* Как задать **ограничения валидации** вроде `maximum_length` или `regex`.
|
* Как задать **ограничения валидации** вроде `maximum_length` или `regex`.
|
||||||
* Очень мощную и простую в использовании систему **<abbr title="также известна как: компоненты, ресурсы, провайдеры, сервисы, инъекции">внедрения зависимостей</abbr>**.
|
* Очень мощную и простую в использовании систему **<abbr title="также известная как: компоненты, ресурсы, провайдеры, сервисы, инъекции">внедрения зависимостей</abbr>**.
|
||||||
* Безопасность и аутентификацию, включая поддержку **OAuth2** с **JWT токенами** и **HTTP Basic** аутентификацию.
|
* Безопасность и аутентификацию, включая поддержку **OAuth2** с **JWT токенами** и **HTTP Basic** аутентификацию.
|
||||||
* Более продвинутые (но столь же простые) приёмы объявления **глубоко вложенных JSON-моделей** (спасибо Pydantic).
|
* Более продвинутые (но столь же простые) приёмы объявления **глубоко вложенных JSON-моделей** (спасибо Pydantic).
|
||||||
* Интеграцию **GraphQL** с <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> и другими библиотеками.
|
* Интеграцию **GraphQL** с <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> и другими библиотеками.
|
||||||
@@ -530,11 +524,11 @@ FastAPI зависит от Pydantic и Starlette.
|
|||||||
|
|
||||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> — обязателен, если вы хотите использовать `TestClient`.
|
* <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://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> — обязателен, если вы хотите использовать конфигурацию шаблонов по умолчанию.
|
||||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - обязателен, если вы хотите поддерживать <abbr title="преобразование строки, полученной из HTTP-запроса, в данные Python">«парсинг»</abbr> форм через `request.form()`.
|
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> — обязателен, если вы хотите поддерживать <abbr title="преобразование строки, полученной из HTTP-запроса, в данные Python">«парсинг»</abbr> форм через `request.form()`.
|
||||||
|
|
||||||
Используется FastAPI:
|
Используется FastAPI:
|
||||||
|
|
||||||
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> — сервер, который загружает и «отдаёт» ваше приложение. Включает `uvicorn[standard]`, содержащий некоторые зависимости (например, `uvloop`), нужные для высокой производительности.
|
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> — сервер, который загружает и обслуживает ваше приложение. Включает `uvicorn[standard]`, содержащий некоторые зависимости (например, `uvloop`), нужные для высокой производительности.
|
||||||
* `fastapi-cli[standard]` — чтобы предоставить команду `fastapi`.
|
* `fastapi-cli[standard]` — чтобы предоставить команду `fastapi`.
|
||||||
* Включает `fastapi-cloud-cli`, который позволяет развернуть ваше приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
|
* Включает `fastapi-cloud-cli`, который позволяет развернуть ваше приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Большие приложения — несколько файлов { #bigger-applications-multiple-files }
|
# Большие приложения, в которых много файлов { #bigger-applications-multiple-files }
|
||||||
|
|
||||||
При построении приложения или веб-API нам редко удается поместить всё в один файл.
|
При построении приложения или веб-API нам редко удается поместить всё в один файл.
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Есть несколько файлов `__init__.py`: по одному в каждом каталоге или подкаталоге.
|
Обратите внимание, что в каждом каталоге и подкаталоге имеется файл `__init__.py`
|
||||||
|
|
||||||
Это как раз то, что позволяет импортировать код из одного файла в другой.
|
Это как раз то, что позволяет импортировать код из одного файла в другой.
|
||||||
|
|
||||||
@@ -43,63 +43,61 @@ from app.routers import items
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией "Python-модулей"): `app`.
|
* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией модулей Python).
|
||||||
* Он содержит файл `app/main.py`. Данный файл является частью Python-пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем этого пакета: `app.main`.
|
* Он содержит файл `app/main.py`. Данный файл является частью пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем пакета: `app.main`.
|
||||||
* Он также содержит файл `app/dependencies.py`, который также, как и `app/main.py`, является модулем: `app.dependencies`.
|
* Он также содержит файл `app/dependencies.py`, который также, как и `app/main.py`, является модулем: `app.dependencies`.
|
||||||
* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`. Он является Python-подпакетом: `app.routers`.
|
* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`. Он является суб-пакетом: `app.routers`.
|
||||||
* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является подмодулем: `app.routers.items`.
|
* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является суб-модулем: `app.routers.items`.
|
||||||
* Точно так же `app/routers/users.py` является ещё одним подмодулем: `app.routers.users`.
|
* Точно также `app/routers/users.py` является ещё одним суб-модулем: `app.routers.users`.
|
||||||
* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним Python-подпакетом: `app.internal`.
|
* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним суб-пакетом: `app.internal`.
|
||||||
* А файл `app/internal/admin.py` является ещё одним подмодулем: `app.internal.admin`.
|
* А файл `app/internal/admin.py` является ещё одним суб-модулем: `app.internal.admin`.
|
||||||
|
|
||||||
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
||||||
|
|
||||||
Та же самая файловая структура приложения, но с комментариями:
|
Та же самая файловая структура приложения, но с комментариями:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
.
|
.
|
||||||
├── app # "app" пакет
|
├── app # "app" пакет
|
||||||
│ ├── __init__.py # этот файл превращает "app" в "Python-пакет"
|
│ ├── __init__.py # этот файл превращает "app" в "Python-пакет"
|
||||||
│ ├── main.py # модуль "main", напр.: import app.main
|
│ ├── main.py # модуль "main", напр.: import app.main
|
||||||
│ ├── dependencies.py # модуль "dependencies", напр.: import app.dependencies
|
│ ├── dependencies.py # модуль "dependencies", напр.: import app.dependencies
|
||||||
│ └── routers # подпакет "routers"
|
│ └── routers # суб-пакет "routers"
|
||||||
│ │ ├── __init__.py # превращает "routers" в подпакет
|
│ │ ├── __init__.py # превращает "routers" в суб-пакет
|
||||||
│ │ ├── items.py # подмодуль "items", напр.: import app.routers.items
|
│ │ ├── items.py # суб-модуль "items", напр.: import app.routers.items
|
||||||
│ │ └── users.py # подмодуль "users", напр.: import app.routers.users
|
│ │ └── users.py # суб-модуль "users", напр.: import app.routers.users
|
||||||
│ └── internal # подпакет "internal"
|
│ └── internal # суб-пакет "internal"
|
||||||
│ ├── __init__.py # превращает "internal" в подпакет
|
│ ├── __init__.py # превращает "internal" в суб-пакет
|
||||||
│ └── admin.py # подмодуль "admin", напр.: import app.internal.admin
|
│ └── admin.py # суб-модуль "admin", напр.: import app.internal.admin
|
||||||
```
|
```
|
||||||
|
|
||||||
## `APIRouter` { #apirouter }
|
## `APIRouter` { #apirouter }
|
||||||
|
|
||||||
Давайте предположим, что для работы с пользователями используется отдельный файл (подмодуль) `/app/routers/users.py`.
|
Давайте предположим, что для работы с пользователями используется отдельный файл (суб-модуль) `/app/routers/users.py`.
|
||||||
|
|
||||||
Вы хотите отделить *операции пути*, связанные с пользователями, от остального кода, чтобы сохранить порядок.
|
Для лучшей организации приложения, вы хотите отделить операции пути, связанные с пользователями, от остального кода.
|
||||||
|
|
||||||
Но это всё равно часть того же приложения/веб-API на **FastAPI** (часть того же «Python-пакета»).
|
Но так, чтобы эти операции по-прежнему оставались частью **FastAPI** приложения/веб-API (частью одного пакета)
|
||||||
|
|
||||||
С помощью `APIRouter` вы можете создать *операции пути* для этого модуля.
|
С помощью `APIRouter` вы можете создать *операции пути* (*эндпоинты*) для данного модуля.
|
||||||
|
|
||||||
### Импорт `APIRouter` { #import-apirouter }
|
### Импорт `APIRouter` { #import-apirouter }
|
||||||
|
|
||||||
Точно так же, как и в случае с классом `FastAPI`, вам нужно импортировать и создать его «экземпляр»:
|
Точно также, как и в случае с классом `FastAPI`, вам нужно импортировать и создать объект класса `APIRouter`.
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
||||||
|
|
||||||
### *Операции пути* с `APIRouter` { #path-operations-with-apirouter }
|
### Создание *эндпоинтов* с помощью `APIRouter` { #path-operations-with-apirouter }
|
||||||
|
|
||||||
И затем вы используете его, чтобы объявить ваши *операции пути*.
|
В дальнейшем используйте `APIRouter` для объявления *эндпоинтов*, точно также, как вы используете класс `FastAPI`:
|
||||||
|
|
||||||
Используйте его так же, как вы использовали бы класс `FastAPI`:
|
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
||||||
|
|
||||||
Вы можете думать об `APIRouter` как об «мини-классе `FastAPI`».
|
Вы можете думать об `APIRouter` как об "уменьшенной версии" класса FastAPI`.
|
||||||
|
|
||||||
Поддерживаются все те же опции.
|
`APIRouter` поддерживает все те же самые опции.
|
||||||
|
|
||||||
Все те же `parameters`, `responses`, `dependencies`, `tags` и т.д.
|
`APIRouter` поддерживает все те же самые параметры, такие как `parameters`, `responses`, `dependencies`, `tags`, и т. д.
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
@@ -107,21 +105,21 @@ from app.routers import items
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и ещё один `APIRouter`.
|
Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и создадим ещё один модуль с `APIRouter`.
|
||||||
|
|
||||||
## Зависимости { #dependencies }
|
## Зависимости { #dependencies }
|
||||||
|
|
||||||
Мы видим, что нам понадобятся некоторые зависимости, которые будут использоваться в нескольких местах приложения.
|
Нам понадобятся некоторые зависимости, которые мы будем использовать в разных местах нашего приложения.
|
||||||
|
|
||||||
Поэтому мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`).
|
Мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`).
|
||||||
|
|
||||||
Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомный HTTP-заголовок `X-Token`:
|
Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомизированный `X-Token` из заголовка:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Для простоты мы воспользовались выдуманным заголовком.
|
Для простоты мы воспользовались неким воображаемым заголовоком.
|
||||||
|
|
||||||
В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md){.internal-link target=_blank}.
|
В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md){.internal-link target=_blank}.
|
||||||
|
|
||||||
@@ -129,29 +127,30 @@ from app.routers import items
|
|||||||
|
|
||||||
## Ещё один модуль с `APIRouter` { #another-module-with-apirouter }
|
## Ещё один модуль с `APIRouter` { #another-module-with-apirouter }
|
||||||
|
|
||||||
Давайте также предположим, что у вас есть эндпоинты, отвечающие за обработку «items» в вашем приложении, и они находятся в модуле `app/routers/items.py`.
|
Давайте также предположим, что у вас есть *эндпоинты*, отвечающие за обработку "items", и они находятся в модуле `app/routers/items.py`.
|
||||||
|
|
||||||
У вас определены *операции пути* для:
|
У вас определены следующие *операции пути* (*эндпоинты*):
|
||||||
|
|
||||||
* `/items/`
|
* `/items/`
|
||||||
* `/items/{item_id}`
|
* `/items/{item_id}`
|
||||||
|
|
||||||
Тут всё та же структура, как и в случае с `app/routers/users.py`.
|
Тут всё точно также, как и в ситуации с `app/routers/users.py`.
|
||||||
|
|
||||||
Но мы хотим поступить умнее и слегка упростить код.
|
Но теперь мы хотим поступить немного умнее и слегка упростить код.
|
||||||
|
|
||||||
Мы знаем, что все *операции пути* этого модуля имеют одинаковые:
|
Мы знаем, что все *эндпоинты* данного модуля имеют некоторые общие свойства:
|
||||||
|
|
||||||
* `prefix` пути: `/items`.
|
* Префикс пути: `/items`.
|
||||||
* `tags`: (один единственный тег: `items`).
|
* Теги: (один единственный тег: `items`).
|
||||||
* Дополнительные `responses`.
|
* Дополнительные ответы (responses)
|
||||||
* `dependencies`: всем им нужна та зависимость `X-Token`, которую мы создали.
|
* Зависимости: использование созданной нами зависимости `X-token`
|
||||||
|
|
||||||
Таким образом, вместо того чтобы добавлять всё это в каждую *операцию пути*, мы можем добавить это в `APIRouter`.
|
Таким образом, вместо того чтобы добавлять все эти свойства в функцию каждого отдельного *эндпоинта*,
|
||||||
|
мы добавим их в `APIRouter`.
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
||||||
|
|
||||||
Так как путь каждой *операции пути* должен начинаться с `/`, как здесь:
|
Так как каждый *эндпоинт* начинается с символа `/`:
|
||||||
|
|
||||||
```Python hl_lines="1"
|
```Python hl_lines="1"
|
||||||
@router.get("/{item_id}")
|
@router.get("/{item_id}")
|
||||||
@@ -163,74 +162,73 @@ async def read_item(item_id: str):
|
|||||||
|
|
||||||
В нашем случае префиксом является `/items`.
|
В нашем случае префиксом является `/items`.
|
||||||
|
|
||||||
Мы также можем добавить список `tags` и дополнительные `responses`, которые будут применяться ко всем *операциям пути*, включённым в этот маршрутизатор.
|
Мы также можем добавить в наш маршрутизатор (router) список `тегов` (`tags`) и дополнительных `ответов` (`responses`), которые являются общими для каждого *эндпоинта*.
|
||||||
|
|
||||||
И ещё мы можем добавить список `dependencies`, которые будут добавлены ко всем *операциям пути* в маршрутизаторе и будут выполняться/разрешаться для каждого HTTP-запроса к ним.
|
И ещё мы можем добавить в наш маршрутизатор список `зависимостей`, которые должны вызываться при каждом обращении к *эндпоинтам*.
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Обратите внимание, что так же, как и в случае с [зависимостями в декораторах *операций пути*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, никакое значение не будет передано в вашу *функцию-обработчик пути*.
|
Обратите внимание, что также, как и в случае с зависимостями в декораторах *эндпоинтов* ([зависимости в декораторах операций пути](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), никакого значения в *функцию эндпоинта* передано не будет.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
В результате пути для items теперь такие:
|
В результате мы получим следующие эндпоинты:
|
||||||
|
|
||||||
* `/items/`
|
* `/items/`
|
||||||
* `/items/{item_id}`
|
* `/items/{item_id}`
|
||||||
|
|
||||||
...как мы и планировали.
|
...как мы и планировали.
|
||||||
|
|
||||||
* Они будут помечены списком тегов, содержащим одну строку `"items"`.
|
* Они будут помечены тегами из заданного списка, в нашем случае это `"items"`.
|
||||||
* Эти «теги» особенно полезны для систем автоматической интерактивной документации (с использованием OpenAPI).
|
* Эти теги особенно полезны для системы автоматической интерактивной документации (с использованием OpenAPI).
|
||||||
* Все они будут включать предопределённые `responses`.
|
* Каждый из них будет включать предопределенные ответы `responses`.
|
||||||
* Все эти *операции пути* будут иметь список `dependencies`, вычисляемых/выполняемых перед ними.
|
* Каждый *эндпоинт* будет иметь список зависимостей (`dependencies`), исполняемых перед вызовом *эндпоинта*.
|
||||||
* Если вы также объявите зависимости в конкретной *операции пути*, **они тоже будут выполнены**.
|
* Если вы определили зависимости в самой операции пути, **то она также будет выполнена**.
|
||||||
* Сначала выполняются зависимости маршрутизатора, затем [`dependencies` в декораторе](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, и затем обычные параметрические зависимости.
|
* Сначала выполняются зависимости маршрутизатора, затем вызываются [зависимости в декораторе](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, и, наконец, обычные параметрические зависимости.
|
||||||
* Вы также можете добавить [`Security`-зависимости с `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
|
* Вы также можете добавить [зависимости `Security` с `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *операций пути*. Даже если зависимости не добавляются по отдельности к каждой из них.
|
Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *эндпоинтов*, не указывая зависимости для каждой отдельной функции *эндпоинта*.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
/// check | Заметка
|
/// check | Заметка
|
||||||
|
|
||||||
Параметры `prefix`, `tags`, `responses` и `dependencies` — это (как и во многих других случаях) просто возможность **FastAPI**, помогающая избежать дублирования кода.
|
Параметры `prefix`, `tags`, `responses` и `dependencies` относятся к функционалу **FastAPI**, помогающему избежать дублирования кода.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Импорт зависимостей { #import-the-dependencies }
|
### Импорт зависимостей { #import-the-dependencies }
|
||||||
|
|
||||||
Этот код находится в модуле `app.routers.items`, в файле `app/routers/items.py`.
|
Наш код находится в модуле `app.routers.items` (файл `app/routers/items.py`).
|
||||||
|
|
||||||
И нам нужно получить функцию зависимости из модуля `app.dependencies`, файла `app/dependencies.py`.
|
И нам нужно вызвать функцию зависимости из модуля `app.dependencies` (файл `app/dependencies.py`).
|
||||||
|
|
||||||
Поэтому мы используем относительный импорт с `..` для зависимостей:
|
Мы используем операцию относительного импорта `..` для импорта зависимости:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
|
||||||
|
|
||||||
#### Как работает относительный импорт { #how-relative-imports-work }
|
#### Как работает относительный импорт? { #how-relative-imports-work }
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Если вы прекрасно знаете, как работает импорт, переходите к следующему разделу ниже.
|
Если вы прекрасно знаете, как работает импорт в Python, то переходите к следующему разделу.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Одна точка `.`, как здесь:
|
Одна точка `.`, как в данном примере:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from .dependencies import get_token_header
|
from .dependencies import get_token_header
|
||||||
```
|
```
|
||||||
|
|
||||||
означает:
|
означает:
|
||||||
|
|
||||||
* Начать в том же пакете, в котором находится этот модуль (файл `app/routers/items.py`) (каталог `app/routers/`)...
|
* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` расположен в каталоге `app/routers/`)...
|
||||||
* найти модуль `dependencies` (воображаемый файл `app/routers/dependencies.py`)...
|
* ... найдите модуль `dependencies` (файл `app/routers/dependencies.py`)...
|
||||||
* и импортировать из него функцию `get_token_header`.
|
* ... и импортируйте из него функцию `get_token_header`.
|
||||||
|
|
||||||
Но такого файла не существует, наши зависимости находятся в файле `app/dependencies.py`.
|
К сожалению, такого файла не существует, и наши зависимости находятся в файле `app/dependencies.py`.
|
||||||
|
|
||||||
Вспомните, как выглядит файловая структура нашего приложения:
|
Вспомните, как выглядит файловая структура нашего приложения:
|
||||||
|
|
||||||
@@ -238,7 +236,7 @@ from .dependencies import get_token_header
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Две точки `..`, как здесь:
|
Две точки `..`, как в данном примере:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from ..dependencies import get_token_header
|
from ..dependencies import get_token_header
|
||||||
@@ -246,12 +244,12 @@ from ..dependencies import get_token_header
|
|||||||
|
|
||||||
означают:
|
означают:
|
||||||
|
|
||||||
* Начать в том же пакете, в котором находится этот модуль (файл `app/routers/items.py`) (каталог `app/routers/`)...
|
* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)...
|
||||||
* перейти в родительский пакет (каталог `app/`)...
|
* ... перейдите в родительский пакет (каталог `app/`)...
|
||||||
* и там найти модуль `dependencies` (файл `app/dependencies.py`)...
|
* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
|
||||||
* и импортировать из него функцию `get_token_header`.
|
* ... и импортируйте из него функцию `get_token_header`.
|
||||||
|
|
||||||
Это работает корректно! 🎉
|
Это работает верно! 🎉
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -263,29 +261,29 @@ from ...dependencies import get_token_header
|
|||||||
|
|
||||||
то это бы означало:
|
то это бы означало:
|
||||||
|
|
||||||
* Начать в том же пакете, в котором находится этот модуль (файл `app/routers/items.py`) расположен в (каталоге `app/routers/`)...
|
* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)...
|
||||||
* перейти в родительский пакет (каталог `app/`)...
|
* ... перейдите в родительский пакет (каталог `app/`)...
|
||||||
* затем перейти в родительский пакет этого пакета (родительского пакета нет, `app` — верхний уровень 😱)...
|
* ... затем перейдите в родительский пакет текущего пакета (такого пакета не существует, `app` находится на самом верхнем уровне 😱)...
|
||||||
* и там найти модуль `dependencies` (файл `app/dependencies.py`)...
|
* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
|
||||||
* и импортировать из него функцию `get_token_header`.
|
* ... и импортируйте из него функцию `get_token_header`.
|
||||||
|
|
||||||
Это ссылалось бы на какой-то пакет выше `app/`, со своим файлом `__init__.py` и т.п. Но у нас такого нет. Поэтому это вызвало бы ошибку в нашем примере. 🚨
|
Это будет относиться к некоторому пакету, находящемуся на один уровень выше чем `app/` и содержащему свой собственный файл `__init__.py`. Но ничего такого у нас нет. Поэтому это приведет к ошибке в нашем примере. 🚨
|
||||||
|
|
||||||
Но теперь вы знаете, как это работает, так что можете использовать относительные импорты в своих приложениях, независимо от того, насколько они сложные. 🤓
|
Теперь вы знаете, как работает импорт в Python, и сможете использовать относительное импортирование в своих собственных приложениях любого уровня сложности. 🤓
|
||||||
|
|
||||||
### Добавление пользовательских `tags`, `responses` и `dependencies` { #add-some-custom-tags-responses-and-dependencies }
|
### Добавление пользовательских тегов (`tags`), ответов (`responses`) и зависимостей (`dependencies`) { #add-some-custom-tags-responses-and-dependencies }
|
||||||
|
|
||||||
Мы не добавляем префикс `/items` и `tags=["items"]` к каждой *операции пути*, потому что мы добавили их в `APIRouter`.
|
Мы не будем добавлять префикс `/items` и список тегов `tags=["items"]` для каждого *эндпоинта*, т.к. мы уже их добавили с помощью `APIRouter`.
|
||||||
|
|
||||||
Но мы всё равно можем добавить _ещё_ `tags`, которые будут применяться к конкретной *операции пути*, а также дополнительные `responses`, специфичные для этой *операции пути*:
|
Но помимо этого мы можем добавить новые теги для каждого отдельного *эндпоинта*, а также некоторые дополнительные ответы (`responses`), характерные для данного *эндпоинта*:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Эта последняя операция пути будет иметь комбинацию тегов: `["items", "custom"]`.
|
Последний *эндпоинт* будет иметь следующую комбинацию тегов: `["items", "custom"]`.
|
||||||
|
|
||||||
И в документации у неё будут оба ответа: один для `404` и один для `403`.
|
А также в его документации будут содержаться оба ответа: один для `404` и другой для `403`.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -295,29 +293,29 @@ from ...dependencies import get_token_header
|
|||||||
|
|
||||||
Именно сюда вы импортируете и именно здесь вы используете класс `FastAPI`.
|
Именно сюда вы импортируете и именно здесь вы используете класс `FastAPI`.
|
||||||
|
|
||||||
Это основной файл вашего приложения, который связывает всё воедино.
|
Это основной файл вашего приложения, который объединяет всё в одно целое.
|
||||||
|
|
||||||
И так как большая часть вашей логики теперь будет находиться в отдельных специфичных модулях, основной файл будет довольно простым.
|
И теперь, когда большая часть логики приложения разделена на отдельные модули, основной файл `app/main.py` будет достаточно простым.
|
||||||
|
|
||||||
### Импорт `FastAPI` { #import-fastapi }
|
### Импорт `FastAPI` { #import-fastapi }
|
||||||
|
|
||||||
Вы импортируете и создаёте класс `FastAPI` как обычно.
|
Вы импортируете и создаете класс `FastAPI` как обычно.
|
||||||
|
|
||||||
И мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого `APIRouter`:
|
Мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого отдельного маршрутизатора:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
|
||||||
|
|
||||||
### Импорт `APIRouter` { #import-the-apirouter }
|
### Импорт `APIRouter` { #import-the-apirouter }
|
||||||
|
|
||||||
Теперь мы импортируем другие подмодули, содержащие `APIRouter`:
|
Теперь мы импортируем другие суб-модули, содержащие `APIRouter`:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
|
||||||
|
|
||||||
Так как файлы `app/routers/users.py` и `app/routers/items.py` являются подмодулями, входящими в один и тот же Python-пакет `app`, мы можем использовать одну точку `.` для импорта через «относительные импорты».
|
Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`.
|
||||||
|
|
||||||
### Как работает импорт { #how-the-importing-works }
|
### Как работает импорт? { #how-the-importing-works }
|
||||||
|
|
||||||
Этот фрагмент:
|
Данная строка кода:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from .routers import items, users
|
from .routers import items, users
|
||||||
@@ -325,15 +323,15 @@ from .routers import items, users
|
|||||||
|
|
||||||
означает:
|
означает:
|
||||||
|
|
||||||
* Начать в том же пакете, в котором находится этот модуль (файл `app/main.py`) расположен в (каталоге `app/`)...
|
* Начните с пакета, в котором содержится данный модуль (файл `app/main.py` содержится в каталоге `app/`)...
|
||||||
* найти подпакет `routers` (каталог `app/routers/`)...
|
* ... найдите суб-пакет `routers` (каталог `app/routers/`)...
|
||||||
* и импортировать из него подмодули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)...
|
* ... и из него импортируйте суб-модули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)...
|
||||||
|
|
||||||
В модуле `items` будет переменная `router` (`items.router`). Это та же самая, которую мы создали в файле `app/routers/items.py`, это объект `APIRouter`.
|
В модуле `items` содержится переменная `router` (`items.router`), та самая, которую мы создали в файле `app/routers/items.py`, она является объектом класса `APIRouter`.
|
||||||
|
|
||||||
И затем мы делаем то же самое для модуля `users`.
|
И затем мы сделаем то же самое для модуля `users`.
|
||||||
|
|
||||||
Мы также могли бы импортировать их так:
|
Мы также могли бы импортировать и другим методом:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from app.routers import items, users
|
from app.routers import items, users
|
||||||
@@ -341,44 +339,44 @@ from app.routers import items, users
|
|||||||
|
|
||||||
/// info | Примечание
|
/// info | Примечание
|
||||||
|
|
||||||
Первая версия — это «относительный импорт»:
|
Первая версия является примером относительного импорта:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from .routers import items, users
|
from .routers import items, users
|
||||||
```
|
```
|
||||||
|
|
||||||
Вторая версия — это «абсолютный импорт»:
|
Вторая версия является примером абсолютного импорта:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from app.routers import items, users
|
from app.routers import items, users
|
||||||
```
|
```
|
||||||
|
|
||||||
Чтобы узнать больше о Python-пакетах и модулях, прочитайте <a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">официальную документацию Python о модулях</a>.
|
Узнать больше о пакетах и модулях в Python вы можете из <a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">официальной документации Python о модулях</a>
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Избегайте конфликтов имён { #avoid-name-collisions }
|
### Избегайте конфликтов имен { #avoid-name-collisions }
|
||||||
|
|
||||||
Мы импортируем подмодуль `items` напрямую, вместо того чтобы импортировать только его переменную `router`.
|
Вместо того чтобы импортировать только переменную `router`, мы импортируем непосредственно суб-модуль `items`.
|
||||||
|
|
||||||
Это потому, что у нас также есть другая переменная с именем `router` в подмодуле `users`.
|
Мы делаем это потому, что у нас есть ещё одна переменная `router` в суб-модуле `users`.
|
||||||
|
|
||||||
Если бы мы импортировали их одну за другой, как здесь:
|
Если бы мы импортировали их одну за другой, как показано в примере:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from .routers.items import router
|
from .routers.items import router
|
||||||
from .routers.users import router
|
from .routers.users import router
|
||||||
```
|
```
|
||||||
|
|
||||||
то `router` из `users` перезаписал бы `router` из `items`, и мы не смогли бы использовать их одновременно.
|
то переменная `router` из `users` переписал бы переменную `router` из `items`, и у нас не было бы возможности использовать их одновременно.
|
||||||
|
|
||||||
Поэтому, чтобы иметь возможность использовать обе в одном файле, мы импортируем подмодули напрямую:
|
Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
|
||||||
|
|
||||||
### Подключение `APIRouter` для `users` и `items` { #include-the-apirouters-for-users-and-items }
|
### Подключение маршрутизаторов (`APIRouter`) для `users` и для `items` { #include-the-apirouters-for-users-and-items }
|
||||||
|
|
||||||
Теперь давайте подключим `router` из подмодулей `users` и `items`:
|
Давайте подключим маршрутизаторы (`router`) из суб-модулей `users` и `items`:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
|
||||||
|
|
||||||
@@ -390,78 +388,79 @@ from .routers.users import router
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
С помощью `app.include_router()` мы можем добавить каждый `APIRouter` в основное приложение `FastAPI`.
|
С помощью `app.include_router()` мы можем добавить каждый из маршрутизаторов (`APIRouter`) в основное приложение `FastAPI`.
|
||||||
|
|
||||||
Он включит все маршруты этого маршрутизатора как часть приложения.
|
Он подключит все маршруты заданного маршрутизатора к нашему приложению.
|
||||||
|
|
||||||
/// note | Технические детали
|
/// note | Технические детали
|
||||||
|
|
||||||
Фактически, внутри он создаст *операцию пути* для каждой *операции пути*, объявленной в `APIRouter`.
|
Фактически, внутри он создаст все *операции пути* для каждой операции пути объявленной в `APIRouter`.
|
||||||
|
|
||||||
Так что под капотом всё будет работать так, как будто всё было одним приложением.
|
И под капотом всё будет работать так, как будто бы мы имеем дело с одним файлом приложения.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
/// check | Заметка
|
/// check | Заметка
|
||||||
|
|
||||||
При подключении маршрутизаторов не нужно беспокоиться о производительности.
|
При подключении маршрутизаторов не стоит беспокоиться о производительности.
|
||||||
|
|
||||||
Это займёт микросекунды и произойдёт только при старте.
|
Операция подключения займёт микросекунды и понадобится только при запуске приложения.
|
||||||
|
|
||||||
Так что это не повлияет на производительность. ⚡
|
Таким образом, это не повлияет на производительность. ⚡
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Подключение `APIRouter` с пользовательскими `prefix`, `tags`, `responses` и `dependencies` { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies }
|
### Подключение `APIRouter` с пользовательскими префиксом (`prefix`), тегами (`tags`), ответами (`responses`), и зависимостями (`dependencies`) { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies }
|
||||||
|
|
||||||
Теперь давайте представим, что ваша организация передала вам файл `app/internal/admin.py`.
|
Теперь давайте представим, что ваша организация передала вам файл `app/internal/admin.py`.
|
||||||
|
|
||||||
Он содержит `APIRouter` с некоторыми административными *операциями пути*, которые ваша организация использует в нескольких проектах.
|
Он содержит `APIRouter` с некоторыми *эндпоитами* администрирования, которые ваша организация использует для нескольких проектов.
|
||||||
|
|
||||||
Для этого примера всё будет очень просто. Но допустим, что поскольку он используется совместно с другими проектами в организации, мы не можем модифицировать его и добавить `prefix`, `dependencies`, `tags` и т.д. непосредственно в `APIRouter`:
|
В данном примере это сделать очень просто. Но давайте предположим, что поскольку файл используется для нескольких проектов,
|
||||||
|
то мы не можем модифицировать его, добавляя префиксы (`prefix`), зависимости (`dependencies`), теги (`tags`), и т.д. непосредственно в `APIRouter`:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
|
||||||
|
|
||||||
Но мы всё равно хотим задать пользовательский `prefix` при подключении `APIRouter`, чтобы все его *операции пути* начинались с `/admin`, хотим защитить его с помощью `dependencies`, которые у нас уже есть для этого проекта, и хотим включить `tags` и `responses`.
|
Но, несмотря на это, мы хотим использовать кастомный префикс (`prefix`) для подключенного маршрутизатора (`APIRouter`), в результате чего, каждая *операция пути* будет начинаться с `/admin`. Также мы хотим защитить наш маршрутизатор с помощью зависимостей, созданных для нашего проекта. И ещё мы хотим включить теги (`tags`) и ответы (`responses`).
|
||||||
|
|
||||||
Мы можем объявить всё это, не изменяя исходный `APIRouter`, передав эти параметры в `app.include_router()`:
|
Мы можем применить все вышеперечисленные настройки, не изменяя начальный `APIRouter`. Нам всего лишь нужно передать нужные параметры в `app.include_router()`.
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
|
||||||
|
|
||||||
Таким образом исходный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
|
Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
|
||||||
|
|
||||||
В результате в нашем приложении каждая из *операций пути* из модуля `admin` будет иметь:
|
В результате, в нашем приложении каждый *эндпоинт* модуля `admin` будет иметь:
|
||||||
|
|
||||||
* Префикс `/admin`.
|
* Префикс `/admin`.
|
||||||
* Тег `admin`.
|
* Тег `admin`.
|
||||||
* Зависимость `get_token_header`.
|
* Зависимость `get_token_header`.
|
||||||
* Ответ `418`. 🍵
|
* Ответ `418`. 🍵
|
||||||
|
|
||||||
Но это повлияет только на этот `APIRouter` в нашем приложении, а не на любой другой код, который его использует.
|
Это будет иметь место исключительно для `APIRouter` в нашем приложении, и не затронет любой другой код, использующий его.
|
||||||
|
|
||||||
Так что, например, другие проекты могут использовать тот же `APIRouter` с другим методом аутентификации.
|
Например, другие проекты, могут использовать тот же самый `APIRouter` с другими методами аутентификации.
|
||||||
|
|
||||||
### Подключение *операции пути* { #include-a-path-operation }
|
### Подключение отдельного *эндпоинта* { #include-a-path-operation }
|
||||||
|
|
||||||
Мы также можем добавлять *операции пути* напрямую в приложение `FastAPI`.
|
Мы также можем добавить *эндпоинт* непосредственно в основное приложение `FastAPI`.
|
||||||
|
|
||||||
Здесь мы делаем это... просто чтобы показать, что можем 🤷:
|
Здесь мы это делаем ... просто, чтобы показать, что это возможно 🤷:
|
||||||
|
|
||||||
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
|
||||||
|
|
||||||
и это будет работать корректно вместе со всеми другими *операциями пути*, добавленными через `app.include_router()`.
|
и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`.
|
||||||
|
|
||||||
/// info | Очень технические детали
|
/// info | Сложные технические детали
|
||||||
|
|
||||||
**Примечание**: это очень техническая деталь, которую, вероятно, можно **просто пропустить**.
|
**Примечание**: это сложная техническая деталь, которую, скорее всего, **вы можете пропустить**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`APIRouter` не «монтируются», они не изолированы от остального приложения.
|
Маршрутизаторы (`APIRouter`) не "монтируются" по-отдельности и не изолируются от остального приложения.
|
||||||
|
|
||||||
Это потому, что мы хотим включить их *операции пути* в OpenAPI-схему и пользовательские интерфейсы.
|
Это происходит потому, что нужно включить их *эндпоинты* в OpenAPI схему и в интерфейс пользователя.
|
||||||
|
|
||||||
Так как мы не можем просто изолировать их и «смонтировать» независимо от остального, *операции пути* «клонируются» (пересоздаются), а не включаются напрямую.
|
В силу того, что мы не можем их изолировать и "примонтировать" независимо от остальных, *эндпоинты* клонируются (пересоздаются) и не подключаются напрямую.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -481,24 +480,24 @@ $ fastapi dev app/main.py
|
|||||||
|
|
||||||
Откройте документацию по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
Откройте документацию по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||||
|
|
||||||
Вы увидите автоматическую документацию API, включая пути из всех подмодулей, с использованием корректных путей (и префиксов) и корректных тегов:
|
Вы увидите автоматическую API документацию. Она включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги:
|
||||||
|
|
||||||
<img src="/img/tutorial/bigger-applications/image01.png">
|
<img src="/img/tutorial/bigger-applications/image01.png">
|
||||||
|
|
||||||
## Подключение одного и того же маршрутизатора несколько раз с разными `prefix` { #include-the-same-router-multiple-times-with-different-prefix }
|
## Подключение существующего маршрута через новый префикс (`prefix`) { #include-the-same-router-multiple-times-with-different-prefix }
|
||||||
|
|
||||||
Вы можете использовать `.include_router()` несколько раз с *одним и тем же* маршрутизатором, используя разные префиксы.
|
Вы можете использовать `.include_router()` несколько раз с одним и тем же маршрутом, применив различные префиксы.
|
||||||
|
|
||||||
Это может быть полезно, например, чтобы предоставить доступ к одному и тому же API с разными префиксами, например `/api/v1` и `/api/latest`.
|
Это может быть полезным, если нужно предоставить доступ к одному и тому же API через различные префиксы, например, `/api/v1` и `/api/latest`.
|
||||||
|
|
||||||
Это продвинутое использование, которое вам может и не понадобиться, но оно есть на случай, если понадобится.
|
Это продвинутый способ, который вам может и не пригодится. Мы приводим его на случай, если вдруг вам это понадобится.
|
||||||
|
|
||||||
## Подключение `APIRouter` в другой `APIRouter` { #include-an-apirouter-in-another }
|
## Включение одного маршрутизатора (`APIRouter`) в другой { #include-an-apirouter-in-another }
|
||||||
|
|
||||||
Точно так же, как вы можете подключить `APIRouter` к приложению `FastAPI`, вы можете подключить `APIRouter` к другому `APIRouter`, используя:
|
Точно так же, как вы включаете `APIRouter` в приложение `FastAPI`, вы можете включить `APIRouter` в другой `APIRouter`:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
router.include_router(other_router)
|
router.include_router(other_router)
|
||||||
```
|
```
|
||||||
|
|
||||||
Убедитесь, что вы сделали это до подключения `router` к приложению `FastAPI`, чтобы *операции пути* из `other_router` также были подключены.
|
Удостоверьтесь, что вы сделали это до того, как подключить маршрутизатор (`router`) к вашему `FastAPI` приложению, и *эндпоинты* маршрутизатора `other_router` были также подключены.
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
## Обновление с заменой при помощи `PUT` { #update-replacing-with-put }
|
## Обновление с заменой при помощи `PUT` { #update-replacing-with-put }
|
||||||
|
|
||||||
Чтобы обновить элемент, вы можете использовать операцию <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
|
Для полного обновления элемента можно воспользоваться операцией <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
|
||||||
|
|
||||||
Вы можете использовать `jsonable_encoder`, чтобы преобразовать входные данные в данные, которые можно сохранить как JSON (например, в NoSQL-базе данных). Например, преобразование `datetime` в `str`.
|
Вы можете использовать `jsonable_encoder`, чтобы преобразовать входные данные в данные, которые можно сохранить как JSON (например, в NoSQL-базе данных). Например, преобразование `datetime` в `str`.
|
||||||
|
|
||||||
{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
|
{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
|
||||||
|
|
||||||
`PUT` используется для получения данных, которые должны заменить существующие данные.
|
`PUT` используется для получения данных, которые должны полностью заменить существующие данные.
|
||||||
|
|
||||||
### Предупреждение о замене { #warning-about-replacing }
|
### Предупреждение о замене { #warning-about-replacing }
|
||||||
|
|
||||||
@@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
поскольку оно не включает уже сохраненный атрибут `"tax": 20.2`, входная модель примет значение по умолчанию `"tax": 10.5`.
|
поскольку оно не включает уже сохраненный атрибут `"tax": 20.2`, входная модель примет значение по умолчанию `"tax": 10.5`.
|
||||||
|
|
||||||
И данные будут сохранены с этим «новым» `tax`, равным `10.5`.
|
И данные будут сохранены с этим "новым" `tax`, равным `10,5`.
|
||||||
|
|
||||||
## Частичное обновление с помощью `PATCH` { #partial-updates-with-patch }
|
## Частичное обновление с помощью `PATCH` { #partial-updates-with-patch }
|
||||||
|
|
||||||
Также можно использовать операцию <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> для *частичного* обновления данных.
|
Также можно использовать <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> операцию для *частичного* обновления данных.
|
||||||
|
|
||||||
Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми.
|
Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми.
|
||||||
|
|
||||||
@@ -46,13 +46,19 @@
|
|||||||
|
|
||||||
### Использование параметра `exclude_unset` в Pydantic { #using-pydantics-exclude-unset-parameter }
|
### Использование параметра `exclude_unset` в Pydantic { #using-pydantics-exclude-unset-parameter }
|
||||||
|
|
||||||
Если вы хотите получать частичные обновления, очень полезно использовать параметр `exclude_unset` в `.model_dump()` модели Pydantic.
|
Если необходимо выполнить частичное обновление, то очень полезно использовать параметр `exclude_unset` в методе `.model_dump()` модели Pydantic.
|
||||||
|
|
||||||
Например, `item.model_dump(exclude_unset=True)`.
|
Например, `item.model_dump(exclude_unset=True)`.
|
||||||
|
|
||||||
В результате будет сгенерирован `dict`, содержащий только те данные, которые были заданы при создании модели `item`, без учета значений по умолчанию.
|
/// info | Информация
|
||||||
|
|
||||||
Затем вы можете использовать это для создания `dict` только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию:
|
В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он помечен как устаревший (но все еще поддерживается) и переименован в `.model_dump()`.
|
||||||
|
|
||||||
|
Примеры здесь используют `.dict()` для совместимости с Pydantic v1, но если вы можете использовать Pydantic v2, лучше используйте `.model_dump()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
В результате будет сгенерирован словарь, содержащий только те данные, которые были заданы при создании модели `item`, без учета значений по умолчанию. Затем вы можете использовать это для создания словаря только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию:
|
||||||
|
|
||||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
|
{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
|
||||||
|
|
||||||
@@ -60,6 +66,14 @@
|
|||||||
|
|
||||||
Теперь можно создать копию существующей модели, используя `.model_copy()`, и передать параметр `update` с `dict`, содержащим данные для обновления.
|
Теперь можно создать копию существующей модели, используя `.model_copy()`, и передать параметр `update` с `dict`, содержащим данные для обновления.
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic v1 метод назывался `.copy()`, в Pydantic v2 он помечен как устаревший (но все еще поддерживается) и переименован в `.model_copy()`.
|
||||||
|
|
||||||
|
Примеры здесь используют `.copy()` для совместимости с Pydantic v1, но если вы можете использовать Pydantic v2, лучше используйте `.model_copy()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
Например, `stored_item_model.model_copy(update=update_data)`:
|
Например, `stored_item_model.model_copy(update=update_data)`:
|
||||||
|
|
||||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
||||||
@@ -70,9 +84,9 @@
|
|||||||
|
|
||||||
* (Опционально) использовать `PATCH` вместо `PUT`.
|
* (Опционально) использовать `PATCH` вместо `PUT`.
|
||||||
* Извлечь сохранённые данные.
|
* Извлечь сохранённые данные.
|
||||||
* Поместить эти данные в Pydantic-модель.
|
* Поместить эти данные в Pydantic модель.
|
||||||
* Сгенерировать `dict` без значений по умолчанию из входной модели (с использованием `exclude_unset`).
|
* Сгенерировать `dict` без значений по умолчанию из входной модели (с использованием `exclude_unset`).
|
||||||
* Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять уже сохраненные значения значениями по умолчанию из вашей модели.
|
* Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять значения, уже сохраненные в модели по умолчанию.
|
||||||
* Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметра `update`).
|
* Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметра `update`).
|
||||||
* Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощью `jsonable_encoder`).
|
* Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощью `jsonable_encoder`).
|
||||||
* Это сравнимо с повторным использованием метода модели `.model_dump()`, но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например, `datetime` в `str`.
|
* Это сравнимо с повторным использованием метода модели `.model_dump()`, но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например, `datetime` в `str`.
|
||||||
@@ -83,7 +97,7 @@
|
|||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
На самом деле эту же технику можно использовать и для операции HTTP `PUT`.
|
Эту же технику можно использовать и для операции HTTP `PUT`.
|
||||||
|
|
||||||
Но в приведенном примере используется `PATCH`, поскольку он был создан именно для таких случаев использования.
|
Но в приведенном примере используется `PATCH`, поскольку он был создан именно для таких случаев использования.
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,9 @@
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
|
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
|
||||||
|
|
||||||
|
|
||||||
Так же, как при объявлении параметров запроса: когда атрибут модели имеет значение по умолчанию, он не обязателен. Иначе он обязателен. Используйте `None`, чтобы сделать его просто необязательным.
|
Так же, как при объявлении параметров запроса: когда атрибут модели имеет значение по умолчанию, он не обязателен. Иначе он обязателен. Используйте `None`, чтобы сделать его просто необязательным.
|
||||||
|
|
||||||
Например, модель выше описывает такой JSON "`object`" (или Python `dict`):
|
Например, модель выше описывает такой JSON "объект" (или Python `dict`):
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -46,7 +45,7 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
...так как `description` и `tax` являются необязательными (со значением по умолчанию `None`), такой JSON "`object`" тоже будет корректным:
|
...так как `description` и `tax` являются необязательными (со значением по умолчанию `None`), такой JSON "объект" тоже будет корректным:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -74,7 +73,7 @@
|
|||||||
* Передаст полученные данные в параметр `item`.
|
* Передаст полученные данные в параметр `item`.
|
||||||
* Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т. п.) для всех атрибутов и их типов.
|
* Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т. п.) для всех атрибутов и их типов.
|
||||||
* Сгенерирует определения <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
|
* Сгенерирует определения <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
|
||||||
* Эти схемы будут частью сгенерированной схемы OpenAPI и будут использоваться автоматической документацией <abbr title="User Interfaces - Пользовательские интерфейсы">UIs</abbr>.
|
* Эти схемы будут частью сгенерированной схемы OpenAPI и будут использоваться автоматической документацией <abbr title="User Interfaces – Пользовательские интерфейсы">UIs</abbr>.
|
||||||
|
|
||||||
## Автоматическая документация { #automatic-docs }
|
## Автоматическая документация { #automatic-docs }
|
||||||
|
|
||||||
@@ -128,6 +127,14 @@ JSON Schema ваших моделей будет частью сгенериро
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial002_py310.py *}
|
{* ../../docs_src/body/tutorial002_py310.py *}
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он был помечен как устаревший (но всё ещё поддерживается) и переименован в `.model_dump()`.
|
||||||
|
|
||||||
|
Примеры здесь используют `.dict()` для совместимости с Pydantic v1, но если вы можете использовать Pydantic v2, используйте `.model_dump()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
## Тело запроса + параметры пути { #request-body-path-parameters }
|
## Тело запроса + параметры пути { #request-body-path-parameters }
|
||||||
|
|
||||||
Вы можете одновременно объявить параметры пути и тело запроса.
|
Вы можете одновременно объявить параметры пути и тело запроса.
|
||||||
@@ -136,7 +143,6 @@ JSON Schema ваших моделей будет частью сгенериро
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
|
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
|
||||||
|
|
||||||
|
|
||||||
## Тело запроса + параметры пути + параметры запроса { #request-body-path-query-parameters }
|
## Тело запроса + параметры пути + параметры запроса { #request-body-path-query-parameters }
|
||||||
|
|
||||||
Вы также можете одновременно объявить параметры **тела**, **пути** и **запроса**.
|
Вы также можете одновременно объявить параметры **тела**, **пути** и **запроса**.
|
||||||
@@ -147,7 +153,7 @@ JSON Schema ваших моделей будет частью сгенериро
|
|||||||
|
|
||||||
Параметры функции будут распознаны следующим образом:
|
Параметры функции будут распознаны следующим образом:
|
||||||
|
|
||||||
* Если параметр также объявлен в **пути**, он будет использоваться как path-параметр.
|
* Если параметр также объявлен в **пути**, он будет использоваться как параметр пути.
|
||||||
* Если параметр имеет **скалярный тип** (например, `int`, `float`, `str`, `bool` и т. п.), он будет интерпретирован как параметр **запроса**.
|
* Если параметр имеет **скалярный тип** (например, `int`, `float`, `str`, `bool` и т. п.), он будет интерпретирован как параметр **запроса**.
|
||||||
* Если параметр объявлен как тип **модели Pydantic**, он будет интерпретирован как **тело** запроса.
|
* Если параметр объявлен как тип **модели Pydantic**, он будет интерпретирован как **тело** запроса.
|
||||||
|
|
||||||
@@ -155,7 +161,7 @@ JSON Schema ваших моделей будет частью сгенериро
|
|||||||
|
|
||||||
FastAPI понимает, что значение `q` не является обязательным из-за значения по умолчанию `= None`.
|
FastAPI понимает, что значение `q` не является обязательным из-за значения по умолчанию `= None`.
|
||||||
|
|
||||||
Аннотации типов `str | None` (Python 3.10+) или `Union` в `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`.
|
Аннотации типов `str | None` (Python 3.10+) или `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`.
|
||||||
|
|
||||||
Но добавление аннотаций типов позволит вашему редактору кода лучше вас поддерживать и обнаруживать ошибки.
|
Но добавление аннотаций типов позволит вашему редактору кода лучше вас поддерживать и обнаруживать ошибки.
|
||||||
|
|
||||||
@@ -163,4 +169,4 @@ FastAPI понимает, что значение `q` не является об
|
|||||||
|
|
||||||
## Без Pydantic { #without-pydantic }
|
## Без Pydantic { #without-pydantic }
|
||||||
|
|
||||||
Если вы не хотите использовать модели Pydantic, вы также можете использовать параметры **Body**. См. раздел документации [Тело запроса - Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
|
Если вы не хотите использовать модели Pydantic, вы также можете использовать параметры **Body**. См. раздел документации [Тело — Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
|
||||||
|
|||||||
@@ -22,13 +22,21 @@
|
|||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
||||||
|
|
||||||
### Про `**user_in.model_dump()` { #about-user-in-model-dump }
|
/// info | Информация
|
||||||
|
|
||||||
#### `.model_dump()` из Pydantic { #pydantics-model-dump }
|
В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он помечен как устаревший (но всё ещё поддерживается) и переименован в `.model_dump()`.
|
||||||
|
|
||||||
`user_in` — это Pydantic-модель класса `UserIn`.
|
В примерах здесь используется `.dict()` для совместимости с Pydantic v1, но если вы используете Pydantic v2, следует использовать `.model_dump()`.
|
||||||
|
|
||||||
У Pydantic-моделей есть метод `.model_dump()`, который возвращает `dict` с данными модели.
|
///
|
||||||
|
|
||||||
|
### Про `**user_in.dict()` { #about-user-in-dict }
|
||||||
|
|
||||||
|
#### `.dict()` из Pydantic { #pydantics-dict }
|
||||||
|
|
||||||
|
`user_in` - это Pydantic-модель класса `UserIn`.
|
||||||
|
|
||||||
|
У Pydantic-моделей есть метод `.dict()`, который возвращает `dict` с данными модели.
|
||||||
|
|
||||||
Поэтому, если мы создадим Pydantic-объект `user_in` таким способом:
|
Поэтому, если мы создадим Pydantic-объект `user_in` таким способом:
|
||||||
|
|
||||||
@@ -39,10 +47,10 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
|
|||||||
и затем вызовем:
|
и затем вызовем:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
user_dict = user_in.model_dump()
|
user_dict = user_in.dict()
|
||||||
```
|
```
|
||||||
|
|
||||||
то теперь у нас есть `dict` с данными в переменной `user_dict` (это `dict` вместо объекта Pydantic-модели).
|
то теперь у нас есть `dict` с данными модели в переменной `user_dict` (это `dict` вместо объекта Pydantic-модели).
|
||||||
|
|
||||||
И если мы вызовем:
|
И если мы вызовем:
|
||||||
|
|
||||||
@@ -50,7 +58,7 @@ user_dict = user_in.model_dump()
|
|||||||
print(user_dict)
|
print(user_dict)
|
||||||
```
|
```
|
||||||
|
|
||||||
мы получим Python `dict` с:
|
мы можем получить `dict` с такими данными:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
{
|
{
|
||||||
@@ -63,7 +71,7 @@ print(user_dict)
|
|||||||
|
|
||||||
#### Распаковка `dict` { #unpacking-a-dict }
|
#### Распаковка `dict` { #unpacking-a-dict }
|
||||||
|
|
||||||
Если мы возьмём `dict` наподобие `user_dict` и передадим его в функцию (или класс), используя `**user_dict`, Python его "распакует". Он передаст ключи и значения `user_dict` напрямую как аргументы типа ключ-значение.
|
Если мы возьмём `dict` наподобие `user_dict` и передадим его в функцию (или класс), используя `**user_dict`, Python распакует его. Он передаст ключи и значения `user_dict` напрямую как аргументы типа ключ-значение.
|
||||||
|
|
||||||
Поэтому, продолжая описанный выше пример с `user_dict`, написание такого кода:
|
Поэтому, продолжая описанный выше пример с `user_dict`, написание такого кода:
|
||||||
|
|
||||||
@@ -71,7 +79,7 @@ print(user_dict)
|
|||||||
UserInDB(**user_dict)
|
UserInDB(**user_dict)
|
||||||
```
|
```
|
||||||
|
|
||||||
будет эквивалентно:
|
Будет работать так же, как примерно такой код:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(
|
UserInDB(
|
||||||
@@ -82,7 +90,7 @@ UserInDB(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Или, более точно, если использовать `user_dict` напрямую, с любым содержимым, которое он может иметь в будущем:
|
Или, если для большей точности мы напрямую используем `user_dict` с любым потенциальным содержимым, то этот пример будет выглядеть так:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(
|
UserInDB(
|
||||||
@@ -93,22 +101,22 @@ UserInDB(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Pydantic-модель из содержимого другой { #a-pydantic-model-from-the-contents-of-another }
|
#### Pydantic-модель из содержимого другой модели { #a-pydantic-model-from-the-contents-of-another }
|
||||||
|
|
||||||
Как в примере выше мы получили `user_dict` из `user_in.model_dump()`, этот код:
|
Как в примере выше мы получили `user_dict` из `user_in.dict()`, этот код:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
user_dict = user_in.model_dump()
|
user_dict = user_in.dict()
|
||||||
UserInDB(**user_dict)
|
UserInDB(**user_dict)
|
||||||
```
|
```
|
||||||
|
|
||||||
будет равнозначен такому:
|
будет равнозначен такому:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(**user_in.model_dump())
|
UserInDB(**user_in.dict())
|
||||||
```
|
```
|
||||||
|
|
||||||
...потому что `user_in.model_dump()` — это `dict`, и затем мы указываем, чтобы Python его "распаковал", когда передаём его в `UserInDB` с префиксом `**`.
|
...потому что `user_in.dict()` - это `dict`, и затем мы указываем, чтобы Python его "распаковал", когда передаём его в `UserInDB` и ставим перед ним `**`.
|
||||||
|
|
||||||
Таким образом мы получаем Pydantic-модель на основе данных из другой Pydantic-модели.
|
Таким образом мы получаем Pydantic-модель на основе данных из другой Pydantic-модели.
|
||||||
|
|
||||||
@@ -117,10 +125,10 @@ UserInDB(**user_in.model_dump())
|
|||||||
И затем, если мы добавим дополнительный именованный аргумент `hashed_password=hashed_password` как здесь:
|
И затем, если мы добавим дополнительный именованный аргумент `hashed_password=hashed_password` как здесь:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
|
UserInDB(**user_in.dict(), hashed_password=hashed_password)
|
||||||
```
|
```
|
||||||
|
|
||||||
...то в итоге получится что-то подобное:
|
... то мы получим что-то подобное:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(
|
UserInDB(
|
||||||
@@ -134,13 +142,13 @@ UserInDB(
|
|||||||
|
|
||||||
/// warning | Предупреждение
|
/// warning | Предупреждение
|
||||||
|
|
||||||
Вспомогательные дополнительные функции `fake_password_hasher` и `fake_save_user` используются только для демонстрации возможного потока данных и, конечно, не обеспечивают настоящую безопасность.
|
Вспомогательные функции `fake_password_hasher` и `fake_save_user` используются только для демонстрации возможного потока данных и, конечно, не обеспечивают настоящую безопасность.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Сократите дублирование { #reduce-duplication }
|
## Сократите дублирование { #reduce-duplication }
|
||||||
|
|
||||||
Сокращение дублирования кода — это одна из главных идей **FastAPI**.
|
Сокращение дублирования кода - это одна из главных идей **FastAPI**.
|
||||||
|
|
||||||
Поскольку дублирование кода повышает риск появления багов, проблем с безопасностью, проблем десинхронизации кода (когда вы обновляете код в одном месте, но не обновляете в другом), и т.д.
|
Поскольку дублирование кода повышает риск появления багов, проблем с безопасностью, проблем десинхронизации кода (когда вы обновляете код в одном месте, но не обновляете в другом), и т.д.
|
||||||
|
|
||||||
@@ -158,7 +166,7 @@ UserInDB(
|
|||||||
|
|
||||||
## `Union` или `anyOf` { #union-or-anyof }
|
## `Union` или `anyOf` { #union-or-anyof }
|
||||||
|
|
||||||
Вы можете объявить HTTP-ответ как `Union` из двух или более типов. Это означает, что HTTP-ответ может быть любым из них.
|
Вы можете определить ответ как `Union` из двух или более типов. Это означает, что ответ должен соответствовать одному из них.
|
||||||
|
|
||||||
Он будет определён в OpenAPI как `anyOf`.
|
Он будет определён в OpenAPI как `anyOf`.
|
||||||
|
|
||||||
@@ -166,7 +174,7 @@ UserInDB(
|
|||||||
|
|
||||||
/// note | Примечание
|
/// note | Примечание
|
||||||
|
|
||||||
При объявлении <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a> сначала указывайте наиболее специфичный тип, затем менее специфичный. В примере ниже более специфичный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
|
При объявлении <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>, сначала указывайте наиболее детальные типы, затем менее детальные. В примере ниже более детальный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -184,19 +192,19 @@ UserInDB(
|
|||||||
some_variable: PlaneItem | CarItem
|
some_variable: PlaneItem | CarItem
|
||||||
```
|
```
|
||||||
|
|
||||||
Но если мы поместим это в присваивание `response_model=PlaneItem | CarItem`, мы получим ошибку, потому что Python попытается произвести **некорректную операцию** между `PlaneItem` и `CarItem` вместо того, чтобы интерпретировать это как аннотацию типа.
|
Но если мы помещаем его в `response_model=PlaneItem | CarItem` мы получим ошибку, потому что Python попытается произвести **некорректную операцию** между `PlaneItem` и `CarItem` вместо того, чтобы интерпретировать это как аннотацию типа.
|
||||||
|
|
||||||
## Список моделей { #list-of-models }
|
## Список моделей { #list-of-models }
|
||||||
|
|
||||||
Таким же образом вы можете объявлять HTTP-ответы, возвращающие списки объектов.
|
Таким же образом вы можете определять ответы как списки объектов.
|
||||||
|
|
||||||
Для этого используйте стандартный `typing.List` в Python (или просто `list` в Python 3.9 и выше):
|
Для этого используйте `typing.List` из стандартной библиотеки Python (или просто `list` в Python 3.9 и выше):
|
||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
|
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
|
||||||
|
|
||||||
## Ответ с произвольным `dict` { #response-with-arbitrary-dict }
|
## Ответ с произвольным `dict` { #response-with-arbitrary-dict }
|
||||||
|
|
||||||
Вы также можете объявить HTTP-ответ, используя обычный произвольный `dict`, объявив только тип ключей и значений, без использования Pydantic-модели.
|
Вы также можете определить ответ, используя произвольный одноуровневый `dict` и определяя только типы ключей и значений без использования Pydantic-моделей.
|
||||||
|
|
||||||
Это полезно, если вы заранее не знаете корректных названий полей/атрибутов (которые будут нужны при использовании Pydantic-модели).
|
Это полезно, если вы заранее не знаете корректных названий полей/атрибутов (которые будут нужны при использовании Pydantic-модели).
|
||||||
|
|
||||||
@@ -206,6 +214,6 @@ some_variable: PlaneItem | CarItem
|
|||||||
|
|
||||||
## Резюме { #recap }
|
## Резюме { #recap }
|
||||||
|
|
||||||
Используйте несколько Pydantic-моделей и свободно применяйте наследование для каждого случая.
|
Используйте несколько Pydantic-моделей и свободно применяйте наследование для каждой из них.
|
||||||
|
|
||||||
Вам не обязательно иметь единственную модель данных для каждой сущности, если эта сущность должна иметь возможность быть в разных "состояниях". Как в случае с "сущностью" пользователя, у которого есть состояние, включающее `password`, `password_hash` и отсутствие пароля.
|
Вам не обязательно иметь единственную модель данных для каждой сущности, если эта сущность должна иметь возможность быть в разных "состояниях". Как в случае с "сущностью" пользователя, у которого есть состояния с полями `password`, `password_hash` и без пароля.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Query-параметр `q` имеет тип `str | None`, это означает, что он имеет тип `str`, но также может быть `None`. Значение по умолчанию действительно `None`, поэтому FastAPI будет знать, что он не обязателен.
|
Query-параметр `q` имеет тип `str | None`, это означает, что он имеет тип `str`, но также может быть `None`. Значение по умолчанию действительно `None`, поэтому FastAPI будет знать, что он не обязателен.
|
||||||
|
|
||||||
/// note | Примечание
|
/// note | Технические детали
|
||||||
|
|
||||||
FastAPI поймёт, что значение `q` не обязательно, из‑за значения по умолчанию `= None`.
|
FastAPI поймёт, что значение `q` не обязательно, из‑за значения по умолчанию `= None`.
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ q: str = Query(default="rick")
|
|||||||
|
|
||||||
**Значение по умолчанию** у **параметра функции** — это **настоящее значение по умолчанию**, что более интуитивно для Python. 😌
|
**Значение по умолчанию** у **параметра функции** — это **настоящее значение по умолчанию**, что более интуитивно для Python. 😌
|
||||||
|
|
||||||
Вы можете **вызвать** эту же функцию в **других местах** без FastAPI, и она будет **работать как ожидается**. Если есть **обязательный** параметр (без значения по умолчанию), ваш **редактор** сообщит об ошибке, **Python** тоже пожалуется, если вы запустите её без передачи обязательного параметра.
|
Вы можете **вызвать** эту же функцию в **других местах** без FastAPI, и она будет **работать как ожидается**. Если есть **обязательный** параметр (без значения по умолчанию), ваш **редактор кода** сообщит об ошибке, **Python** тоже пожалуется, если вы запустите её без передачи обязательного параметра.
|
||||||
|
|
||||||
Если вы не используете `Annotated`, а применяете **(устаревший) стиль со значением по умолчанию**, то при вызове этой функции без FastAPI в **других местах** вам нужно **помнить** о том, что надо передать аргументы, чтобы всё работало корректно, иначе значения будут не такими, как вы ожидаете (например, вместо `str` будет `QueryInfo` или что-то подобное). И ни редактор, ни Python не будут ругаться при самом вызове функции — ошибка проявится лишь при операциях внутри.
|
Если вы не используете `Annotated`, а применяете **(устаревший) стиль со значением по умолчанию**, то при вызове этой функции без FastAPI в **других местах** вам нужно **помнить** о том, что надо передать аргументы, чтобы всё работало корректно, иначе значения будут не такими, как вы ожидаете (например, вместо `str` будет `QueryInfo` или что-то подобное). И ни редактор, ни Python не будут ругаться при самом вызове функции — ошибка проявится лишь при операциях внутри.
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ q: str = Query(default="rick")
|
|||||||
|
|
||||||
## Регулярные выражения { #add-regular-expressions }
|
## Регулярные выражения { #add-regular-expressions }
|
||||||
|
|
||||||
Вы можете определить <abbr title="Регулярное выражение (regex, regexp) - это последовательность символов, задающая шаблон поиска для строк.">регулярное выражение</abbr> `pattern`, которому должен соответствовать параметр:
|
Вы можете определить <abbr title="Регулярное выражение (regex, regexp) — это последовательность символов, задающая шаблон поиска для строк.">регулярное выражение</abbr> `pattern`, которому должен соответствовать параметр:
|
||||||
|
|
||||||
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
||||||
|
|
||||||
@@ -205,6 +205,20 @@ q: str = Query(default="rick")
|
|||||||
|
|
||||||
Теперь вы знаете, что когда они понадобятся, вы сможете использовать их в **FastAPI**.
|
Теперь вы знаете, что когда они понадобятся, вы сможете использовать их в **FastAPI**.
|
||||||
|
|
||||||
|
### `regex` из Pydantic v1 вместо `pattern` { #pydantic-v1-regex-instead-of-pattern }
|
||||||
|
|
||||||
|
До Pydantic версии 2 и до FastAPI 0.100.0 этот параметр назывался `regex`, а не `pattern`, но сейчас он устарел.
|
||||||
|
|
||||||
|
Вы всё ещё можете встретить такой код:
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
Имейте в виду, что это устарело, и код следует обновить на использование нового параметра `pattern`. 🤓
|
||||||
|
|
||||||
## Значения по умолчанию { #default-values }
|
## Значения по умолчанию { #default-values }
|
||||||
|
|
||||||
Конечно, можно использовать и другие значения по умолчанию, не только `None`.
|
Конечно, можно использовать и другие значения по умолчанию, не только `None`.
|
||||||
@@ -265,7 +279,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
|
|||||||
http://localhost:8000/items/?q=foo&q=bar
|
http://localhost:8000/items/?q=foo&q=bar
|
||||||
```
|
```
|
||||||
|
|
||||||
вы получите множественные значения *query-параметров* `q` (`foo` и `bar`) в виде Python-`list` внутри вашей *функции-обработчика пути*, в *параметре функции* `q`.
|
вы получите множественные значения query-параметра `q` (`foo` и `bar`) в виде Python-`list` внутри вашей *функции обработки пути*, в *параметре функции* `q`.
|
||||||
|
|
||||||
Таким образом, ответ на этот URL будет:
|
Таким образом, ответ на этот URL будет:
|
||||||
|
|
||||||
@@ -317,7 +331,7 @@ http://localhost:8000/items/
|
|||||||
|
|
||||||
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
|
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
|
||||||
|
|
||||||
/// note | Примечание
|
/// note | Технические детали
|
||||||
|
|
||||||
Имейте в виду, что в этом случае FastAPI не будет проверять содержимое списка.
|
Имейте в виду, что в этом случае FastAPI не будет проверять содержимое списка.
|
||||||
|
|
||||||
@@ -331,7 +345,7 @@ http://localhost:8000/items/
|
|||||||
|
|
||||||
Эта информация будет включена в сгенерированную OpenAPI-схему и использована интерфейсами документации и внешними инструментами.
|
Эта информация будет включена в сгенерированную OpenAPI-схему и использована интерфейсами документации и внешними инструментами.
|
||||||
|
|
||||||
/// note | Примечание
|
/// note | Технические детали
|
||||||
|
|
||||||
Помните, что разные инструменты могут иметь разный уровень поддержки OpenAPI.
|
Помните, что разные инструменты могут иметь разный уровень поддержки OpenAPI.
|
||||||
|
|
||||||
@@ -401,7 +415,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Например, эта кастомная проверка убеждается, что ID элемента начинается с `isbn-` для номера книги <abbr title="ISBN означает International Standard Book Number - Международный стандартный книжный номер">ISBN</abbr> или с `imdb-` для ID URL фильма на <abbr title="IMDB (Internet Movie Database) - веб‑сайт с информацией о фильмах">IMDB</abbr>:
|
Например, эта кастомная проверка убеждается, что ID элемента начинается с `isbn-` для номера книги <abbr title="ISBN означает International Standard Book Number – Международный стандартный книжный номер">ISBN</abbr> или с `imdb-` для ID URL фильма на <abbr title="IMDB (Internet Movie Database) — веб‑сайт с информацией о фильмах">IMDB</abbr>:
|
||||||
|
|
||||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
||||||
|
|
||||||
@@ -441,7 +455,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
|
|||||||
|
|
||||||
Затем с `random.choice()` можно получить **случайное значение** из списка — то есть кортеж вида `(id, name)`. Это будет что‑то вроде `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
|
Затем с `random.choice()` можно получить **случайное значение** из списка — то есть кортеж вида `(id, name)`. Это будет что‑то вроде `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
|
||||||
|
|
||||||
После этого мы **присваиваем эти два значения** кортежа переменным `id` и `name`.
|
После этого мы **распаковываем** эти два значения кортежа в переменные `id` и `name`.
|
||||||
|
|
||||||
Так что, если пользователь не передал ID элемента, он всё равно получит случайную рекомендацию.
|
Так что, если пользователь не передал ID элемента, он всё равно получит случайную рекомендацию.
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
|
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
|
||||||
|
|
||||||
FastAPI будет использовать этот возвращаемый тип, чтобы:
|
FastAPI будет использовать этот тип ответа для:
|
||||||
|
|
||||||
* **Валидировать** возвращаемые данные.
|
* **Валидации** возвращаемых данных.
|
||||||
* Если данные невалидны (например, отсутствует поле), это означает, что код *вашего* приложения работает некорректно и возвращает не то, что должен. В таком случае будет возвращена ошибка сервера вместо неправильных данных. Так вы и ваши клиенты можете быть уверены, что получите ожидаемые данные и ожидаемую структуру данных.
|
* Если данные невалидны (например, отсутствует поле), это означает, что код *вашего* приложения работает некорректно и возвращает не то, что должен. В таком случае будет возвращена ошибка сервера вместо неправильных данных. Так вы и ваши клиенты можете быть уверены, что получите ожидаемые данные и ожидаемую структуру.
|
||||||
* Добавить **JSON Schema** для ответа в OpenAPI *операции пути*.
|
* Добавления **JSON Schema** для ответа в OpenAPI *операции пути*.
|
||||||
* Это будет использовано **автоматической документацией**.
|
* Это будет использовано **автоматической документацией**.
|
||||||
* Это также будет использовано инструментами автоматической генерации клиентского кода.
|
* Это также будет использовано инструментами автоматической генерации клиентского кода.
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ FastAPI будет использовать этот возвращаемый т
|
|||||||
|
|
||||||
Бывают случаи, когда вам нужно или хочется возвращать данные, которые не в точности соответствуют объявленному типу.
|
Бывают случаи, когда вам нужно или хочется возвращать данные, которые не в точности соответствуют объявленному типу.
|
||||||
|
|
||||||
Например, вы можете хотеть **возвращать словарь** или объект из базы данных, но **объявить его как Pydantic-модель**. Тогда Pydantic-модель выполнит документирование данных, валидацию и т.п. для объекта, который вы вернули (например, словаря или объекта из базы данных).
|
Например, вы можете хотеть **возвращать словарь (dict)** или объект из базы данных, но **объявить его как Pydantic-модель**. Тогда Pydantic-модель выполнит документирование данных, валидацию и т.п. для объекта, который вы вернули (например, словаря или объекта из базы данных).
|
||||||
|
|
||||||
Если вы добавите аннотацию возвращаемого типа, инструменты и редакторы кода начнут жаловаться (и будут правы), что функция возвращает тип (например, dict), отличный от объявленного (например, Pydantic-модель).
|
Если вы добавите аннотацию возвращаемого типа, инструменты и редакторы кода начнут жаловаться (и будут правы), что функция возвращает тип (например, dict), отличный от объявленного (например, Pydantic-модель).
|
||||||
|
|
||||||
@@ -47,13 +47,13 @@ FastAPI будет использовать этот возвращаемый т
|
|||||||
|
|
||||||
`response_model` принимает тот же тип, что вы бы объявили для поля Pydantic-модели, то есть это может быть одна Pydantic-модель, а может быть, например, `list` Pydantic-моделей, как `List[Item]`.
|
`response_model` принимает тот же тип, что вы бы объявили для поля Pydantic-модели, то есть это может быть одна Pydantic-модель, а может быть, например, `list` Pydantic-моделей, как `List[Item]`.
|
||||||
|
|
||||||
FastAPI будет использовать этот `response_model` для документирования, валидации данных и т.п., а также для **конвертации и фильтрации выходных данных** к объявленному типу.
|
FastAPI будет использовать `response_model` для документации, валидации и т. п., а также для **конвертации и фильтрации выходных данных** к объявленному типу.
|
||||||
|
|
||||||
/// tip | Совет
|
/// tip | Совет
|
||||||
|
|
||||||
Если у вас в редакторе кода, mypy и т.п. включены строгие проверки типов, вы можете объявить возвращаемый тип функции как `Any`.
|
Если у вас в редакторе кода, mypy и т. п. включены строгие проверки типов, вы можете объявить возвращаемый тип функции как `Any`.
|
||||||
|
|
||||||
Так вы сообщите редактору, что намеренно возвращаете что угодно. Но FastAPI всё равно выполнит документирование, валидацию, фильтрацию данных и т.д. с помощью `response_model`.
|
Так вы сообщите редактору, что намеренно возвращаете что угодно. Но FastAPI всё равно выполнит документацию данных, валидацию, фильтрацию и т.д. с помощью `response_model`.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ FastAPI будет использовать этот `response_model` для д
|
|||||||
|
|
||||||
Если вы объявите и возвращаемый тип, и `response_model`, приоритет будет у `response_model`, именно его использует FastAPI.
|
Если вы объявите и возвращаемый тип, и `response_model`, приоритет будет у `response_model`, именно его использует FastAPI.
|
||||||
|
|
||||||
Так вы можете добавить корректные аннотации типов к своим функциям, даже если фактически возвращаете тип, отличный от модели ответа, чтобы ими пользовались редактор кода и инструменты вроде mypy. И при этом FastAPI продолжит выполнять валидацию данных, документацию и т.д. с использованием `response_model`.
|
Так вы можете добавить корректные аннотации типов к своим функциям, даже если фактически возвращаете тип, отличный от модели ответа, чтобы ими пользовались редактор и инструменты вроде mypy. И при этом FastAPI продолжит выполнять валидацию данных, документацию и т.д. с использованием `response_model`.
|
||||||
|
|
||||||
Вы также можете указать `response_model=None`, чтобы отключить создание модели ответа для данной *операции пути*. Это может понадобиться, если вы добавляете аннотации типов для вещей, не являющихся валидными полями Pydantic. Пример вы увидите ниже.
|
Вы также можете указать `response_model=None`, чтобы отключить создание модели ответа для данной *операции пути*. Это может понадобиться, если вы добавляете аннотации типов для вещей, не являющихся валидными полями Pydantic. Пример вы увидите ниже.
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ FastAPI будет использовать этот `response_model` для д
|
|||||||
|
|
||||||
Чтобы использовать `EmailStr`, сначала установите <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a>.
|
Чтобы использовать `EmailStr`, сначала установите <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a>.
|
||||||
|
|
||||||
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установите пакет, например:
|
Создайте [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активируйте его и затем установите пакет, например:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ pip install email-validator
|
$ pip install email-validator
|
||||||
@@ -105,7 +105,7 @@ $ pip install "pydantic[email]"
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Добавить выходную модель { #add-an-output-model }
|
## Добавить модель для ответа { #add-an-output-model }
|
||||||
|
|
||||||
Вместо этого мы можем создать входную модель с паролем в открытом виде и выходную модель без него:
|
Вместо этого мы можем создать входную модель с паролем в открытом виде и выходную модель без него:
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ $ pip install "pydantic[email]"
|
|||||||
|
|
||||||
### `response_model` или возвращаемый тип { #response-model-or-return-type }
|
### `response_model` или возвращаемый тип { #response-model-or-return-type }
|
||||||
|
|
||||||
В этом случае, поскольку две модели различаются, если бы мы аннотировали возвращаемый тип функции как `UserOut`, редактор кода и инструменты пожаловались бы, что мы возвращаем неверный тип, так как это разные классы.
|
В этом случае, поскольку две модели различаются, если бы мы аннотировали возвращаемый тип функции как `UserOut`, редактор и инструменты пожаловались бы, что мы возвращаем неверный тип, так как это разные классы.
|
||||||
|
|
||||||
Поэтому в этом примере мы должны объявить тип ответа в параметре `response_model`.
|
Поэтому в этом примере мы должны объявить тип ответа в параметре `response_model`.
|
||||||
|
|
||||||
@@ -135,33 +135,33 @@ $ pip install "pydantic[email]"
|
|||||||
|
|
||||||
Мы хотим, чтобы FastAPI продолжал **фильтровать** данные с помощью модели ответа. Так что, даже если функция возвращает больше данных, в ответ будут включены только поля, объявленные в модели ответа.
|
Мы хотим, чтобы FastAPI продолжал **фильтровать** данные с помощью модели ответа. Так что, даже если функция возвращает больше данных, в ответ будут включены только поля, объявленные в модели ответа.
|
||||||
|
|
||||||
В предыдущем примере, поскольку классы были разными, нам пришлось использовать параметр `response_model`. Но это также означает, что мы теряем поддержку от редактора кода и инструментов, проверяющих возвращаемый тип функции.
|
В предыдущем примере, поскольку классы были разными, нам пришлось использовать параметр `response_model`. Но это также означает, что мы теряем поддержку от редактора и инструментов, проверяющих возвращаемый тип функции.
|
||||||
|
|
||||||
Однако в большинстве таких случаев нам нужно лишь **отфильтровать/убрать** некоторые данные, как в этом примере.
|
Однако в большинстве таких случаев нам нужно лишь **отфильтровать/убрать** некоторые данные, как в этом примере.
|
||||||
|
|
||||||
И в этих случаях мы можем использовать классы и наследование, чтобы воспользоваться **аннотациями типов** функций для лучшей поддержки в редакторе кода и инструментах и при этом получить **фильтрацию данных** от FastAPI.
|
И в этих случаях мы можем использовать классы и наследование, чтобы воспользоваться **аннотациями типов** функций для лучшей поддержки в редакторе и инструментах и при этом получить **фильтрацию данных** от FastAPI.
|
||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
|
{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
|
||||||
|
|
||||||
Так мы получаем поддержку инструментов — редакторов кода и mypy, так как этот код корректен с точки зрения типов — и одновременно получаем фильтрацию данных от FastAPI.
|
Так мы получаем поддержку инструментов (редакторы, mypy) — код корректен с точки зрения типов — и одновременно получаем фильтрацию данных от FastAPI.
|
||||||
|
|
||||||
Как это работает? Давайте разберёмся. 🤓
|
Как это работает? Давайте разберёмся. 🤓
|
||||||
|
|
||||||
### Аннотации типов и инструменты { #type-annotations-and-tooling }
|
### Аннотации типов и инструменты { #type-annotations-and-tooling }
|
||||||
|
|
||||||
Сначала посмотрим, как это увидят редактор кода, mypy и другие инструменты.
|
Сначала посмотрим, как это увидят редакторы, mypy и другие инструменты.
|
||||||
|
|
||||||
`BaseUser` содержит базовые поля. Затем `UserIn` наследуется от `BaseUser` и добавляет поле `password`, то есть он будет включать все поля обеих моделей.
|
`BaseUser` содержит базовые поля. Затем `UserIn` наследуется от `BaseUser` и добавляет поле `password`, то есть он включает все поля обеих моделей.
|
||||||
|
|
||||||
Мы аннотируем возвращаемый тип функции как `BaseUser`, но фактически возвращаем экземпляр `UserIn`.
|
Мы аннотируем возвращаемый тип функции как `BaseUser`, но фактически возвращаем экземпляр `UserIn`.
|
||||||
|
|
||||||
Редактор кода, mypy и другие инструменты не будут возражать, потому что с точки зрения типов `UserIn` — подкласс `BaseUser`, что означает, что это *валидный* тип везде, где ожидается что-то, являющееся `BaseUser`.
|
Редактор, mypy и другие инструменты не будут возражать, потому что с точки зрения типов `UserIn` — подкласс `BaseUser`, что означает, что это *валидный* тип везде, где ожидается что-то, являющееся `BaseUser`.
|
||||||
|
|
||||||
### Фильтрация данных FastAPI { #fastapi-data-filtering }
|
### Фильтрация данных FastAPI { #fastapi-data-filtering }
|
||||||
|
|
||||||
Теперь для FastAPI: он увидит возвращаемый тип и убедится, что то, что вы возвращаете, включает **только** поля, объявленные в этом типе.
|
Теперь, для FastAPI: он увидит возвращаемый тип и убедится, что то, что вы возвращаете, включает **только** поля, объявленные в этом типе.
|
||||||
|
|
||||||
FastAPI делает несколько вещей внутри вместе с Pydantic, чтобы гарантировать, что те же правила наследования классов не используются для фильтрации возвращаемых данных, иначе вы могли бы в итоге вернуть намного больше данных, чем ожидали.
|
FastAPI делает несколько вещей внутри вместе с Pydantic, чтобы гарантировать, что те же правила наследования классов не используются для фильтрации возвращаемых данных, иначе вы могли бы вернуть гораздо больше данных, чем ожидали.
|
||||||
|
|
||||||
Таким образом вы получаете лучшее из обоих миров: аннотации типов с **поддержкой инструментов** и **фильтрацию данных**.
|
Таким образом вы получаете лучшее из обоих миров: аннотации типов с **поддержкой инструментов** и **фильтрацию данных**.
|
||||||
|
|
||||||
@@ -171,17 +171,17 @@ FastAPI делает несколько вещей внутри вместе с
|
|||||||
|
|
||||||
<img src="/img/tutorial/response-model/image01.png">
|
<img src="/img/tutorial/response-model/image01.png">
|
||||||
|
|
||||||
И обе модели будут использоваться в интерактивной документации API:
|
И обе модели используются в интерактивной документации API:
|
||||||
|
|
||||||
<img src="/img/tutorial/response-model/image02.png">
|
<img src="/img/tutorial/response-model/image02.png">
|
||||||
|
|
||||||
## Другие аннотации возвращаемых типов { #other-return-type-annotations }
|
## Другие аннотации возвращаемых типов { #other-return-type-annotations }
|
||||||
|
|
||||||
Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор кода, mypy и т.д.).
|
Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор, mypy и т. д.).
|
||||||
|
|
||||||
### Возврат Response напрямую { #return-a-response-directly }
|
### Возврат Response напрямую { #return-a-response-directly }
|
||||||
|
|
||||||
Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах документации для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}.
|
Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}.
|
||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
|
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ FastAPI делает несколько вещей внутри вместе с
|
|||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
|
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
|
||||||
|
|
||||||
Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот простой случай.
|
Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот случай.
|
||||||
|
|
||||||
### Некорректные аннотации возвращаемых типов { #invalid-return-type-annotations }
|
### Некорректные аннотации возвращаемых типов { #invalid-return-type-annotations }
|
||||||
|
|
||||||
@@ -209,15 +209,15 @@ FastAPI делает несколько вещей внутри вместе с
|
|||||||
|
|
||||||
### Отключить модель ответа { #disable-response-model }
|
### Отключить модель ответа { #disable-response-model }
|
||||||
|
|
||||||
Продолжая пример выше, вы можете не хотеть использовать стандартные валидацию данных, документирование, фильтрацию и т.п., выполняемые FastAPI.
|
Продолжая пример выше, вы можете не хотеть использовать стандартную валидацию данных, документацию, фильтрацию и т.д., выполняемые FastAPI.
|
||||||
|
|
||||||
Но при этом вы можете хотеть сохранить аннотацию возвращаемого типа в функции, чтобы пользоваться поддержкой инструментов вроде редакторов кода и инструментов проверки типов (например, mypy).
|
Но при этом вы можете хотеть сохранить аннотацию возвращаемого типа в функции, чтобы пользоваться поддержкой инструментов (редакторы, проверки типов вроде mypy).
|
||||||
|
|
||||||
В этом случае вы можете отключить генерацию модели ответа, установив `response_model=None`:
|
В этом случае вы можете отключить генерацию модели ответа, установив `response_model=None`:
|
||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
|
{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
|
||||||
|
|
||||||
Так FastAPI пропустит генерацию модели ответа, и вы сможете использовать любые аннотации возвращаемых типов, которые вам нужны, без влияния на ваше приложение FastAPI. 🤓
|
Так FastAPI пропустит генерацию модели ответа, и вы сможете использовать любые аннотации возвращаемых типов, не влияя на ваше приложение FastAPI. 🤓
|
||||||
|
|
||||||
## Параметры кодирования модели ответа { #response-model-encoding-parameters }
|
## Параметры кодирования модели ответа { #response-model-encoding-parameters }
|
||||||
|
|
||||||
@@ -252,6 +252,20 @@ FastAPI делает несколько вещей внутри вместе с
|
|||||||
|
|
||||||
/// info | Информация
|
/// info | Информация
|
||||||
|
|
||||||
|
В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он был помечен как устаревший (но всё ещё поддерживается) и переименован в `.model_dump()`.
|
||||||
|
|
||||||
|
Примеры здесь используют `.dict()` для совместимости с Pydantic v1, но если вы используете Pydantic v2, применяйте `.model_dump()`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
|
FastAPI использует метод `.dict()` у Pydantic-моделей с <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">параметром `exclude_unset`</a>, чтобы добиться такого поведения.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/// info | Информация
|
||||||
|
|
||||||
Вы также можете использовать:
|
Вы также можете использовать:
|
||||||
|
|
||||||
* `response_model_exclude_defaults=True`
|
* `response_model_exclude_defaults=True`
|
||||||
@@ -298,7 +312,7 @@ FastAPI достаточно умен (на самом деле, это Pydantic
|
|||||||
|
|
||||||
Обратите внимание, что значения по умолчанию могут быть любыми, не только `None`.
|
Обратите внимание, что значения по умолчанию могут быть любыми, не только `None`.
|
||||||
|
|
||||||
Это может быть список (`[]`), число с плавающей точкой `10.5` и т.д.
|
Это может быть список (`[]`), число с плавающей точкой `10.5` и т. д.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -332,7 +346,7 @@ FastAPI достаточно умен (на самом деле, это Pydantic
|
|||||||
|
|
||||||
#### Использование `list` вместо `set` { #using-lists-instead-of-sets }
|
#### Использование `list` вместо `set` { #using-lists-instead-of-sets }
|
||||||
|
|
||||||
Если вы забыли использовать `set` и применили `list` или `tuple` вместо него, FastAPI всё равно преобразует это в `set`, и всё будет работать корректно:
|
Если вы забыли использовать `set` и применили `list` или `tuple`, FastAPI всё равно преобразует это в `set`, и всё будет работать корректно:
|
||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
|
{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,36 @@
|
|||||||
|
|
||||||
Вы можете объявить `examples` для модели Pydantic, которые будут добавлены в сгенерированную JSON Schema.
|
Вы можете объявить `examples` для модели Pydantic, которые будут добавлены в сгенерированную JSON Schema.
|
||||||
|
|
||||||
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
|
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
Эта дополнительная информация будет добавлена как есть в выходную **JSON Schema** этой модели и будет использоваться в документации API.
|
Эта дополнительная информация будет добавлена как есть в выходную **JSON Schema** этой модели и будет использоваться в документации API.
|
||||||
|
|
||||||
Вы можете использовать атрибут `model_config`, который принимает `dict`, как описано в <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Документации Pydantic: Конфигурация</a>.
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
|
В Pydantic версии 2 вы будете использовать атрибут `model_config`, который принимает `dict`, как описано в <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Документации Pydantic: Конфигурация</a>.
|
||||||
|
|
||||||
Вы можете задать `"json_schema_extra"` с `dict`, содержащим любые дополнительные данные, которые вы хотите видеть в сгенерированной JSON Schema, включая `examples`.
|
Вы можете задать `"json_schema_extra"` с `dict`, содержащим любые дополнительные данные, которые вы хотите видеть в сгенерированной JSON Schema, включая `examples`.
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Pydantic v1
|
||||||
|
|
||||||
|
В Pydantic версии 1 вы будете использовать внутренний класс `Config` и `schema_extra`, как описано в <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Документации Pydantic: Настройка схемы</a>.
|
||||||
|
|
||||||
|
Вы можете задать `schema_extra` со `dict`, содержащим любые дополнительные данные, которые вы хотите видеть в сгенерированной JSON Schema, включая `examples`.
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
/// tip | Подсказка
|
/// tip | Подсказка
|
||||||
|
|
||||||
Вы можете использовать тот же приём, чтобы расширить JSON Schema и добавить свою собственную дополнительную информацию.
|
Вы можете использовать тот же приём, чтобы расширить JSON Schema и добавить свою собственную дополнительную информацию.
|
||||||
@@ -102,7 +124,7 @@ OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) доб
|
|||||||
|
|
||||||
Ключи `dict` идентифицируют каждый пример, а каждое значение — это ещё один `dict`.
|
Ключи `dict` идентифицируют каждый пример, а каждое значение — это ещё один `dict`.
|
||||||
|
|
||||||
Каждый конкретный пример `dict` в `examples` может содержать:
|
Каждый конкретный пример‑`dict` в `examples` может содержать:
|
||||||
|
|
||||||
* `summary`: Краткое описание примера.
|
* `summary`: Краткое описание примера.
|
||||||
* `description`: Подробное описание, которое может содержать текст в Markdown.
|
* `description`: Подробное описание, которое может содержать текст в Markdown.
|
||||||
@@ -113,7 +135,7 @@ OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) доб
|
|||||||
|
|
||||||
{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
|
{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
|
||||||
|
|
||||||
### OpenAPI-примеры в UI документации { #openapi-examples-in-the-docs-ui }
|
### OpenAPI-примеры в UI документации { #openapi-examples-in-the-docs-ui }
|
||||||
|
|
||||||
С `openapi_examples`, добавленным в `Body()`, страница `/docs` будет выглядеть так:
|
С `openapi_examples`, добавленным в `Body()`, страница `/docs` будет выглядеть так:
|
||||||
|
|
||||||
@@ -191,7 +213,7 @@ OpenAPI также добавила поля `example` и `examples` в друг
|
|||||||
|
|
||||||
### Swagger UI и специфичные для OpenAPI `examples` { #swagger-ui-and-openapi-specific-examples }
|
### Swagger UI и специфичные для OpenAPI `examples` { #swagger-ui-and-openapi-specific-examples }
|
||||||
|
|
||||||
Теперь, поскольку Swagger UI не поддерживал несколько примеров JSON Schema (по состоянию на 2023-08-26), у пользователей не было способа показать несколько примеров в документации.
|
Раньше, поскольку Swagger UI не поддерживал несколько примеров JSON Schema (по состоянию на 2023-08-26), у пользователей не было способа показать несколько примеров в документации.
|
||||||
|
|
||||||
Чтобы решить это, FastAPI `0.103.0` **добавил поддержку** объявления того же старого, **специфичного для OpenAPI**, поля `examples` с новым параметром `openapi_examples`. 🤓
|
Чтобы решить это, FastAPI `0.103.0` **добавил поддержку** объявления того же старого, **специфичного для OpenAPI**, поля `examples` с новым параметром `openapi_examples`. 🤓
|
||||||
|
|
||||||
|
|||||||
@@ -90,12 +90,5 @@ For the following technical terms, use these specific translations to ensure con
|
|||||||
* serve (meaning providing access to something): «отдавать» (or `предоставлять доступ к`)
|
* serve (meaning providing access to something): «отдавать» (or `предоставлять доступ к`)
|
||||||
* recap (noun): резюме
|
* recap (noun): резюме
|
||||||
* utility function: вспомогательная функция
|
* utility function: вспомогательная функция
|
||||||
* fast to code: позволяет быстро писать код
|
|
||||||
* Tutorial - User Guide: Учебник - Руководство пользователя
|
|
||||||
* submodule: подмодуль
|
|
||||||
* subpackage: подпакет
|
|
||||||
* router: роутер
|
|
||||||
* building, deploying, accessing (when describing features of FastAPI Cloud): созданиe образа, развертывание и доступ
|
|
||||||
* type checker tool: инструмент проверки типов
|
|
||||||
|
|
||||||
Do not add whitespace in `т.д.`, `т.п.`.
|
Do not add whitespace in `т.д.`, `т.п.`.
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Hakkında
|
# Hakkında { #about }
|
||||||
|
|
||||||
FastAPI, tasarımı, ilham kaynağı ve daha fazlası hakkında. 🤓
|
FastAPI, tasarımı, ilham kaynağı ve daha fazlası hakkında. 🤓
|
||||||
|
|||||||
@@ -1,36 +1,21 @@
|
|||||||
# Gelişmiş Kullanıcı Rehberi
|
# Gelişmiş Kullanıcı Rehberi { #advanced-user-guide }
|
||||||
|
|
||||||
## Ek Özellikler
|
## Ek Özellikler { #additional-features }
|
||||||
|
|
||||||
[Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası **FastAPI**'ın tüm ana özelliklerini tanıtmaya yetecektir.
|
Ana [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası, **FastAPI**'ın tüm temel özelliklerini tanımanız için yeterli olmalıdır.
|
||||||
|
|
||||||
İlerleyen bölümlerde diğer seçenekler, konfigürasyonlar ve ek özellikleri göreceğiz.
|
Sonraki bölümlerde diğer seçenekleri, konfigürasyonları ve ek özellikleri göreceksiniz.
|
||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
|
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
|
||||||
|
|
||||||
Kullanım şeklinize bağlı olarak, çözümünüz bu bölümlerden birinde olabilir.
|
Ve kullanım amacınıza bağlı olarak, çözüm bunlardan birinde olabilir.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Önce Öğreticiyi Okuyun
|
## Önce Tutorial'ı Okuyun { #read-the-tutorial-first }
|
||||||
|
|
||||||
[Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfasındaki bilgilerle **FastAPI**'nın çoğu özelliğini kullanabilirsiniz.
|
Ana [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfasındaki bilgilerle **FastAPI**'nın çoğu özelliğini yine de kullanabilirsiniz.
|
||||||
|
|
||||||
Sonraki bölümler bu sayfayı okuduğunuzu ve bu ana fikirleri bildiğinizi varsayarak hazırlanmıştır.
|
Ve sonraki bölümler, onu zaten okuduğunuzu ve bu temel fikirleri bildiğinizi varsayar.
|
||||||
|
|
||||||
## Diğer Kurslar
|
|
||||||
|
|
||||||
[Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası ve bu **Gelişmiş Kullanıcı Rehberi**, öğretici bir kılavuz (bir kitap gibi) şeklinde yazılmıştır ve **FastAPI'ı öğrenmek** için yeterli olsa da, ek kurslarla desteklemek isteyebilirsiniz.
|
|
||||||
|
|
||||||
Belki de öğrenme tarzınıza daha iyi uyduğu için başka kursları tercih edebilirsiniz.
|
|
||||||
|
|
||||||
Bazı kurs sağlayıcıları ✨ [**FastAPI destekçileridir**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, bu FastAPI ve **ekosisteminin** sürekli ve sağlıklı bir şekilde **gelişmesini** sağlar.
|
|
||||||
|
|
||||||
Ayrıca, size **iyi bir öğrenme deneyimi** sağlamakla kalmayıp, **iyi ve sağlıklı bir framework** olan FastAPI'a ve ve **topluluğuna** (yani size) olan gerçek bağlılıklarını gösterir.
|
|
||||||
|
|
||||||
Onların kurslarını denemek isteyebilirsiniz:
|
|
||||||
|
|
||||||
* <a href="https://training.talkpython.fm/fastapi-courses" class="external-link" target="_blank">Talk Python Training</a>
|
|
||||||
* <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development</a>
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Gelişmiş Güvenlik
|
# Gelişmiş Güvenlik { #advanced-security }
|
||||||
|
|
||||||
## Ek Özellikler
|
## Ek Özellikler { #additional-features }
|
||||||
|
|
||||||
[Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
|
[Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
|
||||||
|
|
||||||
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
|
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
|
||||||
|
|
||||||
Kullanım şeklinize bağlı olarak, çözümünüz bu bölümlerden birinde olabilir.
|
Ve kullanım durumunuza göre, çözüm bu bölümlerden birinde olabilir.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Önce Öğreticiyi Okuyun
|
## Önce Öğreticiyi Okuyun { #read-the-tutorial-first }
|
||||||
|
|
||||||
Sonraki bölümler [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasını okuduğunuzu varsayarak hazırlanmıştır.
|
Sonraki bölümler, ana [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasını zaten okuduğunuzu varsayar.
|
||||||
|
|
||||||
Bu bölümler aynı kavramlara dayanır, ancak bazı ek işlevsellikler sağlar.
|
Hepsi aynı kavramlara dayanır, ancak bazı ek işlevselliklere izin verir.
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# WebSockets'i Test Etmek
|
# WebSockets'i Test Etmek { #testing-websockets }
|
||||||
|
|
||||||
WebSockets testi yapmak için `TestClient`'ı kullanabilirsiniz.
|
WebSockets'i test etmek için aynı `TestClient`'ı kullanabilirsiniz.
|
||||||
|
|
||||||
Bu işlem için, `TestClient`'ı bir `with` ifadesinde kullanarak WebSocket'e bağlanabilirsiniz:
|
Bunun için `TestClient`'ı bir `with` ifadesinde kullanarak WebSocket'e bağlanırsınız:
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
|
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
|
||||||
|
|
||||||
/// note | Not
|
/// note | Not
|
||||||
|
|
||||||
Daha fazla detay için Starlette'in <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Websockets'i Test Etmek</a> dokümantasyonunu inceleyin.
|
Daha fazla detay için Starlette'in <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">WebSockets'i test etme</a> dokümantasyonuna bakın.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
# WSGI - Flask, Django ve Daha Fazlasını FastAPI ile Kullanma
|
# WSGI'yi Dahil Etme - Flask, Django ve Diğerleri { #including-wsgi-flask-django-others }
|
||||||
|
|
||||||
WSGI uygulamalarını [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank} bölümlerinde gördüğünüz gibi bağlayabilirsiniz.
|
WSGI uygulamalarını [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank} bölümlerinde gördüğünüz gibi mount edebilirsiniz.
|
||||||
|
|
||||||
Bunun için `WSGIMiddleware` ile Flask, Django vb. WSGI uygulamanızı sarmalayabilir ve FastAPI'ya bağlayabilirsiniz.
|
Bunun için `WSGIMiddleware`'ı kullanabilir ve bunu WSGI uygulamanızı (örneğin Flask, Django vb.) sarmalamak için kullanabilirsiniz.
|
||||||
|
|
||||||
## `WSGIMiddleware` Kullanımı
|
## `WSGIMiddleware` Kullanımı { #using-wsgimiddleware }
|
||||||
|
|
||||||
`WSGIMiddleware`'ı projenize dahil edin.
|
`WSGIMiddleware`'ı import etmeniz gerekir.
|
||||||
|
|
||||||
Ardından WSGI (örneğin Flask) uygulamanızı middleware ile sarmalayın.
|
Ardından WSGI (örn. Flask) uygulamasını middleware ile sarmalayın.
|
||||||
|
|
||||||
Son olarak da bir yol altında bağlama işlemini gerçekleştirin.
|
Ve sonra bunu bir path'in altına mount edin.
|
||||||
|
|
||||||
{* ../../docs_src/wsgi/tutorial001.py hl[2:3,23] *}
|
{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
|
||||||
|
|
||||||
## Kontrol Edelim
|
## Kontrol Edelim { #check-it }
|
||||||
|
|
||||||
Artık `/v1/` yolunun altındaki her istek Flask uygulaması tarafından işlenecektir.
|
Artık `/v1/` path'i altındaki her request Flask uygulaması tarafından işlenecektir.
|
||||||
|
|
||||||
Geri kalanı ise **FastAPI** tarafından işlenecektir.
|
Geri kalanı ise **FastAPI** tarafından işlenecektir.
|
||||||
|
|
||||||
Eğer uygulamanızı çalıştırıp <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a> adresine giderseniz, Flask'tan gelen yanıtı göreceksiniz:
|
Eğer uygulamanızı çalıştırıp <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a> adresine giderseniz, Flask'tan gelen response'u göreceksiniz:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
Hello, World from Flask!
|
Hello, World from Flask!
|
||||||
```
|
```
|
||||||
|
|
||||||
Eğer <a href="http://localhost:8000/v2/" class="external-link" target="_blank">http://localhost:8000/v2/</a> adresine giderseniz, FastAPI'dan gelen yanıtı göreceksiniz:
|
Ve eğer <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a> adresine giderseniz, FastAPI'dan gelen response'u göreceksiniz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
# Kıyaslamalar
|
# Kıyaslamalar { #benchmarks }
|
||||||
|
|
||||||
Bağımsız TechEmpower kıyaslamaları gösteriyor ki <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">en hızlı Python frameworklerinden birisi</a> olan Uvicorn ile çalıştırılan **FastAPI** uygulamaları, sadece Starlette ve Uvicorn'dan daha düşük sıralamada (FastAPI bu frameworklerin üzerine kurulu) yer alıyor. (*)
|
Bağımsız TechEmpower kıyaslamaları, Uvicorn altında çalışan **FastAPI** uygulamalarının <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">mevcut en hızlı Python frameworklerinden biri</a> olduğunu, yalnızca Starlette ve Uvicorn'un kendilerinin altında yer aldığını gösteriyor (FastAPI bunları dahili olarak kullanır).
|
||||||
|
|
||||||
Fakat kıyaslamaları ve karşılaştırmaları incelerken şunları aklınızda bulundurmalısınız.
|
Fakat kıyaslamaları ve karşılaştırmaları incelerken şunları aklınızda bulundurmalısınız.
|
||||||
|
|
||||||
## Kıyaslamalar ve Hız
|
## Kıyaslamalar ve Hız { #benchmarks-and-speed }
|
||||||
|
|
||||||
Kıyaslamaları incelediğinizde, farklı özelliklere sahip araçların eşdeğer olarak karşılaştırıldığını yaygın bir şekilde görebilirsiniz.
|
Kıyaslamalara baktığınızda, farklı türlerdeki birkaç aracın eşdeğermiş gibi karşılaştırıldığını görmek yaygındır.
|
||||||
|
|
||||||
Özellikle, (diğer birçok araç arasında) Uvicorn, Starlette ve FastAPI'ın birlikte karşılaştırıldığını görebilirsiniz.
|
Özellikle, (diğer birçok araç arasında) Uvicorn, Starlette ve FastAPI'ın birlikte karşılaştırıldığını görebilirsiniz.
|
||||||
|
|
||||||
Aracın çözdüğü problem ne kadar basitse, performansı o kadar iyi olacaktır. Ancak kıyaslamaların çoğu, aracın sağladığı ek özellikleri test etmez.
|
Aracın çözdüğü problem ne kadar basitse, elde edeceği performans o kadar iyi olur. Ayrıca kıyaslamaların çoğu, aracın sağladığı ek özellikleri test etmez.
|
||||||
|
|
||||||
Hiyerarşi şöyledir:
|
Hiyerarşi şöyledir:
|
||||||
|
|
||||||
* **Uvicorn**: bir ASGI sunucusu
|
* **Uvicorn**: bir ASGI sunucusu
|
||||||
* **Starlette**: (Uvicorn'u kullanır) bir web mikroframeworkü
|
* **Starlette**: (Uvicorn'u kullanır) bir web mikroframework'ü
|
||||||
* **FastAPI**: (Starlette'i kullanır) veri doğrulama vb. çeşitli ek özelliklere sahip, API oluşturmak için kullanılan bir API mikroframeworkü
|
* **FastAPI**: (Starlette'i kullanır) veri doğrulama vb. ile API'lar oluşturmak için çeşitli ek özelliklere sahip bir API mikroframework'ü
|
||||||
|
|
||||||
* **Uvicorn**:
|
* **Uvicorn**:
|
||||||
* Sunucunun kendisi dışında ekstra bir kod içermediği için en iyi performansa sahip olacaktır.
|
* Sunucunun kendisi dışında çok fazla ekstra kod içermediği için en iyi performansa sahip olacaktır.
|
||||||
* Doğrudan Uvicorn ile bir uygulama yazmazsınız. Bu, yazdığınız kodun en azından Starlette tarafından sağlanan tüm kodu (veya **FastAPI**) az çok içermesi gerektiği anlamına gelir. Eğer bunu yaptıysanız, son uygulamanız bir framework kullanmak ve uygulama kodlarını ve hataları en aza indirmekle aynı ek yüke sahip olacaktır.
|
* Uvicorn ile doğrudan bir uygulama yazmazsınız. Bu, kodunuzun en azından Starlette'in (veya **FastAPI**'ın) sağladığı kodun aşağı yukarı tamamını içermesi gerektiği anlamına gelir. Bunu yaparsanız, nihai uygulamanız; bir framework kullanmış olmanın ve uygulama kodunu ve bug'ları en aza indirmenin getirdiği ek yükle aynı ek yüke sahip olur.
|
||||||
* Eğer Uvicorn'u karşılaştırıyorsanız, Daphne, Hypercorn, uWSGI, vb. uygulama sunucuları ile karşılaştırın.
|
* Uvicorn'u karşılaştırıyorsanız, Daphne, Hypercorn, uWSGI vb. application server'larla karşılaştırın.
|
||||||
* **Starlette**:
|
* **Starlette**:
|
||||||
* Uvicorn'dan sonraki en iyi performansa sahip olacaktır. İşin aslı, Starlette çalışmak için Uvicorn'u kullanıyor. Dolayısıyla, daha fazla kod çalıştırmaası gerektiğinden muhtemelen Uvicorn'dan sadece "daha yavaş" olabilir.
|
* Uvicorn'dan sonra en iyi performansa sahip olacaktır. Aslında Starlette çalışmak için Uvicorn'u kullanır. Bu yüzden muhtemelen yalnızca daha fazla kod çalıştırmak zorunda kaldığı için Uvicorn'dan "daha yavaş" olabilir.
|
||||||
* Ancak yol bazlı yönlendirme vb. basit web uygulamaları oluşturmak için araçlar sağlar.
|
* Ancak path tabanlı routing vb. ile basit web uygulamaları oluşturmanız için araçlar sağlar.
|
||||||
* Eğer Starlette'i karşılaştırıyorsanız, Sanic, Flask, Django, vb. frameworkler (veya mikroframeworkler) ile karşılaştırın.
|
* Starlette'i karşılaştırıyorsanız, Sanic, Flask, Django vb. web framework'lerle (veya mikroframework'lerle) karşılaştırın.
|
||||||
* **FastAPI**:
|
* **FastAPI**:
|
||||||
* Starlette'in Uvicorn'u kullandığı ve ondan daha hızlı olamayacağı gibi, **FastAPI**'da Starlette'i kullanır, dolayısıyla ondan daha hızlı olamaz.
|
* Starlette'in Uvicorn'u kullanıp ondan daha hızlı olamaması gibi, **FastAPI** da Starlette'i kullanır; dolayısıyla ondan daha hızlı olamaz.
|
||||||
* FastAPI, Starlette'e ek olarak daha fazla özellik sunar. Bunlar veri doğrulama ve <abbr title="Dönüşüm: serialization, parsing, marshalling olarak da biliniyor">dönüşümü</abbr> gibi API'lar oluştururken neredeyse ve her zaman ihtiyaç duyduğunuz özelliklerdir. Ve bunu kullanarak, ücretsiz olarak otomatik dokümantasyon elde edersiniz (otomatik dokümantasyon çalışan uygulamalara ek yük getirmez, başlangıçta oluşturulur).
|
* FastAPI, Starlette'in üzerine daha fazla özellik sağlar. API'lar oluştururken neredeyse her zaman ihtiyaç duyduğunuz veri doğrulama ve <abbr title="serialization - serileştirme">serialization</abbr> gibi özellikler. Ayrıca bunu kullanarak ücretsiz olarak otomatik dokümantasyon elde edersiniz (otomatik dokümantasyon, çalışan uygulamalara ek yük bile getirmez; startup'ta üretilir).
|
||||||
* FastAPI'ı kullanmadıysanız ve Starlette'i doğrudan kullandıysanız (veya başka bir araç, Sanic, Flask, Responder, vb.) tüm veri doğrulama ve dönüştürme araçlarını kendiniz geliştirmeniz gerekir. Dolayısıyla, son uygulamanız FastAPI kullanılarak oluşturulmuş gibi hâlâ aynı ek yüke sahip olacaktır. Çoğu durumda, uygulamalarda yazılan kodun büyük bir kısmını veri doğrulama ve dönüştürme kodları oluşturur.
|
* FastAPI'ı kullanmayıp Starlette'i doğrudan kullansaydınız (veya Sanic, Flask, Responder vb. başka bir aracı), tüm veri doğrulama ve serialization işlemlerini kendiniz uygulamak zorunda kalırdınız. Dolayısıyla nihai uygulamanız, FastAPI kullanılarak inşa edilmiş olsaydı sahip olacağı ek yükle hâlâ aynı ek yüke sahip olurdu. Ve çoğu durumda, uygulamalarda yazılan en büyük kod miktarı veri doğrulama ve serialization kısmıdır.
|
||||||
* Dolayısıyla, FastAPI'ı kullanarak geliştirme süresinden, hatalardan, kod satırlarından tasarruf edersiniz ve kullanmadığınız durumda (birçok özelliği geliştirmek zorunda kalmakla birlikte) muhtemelen aynı performansı (veya daha iyisini) elde ederdiniz.
|
* Bu nedenle FastAPI kullanarak geliştirme süresinden, bug'lardan, kod satırlarından tasarruf edersiniz; ayrıca muhtemelen, onu kullanmasaydınız (tüm bunları kodunuzda kendiniz uygulamak zorunda kalacağınız için) elde edeceğiniz performansın aynısını (veya daha iyisini) elde edersiniz.
|
||||||
* Eğer FastAPI'ı karşılaştırıyorsanız, Flask-apispec, NestJS, Molten, vb. gibi veri doğrulama, dönüştürme ve dokümantasyon sağlayan bir web uygulaması frameworkü ile (veya araç setiyle) karşılaştırın.
|
* FastAPI'ı karşılaştırıyorsanız, Flask-apispec, NestJS, Molten vb. veri doğrulama, serialization ve dokümantasyon sağlayan bir web uygulaması framework'ü (veya araç seti) ile karşılaştırın. Entegre otomatik veri doğrulama, serialization ve dokümantasyona sahip framework'ler.
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
# FastAPI Uygulamasını Bulut Sağlayıcılar Üzerinde Yayınlama
|
# Bulut Sağlayıcılar Üzerinde FastAPI Yayınlama { #deploy-fastapi-on-cloud-providers }
|
||||||
|
|
||||||
FastAPI uygulamasını yayınlamak için hemen hemen **herhangi bir bulut sağlayıcıyı** kullanabilirsiniz.
|
FastAPI uygulamanızı yayınlamak için neredeyse **herhangi bir bulut sağlayıcıyı** kullanabilirsiniz.
|
||||||
|
|
||||||
Büyük bulut sağlayıcıların çoğu FastAPI uygulamasını yayınlamak için kılavuzlara sahiptir.
|
Çoğu durumda, ana bulut sağlayıcıların FastAPI'yi onlarla birlikte yayınlamak için kılavuzları vardır.
|
||||||
|
|
||||||
## Bulut Sağlayıcılar - Sponsorlar
|
## FastAPI Cloud { #fastapi-cloud }
|
||||||
|
|
||||||
Bazı bulut sağlayıcılar ✨ [**FastAPI destekçileridir**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, bu FastAPI ve **ekosisteminin** sürekli ve sağlıklı bir şekilde **gelişmesini** sağlar.
|
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**, **FastAPI**'nin arkasındaki aynı yazar ve ekip tarafından geliştirilmiştir.
|
||||||
|
|
||||||
Ayrıca, size **iyi servisler** sağlamakla kalmayıp, **iyi ve sağlıklı bir framework** olan FastAPI'a bağlılıklarını gösterir.
|
Bir API'yi minimum çabayla **oluşturma**, **yayınlama** ve **erişme** sürecini kolaylaştırır.
|
||||||
|
|
||||||
Bu hizmetleri denemek ve kılavuzlarını incelemek isteyebilirsiniz.
|
FastAPI ile uygulama geliştirirken elde edilen aynı **geliştirici deneyimini**, onları buluta **yayınlamaya** da taşır. 🎉
|
||||||
|
|
||||||
|
FastAPI Cloud, *FastAPI and friends* açık kaynak projelerinin birincil sponsoru ve finansman sağlayıcısıdır. ✨
|
||||||
|
|
||||||
|
## Bulut Sağlayıcılar - Sponsorlar { #cloud-providers-sponsors }
|
||||||
|
|
||||||
|
Diğer bazı bulut sağlayıcılar da ✨ [**FastAPI'ye sponsor olur**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨. 🙇
|
||||||
|
|
||||||
|
Kılavuzlarını takip etmek ve servislerini denemek için onları da değerlendirmek isteyebilirsiniz:
|
||||||
|
|
||||||
|
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
|
||||||
|
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
# Deployment (Yayınlama)
|
# Deployment { #deployment }
|
||||||
|
|
||||||
**FastAPI** uygulamasını deploy etmek oldukça kolaydır.
|
**FastAPI** uygulamasını deploy etmek nispeten kolaydır.
|
||||||
|
|
||||||
## Deployment Ne Anlama Gelir?
|
## Deployment Ne Anlama Gelir? { #what-does-deployment-mean }
|
||||||
|
|
||||||
Bir uygulamayı **deploy** etmek (yayınlamak), uygulamayı **kullanıcılara erişilebilir hale getirmek** için gerekli adımları gerçekleştirmek anlamına gelir.
|
Bir uygulamayı **deploy** etmek, onu **kullanıcılara erişilebilir hale getirmek** için gerekli adımları gerçekleştirmek anlamına gelir.
|
||||||
|
|
||||||
Bir **Web API** için bu süreç normalde uygulamayı **uzak bir makineye** yerleştirmeyi, iyi performans, kararlılık vb. özellikler sağlayan bir **sunucu programı** ile **kullanıcılarınızın** uygulamaya etkili ve kesintisiz bir şekilde **erişebilmesini** kapsar.
|
Bir **web API** için bu süreç normalde uygulamayı **uzak bir makineye** yerleştirmeyi, iyi performans, kararlılık vb. özellikler sağlayan bir **sunucu programı** ile **kullanıcılarınızın** uygulamaya etkili ve kesintisiz bir şekilde, sorun yaşamadan **erişebilmesini** kapsar.
|
||||||
|
|
||||||
Bu, kodu sürekli olarak değiştirdiğiniz, hata alıp hata giderdiğiniz, geliştirme sunucusunu durdurup yeniden başlattığınız vb. **geliştirme** aşamalarının tam tersidir.
|
Bu, kodu sürekli olarak değiştirdiğiniz, bozup düzelttiğiniz, geliştirme sunucusunu durdurup yeniden başlattığınız vb. **geliştirme** aşamalarının tam tersidir.
|
||||||
|
|
||||||
## Deployment Stratejileri
|
## Deployment Stratejileri { #deployment-strategies }
|
||||||
|
|
||||||
Kullanım durumunuza ve kullandığınız araçlara bağlı olarak bir kaç farklı yol izleyebilirsiniz.
|
Kullanım durumunuza ve kullandığınız araçlara bağlı olarak bunu yapmanın birkaç yolu vardır.
|
||||||
|
|
||||||
Bir dizi araç kombinasyonunu kullanarak kendiniz **bir sunucu yayınlayabilirsiniz**, yayınlama sürecinin bir kısmını sizin için gerçekleştiren bir **bulut hizmeti** veya diğer olası seçenekleri kullanabilirsiniz.
|
Bir dizi araç kombinasyonunu kullanarak kendiniz **bir sunucu deploy edebilirsiniz**, yayınlama sürecinin bir kısmını sizin için gerçekleştiren bir **bulut hizmeti** veya diğer olası seçenekleri kullanabilirsiniz.
|
||||||
|
|
||||||
|
Örneğin, FastAPI'nin arkasındaki ekip olarak, FastAPI uygulamalarını buluta mümkün olduğunca akıcı şekilde deploy etmeyi sağlamak için, FastAPI ile çalışmanın aynı geliştirici deneyimini sunarak <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>'u oluşturduk.
|
||||||
|
|
||||||
**FastAPI** uygulamasını yayınlarken aklınızda bulundurmanız gereken ana kavramlardan bazılarını size göstereceğim (ancak bunların çoğu diğer web uygulamaları için de geçerlidir).
|
**FastAPI** uygulamasını yayınlarken aklınızda bulundurmanız gereken ana kavramlardan bazılarını size göstereceğim (ancak bunların çoğu diğer web uygulamaları için de geçerlidir).
|
||||||
|
|
||||||
Sonraki bölümlerde akılda tutulması gereken diğer ayrıntıları ve yayınlama tekniklerinden bazılarını göreceksiniz. ✨
|
Sonraki bölümlerde akılda tutulması gereken diğer ayrıntıları ve bunu yapmaya yönelik bazı teknikleri göreceksiniz. ✨
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
# Genel - Nasıl Yapılır - Tarifler
|
# Genel - Nasıl Yapılır - Tarifler { #general-how-to-recipes }
|
||||||
|
|
||||||
Bu sayfada genel ve sıkça sorulan sorular için dokümantasyonun diğer sayfalarına yönlendirmeler bulunmaktadır.
|
Bu sayfada genel veya sık sorulan sorular için dokümantasyonun diğer bölümlerine çeşitli yönlendirmeler bulunmaktadır.
|
||||||
|
|
||||||
## Veri Filtreleme - Güvenlik
|
## Veri Filtreleme - Güvenlik { #filter-data-security }
|
||||||
|
|
||||||
Döndürmeniz gereken veriden fazlasını döndürmediğinizden emin olmak için, [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank} sayfasını okuyun.
|
Döndürmeniz gerekenden daha fazla veri döndürmediğinizden emin olmak için, [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## Dokümantasyon Etiketleri - OpenAPI
|
## Dokümantasyon Etiketleri - OpenAPI { #documentation-tags-openapi }
|
||||||
|
|
||||||
*Yol operasyonlarınıza* etiketler ekleyerek dokümantasyon arayüzünde gruplar halinde görünmesini sağlamak için, [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank} sayfasını okuyun.
|
*path operation*'larınıza etiketler eklemek ve dokümantasyon arayüzünde gruplamak için, [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## Dokümantasyon Özeti ve Açıklaması - OpenAPI
|
## Dokümantasyon Özeti ve Açıklaması - OpenAPI { #documentation-summary-and-description-openapi }
|
||||||
|
|
||||||
*Yol operasyonlarınıza* özet ve açıklama ekleyip dokümantasyon arayüzünde görünmesini sağlamak için, [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank} sayfasını okuyun.
|
*path operation*'larınıza özet ve açıklama eklemek ve bunları dokümantasyon arayüzünde göstermek için, [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## Yanıt Açıklaması Dokümantasyonu - OpenAPI
|
## Dokümantasyon Yanıt Açıklaması - OpenAPI { #documentation-response-description-openapi }
|
||||||
|
|
||||||
Dokümantasyon arayüzünde yer alan yanıt açıklamasını tanımlamak için, [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank} sayfasını okuyun.
|
Dokümantasyon arayüzünde gösterilen response açıklamasını tanımlamak için, [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## *Yol Operasyonunu* Kullanımdan Kaldırma - OpenAPI
|
## Dokümantasyonda Bir *Path Operation*'ı Kullanımdan Kaldırma - OpenAPI { #documentation-deprecate-a-path-operation-openapi }
|
||||||
|
|
||||||
Bir *yol işlemi*ni kullanımdan kaldırmak ve bunu dokümantasyon arayüzünde göstermek için, [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank} sayfasını okuyun.
|
Bir *path operation*'ı kullanımdan kaldırmak ve bunu dokümantasyon arayüzünde göstermek için, [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## Herhangi Bir Veriyi JSON Uyumlu Hale Getirme
|
## Herhangi Bir Veriyi JSON Uyumlu Hale Getirme { #convert-any-data-to-json-compatible }
|
||||||
|
|
||||||
Herhangi bir veriyi JSON uyumlu hale getirmek için, [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} sayfasını okuyun.
|
Herhangi bir veriyi JSON uyumlu hale getirmek için, [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## OpenAPI Meta Verileri - Dokümantasyon
|
## OpenAPI Meta Verileri - Dokümantasyon { #openapi-metadata-docs }
|
||||||
|
|
||||||
OpenAPI şemanıza lisans, sürüm, iletişim vb. meta veriler eklemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank} sayfasını okuyun.
|
Lisans, sürüm, iletişim vb. dahil olmak üzere OpenAPI şemanıza meta veriler eklemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## OpenAPI Bağlantı Özelleştirme
|
## OpenAPI Özel URL { #openapi-custom-url }
|
||||||
|
|
||||||
OpenAPI bağlantısını özelleştirmek (veya kaldırmak) için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank} sayfasını okuyun.
|
OpenAPI URL'ini özelleştirmek (veya kaldırmak) için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|
||||||
## OpenAPI Dokümantasyon Bağlantıları
|
## OpenAPI Dokümantasyon URL'leri { #openapi-docs-urls }
|
||||||
|
|
||||||
Dokümantasyonu arayüzünde kullanılan bağlantıları güncellemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank} sayfasını okuyun.
|
Otomatik olarak oluşturulan dokümantasyon kullanıcı arayüzlerinde kullanılan URL'leri güncellemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank} dokümantasyonunu okuyun.
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# Nasıl Yapılır - Tarifler
|
# Nasıl Yapılır - Tarifler { #how-to-recipes }
|
||||||
|
|
||||||
Burada çeşitli konular hakkında farklı tarifler veya "nasıl yapılır" kılavuzları yer alıyor.
|
Burada **çeşitli konular** hakkında farklı tarifler veya "nasıl yapılır" kılavuzları göreceksiniz.
|
||||||
|
|
||||||
Bu fikirlerin büyük bir kısmı aşağı yukarı **bağımsız** olacaktır, çoğu durumda bunları sadece **projenize** hitap ediyorsa incelemelisiniz.
|
Bu fikirlerin büyük bir kısmı aşağı yukarı **bağımsız** olacaktır ve çoğu durumda bunları yalnızca doğrudan **projenize** uygulanıyorsa incelemeniz yeterli olacaktır.
|
||||||
|
|
||||||
Projeniz için ilginç ve yararlı görünen bir şey varsa devam edin ve inceleyin, aksi halde bunları atlayabilirsiniz.
|
Projeniz için ilginç ve yararlı görünen bir şey varsa devam edin ve inceleyin; aksi halde muhtemelen bunları atlayabilirsiniz.
|
||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
**FastAPI**'ı düzgün (ve önerilen) şekilde öğrenmek istiyorsanız [Öğretici - Kullanıcı Rehberi](../tutorial/index.md){.internal-link target=_blank}'ni bölüm bölüm okuyun.
|
**FastAPI**'ı yapılandırılmış bir şekilde (önerilir) **öğrenmek** istiyorsanız bunun yerine [Öğretici - Kullanıcı Rehberi](../tutorial/index.md){.internal-link target=_blank}'ni bölüm bölüm okuyun.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# FastAPI
|
# FastAPI { #fastapi }
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.md-content .md-typeset h1 { display: none; }
|
.md-content .md-typeset h1 { display: none; }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
<a href="https://fastapi.tiangolo.com/tr"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<em>FastAPI framework, yüksek performanslı, öğrenmesi oldukça kolay, kodlaması hızlı, kullanıma hazır</em>
|
<em>FastAPI framework, yüksek performanslı, öğrenmesi kolay, kodlaması hızlı, production'a hazır</em>
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||||
@@ -27,59 +27,65 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Dokümantasyon**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
**Dokümantasyon**: <a href="https://fastapi.tiangolo.com/tr" target="_blank">https://fastapi.tiangolo.com</a>
|
||||||
|
|
||||||
**Kaynak Kod**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
|
**Kaynak Kod**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
FastAPI, Python 'nin standart <abbr title="Tip Belirteçleri: Type Hints">tip belirteçleri</abbr>ne dayalı, modern ve hızlı (yüksek performanslı) API'lar oluşturmak için kullanılabilecek web framework'tür.
|
FastAPI, Python'un standart type hints'lerine dayalı olarak Python ile API'lar oluşturmak için kullanılan modern ve hızlı (yüksek performanslı) bir web framework'üdür.
|
||||||
|
|
||||||
Temel özellikleri şunlardır:
|
Temel özellikleri şunlardır:
|
||||||
|
|
||||||
* **Hızlı**: Çok yüksek performanslı, **NodeJS** ve **Go** ile eşit düzeyde (Starlette ve Pydantic sayesinde). [En hızlı Python framework'lerinden bir tanesidir](#performans).
|
* **Hızlı**: Çok yüksek performanslı, **NodeJS** ve **Go** ile eşit düzeyde (Starlette ve Pydantic sayesinde). [Mevcut en hızlı Python framework'lerinden biri](#performance).
|
||||||
* **Kodlaması Hızlı**: Geliştirme hızını yaklaşık %200 ile %300 aralığında arttırır. *
|
* **Kodlaması Hızlı**: Özellik geliştirme hızını yaklaşık %200 ile %300 aralığında artırır. *
|
||||||
* **Daha az hata**: İnsan (geliştirici) kaynaklı hataları yaklaşık %40 azaltır. *
|
* **Daha az hata**: İnsan (geliştirici) kaynaklı hataları yaklaşık %40 azaltır. *
|
||||||
* **Sezgisel**: Muhteşem bir editör desteği. Her yerde <abbr title="Otomatik Tamamlama: auto-complete, autocompletion, IntelliSense">otomatik tamamlama</abbr>. Hata ayıklama ile daha az zaman harcayacaksınız.
|
* **Sezgisel**: Harika bir editör desteği. Her yerde <abbr title="auto-complete, autocompletion, IntelliSense olarak da bilinir">Completion</abbr>. Hata ayıklamaya daha az zaman.
|
||||||
* **Kolay**: Öğrenmesi ve kullanması kolay olacak şekilde tasarlandı. Doküman okuma ile daha az zaman harcayacaksınız.
|
* **Kolay**: Kullanımı ve öğrenmesi kolay olacak şekilde tasarlandı. Doküman okumaya daha az zaman.
|
||||||
* **Kısa**: Kod tekrarı minimize edildi. Her parametre tanımlamasında birden fazla özellik ve daha az hatayla karşılaşacaksınız.
|
* **Kısa**: Kod tekrarını minimize eder. Her parametre tanımından birden fazla özellik. Daha az hata.
|
||||||
* **Güçlü**: Otomatik ve etkileşimli dokümantasyon ile birlikte, kullanıma hazır kod elde edebilirsiniz.
|
* **Sağlam**: Production'a hazır kod elde edersiniz. Otomatik etkileşimli dokümantasyon ile birlikte.
|
||||||
* **Standard öncelikli**: API'lar için açık standartlara dayalı (ve tamamen uyumlu); <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (eski adıyla Swagger) ve <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
* **Standardlara dayalı**: API'lar için açık standartlara dayalıdır (ve tamamen uyumludur); <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (önceden Swagger olarak biliniyordu) ve <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||||
|
|
||||||
<small>* ilgili kanılar, dahili geliştirme ekibinin geliştirdikleri ürünlere yaptıkları testlere dayanmaktadır.</small>
|
<small>* tahmin, production uygulamalar geliştiren dahili bir geliştirme ekibinin yaptığı testlere dayanmaktadır.</small>
|
||||||
|
|
||||||
## Sponsorlar
|
## Sponsorlar { #sponsors }
|
||||||
|
|
||||||
<!-- sponsors -->
|
<!-- sponsors -->
|
||||||
|
|
||||||
{% if sponsors %}
|
### Keystone Sponsor { #keystone-sponsor }
|
||||||
|
|
||||||
|
{% for sponsor in sponsors.keystone -%}
|
||||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
|
{% endfor -%}
|
||||||
|
|
||||||
|
### Gold and Silver Sponsors { #gold-and-silver-sponsors }
|
||||||
|
|
||||||
{% for sponsor in sponsors.gold -%}
|
{% for sponsor in sponsors.gold -%}
|
||||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
{%- for sponsor in sponsors.silver -%}
|
{%- for sponsor in sponsors.silver -%}
|
||||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- /sponsors -->
|
<!-- /sponsors -->
|
||||||
|
|
||||||
<a href="https://fastapi.tiangolo.com/tr/fastapi-people/#sponsors" class="external-link" target="_blank">Diğer Sponsorlar</a>
|
<a href="https://fastapi.tiangolo.com/tr/fastapi-people/#sponsors" class="external-link" target="_blank">Diğer sponsorlar</a>
|
||||||
|
|
||||||
## Görüşler
|
## Görüşler { #opinions }
|
||||||
|
|
||||||
"_[...] Bugünlerde **FastAPI**'ı çok fazla kullanıyorum. [...] Aslında bunu ekibimin **Microsoft'taki Machine Learning servislerinin** tamamında kullanmayı planlıyorum. Bunlardan bazıları **Windows**'un ana ürünlerine ve **Office** ürünlerine entegre ediliyor._"
|
"_[...] Bugünlerde **FastAPI**'ı çok fazla kullanıyorum. [...] Aslında bunu ekibimin **Microsoft'taki ML servislerinin** tamamında kullanmayı planlıyorum. Bunlardan bazıları ana **Windows** ürününe ve bazı **Office** ürünlerine entegre ediliyor._"
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_**FastAPI**'ı **tahminlerimiz**'i sorgulanabilir hale getirecek bir **REST** sunucu oluşturmak için benimsedik/kullanmaya başladık._"
|
"_**predictions** almak için sorgulanabilecek bir **REST** server oluşturmak amacıyla **FastAPI** kütüphanesini benimsedik. [Ludwig için]_"
|
||||||
|
|
||||||
<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>
|
<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**, **kriz yönetiminde** orkestrasyon yapabilmek için geliştirdiği yeni framework'ü **Dispatch**'in, açık kaynak sürümünü paylaşmaktan gurur duyuyor. [**FastAPI** ile yapıldı.]_"
|
"_**Netflix**, **kriz yönetimi** orkestrasyon framework'ümüz: **Dispatch**'in open-source sürümünü duyurmaktan memnuniyet duyar! [**FastAPI** ile geliştirildi]_"
|
||||||
|
|
||||||
<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>
|
<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>
|
||||||
|
|
||||||
@@ -91,70 +97,68 @@ Temel özellikleri şunlardır:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Dürüst olmak gerekirse, inşa ettiğiniz şey gerçekten sağlam ve profesyonel görünüyor. Birçok açıdan **Hug**'ın olmasını istediğim şey tam da bu - böyle bir şeyi inşa eden birini görmek gerçekten ilham verici._"
|
"_Dürüst olmak gerekirse, inşa ettiğiniz şey gerçekten sağlam ve profesyonel görünüyor. Birçok açıdan, **Hug**'ın olmasını istediğim şey tam da bu - böyle bir şeyi inşa eden birini görmek gerçekten ilham verici._"
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="http://www.hug.rest/" target="_blank">Hug</a>'ın Yaratıcısı</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> yaratıcısı</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Eğer REST API geliştirmek için **modern bir framework** öğrenme arayışında isen, **FastAPI**'a bir göz at [...] Hızlı, kullanımı ve öğrenmesi kolay. [...]_"
|
"_REST API'lar geliştirmek için **modern bir framework** öğrenmek istiyorsanız, **FastAPI**'a bir göz atın [...] Hızlı, kullanımı ve öğrenmesi kolay [...]_"
|
||||||
|
|
||||||
"_**API** servislerimizi **FastAPI**'a taşıdık [...] Sizin de beğeneceğinizi düşünüyoruz. [...]_"
|
"_**API**'larımız için **FastAPI**'a geçtik [...] Bence hoşunuza gidecek [...]_"
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> kurucuları - <a href="https://spacy.io" target="_blank">spaCy</a> yaratıcıları</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> kurucuları - <a href="https://spacy.io" target="_blank">spaCy</a> yaratıcıları</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
"_Python ile kullanıma hazır bir API oluşturmak isteyen herhangi biri için, **FastAPI**'ı şiddetle tavsiye ederim. **Harika tasarlanmış**, **kullanımı kolay** ve **yüksek ölçeklenebilir**, API odaklı geliştirme stratejimizin **ana bileşeni** haline geldi ve Virtual TAC Engineer gibi birçok otomasyon ve servisi yönetiyor._"
|
"_Production'da Python API geliştirmek isteyen herkese **FastAPI**'ı şiddetle tavsiye ederim. **Harika tasarlanmış**, **kullanımı kolay** ve **yüksek ölçeklenebilir**; API-first geliştirme stratejimizin **kilit bir bileşeni** haline geldi ve Virtual TAC Engineer gibi birçok otomasyon ve servise güç veriyor._"
|
||||||
|
|
||||||
<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>
|
<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>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Komut Satırı Uygulamalarının FastAPI'ı: **Typer**
|
## FastAPI mini belgeseli { #fastapi-mini-documentary }
|
||||||
|
|
||||||
|
2025'in sonunda yayınlanan bir <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI mini belgeseli</a> var, online olarak izleyebilirsiniz:
|
||||||
|
|
||||||
|
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
||||||
|
|
||||||
|
## CLI'ların FastAPI'ı: **Typer** { #typer-the-fastapi-of-clis }
|
||||||
|
|
||||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
<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>
|
||||||
|
|
||||||
Eğer API yerine, terminalde kullanılmak üzere bir <abbr title="Komut Satırı: Command Line Interface">komut satırı uygulaması</abbr> geliştiriyorsanız <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>'a göz atabilirsiniz.
|
Web API yerine terminalde kullanılacak bir <abbr title="Command Line Interface">CLI</abbr> uygulaması geliştiriyorsanız <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>'a göz atın.
|
||||||
|
|
||||||
**Typer** kısaca FastAPI'ın küçük kardeşi. Ve hedefi komut satırı uygulamalarının **FastAPI'ı** olmak. ⌨️ 🚀
|
**Typer**, FastAPI'ın küçük kardeşi. Ve hedefi CLI'ların **FastAPI'ı** olmak. ⌨️ 🚀
|
||||||
|
|
||||||
## Gereksinimler
|
## Gereksinimler { #requirements }
|
||||||
|
|
||||||
FastAPI iki devin omuzları üstünde duruyor:
|
FastAPI iki devin omuzları üstünde duruyor:
|
||||||
|
|
||||||
* Web tarafı için <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>.
|
* Web kısımları için <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>.
|
||||||
* Data tarafı için <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>.
|
* Data kısımları için <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>.
|
||||||
|
|
||||||
## Kurulum
|
## Kurulum { #installation }
|
||||||
|
|
||||||
|
Bir <a href="https://fastapi.tiangolo.com/tr/virtual-environments/" class="external-link" target="_blank">virtual environment</a> oluşturup etkinleştirelim ve ardından FastAPI'ı yükleyelim:
|
||||||
|
|
||||||
<div class="termy">
|
<div class="termy">
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ pip install fastapi
|
$ pip install "fastapi[standard]"
|
||||||
|
|
||||||
---> 100%
|
---> 100%
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Uygulamamızı kullanılabilir hale getirmek için <a href="http://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> ya da <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a> gibi bir ASGI sunucusuna ihtiyacımız olacak.
|
**Not**: Tüm terminallerde çalıştığından emin olmak için `"fastapi[standard]"` ifadesini tırnak içinde yazdığınızdan emin olun.
|
||||||
|
|
||||||
<div class="termy">
|
## Örnek { #example }
|
||||||
|
|
||||||
```console
|
### Oluşturalım { #create-it }
|
||||||
$ pip install "uvicorn[standard]"
|
|
||||||
|
|
||||||
---> 100%
|
Şu içerikle `main.py` adında bir dosya oluşturalım:
|
||||||
```
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Örnek
|
|
||||||
|
|
||||||
### Kodu Oluşturalım
|
|
||||||
|
|
||||||
* `main.py` adında bir dosya oluşturup içine şu kodu yapıştıralım:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@@ -175,9 +179,9 @@ def read_item(item_id: int, q: Union[str, None] = None):
|
|||||||
```
|
```
|
||||||
|
|
||||||
<details markdown="1">
|
<details markdown="1">
|
||||||
<summary>Ya da <code>async def</code>...</summary>
|
<summary>Ya da <code>async def</code> kullanalım...</summary>
|
||||||
|
|
||||||
Eğer kodunuzda `async` / `await` varsa, `async def` kullanalım:
|
Eğer kodunuz `async` / `await` kullanıyorsa, `async def` kullanın:
|
||||||
|
|
||||||
```Python hl_lines="9 14"
|
```Python hl_lines="9 14"
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@@ -199,22 +203,35 @@ async def read_item(item_id: int, q: Union[str, None] = None):
|
|||||||
|
|
||||||
**Not**:
|
**Not**:
|
||||||
|
|
||||||
Eğer bu konu hakkında bilginiz yoksa <a href="https://fastapi.tiangolo.com/tr/async/#in-a-hurry" target="_blank">`async` ve `await`</a> dokümantasyonundaki _"Aceleniz mi var?"_ kısmını kontrol edebilirsiniz.
|
Eğer bilmiyorsanız, dokümanlardaki <a href="https://fastapi.tiangolo.com/tr/async/#in-a-hurry" target="_blank">`async` ve `await`</a> hakkında _"Aceleniz mi var?"_ bölümüne bakın.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Kodu Çalıştıralım
|
### Çalıştıralım { #run-it }
|
||||||
|
|
||||||
Sunucuyu aşağıdaki komutla çalıştıralım:
|
Sunucuyu şu komutla çalıştıralım:
|
||||||
|
|
||||||
<div class="termy">
|
<div class="termy">
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ uvicorn main:app --reload
|
$ fastapi dev main.py
|
||||||
|
|
||||||
|
╭────────── FastAPI CLI - Development mode ───────────╮
|
||||||
|
│ │
|
||||||
|
│ Serving at: http://127.0.0.1:8000 │
|
||||||
|
│ │
|
||||||
|
│ API docs: http://127.0.0.1:8000/docs │
|
||||||
|
│ │
|
||||||
|
│ Running in development mode, for production use: │
|
||||||
|
│ │
|
||||||
|
│ fastapi run │
|
||||||
|
│ │
|
||||||
|
╰─────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
|
||||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||||
INFO: Started reloader process [28720]
|
INFO: Started reloader process [2248755] using WatchFiles
|
||||||
INFO: Started server process [28722]
|
INFO: Started server process [2248757]
|
||||||
INFO: Waiting for application startup.
|
INFO: Waiting for application startup.
|
||||||
INFO: Application startup complete.
|
INFO: Application startup complete.
|
||||||
```
|
```
|
||||||
@@ -222,54 +239,54 @@ INFO: Application startup complete.
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<details markdown="1">
|
<details markdown="1">
|
||||||
<summary><code>uvicorn main:app --reload</code> komutuyla ilgili...</summary>
|
<summary><code>fastapi dev main.py</code> komutu hakkında...</summary>
|
||||||
|
|
||||||
`uvicorn main:app` komutunu şu şekilde açıklayabiliriz:
|
`fastapi dev` komutu, `main.py` dosyanızı okur, içindeki **FastAPI** uygulamasını algılar ve <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> kullanarak bir server başlatır.
|
||||||
|
|
||||||
* `main`: dosya olan `main.py` (yani Python "modülü").
|
Varsayılan olarak `fastapi dev`, local geliştirme için auto-reload etkin şekilde başlar.
|
||||||
* `app`: ise `main.py` dosyasının içerisinde `app = FastAPI()` satırında oluşturduğumuz `FastAPI` nesnesi.
|
|
||||||
* `--reload`: kod değişikliklerinin ardından sunucuyu otomatik olarak yeniden başlatır. Bu parameteyi sadece geliştirme aşamasında kullanmalıyız.
|
Daha fazla bilgi için <a href="https://fastapi.tiangolo.com/tr/fastapi-cli/" target="_blank">FastAPI CLI dokümantasyonu</a>'nu okuyabilirsiniz.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Şimdi de Kontrol Edelim
|
### Kontrol Edelim { #check-it }
|
||||||
|
|
||||||
Tarayıcımızda şu bağlantıyı açalım <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>.
|
Tarayıcınızda şu bağlantıyı açın: <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ğıdaki gibi bir JSON yanıtıyla karşılaşacağız:
|
Şu JSON response'unu göreceksiniz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{"item_id": 5, "q": "somequery"}
|
{"item_id": 5, "q": "somequery"}
|
||||||
```
|
```
|
||||||
|
|
||||||
Az önce oluşturduğumuz API:
|
Artık şunları yapan bir API oluşturdunuz:
|
||||||
|
|
||||||
* `/` ve `/items/{item_id}` <abbr title="Adres / Yol: Path ">_yollarına_</abbr> HTTP isteği alabilir.
|
* `/` ve `/items/{item_id}` _path_'lerinde HTTP request'leri alır.
|
||||||
* İki _yolda_ `GET` <em>operasyonlarını</em> (HTTP _metodları_ olarak da bilinen) kabul ediyor.
|
* Her iki _path_ de `GET` <em>operasyonlarını</em> (HTTP _method_'ları olarak da bilinir) kabul eder.
|
||||||
* `/items/{item_id}` _yolu_ `item_id` adında bir _yol parametresine_ sahip ve bu parametre `int` değer almak zorundadır.
|
* `/items/{item_id}` _path_'i, `int` olması gereken `item_id` adlı bir _path parameter_'a sahiptir.
|
||||||
* `/items/{item_id}` _yolu_ `q` adında bir _yol parametresine_ sahip ve bu parametre opsiyonel olmakla birlikte, `str` değer almak zorundadır.
|
* `/items/{item_id}` _path_'i, opsiyonel `str` bir _query parameter_ olan `q`'ya sahiptir.
|
||||||
|
|
||||||
### Etkileşimli API Dokümantasyonu
|
### Etkileşimli API dokümantasyonu { #interactive-api-docs }
|
||||||
|
|
||||||
Şimdi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> bağlantısını açalım.
|
Şimdi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> adresine gidin.
|
||||||
|
|
||||||
<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tarafından sağlanan otomatik etkileşimli bir API dokümantasyonu göreceğiz:
|
Otomatik etkileşimli API dokümantasyonunu göreceksiniz (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tarafından sağlanır):
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Alternatif API Dokümantasyonu
|
### Alternatif API dokümantasyonu { #alternative-api-docs }
|
||||||
|
|
||||||
Şimdi <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> bağlantısını açalım.
|
Ve şimdi <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> adresine gidin.
|
||||||
|
|
||||||
<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tarafından sağlanan otomatik dokümantasyonu göreceğiz:
|
Alternatif otomatik dokümantasyonu göreceksiniz (<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tarafından sağlanır):
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Örneği Güncelleyelim
|
## Örneği Güncelleyelim { #example-upgrade }
|
||||||
|
|
||||||
Şimdi `main.py` dosyasını, `PUT` isteğiyle birlikte bir gövde alacak şekilde değiştirelim.
|
Şimdi `main.py` dosyasını, `PUT` request'iyle gelen bir body alacak şekilde değiştirelim.
|
||||||
|
|
||||||
<abbr title="Gövde: Body">Gövde</abbr>yi Pydantic sayesinde standart python tiplerini kullanarak tanımlayalım.
|
Body'yi Pydantic sayesinde standart Python tiplerini kullanarak tanımlayalım.
|
||||||
|
|
||||||
```Python hl_lines="4 9-12 25-27"
|
```Python hl_lines="4 9-12 25-27"
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@@ -301,174 +318,248 @@ def update_item(item_id: int, item: Item):
|
|||||||
return {"item_name": item.name, "item_id": item_id}
|
return {"item_name": item.name, "item_id": item_id}
|
||||||
```
|
```
|
||||||
|
|
||||||
Sunucu otomatik olarak yeniden başlamış olmalı (çünkü yukarıda `uvicorn` komutuyla birlikte `--reload` parametresini kullandık).
|
`fastapi dev` server'ı otomatik olarak yeniden yüklemelidir.
|
||||||
|
|
||||||
### Etkileşimli API Dokümantasyonundaki Değişimi Görelim
|
### Etkileşimli API dokümantasyonu güncellemesi { #interactive-api-docs-upgrade }
|
||||||
|
|
||||||
Şimdi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> bağlantısına tekrar gidelim.
|
Şimdi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> adresine gidin.
|
||||||
|
|
||||||
* Etkileşimli API dokümantasyonu, yeni gövdede dahil olmak üzere otomatik olarak güncellenmiş olacak:
|
* Etkileşimli API dokümantasyonu, yeni body dahil olacak şekilde otomatik olarak güncellenecek:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
* "Try it out" butonuna tıklayalım, bu işlem API parametleri üzerinde değişiklik yapmamıza ve doğrudan API ile etkileşime geçmemize imkan sağlayacak:
|
* "Try it out" butonuna tıklayın; parametreleri doldurmanıza ve API ile doğrudan etkileşime girmenize olanak sağlar:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
* Şimdi "Execute" butonuna tıklayalım, kullanıcı arayüzü API'ımız ile bağlantı kurup parametreleri gönderecek ve sonucu ekranımıza getirecek:
|
* Sonra "Execute" butonuna tıklayın; kullanıcı arayüzü API'nız ile iletişim kuracak, parametreleri gönderecek, sonuçları alacak ve ekranda gösterecek:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Alternatif API Dokümantasyonundaki Değişimi Görelim
|
### Alternatif API dokümantasyonu güncellemesi { #alternative-api-docs-upgrade }
|
||||||
|
|
||||||
Şimdi ise <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> bağlantısına tekrar gidelim.
|
Ve şimdi <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> adresine gidin.
|
||||||
|
|
||||||
* Alternatif dokümantasyonda yaptığımız değişiklikler ile birlikte yeni sorgu parametresi ve gövde bilgisi ile güncelemiş olacak:
|
* Alternatif dokümantasyon da yeni query parameter ve body'yi yansıtacak:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Özet
|
### Özet { #recap }
|
||||||
|
|
||||||
Özetlemek gerekirse, parametrelerin, gövdenin, vb. veri tiplerini fonksiyon parametreleri olarak **bir kere** tanımlıyoruz.
|
Özetle, parametrelerin, body'nin vb. type'larını fonksiyon parametreleri olarak **bir kere** tanımlarsınız.
|
||||||
|
|
||||||
Bu işlemi standart modern Python tipleriyle yapıyoruz.
|
Bunu standart modern Python tipleriyle yaparsınız.
|
||||||
|
|
||||||
Yeni bir sözdizimi yapısını, bir kütüphane özel metod veya sınıfları öğrenmeye gerek yoktur.
|
Yeni bir syntax, belirli bir kütüphanenin method'larını ya da class'larını vb. öğrenmeniz gerekmez.
|
||||||
|
|
||||||
Hepsi sadece **Python** standartlarına dayalıdır.
|
Sadece standart **Python**.
|
||||||
|
|
||||||
Örnek olarak, `int` tanımlamak için:
|
Örneğin bir `int` için:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
item_id: int
|
item_id: int
|
||||||
```
|
```
|
||||||
|
|
||||||
ya da daha kompleks herhangi bir python modelini tanımlayabiliriz, örneğin `Item` modeli için:
|
ya da daha karmaşık bir `Item` modeli için:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
item: Item
|
item: Item
|
||||||
```
|
```
|
||||||
|
|
||||||
...ve sadece kısa bir parametre tipi belirterek elde ettiklerimiz:
|
...ve bu tek tanımla şunları elde edersiniz:
|
||||||
|
|
||||||
* Editör desteğiyle birlikte:
|
* Şunlar dahil editör desteği:
|
||||||
* Otomatik tamamlama.
|
* Completion.
|
||||||
* Tip kontrolü.
|
* Type kontrolleri.
|
||||||
* Veri Doğrulama:
|
* Verinin doğrulanması:
|
||||||
* Veri geçerli değilse, otomatik olarak açıklayıcı hatalar gösterir.
|
* Veri geçersiz olduğunda otomatik ve anlaşılır hatalar.
|
||||||
* Çok <abbr title="Derin / İç içe: Nested">derin</abbr> JSON nesnelerinde bile doğrulama yapar.
|
* Çok derin iç içe JSON nesneleri için bile doğrulama.
|
||||||
* Gelen verinin <abbr title="Dönüşüm: serialization, parsing, marshalling olarak da biliniyor">dönüşümünü</abbr> aşağıdaki veri tiplerini kullanarak gerçekleştirir:
|
* Girdi verisinin <abbr title="serialization, parsing, marshalling olarak da bilinir">Dönüşümü</abbr>: network'ten gelen veriyi Python verisine ve type'larına çevirir. Şunlardan okur:
|
||||||
* JSON.
|
* JSON.
|
||||||
* Yol parametreleri.
|
* Path parameter'lar.
|
||||||
* Sorgu parametreleri.
|
* Query parameter'lar.
|
||||||
* Çerezler.
|
* Cookie'ler.
|
||||||
* Headers.
|
* Header'lar.
|
||||||
* Formlar.
|
* Form'lar.
|
||||||
* Dosyalar.
|
* File'lar.
|
||||||
* Giden verinin <abbr title="Dönüşüm: serialization, parsing, marshalling olarak da biliniyor">dönüşümünü</abbr> aşağıdaki veri tiplerini kullanarak gerçekleştirir (JSON olarak):
|
* Çıktı verisinin <abbr title="serialization, parsing, marshalling olarak da bilinir">Dönüşümü</abbr>: Python verisini ve type'larını network verisine çevirir (JSON olarak):
|
||||||
* Python tiplerinin (`str`, `int`, `float`, `bool`, `list`, vb) dönüşümü.
|
* Python type'larını dönüştürür (`str`, `int`, `float`, `bool`, `list`, vb.).
|
||||||
* `datetime` nesnesi.
|
* `datetime` nesneleri.
|
||||||
* `UUID` nesnesi.
|
* `UUID` nesneleri.
|
||||||
* Veritabanı modelleri.
|
* Veritabanı modelleri.
|
||||||
* ve çok daha fazlası...
|
* ...ve daha fazlası.
|
||||||
* 2 alternatif kullanıcı arayüzü dahil olmak üzere, otomatik etkileşimli API dokümantasyonu sağlar:
|
* 2 alternatif kullanıcı arayüzü dahil otomatik etkileşimli API dokümantasyonu:
|
||||||
* Swagger UI.
|
* Swagger UI.
|
||||||
* ReDoc.
|
* ReDoc.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Az önceki örneğe geri dönelim, **FastAPI**'ın yapacaklarına bir bakış atalım:
|
Önceki kod örneğine dönersek, **FastAPI** şunları yapacaktır:
|
||||||
|
|
||||||
* `item_id`'nin `GET` ve `PUT` istekleri için, yolda olup olmadığının kontol edecek.
|
* `GET` ve `PUT` request'leri için path'te `item_id` olduğunu doğrular.
|
||||||
* `item_id`'nin `GET` ve `PUT` istekleri için, tipinin `int` olduğunu doğrulayacak.
|
* `GET` ve `PUT` request'leri için `item_id`'nin type'ının `int` olduğunu doğrular.
|
||||||
* Eğer değilse, sebebini belirten bir hata mesajı gösterecek.
|
* Değilse, client faydalı ve anlaşılır bir hata görür.
|
||||||
* Opsiyonel bir `q` parametresinin `GET` isteği içinde (`http://127.0.0.1:8000/items/foo?q=somequery` gibi) olup olmadığını kontrol edecek
|
* `GET` request'leri için `q` adlı opsiyonel bir query parameter olup olmadığını kontrol eder (`http://127.0.0.1:8000/items/foo?q=somequery` örneğindeki gibi).
|
||||||
* `q` parametresini `= None` ile oluşturduğumuz için, opsiyonel bir parametre olacak.
|
* `q` parametresi `= None` ile tanımlandığı için opsiyoneldir.
|
||||||
* Eğer `None` olmasa zorunlu bir parametre olacaktı (`PUT` metodunun gövdesinde olduğu gibi).
|
* `None` olmasaydı zorunlu olurdu (tıpkı `PUT` örneğindeki body gibi).
|
||||||
* `PUT` isteği için `/items/{item_id}`'nin gövdesini, JSON olarak doğrulayıp okuyacak:
|
* `/items/{item_id}`'ye yapılan `PUT` request'leri için body'yi JSON olarak okur:
|
||||||
* `name` adında zorunlu bir parametre olup olmadığını ve varsa tipinin `str` olup olmadığını kontol edecek.
|
* `str` olması gereken, zorunlu `name` alanı olduğunu kontrol eder.
|
||||||
* `price` adında zorunlu bir parametre olup olmadığını ve varsa tipinin `float` olup olmadığını kontol edecek.
|
* `float` olması gereken, zorunlu `price` alanı olduğunu kontrol eder.
|
||||||
* `is_offer` adında opsiyonel bir parametre olup olmadığını ve varsa tipinin `float` olup olmadığını kontol edecek.
|
* Varsa, `bool` olması gereken opsiyonel `is_offer` alanını kontrol eder.
|
||||||
* Bunların hepsi en derin JSON nesnelerinde bile çalışacak.
|
* Bunların hepsi çok derin iç içe JSON nesneleri için de çalışır.
|
||||||
* Verilerin JSON'a ve JSON'ın python nesnesine dönüşümü otomatik olarak yapılacak.
|
* JSON'a ve JSON'dan dönüşümü otomatik yapar.
|
||||||
* Her şeyi OpenAPI ile uyumlu bir şekilde otomatik olarak dokümanlayacak ve bunlarda aşağıdaki gibi kullanılabilecek:
|
* Her şeyi OpenAPI ile dokümante eder; bu dokümantasyon şunlar tarafından kullanılabilir:
|
||||||
* Etkileşimli dokümantasyon sistemleri.
|
* Etkileşimli dokümantasyon sistemleri.
|
||||||
* Bir çok programlama dili için otomatik istemci kodu üretim sistemleri.
|
* Birçok dil için otomatik client kodu üretim sistemleri.
|
||||||
* İki ayrı etkileşimli dokümantasyon arayüzünü doğrudan sağlayacak.
|
* 2 etkileşimli dokümantasyon web arayüzünü doğrudan sunar.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Daha yeni başladık ama çalışma mantığını çoktan anlamış oldunuz.
|
Daha yolun başındayız, ama bunun nasıl çalıştığı hakkında fikri kaptınız.
|
||||||
|
|
||||||
Şimdi aşağıdaki satırı değiştirmeyi deneyin:
|
Şu satırı değiştirmeyi deneyin:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
return {"item_name": item.name, "item_id": item_id}
|
return {"item_name": item.name, "item_id": item_id}
|
||||||
```
|
```
|
||||||
|
|
||||||
...bundan:
|
...şundan:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
... "item_name": item.name ...
|
... "item_name": item.name ...
|
||||||
```
|
```
|
||||||
|
|
||||||
...buna:
|
...şuna:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
... "item_price": item.price ...
|
... "item_price": item.price ...
|
||||||
```
|
```
|
||||||
|
|
||||||
...ve editörünün veri tiplerini bildiğini ve otomatik tamamladığını göreceksiniz:
|
...ve editörünüzün alanları otomatik tamamladığını ve type'larını bildiğini görün:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Daha fazal özellik içeren, daha eksiksiz bir örnek için <a href="https://fastapi.tiangolo.com/tr/tutorial/">Öğretici - Kullanıcı Rehberi</a> sayfasını ziyaret edebilirsin.
|
Daha fazla özellik içeren daha kapsamlı bir örnek için <a href="https://fastapi.tiangolo.com/tr/tutorial/">Öğretici - Kullanıcı Rehberi</a>'ne bakın.
|
||||||
|
|
||||||
**Spoiler**: Öğretici - Kullanıcı rehberi şunları içerir:
|
**Spoiler alert**: öğretici - kullanıcı rehberi şunları içerir:
|
||||||
|
|
||||||
* **Parameterlerin**, **headers**, **çerezler**, **form alanları** ve **dosyalar** olarak tanımlanması.
|
* **parameter**'ların farklı yerlerden: **header**'lar, **cookie**'ler, **form alanları** ve **file**'lar olarak tanımlanması.
|
||||||
* `maximum_length` ya da `regex` gibi **doğrulama kısıtlamalarının** nasıl yapılabileceği.
|
* `maximum_length` ya da `regex` gibi **doğrulama kısıtlamalarının** nasıl ayarlanacağı.
|
||||||
* Çok güçlü ve kullanımı kolay **<abbr title="Bağımlılık Enjeksiyonu: components, resources, providers, services, injectables olarak da biliniyor.">Bağımlılık Enjeksiyonu</abbr>** sistemi oluşturmayı.
|
* Çok güçlü ve kullanımı kolay bir **<abbr title="components, resources, providers, services, injectables olarak da bilinir">Dependency Injection</abbr>** sistemi.
|
||||||
* Güvenlik ve kimlik doğrulama, **JWT tokenleri** ile **OAuth2** desteği, ve **HTTP Basic** doğrulaması.
|
* **JWT tokens** ve **HTTP Basic** auth ile **OAuth2** desteği dahil güvenlik ve kimlik doğrulama.
|
||||||
* İleri seviye fakat bir o kadarda basit olan **çok derin JSON modelleri** (Pydantic sayesinde).
|
* **Çok derin iç içe JSON modelleri** tanımlamak için daha ileri (ama aynı derecede kolay) teknikler (Pydantic sayesinde).
|
||||||
* **GraphQL** entegrasyonu: <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> ve diğer kütüphaneleri kullanarak.
|
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> ve diğer kütüphaneler ile **GraphQL** entegrasyonu.
|
||||||
* Diğer ekstra özellikler (Starlette sayesinde):
|
* Starlette sayesinde gelen birçok ek özellik:
|
||||||
* **WebSocketler**
|
* **WebSockets**
|
||||||
* HTTPX ve `pytest` sayesinde aşırı kolay testler.
|
* HTTPX ve `pytest` tabanlı aşırı kolay testler
|
||||||
* **CORS**
|
* **CORS**
|
||||||
* **Cookie Sessions**
|
* **Cookie Sessions**
|
||||||
* ...ve daha fazlası.
|
* ...ve daha fazlası.
|
||||||
|
|
||||||
## Performans
|
### Uygulamanızı deploy edin (opsiyonel) { #deploy-your-app-optional }
|
||||||
|
|
||||||
Bağımsız TechEmpower kıyaslamaları gösteriyor ki, Uvicorn ile çalıştırılan **FastAPI** uygulamaları <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">en hızlı Python framework'lerinden birisi</a>, sadece Starlette ve Uvicorn'dan yavaş, ki FastAPI bunların üzerine kurulu bir kütüphanedir.
|
İsterseniz FastAPI uygulamanızı <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>'a deploy edebilirsiniz; eğer henüz yapmadıysanız gidip bekleme listesine katılın. 🚀
|
||||||
|
|
||||||
Daha fazla bilgi için, bu bölüme bir göz at <a href="https://fastapi.tiangolo.com/tr/benchmarks/" class="internal-link" target="_blank">Kıyaslamalar</a>.
|
Zaten bir **FastAPI Cloud** hesabınız varsa (bekleme listesinden sizi davet ettiysek 😉), uygulamanızı tek bir komutla deploy edebilirsiniz.
|
||||||
|
|
||||||
## Opsiyonel Gereksinimler
|
Deploy etmeden önce, giriş yaptığınızdan emin olun:
|
||||||
|
|
||||||
Pydantic tarafında kullanılan:
|
<div class="termy">
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ fastapi login
|
||||||
|
|
||||||
|
You are logged in to FastAPI Cloud 🚀
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Sonra uygulamanızı deploy edin:
|
||||||
|
|
||||||
|
<div class="termy">
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ fastapi deploy
|
||||||
|
|
||||||
|
Deploying to FastAPI Cloud...
|
||||||
|
|
||||||
|
✅ Deployment successful!
|
||||||
|
|
||||||
|
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Hepsi bu! Artık uygulamanıza bu URL'den erişebilirsiniz. ✨
|
||||||
|
|
||||||
|
#### FastAPI Cloud hakkında { #about-fastapi-cloud }
|
||||||
|
|
||||||
|
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**, **FastAPI**'ın arkasındaki aynı yazar ve ekip tarafından geliştirilmiştir.
|
||||||
|
|
||||||
|
**Bir API'ı build etmek**, **deploy etmek** ve **erişmek** süreçlerini minimum eforla kolaylaştırır.
|
||||||
|
|
||||||
|
FastAPI ile uygulama geliştirmenin sağladığı aynı **developer experience**'ı, onları cloud'a **deploy etmeye** de taşır. 🎉
|
||||||
|
|
||||||
|
FastAPI Cloud, *FastAPI and friends* open source projelerinin ana sponsoru ve finansman sağlayıcısıdır. ✨
|
||||||
|
|
||||||
|
#### Diğer cloud sağlayıcılarına deploy { #deploy-to-other-cloud-providers }
|
||||||
|
|
||||||
|
FastAPI open source'tur ve standartlara dayanır. FastAPI uygulamalarını seçtiğiniz herhangi bir cloud sağlayıcısına deploy edebilirsiniz.
|
||||||
|
|
||||||
|
FastAPI uygulamalarını onlarla deploy etmek için cloud sağlayıcınızın rehberlerini takip edin. 🤓
|
||||||
|
|
||||||
|
## Performans { #performance }
|
||||||
|
|
||||||
|
Bağımsız TechEmpower kıyaslamaları, Uvicorn altında çalışan **FastAPI** uygulamalarının <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">mevcut en hızlı Python framework'lerinden biri</a> olduğunu gösteriyor; sadece Starlette ve Uvicorn'un kendisinin gerisinde (FastAPI tarafından dahili olarak kullanılır). (*)
|
||||||
|
|
||||||
|
Daha iyi anlamak için <a href="https://fastapi.tiangolo.com/tr/benchmarks/" class="internal-link" target="_blank">Kıyaslamalar</a> bölümüne bakın.
|
||||||
|
|
||||||
|
## Bağımlılıklar { #dependencies }
|
||||||
|
|
||||||
|
FastAPI, Pydantic ve Starlette'a bağımlıdır.
|
||||||
|
|
||||||
|
### `standard` Bağımlılıkları { #standard-dependencies }
|
||||||
|
|
||||||
|
FastAPI'ı `pip install "fastapi[standard]"` ile yüklediğinizde, opsiyonel bağımlılıkların `standard` grubuyla birlikte gelir:
|
||||||
|
|
||||||
|
Pydantic tarafından kullanılanlar:
|
||||||
|
|
||||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - email doğrulaması için.
|
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - email doğrulaması için.
|
||||||
|
|
||||||
|
Starlette tarafından kullanılanlar:
|
||||||
|
|
||||||
|
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient` kullanmak istiyorsanız gereklidir.
|
||||||
|
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - varsayılan template yapılandırmasını kullanmak istiyorsanız gereklidir.
|
||||||
|
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` ile, form <abbr title="HTTP request'inden gelen string'i Python verisine dönüştürme">"parsing"</abbr> desteği istiyorsanız gereklidir.
|
||||||
|
|
||||||
|
FastAPI tarafından kullanılanlar:
|
||||||
|
|
||||||
|
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - uygulamanızı yükleyen ve servis eden server için. Buna, yüksek performanslı servis için gereken bazı bağımlılıkları (örn. `uvloop`) içeren `uvicorn[standard]` dahildir.
|
||||||
|
* `fastapi-cli[standard]` - `fastapi` komutunu sağlamak için.
|
||||||
|
* Buna, FastAPI uygulamanızı <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>'a deploy etmenizi sağlayan `fastapi-cloud-cli` dahildir.
|
||||||
|
|
||||||
|
### `standard` Bağımlılıkları Olmadan { #without-standard-dependencies }
|
||||||
|
|
||||||
|
`standard` opsiyonel bağımlılıklarını dahil etmek istemiyorsanız, `pip install "fastapi[standard]"` yerine `pip install fastapi` ile kurabilirsiniz.
|
||||||
|
|
||||||
|
### `fastapi-cloud-cli` Olmadan { #without-fastapi-cloud-cli }
|
||||||
|
|
||||||
|
FastAPI'ı standard bağımlılıklarla ama `fastapi-cloud-cli` olmadan kurmak istiyorsanız, `pip install "fastapi[standard-no-fastapi-cloud-cli]"` ile yükleyebilirsiniz.
|
||||||
|
|
||||||
|
### Ek Opsiyonel Bağımlılıklar { #additional-optional-dependencies }
|
||||||
|
|
||||||
|
Yüklemek isteyebileceğiniz bazı ek bağımlılıklar da vardır.
|
||||||
|
|
||||||
|
Ek opsiyonel Pydantic bağımlılıkları:
|
||||||
|
|
||||||
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - ayar yönetimi için.
|
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - ayar yönetimi için.
|
||||||
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - Pydantic ile birlikte kullanılabilecek ek tipler için.
|
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - Pydantic ile kullanılacak ek type'lar için.
|
||||||
|
|
||||||
Starlette tarafında kullanılan:
|
Ek opsiyonel FastAPI bağımlılıkları:
|
||||||
|
|
||||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Eğer `TestClient` yapısını kullanacaksanız gereklidir.
|
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse` kullanmak istiyorsanız gereklidir.
|
||||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Eğer varsayılan template konfigürasyonunu kullanacaksanız gereklidir.
|
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse` kullanmak istiyorsanız gereklidir.
|
||||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Eğer `request.form()` ile form <abbr title="HTTP isteği ile gelen string veriyi Python nesnesine çevirme.">dönüşümü</abbr> desteğini kullanacaksanız gereklidir.
|
|
||||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` desteği için gerekli.
|
|
||||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - `SchemaGenerator` desteği için gerekli (Muhtemelen FastAPI kullanırken ihtiyacınız olmaz).
|
|
||||||
|
|
||||||
Hem FastAPI hem de Starlette tarafından kullanılan:
|
## Lisans { #license }
|
||||||
|
|
||||||
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - oluşturduğumuz uygulamayı servis edecek web sunucusu görevini üstlenir.
|
Bu proje MIT lisansı şartları altında lisanslanmıştır.
|
||||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse` kullanacaksanız gereklidir.
|
|
||||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse` kullanacaksanız gerekli.
|
|
||||||
|
|
||||||
Bunların hepsini `pip install fastapi[all]` ile yükleyebilirsin.
|
|
||||||
|
|
||||||
## Lisans
|
|
||||||
|
|
||||||
Bu proje, MIT lisansı şartları altında lisanslanmıştır.
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Öğren
|
# Öğren { #learn }
|
||||||
|
|
||||||
**FastAPI** öğrenmek için giriş bölümleri ve öğreticiler burada yer alıyor.
|
**FastAPI** öğrenmek için giriş bölümleri ve öğreticiler burada yer alıyor.
|
||||||
|
|
||||||
Burayı, bir **kitap**, bir **kurs**, ve FastAPI öğrenmenin **resmi** ve önerilen yolu olarak düşünülebilirsiniz. 😎
|
Burayı, bir **kitap**, bir **kurs**, FastAPI öğrenmenin **resmi** ve önerilen yolu olarak düşünebilirsiniz. 😎
|
||||||
|
|||||||
@@ -1,84 +1,28 @@
|
|||||||
# Proje oluşturma - Şablonlar
|
# Full Stack FastAPI Şablonu { #full-stack-fastapi-template }
|
||||||
|
|
||||||
Başlamak için bir proje oluşturucu kullanabilirsiniz, çünkü sizin için önceden yapılmış birçok başlangıç kurulumu, güvenlik, veritabanı ve temel API endpoinlerini içerir.
|
Şablonlar genellikle belirli bir kurulumla gelir, ancak esnek ve özelleştirilebilir olacak şekilde tasarlanırlar. Bu sayede şablonu projenizin gereksinimlerine göre değiştirip uyarlayabilir, çok iyi bir başlangıç noktası olarak kullanabilirsiniz. 🏁
|
||||||
|
|
||||||
Bir proje oluşturucu, her zaman kendi ihtiyaçlarınıza göre güncellemeniz ve uyarlamanız gereken esnek bir kuruluma sahip olacaktır, ancak bu, projeniz için iyi bir başlangıç noktası olabilir.
|
Bu şablonu başlangıç için kullanabilirsiniz; çünkü ilk kurulumun, güvenliğin, veritabanının ve bazı API endpoint'lerinin önemli bir kısmı sizin için zaten hazırlanmıştır.
|
||||||
|
|
||||||
## Full Stack FastAPI PostgreSQL
|
GitHub Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Full Stack FastAPI Template</a>
|
||||||
|
|
||||||
GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-postgresql</a>
|
## Full Stack FastAPI Şablonu - Teknoloji Yığını ve Özellikler { #full-stack-fastapi-template-technology-stack-and-features }
|
||||||
|
|
||||||
### Full Stack FastAPI PostgreSQL - Özellikler
|
- ⚡ Python backend API için [**FastAPI**](https://fastapi.tiangolo.com/tr).
|
||||||
|
- 🧰 Python SQL veritabanı etkileşimleri (ORM) için [SQLModel](https://sqlmodel.tiangolo.com).
|
||||||
* Full **Docker** entegrasyonu (Docker based).
|
- 🔍 FastAPI'nin kullandığı; veri doğrulama ve ayarlar yönetimi için [Pydantic](https://docs.pydantic.dev).
|
||||||
* Docker Swarm Mode ile deployment.
|
- 💾 SQL veritabanı olarak [PostgreSQL](https://www.postgresql.org).
|
||||||
* **Docker Compose** entegrasyonu ve lokal geliştirme için optimizasyon.
|
- 🚀 frontend için [React](https://react.dev).
|
||||||
* Uvicorn ve Gunicorn ile **Production ready** Python web server'ı.
|
- 💃 TypeScript, hooks, Vite ve modern bir frontend stack'inin diğer parçalarını kullanır.
|
||||||
* Python <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI**</a> backend:
|
- 🎨 frontend component'leri için [Tailwind CSS](https://tailwindcss.com) ve [shadcn/ui](https://ui.shadcn.com).
|
||||||
* **Hızlı**: **NodeJS** ve **Go** ile eşit, çok yüksek performans (Starlette ve Pydantic'e teşekkürler).
|
- 🤖 Otomatik üretilen bir frontend client.
|
||||||
* **Sezgisel**: Editor desteğı. <abbr title="auto-complete, IntelliSense gibi isimlerle de bilinir">Otomatik tamamlama</abbr>. Daha az debugging.
|
- 🧪 End-to-End testleri için [Playwright](https://playwright.dev).
|
||||||
* **Kolay**: Kolay öğrenip kolay kullanmak için tasarlandı. Daha az döküman okuma daha çok iş.
|
- 🦇 Dark mode desteği.
|
||||||
* **Kısa**: Minimum kod tekrarı. Her parametre bildiriminde birden çok özellik.
|
- 🐋 Geliştirme ve production için [Docker Compose](https://www.docker.com).
|
||||||
* **Güçlü**: Production-ready. Otomatik interaktif dökümantasyon.
|
- 🔒 Varsayılan olarak güvenli password hashing.
|
||||||
* **Standartlara dayalı**: API'ler için açık standartlara dayanır (ve tamamen uyumludur): <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> ve <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Şeması</a>.
|
- 🔑 JWT (JSON Web Token) authentication.
|
||||||
* <a href="https://fastapi.tiangolo.com/features/" class="external-link" target="_blank">**Birçok diger özelliği**</a> dahili otomatik doğrulama, serialization, interaktif dokümantasyon, OAuth2 JWT token ile authentication, vb.
|
- 📫 E-posta tabanlı şifre kurtarma.
|
||||||
* **Güvenli şifreleme** .
|
- ✅ [Pytest](https://pytest.org) ile testler.
|
||||||
* **JWT token** kimlik doğrulama.
|
- 📞 Reverse proxy / load balancer olarak [Traefik](https://traefik.io).
|
||||||
* **SQLAlchemy** models (Flask dan bağımsızdır. Celery worker'ları ile kullanılabilir).
|
- 🚢 Docker Compose kullanarak deployment talimatları; otomatik HTTPS sertifikalarını yönetmek için bir frontend Traefik proxy'sini nasıl kuracağınız dahil.
|
||||||
* Kullanıcılar için temel başlangıç modeli (gerektiği gibi değiştirin ve kaldırın).
|
- 🏭 GitHub Actions tabanlı CI (continuous integration) ve CD (continuous deployment).
|
||||||
* **Alembic** migration.
|
|
||||||
* **CORS** (Cross Origin Resource Sharing).
|
|
||||||
* **Celery** worker'ları ile backend içerisinden seçilen işleri çalıştırabilirsiniz.
|
|
||||||
* **Pytest**'e dayalı, Docker ile entegre REST backend testleri ile veritabanından bağımsız olarak tam API etkileşimini test edebilirsiniz. Docker'da çalıştığı için her seferinde sıfırdan yeni bir veri deposu oluşturabilir (böylece ElasticSearch, MongoDB, CouchDB veya ne istersen kullanabilirsin ve sadece API'nin çalışıp çalışmadığını test edebilirsin).
|
|
||||||
* Atom Hydrogen veya Visual Studio Code Jupyter gibi uzantılarla uzaktan veya Docker içi geliştirme için **Jupyter Çekirdekleri** ile kolay Python entegrasyonu.
|
|
||||||
* **Vue** ile frontend:
|
|
||||||
* Vue CLI ile oluşturulmuş.
|
|
||||||
* Dahili **JWT kimlik doğrulama**.
|
|
||||||
* Dahili Login.
|
|
||||||
* Login sonrası, Kontrol paneli.
|
|
||||||
* Kullanıcı oluşturma ve düzenleme kontrol paneli
|
|
||||||
* Kendi kendine kullanıcı sürümü.
|
|
||||||
* **Vuex**.
|
|
||||||
* **Vue-router**.
|
|
||||||
* **Vuetify** güzel material design kompanentleri için.
|
|
||||||
* **TypeScript**.
|
|
||||||
* **Nginx** tabanlı Docker sunucusu (Vue-router için yapılandırılmış).
|
|
||||||
* Docker ile multi-stage yapı, böylece kodu derlemeniz, kaydetmeniz veya işlemeniz gerekmez.
|
|
||||||
* Derleme zamanında Frontend testi (devre dışı bırakılabilir).
|
|
||||||
* Mümkün olduğu kadar modüler yapılmıştır, bu nedenle kutudan çıktığı gibi çalışır, ancak Vue CLI ile yeniden oluşturabilir veya ihtiyaç duyduğunuz şekilde oluşturabilir ve istediğinizi yeniden kullanabilirsiniz.
|
|
||||||
* **PGAdmin** PostgreSQL database admin tool'u, PHPMyAdmin ve MySQL ile kolayca değiştirilebilir.
|
|
||||||
* **Flower** ile Celery job'larını monitörleme.
|
|
||||||
* **Traefik** ile backend ve frontend arasında yük dengeleme, böylece her ikisini de aynı domain altında, path ile ayrılmış, ancak farklı kapsayıcılar tarafından sunulabilirsiniz.
|
|
||||||
* Let's Encrypt **HTTPS** sertifikalarının otomatik oluşturulması dahil olmak üzere Traefik entegrasyonu.
|
|
||||||
* GitLab **CI** (sürekli entegrasyon), backend ve frontend testi dahil.
|
|
||||||
|
|
||||||
## Full Stack FastAPI Couchbase
|
|
||||||
|
|
||||||
GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-couchbase</a>
|
|
||||||
|
|
||||||
⚠️ **UYARI** ⚠️
|
|
||||||
|
|
||||||
Sıfırdan bir projeye başlıyorsanız alternatiflerine bakın.
|
|
||||||
|
|
||||||
Örneğin, <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" class="external-link" target="_blank">Full Stack FastAPI PostgreSQL</a> daha iyi bir alternatif olabilir, aktif olarak geliştiriliyor ve kullanılıyor. Ve yeni özellik ve ilerlemelere sahip.
|
|
||||||
|
|
||||||
İsterseniz Couchbase tabanlı generator'ı kullanmakta özgürsünüz, hala iyi çalışıyor olmalı ve onunla oluşturulmuş bir projeniz varsa bu da sorun değil (ve muhtemelen zaten ihtiyaçlarınıza göre güncellediniz).
|
|
||||||
|
|
||||||
Bununla ilgili daha fazla bilgiyi repo belgelerinde okuyabilirsiniz.
|
|
||||||
|
|
||||||
## Full Stack FastAPI MongoDB
|
|
||||||
|
|
||||||
... müsaitliğime ve diğer faktörlere bağlı olarak daha sonra gelebilir. 😅 🎉
|
|
||||||
|
|
||||||
## Machine Learning modelleri, spaCy ve FastAPI
|
|
||||||
|
|
||||||
GitHub: <a href="https://github.com/microsoft/cookiecutter-spacy-fastapi" class="external-link" target="_blank">https://github.com/microsoft/cookiecutter-spacy-fastapi</a>
|
|
||||||
|
|
||||||
### Machine Learning modelleri, spaCy ve FastAPI - Features
|
|
||||||
|
|
||||||
* **spaCy** NER model entegrasyonu.
|
|
||||||
* **Azure Cognitive Search** yerleşik istek biçimi.
|
|
||||||
* Uvicorn ve Gunicorn ile **Production ready** Python web server'ı.
|
|
||||||
* Dahili **Azure DevOps** Kubernetes (AKS) CI/CD deployment.
|
|
||||||
* **Multilingual**, Proje kurulumu sırasında spaCy'nin yerleşik dillerinden birini kolayca seçin.
|
|
||||||
* **Esnetilebilir** diğer frameworkler (Pytorch, Tensorflow) ile de çalışır sadece spaCy değil.
|
|
||||||
|
|||||||
@@ -1,76 +1,74 @@
|
|||||||
# Python Veri Tiplerine Giriş
|
# Python Tiplerine Giriş { #python-types-intro }
|
||||||
|
|
||||||
Python isteğe bağlı olarak "tip belirteçlerini" destekler.
|
Python, isteğe bağlı "type hints" (diğer adıyla "type annotations") desteğine sahiptir.
|
||||||
|
|
||||||
**"Tip belirteçleri"** bir değişkenin <abbr title="örneğin: str, int, float, bool">tipinin</abbr> belirtilmesine olanak sağlayan özel bir sözdizimidir.
|
Bu **"type hints"** veya annotations, bir değişkenin <abbr title="örneğin: str, int, float, bool">type</abbr>'ını bildirmeye yarayan özel bir sözdizimidir.
|
||||||
|
|
||||||
Değişkenlerin tiplerini belirterek editör ve araçlardan daha fazla destek alabilirsiniz.
|
Değişkenleriniz için type bildirerek, editörler ve araçlar size daha iyi destek sağlayabilir.
|
||||||
|
|
||||||
Bu pythonda tip belirteçleri için **hızlı bir başlangıç / bilgi tazeleme** rehberidir . Bu rehber **FastAPI** kullanmak için gereken minimum konuyu kapsar ki bu da çok az bir miktardır.
|
Bu, Python type hints hakkında sadece **hızlı bir eğitim / bilgi tazeleme** dokümanıdır. **FastAPI** ile kullanmak için gereken minimum bilgiyi kapsar... ki aslında bu çok azdır.
|
||||||
|
|
||||||
**FastAPI' nin** tamamı bu tür tip belirteçleri ile donatılmıştır ve birçok avantaj sağlamaktadır.
|
**FastAPI** tamamen bu type hints üzerine kuruludur; bunlar ona birçok avantaj ve fayda sağlar.
|
||||||
|
|
||||||
**FastAPI** kullanmayacak olsanız bile tür belirteçleri hakkında bilgi edinmenizde fayda var.
|
Ancak hiç **FastAPI** kullanmasanız bile, bunlar hakkında biraz öğrenmeniz size fayda sağlayacaktır.
|
||||||
|
|
||||||
/// note | Not
|
/// note | Not
|
||||||
|
|
||||||
Python uzmanıysanız ve tip belirteçleri ilgili her şeyi zaten biliyorsanız, sonraki bölüme geçin.
|
Eğer bir Python uzmanıysanız ve type hints hakkında her şeyi zaten biliyorsanız, sonraki bölüme geçin.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Motivasyon
|
## Motivasyon { #motivation }
|
||||||
|
|
||||||
Basit bir örnek ile başlayalım:
|
Basit bir örnekle başlayalım:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial001.py *}
|
{* ../../docs_src/python_types/tutorial001_py39.py *}
|
||||||
|
|
||||||
|
Bu programı çalıştırınca şu çıktıyı alırsınız:
|
||||||
Programın çıktısı:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
John Doe
|
John Doe
|
||||||
```
|
```
|
||||||
|
|
||||||
Fonksiyon sırayla şunları yapar:
|
Fonksiyon şunları yapar:
|
||||||
|
|
||||||
* `first_name` ve `last_name` değerlerini alır.
|
* `first_name` ve `last_name` değerlerini alır.
|
||||||
* `title()` ile değişkenlerin ilk karakterlerini büyütür.
|
* `title()` ile her birinin ilk harfini büyük harfe çevirir.
|
||||||
* Değişkenleri aralarında bir boşlukla beraber <abbr title="Onları bir bütün olarak sırayla birleştirir.">Birleştirir</abbr>.
|
* Ortada bir boşluk olacak şekilde <abbr title="Hepsini, tek bir bütün olacak şekilde bir araya koyar. İçerikler ardışık şekilde yer alır.">Concatenates</abbr> eder.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
|
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
|
||||||
|
|
||||||
|
### Düzenleyelim { #edit-it }
|
||||||
### Düzenle
|
|
||||||
|
|
||||||
Bu çok basit bir program.
|
Bu çok basit bir program.
|
||||||
|
|
||||||
Ama şimdi sıfırdan yazdığınızı hayal edin.
|
Ama şimdi bunu sıfırdan yazdığınızı hayal edin.
|
||||||
|
|
||||||
Bir noktada fonksiyonun tanımına başlayacaktınız, parametreleri hazır hale getirdiniz...
|
Bir noktada fonksiyon tanımını yazmaya başlamış olacaktınız, parametreler hazır...
|
||||||
|
|
||||||
Ama sonra "ilk harfi büyük harfe dönüştüren yöntemi" çağırmanız gerekir.
|
Ama sonra "ilk harfi büyük harfe çeviren method"u çağırmanız gerekiyor.
|
||||||
|
|
||||||
`upper` mıydı ? Yoksa `uppercase`' mi? `first_uppercase`? `capitalize`?
|
`upper` mıydı? `uppercase` miydi? `first_uppercase`? `capitalize`?
|
||||||
|
|
||||||
Ardından, programcıların en iyi arkadaşı olan otomatik tamamlama ile denediniz.
|
Sonra eski programcı dostuyla denersiniz: editör autocomplete.
|
||||||
|
|
||||||
'first_name', ardından bir nokta ('.') yazıp otomatik tamamlamayı tetiklemek için 'Ctrl+Space' tuşlarına bastınız.
|
Fonksiyonun ilk parametresi olan `first_name`'i yazarsınız, sonra bir nokta (`.`) ve ardından autocomplete'i tetiklemek için `Ctrl+Space`'e basarsınız.
|
||||||
|
|
||||||
Ancak, ne yazık ki, yararlı hiçbir şey elde edemediniz:
|
Ama ne yazık ki, işe yarar bir şey göremezsiniz:
|
||||||
|
|
||||||
<img src="/img/python-types/image01.png">
|
<img src="/img/python-types/image01.png">
|
||||||
|
|
||||||
### Tipleri ekle
|
### Tipleri ekleyelim { #add-types }
|
||||||
|
|
||||||
Önceki sürümden sadece bir satırı değiştirelim.
|
Önceki sürümden tek bir satırı değiştirelim.
|
||||||
|
|
||||||
Tam olarak bu parçayı, işlevin parametrelerini değiştireceğiz:
|
Fonksiyonun parametreleri olan şu parçayı:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
first_name, last_name
|
first_name, last_name
|
||||||
```
|
```
|
||||||
|
|
||||||
ve bu hale getireceğiz:
|
şuna çevireceğiz:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
first_name: str, last_name: str
|
first_name: str, last_name: str
|
||||||
@@ -78,58 +76,55 @@ ve bu hale getireceğiz:
|
|||||||
|
|
||||||
Bu kadar.
|
Bu kadar.
|
||||||
|
|
||||||
İşte bunlar "tip belirteçleri":
|
Bunlar "type hints":
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial002.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
|
||||||
|
|
||||||
|
Bu, aşağıdaki gibi default değerler bildirmekle aynı şey değildir:
|
||||||
Bu, aşağıdaki gibi varsayılan değerleri bildirmekle aynı şey değildir:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
first_name="john", last_name="doe"
|
first_name="john", last_name="doe"
|
||||||
```
|
```
|
||||||
|
|
||||||
Bu tamamen farklı birşey
|
Bu farklı bir şey.
|
||||||
|
|
||||||
İki nokta üst üste (`:`) kullanıyoruz , eşittir (`=`) değil.
|
Eşittir (`=`) değil, iki nokta (`:`) kullanıyoruz.
|
||||||
|
|
||||||
Normalde tip belirteçleri eklemek, kod üzerinde olacakları değiştirmez.
|
Ve type hints eklemek, normalde onlarsız ne oluyorsa onu değiştirmez.
|
||||||
|
|
||||||
Şimdi programı sıfırdan birdaha yazdığınızı hayal edin.
|
Ama şimdi, type hints ile o fonksiyonu oluşturmanın ortasında olduğunuzu tekrar hayal edin.
|
||||||
|
|
||||||
Aynı noktada, `Ctrl+Space` ile otomatik tamamlamayı tetiklediniz ve şunu görüyorsunuz:
|
Aynı noktada, `Ctrl+Space` ile autocomplete'i tetiklemeye çalışırsınız ve şunu görürsünüz:
|
||||||
|
|
||||||
<img src="/img/python-types/image02.png">
|
<img src="/img/python-types/image02.png">
|
||||||
|
|
||||||
Aradığınızı bulana kadar seçenekleri kaydırabilirsiniz:
|
Bununla birlikte, seçenekleri görerek kaydırabilirsiniz; ta ki "tanıdık gelen" seçeneği bulana kadar:
|
||||||
|
|
||||||
<img src="/img/python-types/image03.png">
|
<img src="/img/python-types/image03.png">
|
||||||
|
|
||||||
## Daha fazla motivasyon
|
## Daha fazla motivasyon { #more-motivation }
|
||||||
|
|
||||||
Bu fonksiyon, zaten tür belirteçlerine sahip:
|
Şu fonksiyona bakın, zaten type hints içeriyor:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial003.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
|
||||||
|
|
||||||
|
Editör değişkenlerin tiplerini bildiği için, sadece completion değil, aynı zamanda hata kontrolleri de alırsınız:
|
||||||
Editör değişkenlerin tiplerini bildiğinden, yalnızca otomatik tamamlama değil, hata kontrolleri de sağlar:
|
|
||||||
|
|
||||||
<img src="/img/python-types/image04.png">
|
<img src="/img/python-types/image04.png">
|
||||||
|
|
||||||
Artık `age` değişkenini `str(age)` olarak kullanmanız gerektiğini biliyorsunuz:
|
Artık bunu düzeltmeniz gerektiğini, `age`'i `str(age)` ile string'e çevirmeniz gerektiğini biliyorsunuz:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial004.py hl[2] *}
|
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
|
||||||
|
|
||||||
|
## Tipleri bildirmek { #declaring-types }
|
||||||
|
|
||||||
## Tip bildirme
|
Type hints bildirmek için ana yeri az önce gördünüz: fonksiyon parametreleri.
|
||||||
|
|
||||||
Az önce tip belirteçlerinin en çok kullanıldığı yeri gördünüz.
|
Bu, **FastAPI** ile kullanırken de onları en çok kullanacağınız yerdir.
|
||||||
|
|
||||||
**FastAPI**ile çalışırken tip belirteçlerini en çok kullanacağımız yer yine fonksiyonlardır.
|
### Basit tipler { #simple-types }
|
||||||
|
|
||||||
### Basit tipler
|
Sadece `str` değil, tüm standart Python tiplerini bildirebilirsiniz.
|
||||||
|
|
||||||
Yalnızca `str` değil, tüm standart Python tiplerinin bildirebilirsiniz.
|
|
||||||
|
|
||||||
Örneğin şunları kullanabilirsiniz:
|
Örneğin şunları kullanabilirsiniz:
|
||||||
|
|
||||||
@@ -138,176 +133,332 @@ Yalnızca `str` değil, tüm standart Python tiplerinin bildirebilirsiniz.
|
|||||||
* `bool`
|
* `bool`
|
||||||
* `bytes`
|
* `bytes`
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
|
||||||
|
|
||||||
|
### Tip parametreleri ile Generic tipler { #generic-types-with-type-parameters }
|
||||||
|
|
||||||
### Tip parametreleri ile Generic tipler
|
`dict`, `list`, `set` ve `tuple` gibi, başka değerler içerebilen bazı veri yapıları vardır. Ve iç değerlerin kendi tipi de olabilir.
|
||||||
|
|
||||||
"dict", "list", "set" ve "tuple" gibi diğer değerleri içerebilen bazı veri yapıları vardır. Ve dahili değerlerinin de tip belirtecleri olabilir.
|
İç tipleri olan bu tiplere "**generic**" tipler denir. Ve bunları, iç tipleriyle birlikte bildirmek mümkündür.
|
||||||
|
|
||||||
Bu tipleri ve dahili tpileri bildirmek için standart Python modülünü "typing" kullanabilirsiniz.
|
Bu tipleri ve iç tipleri bildirmek için standart Python modülü `typing`'i kullanabilirsiniz. Bu modül, özellikle bu type hints desteği için vardır.
|
||||||
|
|
||||||
Bu tür tip belirteçlerini desteklemek için özel olarak mevcuttur.
|
#### Python'un daha yeni sürümleri { #newer-versions-of-python }
|
||||||
|
|
||||||
#### `List`
|
`typing` kullanan sözdizimi, Python 3.6'dan en yeni sürümlere kadar (Python 3.9, Python 3.10, vb. dahil) tüm sürümlerle **uyumludur**.
|
||||||
|
|
||||||
Örneğin `str` değerlerden oluşan bir `list` tanımlayalım.
|
Python geliştikçe, **daha yeni sürümler** bu type annotations için daha iyi destekle gelir ve çoğu durumda type annotations bildirmek için `typing` modülünü import edip kullanmanız bile gerekmez.
|
||||||
|
|
||||||
From `typing`, import `List` (büyük harf olan `L` ile):
|
Projeniz için daha yeni bir Python sürümü seçebiliyorsanız, bu ek sadelikten yararlanabilirsiniz.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial006.py hl[1] *}
|
Tüm dokümanlarda her Python sürümüyle uyumlu örnekler vardır (fark olduğunda).
|
||||||
|
|
||||||
|
Örneğin "**Python 3.6+**", Python 3.6 veya üstüyle (3.7, 3.8, 3.9, 3.10, vb. dahil) uyumludur. "**Python 3.9+**" ise Python 3.9 veya üstüyle (3.10 vb. dahil) uyumludur.
|
||||||
|
|
||||||
Değişkenin tipini yine iki nokta üstüste (`:`) ile belirleyin.
|
Eğer **Python'un en güncel sürümlerini** kullanabiliyorsanız, en güncel sürüme ait örnekleri kullanın; bunlar **en iyi ve en basit sözdizimine** sahip olur, örneğin "**Python 3.10+**".
|
||||||
|
|
||||||
tip olarak `List` kullanın.
|
#### List { #list }
|
||||||
|
|
||||||
Liste, bazı dahili tipleri içeren bir tür olduğundan, bunları köşeli parantez içine alırsınız:
|
Örneğin, `str`'lerden oluşan bir `list` olan bir değişken tanımlayalım.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial006.py hl[4] *}
|
Değişkeni, aynı iki nokta (`:`) sözdizimiyle bildirin.
|
||||||
|
|
||||||
|
Type olarak `list` yazın.
|
||||||
|
|
||||||
/// tip | Ipucu
|
`list`, bazı iç tipleri barındıran bir tip olduğundan, bunları köşeli parantez içine yazarsınız:
|
||||||
|
|
||||||
Köşeli parantez içindeki bu dahili tiplere "tip parametreleri" denir.
|
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
|
||||||
|
|
||||||
Bu durumda `str`, `List`e iletilen tür parametresidir.
|
/// info | Bilgi
|
||||||
|
|
||||||
|
Köşeli parantez içindeki bu iç tiplere "type parameters" denir.
|
||||||
|
|
||||||
|
Bu durumda `str`, `list`'e verilen type parameter'dır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Bunun anlamı şudur: "`items` değişkeni bir `list`tir ve bu listedeki öğelerin her biri bir `str`dir".
|
Bu şu demektir: "`items` değişkeni bir `list` ve bu listedeki her bir öğe `str`".
|
||||||
|
|
||||||
Bunu yaparak, düzenleyicinizin listedeki öğeleri işlerken bile destek sağlamasını sağlayabilirsiniz:
|
Bunu yaparak, editörünüz listeden öğeleri işlerken bile destek sağlayabilir:
|
||||||
|
|
||||||
<img src="/img/python-types/image05.png">
|
<img src="/img/python-types/image05.png">
|
||||||
|
|
||||||
Tip belirteçleri olmadan, bunu başarmak neredeyse imkansızdır.
|
Tipler olmadan, bunu başarmak neredeyse imkansızdır.
|
||||||
|
|
||||||
`item` değişkeninin `items` listesindeki öğelerden biri olduğuna dikkat edin.
|
`item` değişkeninin, `items` listesindeki elemanlardan biri olduğuna dikkat edin.
|
||||||
|
|
||||||
Ve yine, editör bunun bir `str` olduğunu biliyor ve bunun için destek sağlıyor.
|
Ve yine de editör bunun bir `str` olduğunu bilir ve buna göre destek sağlar.
|
||||||
|
|
||||||
#### `Tuple` ve `Set`
|
#### Tuple ve Set { #tuple-and-set }
|
||||||
|
|
||||||
`Tuple` ve `set`lerin tiplerini bildirmek için de aynısını yapıyoruz:
|
`tuple`'ları ve `set`'leri bildirmek için de aynısını yaparsınız:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial007.py hl[1,4] *}
|
|
||||||
|
|
||||||
|
|
||||||
Bu şu anlama geliyor:
|
|
||||||
|
|
||||||
* `items_t` değişkeni sırasıyla `int`, `int`, ve `str` tiplerinden oluşan bir `tuple` türündedir .
|
|
||||||
* `items_s` ise her öğesi `bytes` türünde olan bir `set` örneğidir.
|
|
||||||
|
|
||||||
#### `Dict`
|
|
||||||
|
|
||||||
Bir `dict` tanımlamak için virgülle ayrılmış iki parametre verebilirsiniz.
|
|
||||||
|
|
||||||
İlk tip parametresi `dict` değerinin `key` değeri içindir.
|
|
||||||
|
|
||||||
İkinci parametre ise `dict` değerinin `value` değeri içindir:
|
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial008.py hl[1,4] *}
|
|
||||||
|
|
||||||
|
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
|
||||||
|
|
||||||
Bu şu anlama gelir:
|
Bu şu anlama gelir:
|
||||||
|
|
||||||
* `prices` değişkeni `dict` tipindedir:
|
* `items_t` değişkeni 3 öğeli bir `tuple`'dır: bir `int`, bir başka `int` ve bir `str`.
|
||||||
* `dict` değişkeninin `key` değeri `str` tipindedir (herbir item'ın "name" değeri).
|
* `items_s` değişkeni bir `set`'tir ve her bir öğesi `bytes` tipindedir.
|
||||||
* `dict` değişkeninin `value` değeri `float` tipindedir (lherbir item'ın "price" değeri).
|
|
||||||
|
|
||||||
#### `Optional`
|
#### Dict { #dict }
|
||||||
|
|
||||||
`Optional` bir değişkenin `str`gibi bir tipi olabileceğini ama isteğe bağlı olarak tipinin `None` olabileceğini belirtir:
|
Bir `dict` tanımlamak için, virgülle ayrılmış 2 type parameter verirsiniz.
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
İlk type parameter, `dict`'in key'leri içindir.
|
||||||
{!../../docs_src/python_types/tutorial009.py!}
|
|
||||||
|
İkinci type parameter, `dict`'in value'ları içindir:
|
||||||
|
|
||||||
|
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
|
||||||
|
|
||||||
|
Bu şu anlama gelir:
|
||||||
|
|
||||||
|
* `prices` değişkeni bir `dict`'tir:
|
||||||
|
* Bu `dict`'in key'leri `str` tipindedir (örneğin her bir öğenin adı).
|
||||||
|
* Bu `dict`'in value'ları `float` tipindedir (örneğin her bir öğenin fiyatı).
|
||||||
|
|
||||||
|
#### Union { #union }
|
||||||
|
|
||||||
|
Bir değişkenin **birkaç tipten herhangi biri** olabileceğini bildirebilirsiniz; örneğin bir `int` veya bir `str`.
|
||||||
|
|
||||||
|
Python 3.6 ve üzeri sürümlerde (Python 3.10 dahil), `typing` içinden `Union` tipini kullanabilir ve köşeli parantez içine kabul edilecek olası tipleri yazabilirsiniz.
|
||||||
|
|
||||||
|
Python 3.10'da ayrıca, olası tipleri <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> ile ayırabildiğiniz **yeni bir sözdizimi** de vardır.
|
||||||
|
|
||||||
|
//// tab | Python 3.10+
|
||||||
|
|
||||||
|
```Python hl_lines="1"
|
||||||
|
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
||||||
```
|
```
|
||||||
|
|
||||||
`str` yerine `Optional[str]` kullanmak editorün bu değerin her zaman `str` tipinde değil bazen `None` tipinde de olabileceğini belirtir ve hataları tespit etmemizde yardımcı olur.
|
////
|
||||||
|
|
||||||
#### Generic tipler
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
Köşeli parantez içinde tip parametreleri alan bu türler, örneğin:
|
```Python hl_lines="1 4"
|
||||||
|
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
|
||||||
|
```
|
||||||
|
|
||||||
* `List`
|
////
|
||||||
* `Tuple`
|
|
||||||
* `Set`
|
Her iki durumda da bu, `item`'ın `int` veya `str` olabileceği anlamına gelir.
|
||||||
* `Dict`
|
|
||||||
|
#### Muhtemelen `None` { #possibly-none }
|
||||||
|
|
||||||
|
Bir değerin `str` gibi bir tipi olabileceğini ama aynı zamanda `None` da olabileceğini bildirebilirsiniz.
|
||||||
|
|
||||||
|
Python 3.6 ve üzeri sürümlerde (Python 3.10 dahil), `typing` modülünden `Optional` import edip kullanarak bunu bildirebilirsiniz.
|
||||||
|
|
||||||
|
```Python hl_lines="1 4"
|
||||||
|
{!../../docs_src/python_types/tutorial009_py39.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
Sadece `str` yerine `Optional[str]` kullanmak, aslında değer `None` olabilecekken her zaman `str` olduğunu varsaydığınız hataları editörün yakalamanıza yardımcı olmasını sağlar.
|
||||||
|
|
||||||
|
`Optional[Something]`, aslında `Union[Something, None]` için bir kısayoldur; eşdeğerdirler.
|
||||||
|
|
||||||
|
Bu aynı zamanda Python 3.10'da `Something | None` kullanabileceğiniz anlamına gelir:
|
||||||
|
|
||||||
|
//// tab | Python 3.10+
|
||||||
|
|
||||||
|
```Python hl_lines="1"
|
||||||
|
{!> ../../docs_src/python_types/tutorial009_py310.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
|
```Python hl_lines="1 4"
|
||||||
|
{!> ../../docs_src/python_types/tutorial009_py39.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
//// tab | Python 3.9+ alternatif
|
||||||
|
|
||||||
|
```Python hl_lines="1 4"
|
||||||
|
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
#### `Union` veya `Optional` kullanmak { #using-union-or-optional }
|
||||||
|
|
||||||
|
Python sürümünüz 3.10'un altındaysa, benim oldukça **öznel** bakış açıma göre küçük bir ipucu:
|
||||||
|
|
||||||
|
* 🚨 `Optional[SomeType]` kullanmaktan kaçının
|
||||||
|
* Bunun yerine ✨ **`Union[SomeType, None]` kullanın** ✨.
|
||||||
|
|
||||||
|
İkisi eşdeğerdir ve altta aynı şeydir; ama ben `Optional` yerine `Union` önermeyi tercih ederim. Çünkü "**optional**" kelimesi değerin optional olduğunu ima ediyor gibi durur; ama gerçekte anlamı "değer `None` olabilir"dir. Değer optional olmasa ve hâlâ required olsa bile.
|
||||||
|
|
||||||
|
Bence `Union[SomeType, None]` ne anlama geldiğini daha açık şekilde ifade ediyor.
|
||||||
|
|
||||||
|
Bu, tamamen kelimeler ve isimlendirmelerle ilgili. Ancak bu kelimeler, sizin ve ekip arkadaşlarınızın kod hakkında nasıl düşündüğünü etkileyebilir.
|
||||||
|
|
||||||
|
Örnek olarak şu fonksiyonu ele alalım:
|
||||||
|
|
||||||
|
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
|
||||||
|
|
||||||
|
`name` parametresi `Optional[str]` olarak tanımlanmış, ama **optional değil**; parametre olmadan fonksiyonu çağıramazsınız:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
say_hi() # Oh, no, this throws an error! 😱
|
||||||
|
```
|
||||||
|
|
||||||
|
`name` parametresi **hâlâ required**'dır (*optional* değildir) çünkü bir default değeri yoktur. Yine de `name`, değer olarak `None` kabul eder:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
say_hi(name=None) # This works, None is valid 🎉
|
||||||
|
```
|
||||||
|
|
||||||
|
İyi haber şu ki, Python 3.10'a geçtiğinizde bununla uğraşmanız gerekmeyecek; çünkü tiplerin union'larını tanımlamak için doğrudan `|` kullanabileceksiniz:
|
||||||
|
|
||||||
|
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
|
||||||
|
|
||||||
|
Ve böylece `Optional` ve `Union` gibi isimlerle de uğraşmanız gerekmeyecek. 😎
|
||||||
|
|
||||||
|
#### Generic tipler { #generic-types }
|
||||||
|
|
||||||
|
Köşeli parantez içinde type parameter alan bu tiplere **Generic types** veya **Generics** denir, örneğin:
|
||||||
|
|
||||||
|
//// tab | Python 3.10+
|
||||||
|
|
||||||
|
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içindeki tiplerle):
|
||||||
|
|
||||||
|
* `list`
|
||||||
|
* `tuple`
|
||||||
|
* `set`
|
||||||
|
* `dict`
|
||||||
|
|
||||||
|
Ve önceki Python sürümlerinde olduğu gibi `typing` modülünden:
|
||||||
|
|
||||||
|
* `Union`
|
||||||
* `Optional`
|
* `Optional`
|
||||||
* ...and others.
|
* ...and others.
|
||||||
|
|
||||||
**Generic types** yada **Generics** olarak adlandırılır.
|
Python 3.10'da, `Union` ve `Optional` generics'lerini kullanmaya alternatif olarak, tip union'larını bildirmek için <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> kullanabilirsiniz; bu çok daha iyi ve daha basittir.
|
||||||
|
|
||||||
### Tip olarak Sınıflar
|
////
|
||||||
|
|
||||||
Bir değişkenin tipini bir sınıf ile bildirebilirsiniz.
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
Diyelim ki `name` değerine sahip `Person` sınıfınız var:
|
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içindeki tiplerle):
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
|
* `list`
|
||||||
|
* `tuple`
|
||||||
|
* `set`
|
||||||
|
* `dict`
|
||||||
|
|
||||||
|
Ve `typing` modülünden gelen generics:
|
||||||
|
|
||||||
Sonra bir değişkeni 'Person' tipinde tanımlayabilirsiniz:
|
* `Union`
|
||||||
|
* `Optional`
|
||||||
|
* ...and others.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial010.py hl[6] *}
|
////
|
||||||
|
|
||||||
|
### Tip olarak sınıflar { #classes-as-types }
|
||||||
|
|
||||||
Ve yine bütün editör desteğini alırsınız:
|
Bir sınıfı da bir değişkenin tipi olarak bildirebilirsiniz.
|
||||||
|
|
||||||
|
Örneğin, adı olan bir `Person` sınıfınız olsun:
|
||||||
|
|
||||||
|
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
|
||||||
|
|
||||||
|
Sonra bir değişkeni `Person` tipinde olacak şekilde bildirebilirsiniz:
|
||||||
|
|
||||||
|
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
|
||||||
|
|
||||||
|
Ve sonra, yine tüm editör desteğini alırsınız:
|
||||||
|
|
||||||
<img src="/img/python-types/image06.png">
|
<img src="/img/python-types/image06.png">
|
||||||
|
|
||||||
## Pydantic modelleri
|
Bunun "`one_person`, `Person` sınıfının bir **instance**'ıdır" anlamına geldiğine dikkat edin.
|
||||||
|
|
||||||
<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> veri doğrulaması yapmak için bir Python kütüphanesidir.
|
"`one_person`, `Person` adlı **class**'tır" anlamına gelmez.
|
||||||
|
|
||||||
Verilerin "biçimini" niteliklere sahip sınıflar olarak düzenlersiniz.
|
## Pydantic modelleri { #pydantic-models }
|
||||||
|
|
||||||
Ve her niteliğin bir türü vardır.
|
<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, data validation yapmak için bir Python kütüphanesidir.
|
||||||
|
|
||||||
Sınıfın bazı değerlerle bir örneğini oluşturursunuz ve değerleri doğrular, bunları uygun türe dönüştürür ve size tüm verileri içeren bir nesne verir.
|
Verinin "shape"'ini attribute'lara sahip sınıflar olarak tanımlarsınız.
|
||||||
|
|
||||||
Ve ortaya çıkan nesne üzerindeki bütün editör desteğini alırsınız.
|
Ve her attribute'un bir tipi vardır.
|
||||||
|
|
||||||
Resmi Pydantic dokümanlarından alınmıştır:
|
Ardından o sınıfın bir instance'ını bazı değerlerle oluşturursunuz; bu değerleri doğrular, uygun tipe dönüştürür (gerekliyse) ve size tüm veriyi içeren bir nesne verir.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial011.py *}
|
Ve bu ortaya çıkan nesne ile tüm editör desteğini alırsınız.
|
||||||
|
|
||||||
|
Resmî Pydantic dokümanlarından bir örnek:
|
||||||
|
|
||||||
/// info
|
{* ../../docs_src/python_types/tutorial011_py310.py *}
|
||||||
|
|
||||||
Daha fazla şey öğrenmek için <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic'i takip edin</a>.
|
/// info | Bilgi
|
||||||
|
|
||||||
|
Daha fazlasını öğrenmek için <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic'in dokümanlarına bakın</a>.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
**FastAPI** tamamen Pydantic'e dayanmaktadır.
|
**FastAPI** tamamen Pydantic üzerine kuruludur.
|
||||||
|
|
||||||
Daha fazlasini görmek için [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
|
Bunların pratikte nasıl çalıştığını [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank} içinde çok daha fazla göreceksiniz.
|
||||||
|
|
||||||
## **FastAPI** tip belirteçleri
|
/// tip | İpucu
|
||||||
|
|
||||||
**FastAPI** birkaç şey yapmak için bu tür tip belirteçlerinden faydalanır.
|
Pydantic, default value olmadan `Optional` veya `Union[Something, None]` kullandığınızda özel bir davranışa sahiptir; bununla ilgili daha fazla bilgiyi Pydantic dokümanlarında <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a> bölümünde okuyabilirsiniz.
|
||||||
|
|
||||||
**FastAPI** ile parametre tiplerini bildirirsiniz ve şunları elde edersiniz:
|
///
|
||||||
|
|
||||||
* **Editor desteği**.
|
## Metadata Annotations ile Type Hints { #type-hints-with-metadata-annotations }
|
||||||
* **Tip kontrolü**.
|
|
||||||
|
Python'da ayrıca, `Annotated` kullanarak bu type hints içine **ek <abbr title="Veri hakkında veri; bu durumda type hakkında bilgi, örneğin bir açıklama.">metadata</abbr>** koymayı sağlayan bir özellik de vardır.
|
||||||
...ve **FastAPI** aynı belirteçleri şunlar için de kullanıyor:
|
|
||||||
|
Python 3.9'dan itibaren `Annotated`, standart kütüphanenin bir parçasıdır; bu yüzden `typing` içinden import edebilirsiniz.
|
||||||
* **Gereksinimleri tanımlama**: request path parameters, query parameters, headers, bodies, dependencies, ve benzeri gereksinimlerden
|
|
||||||
* **Verileri çevirme**: Gönderilen veri tipinden istenilen veri tipine çevirme.
|
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
|
||||||
* **Verileri doğrulama**: Her gönderilen verinin:
|
|
||||||
* doğrulanması ve geçersiz olduğunda **otomatik hata** oluşturma.
|
Python'un kendisi bu `Annotated` ile bir şey yapmaz. Editörler ve diğer araçlar için tip hâlâ `str`'dir.
|
||||||
* OpenAPI kullanarak apinizi **Belgeleyin** :
|
|
||||||
* bu daha sonra otomatik etkileşimli dokümantasyon kullanıcı arayüzü tarafından kullanılır.
|
Ama **FastAPI**'ye uygulamanızın nasıl davranmasını istediğinize dair ek metadata sağlamak için `Annotated` içindeki bu alanı kullanabilirsiniz.
|
||||||
|
|
||||||
Bütün bunlar kulağa soyut gelebilir. Merak etme. Tüm bunları çalışırken göreceksiniz. [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
|
Hatırlanması gereken önemli nokta: `Annotated`'a verdiğiniz **ilk *type parameter***, **gerçek tip**tir. Geri kalanı ise diğer araçlar için metadatadır.
|
||||||
|
|
||||||
Önemli olan, standart Python türlerini tek bir yerde kullanarak (daha fazla sınıf, dekoratör vb. eklemek yerine), **FastAPI**'nin bizim için işi yapmasını sağlamak.
|
Şimdilik, sadece `Annotated`'ın var olduğunu ve bunun standart Python olduğunu bilmeniz yeterli. 😎
|
||||||
|
|
||||||
/// info
|
İleride bunun ne kadar **güçlü** olabildiğini göreceksiniz.
|
||||||
|
|
||||||
Tüm öğreticiyi zaten okuduysanız ve türler hakkında daha fazla bilgi için geri döndüyseniz, iyi bir kaynak:<a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank"> the "cheat sheet" from `mypy`</a>.
|
/// tip | İpucu
|
||||||
|
|
||||||
|
Bunun **standart Python** olması, editörünüzde mümkün olan **en iyi developer experience**'ı almaya devam edeceğiniz anlamına gelir; kodu analiz etmek ve refactor etmek için kullandığınız araçlarla da, vb. ✨
|
||||||
|
|
||||||
|
Ayrıca kodunuzun pek çok başka Python aracı ve kütüphanesiyle çok uyumlu olacağı anlamına gelir. 🚀
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
## **FastAPI**'de type hints { #type-hints-in-fastapi }
|
||||||
|
|
||||||
|
**FastAPI**, birkaç şey yapmak için bu type hints'ten faydalanır.
|
||||||
|
|
||||||
|
**FastAPI** ile type hints kullanarak parametreleri bildirirsiniz ve şunları elde edersiniz:
|
||||||
|
|
||||||
|
* **Editör desteği**.
|
||||||
|
* **Tip kontrolleri**.
|
||||||
|
|
||||||
|
...ve **FastAPI** aynı bildirimleri şunlar için de kullanır:
|
||||||
|
|
||||||
|
* **Gereksinimleri tanımlamak**: request path parameters, query parameters, headers, bodies, dependencies, vb.
|
||||||
|
* **Veriyi dönüştürmek**: request'ten gerekli tipe.
|
||||||
|
* **Veriyi doğrulamak**: her request'ten gelen veriyi:
|
||||||
|
* Veri geçersiz olduğunda client'a dönen **otomatik hatalar** üretmek.
|
||||||
|
* OpenAPI kullanarak API'yi **dokümante etmek**:
|
||||||
|
* bu, daha sonra otomatik etkileşimli dokümantasyon kullanıcı arayüzleri tarafından kullanılır.
|
||||||
|
|
||||||
|
Bunların hepsi kulağa soyut gelebilir. Merak etmeyin. Tüm bunları [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank} içinde çalışırken göreceksiniz.
|
||||||
|
|
||||||
|
Önemli olan, standart Python tiplerini tek bir yerde kullanarak (daha fazla sınıf, decorator vb. eklemek yerine), **FastAPI**'nin sizin için işin büyük kısmını yapmasıdır.
|
||||||
|
|
||||||
|
/// info | Bilgi
|
||||||
|
|
||||||
|
Tüm tutorial'ı zaten bitirdiyseniz ve tipler hakkında daha fazlasını görmek için geri döndüyseniz, iyi bir kaynak: <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">`mypy`'nin "cheat sheet"i</a>.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Kaynaklar
|
# Kaynaklar { #resources }
|
||||||
|
|
||||||
Ek kaynaklar, dış bağlantılar, makaleler ve daha fazlası. ✈️
|
Ek kaynaklar, dış bağlantılar ve daha fazlası. ✈️
|
||||||
|
|||||||
@@ -1,35 +1,45 @@
|
|||||||
# Çerez (Cookie) Parametreleri
|
# Çerez (Cookie) Parametreleri { #cookie-parameters }
|
||||||
|
|
||||||
`Query` (Sorgu) ve `Path` (Yol) parametrelerini tanımladığınız şekilde çerez parametreleri tanımlayabilirsiniz.
|
`Query` ve `Path` parametrelerini tanımladığınız şekilde Cookie parametreleri tanımlayabilirsiniz.
|
||||||
|
|
||||||
## Import `Cookie`
|
## `Cookie`'yi Import Edin { #import-cookie }
|
||||||
|
|
||||||
Öncelikle, `Cookie`'yi projenize dahil edin:
|
Öncelikle, `Cookie`'yi import edin:
|
||||||
|
|
||||||
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
|
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
|
||||||
|
|
||||||
## `Cookie` Parametrelerini Tanımlayın
|
## `Cookie` Parametrelerini Tanımlayın { #declare-cookie-parameters }
|
||||||
|
|
||||||
Çerez parametrelerini `Path` veya `Query` tanımlaması yapar gibi tanımlayın.
|
Ardından, `Path` ve `Query` ile aynı yapıyı kullanarak Cookie parametrelerini tanımlayın.
|
||||||
|
|
||||||
İlk değer varsayılan değerdir; tüm ekstra doğrulama veya belirteç parametrelerini kullanabilirsiniz:
|
Varsayılan değeri ve tüm ekstra doğrulama veya annotation parametrelerini tanımlayabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
|
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
|
||||||
|
|
||||||
/// note | Teknik Detaylar
|
/// note | Teknik Detaylar
|
||||||
|
|
||||||
`Cookie` sınıfı `Path` ve `Query` sınıflarının kardeşidir. Diğerleri gibi `Param` sınıfını miras alan bir sınıftır.
|
`Cookie`, `Path` ve `Query`'nin "kardeş" sınıfıdır. O da aynı ortak `Param` sınıfından miras alır.
|
||||||
|
|
||||||
Ancak `fastapi`'dan projenize dahil ettiğiniz `Query`, `Path`, `Cookie` ve diğerleri aslında özel sınıflar döndüren birer fonksiyondur.
|
Ancak `fastapi`'dan `Query`, `Path`, `Cookie` ve diğerlerini import ettiğinizde, bunlar aslında özel sınıflar döndüren fonksiyonlardır, bunu unutmayın.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
/// info | Bilgi
|
/// info | Bilgi
|
||||||
|
|
||||||
Çerez tanımlamak için `Cookie` sınıfını kullanmanız gerekmektedir, aksi taktirde parametreler sorgu parametreleri olarak yorumlanır.
|
Çerezleri tanımlamak için `Cookie` kullanmanız gerekir, aksi halde parametreler query parametreleri olarak yorumlanır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Özet
|
/// info | Bilgi
|
||||||
|
|
||||||
Çerez tanımlamalarını `Cookie` sınıfını kullanarak `Query` ve `Path` tanımlar gibi tanımlayın.
|
**Tarayıcılar çerezleri** özel şekillerde ve arka planda işlediği için, **JavaScript**'in onlara dokunmasına kolayca izin **vermezler**.
|
||||||
|
|
||||||
|
`/docs` adresindeki **API docs UI**'a giderseniz, *path operation*'larınız için çerezlerin **dokümantasyonunu** görebilirsiniz.
|
||||||
|
|
||||||
|
Ancak **veriyi doldurup** "Execute" düğmesine tıklasanız bile, docs UI **JavaScript** ile çalıştığı için çerezler gönderilmez ve herhangi bir değer yazmamışsınız gibi bir **hata** mesajı görürsünüz.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
## Özet { #recap }
|
||||||
|
|
||||||
|
`Query` ve `Path` ile aynı ortak deseni kullanarak, çerezleri `Cookie` ile tanımlayın.
|
||||||
|
|||||||
@@ -1,102 +1,118 @@
|
|||||||
# İlk Adımlar
|
# İlk Adımlar { #first-steps }
|
||||||
|
|
||||||
En sade FastAPI dosyası şu şekilde görünür:
|
En sade FastAPI dosyası şu şekilde görünür:
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py *}
|
||||||
|
|
||||||
Yukarıdaki içeriği bir `main.py` dosyasına kopyalayalım.
|
Yukarıdakini `main.py` adlı bir dosyaya kopyalayın.
|
||||||
|
|
||||||
Uygulamayı çalıştıralım:
|
Canlı sunucuyu çalıştırın:
|
||||||
|
|
||||||
<div class="termy">
|
<div class="termy">
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ uvicorn main:app --reload
|
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
|
||||||
|
|
||||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||||
<span style="color: green;">INFO</span>: Started reloader process [28720]
|
|
||||||
<span style="color: green;">INFO</span>: Started server process [28722]
|
Searching for package file structure from directories
|
||||||
<span style="color: green;">INFO</span>: Waiting for application startup.
|
with <font color="#3465A4">__init__.py</font> files
|
||||||
<span style="color: green;">INFO</span>: Application startup complete.
|
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||||
|
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
|
||||||
|
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
|
||||||
|
the following code:
|
||||||
|
|
||||||
|
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
|
||||||
|
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
|
||||||
|
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
|
||||||
|
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span> Running in development mode, for production use:
|
||||||
|
<b>fastapi run</b>
|
||||||
|
|
||||||
|
Logs:
|
||||||
|
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Will watch for changes in these directories:
|
||||||
|
<b>[</b><font color="#4E9A06">'/home/user/code/awesomeapp'</font><b>]</b>
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
|
||||||
|
to quit<b>)</b>
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
/// note | Not
|
Çıktıda, şuna benzer bir satır göreceksiniz:
|
||||||
|
|
||||||
`uvicorn main:app` komutunu şu şekilde açıklayabiliriz:
|
|
||||||
|
|
||||||
* `main`: dosya olan `main.py` (yani Python "modülü").
|
|
||||||
* `app`: ise `main.py` dosyasının içerisinde `app = FastAPI()` satırında oluşturduğumuz `FastAPI` nesnesi.
|
|
||||||
* `--reload`: kod değişikliklerinin ardından sunucuyu otomatik olarak yeniden başlatır. Bu parameteyi sadece geliştirme aşamasında kullanmalıyız.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
Çıktı olarak şöyle bir satır ile karşılaşacaksınız:
|
|
||||||
|
|
||||||
```hl_lines="4"
|
```hl_lines="4"
|
||||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||||
```
|
```
|
||||||
|
|
||||||
Bu satır, yerel makinenizde uygulamanızın çalıştığı bağlantıyı gösterir.
|
Bu satır, uygulamanızın yerel makinenizde hangi URL'de sunulduğunu gösterir.
|
||||||
|
|
||||||
### Kontrol Edelim
|
### Kontrol Edelim { #check-it }
|
||||||
|
|
||||||
Tarayıcınızı açıp <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> bağlantısına gidin.
|
Tarayıcınızı açıp <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> adresine gidin.
|
||||||
|
|
||||||
Şu şekilde bir JSON yanıtı ile karşılaşacağız:
|
Şu şekilde bir JSON response göreceksiniz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{"message": "Hello World"}
|
{"message": "Hello World"}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Etkileşimli API Dokümantasyonu
|
### Etkileşimli API Dokümantasyonu { #interactive-api-docs }
|
||||||
|
|
||||||
Şimdi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> bağlantısını açalım.
|
Şimdi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> adresine gidin.
|
||||||
|
|
||||||
<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tarafından sağlanan otomatik etkileşimli bir API dokümantasyonu göreceğiz:
|
Otomatik etkileşimli API dokümantasyonunu ( <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tarafından sağlanan) göreceksiniz:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Alternatif API Dokümantasyonu
|
### Alternatif API Dokümantasyonu { #alternative-api-docs }
|
||||||
|
|
||||||
Şimdi <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> bağlantısını açalım.
|
Ve şimdi <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> adresine gidin.
|
||||||
|
|
||||||
<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tarafından sağlanan otomatik dokümantasyonu göreceğiz:
|
Alternatif otomatik dokümantasyonu ( <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tarafından sağlanan) göreceksiniz:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### OpenAPI
|
### OpenAPI { #openapi }
|
||||||
|
|
||||||
**FastAPI**, **OpenAPI** standardını kullanarak tüm API'ınızın tamamını tanımlayan bir "şema" oluşturur.
|
**FastAPI**, API'ları tanımlamak için **OpenAPI** standardını kullanarak tüm API'nızın tamamını içeren bir "şema" üretir.
|
||||||
|
|
||||||
#### "Şema"
|
#### "Şema" { #schema }
|
||||||
|
|
||||||
"Şema", bir şeyin tanımı veya açıklamasıdır. Geliştirilen koddan ziyade soyut bir açıklamadır.
|
"Şema", bir şeyin tanımı veya açıklamasıdır. Onu uygulayan kod değil, sadece soyut bir açıklamadır.
|
||||||
|
|
||||||
#### API "Şeması"
|
#### API "şeması" { #api-schema }
|
||||||
|
|
||||||
Bu durumda, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>, API şemasını nasıl tanımlayacağınızı belirten bir şartnamedir.
|
Bu durumda, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>, API'nızın şemasını nasıl tanımlayacağınızı belirleyen bir şartnamedir.
|
||||||
|
|
||||||
Bu şema tanımı, API yollarınızla birlikte yollarınızın aldığı olası parametreler gibi tanımlamaları içerir.
|
Bu şema tanımı, API path'leriniz, alabilecekleri olası parametreler vb. şeyleri içerir.
|
||||||
|
|
||||||
#### Veri "Şeması"
|
#### Veri "şeması" { #data-schema }
|
||||||
|
|
||||||
"Şema" terimi, JSON içeriği gibi bazı verilerin şeklini de ifade edebilir.
|
"Şema" terimi, JSON içeriği gibi bazı verilerin şeklini de ifade edebilir.
|
||||||
|
|
||||||
Bu durumda, JSON özellikleri ve sahip oldukları veri türleri gibi anlamlarına gelir.
|
Bu durumda, JSON attribute'ları ve sahip oldukları veri türleri vb. anlamına gelir.
|
||||||
|
|
||||||
#### OpenAPI ve JSON Şema
|
#### OpenAPI ve JSON Schema { #openapi-and-json-schema }
|
||||||
|
|
||||||
OpenAPI, API'niz için bir API şeması tanımlar. Ve bu şema, JSON veri şemaları standardı olan **JSON Şema** kullanılarak API'niz tarafından gönderilen ve alınan verilerin tanımlarını (veya "şemalarını") içerir.
|
OpenAPI, API'nız için bir API şeması tanımlar. Ve bu şema, JSON veri şemaları standardı olan **JSON Schema** kullanılarak API'nız tarafından gönderilen ve alınan verilerin tanımlarını (veya "şemalarını") içerir.
|
||||||
|
|
||||||
#### `openapi.json` Dosyasına Göz At
|
#### `openapi.json` Dosyasına Göz At { #check-the-openapi-json }
|
||||||
|
|
||||||
Ham OpenAPI şemasının nasıl göründüğünü merak ediyorsanız, FastAPI otomatik olarak tüm API'ınızın tanımlamalarını içeren bir JSON (şeması) oluşturur.
|
Ham OpenAPI şemasının nasıl göründüğünü merak ediyorsanız, FastAPI otomatik olarak tüm API'nızın açıklamalarını içeren bir JSON (şema) üretir.
|
||||||
|
|
||||||
Bu şemayı direkt olarak <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a> bağlantısından görüntüleyebilirsiniz.
|
Bunu doğrudan şuradan görebilirsiniz: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
|
||||||
|
|
||||||
Aşağıdaki gibi başlayan bir JSON ile karşılaşacaksınız:
|
Şuna benzer bir şekilde başlayan bir JSON gösterecektir:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -119,79 +135,87 @@ Aşağıdaki gibi başlayan bir JSON ile karşılaşacaksınız:
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
#### OpenAPI Ne İşe Yarar?
|
#### OpenAPI Ne İşe Yarar? { #what-is-openapi-for }
|
||||||
|
|
||||||
OpenAPI şeması, FastAPI projesinde bulunan iki etkileşimli dokümantasyon sistemine güç veren şeydir.
|
OpenAPI şeması, dahil edilen iki etkileşimli dokümantasyon sistemine güç veren şeydir.
|
||||||
|
|
||||||
OpenAPI'ya dayalı düzinelerce alternatif etkileşimli dokümantasyon aracı mevcuttur. **FastAPI** ile oluşturulmuş uygulamanıza bu alternatiflerden herhangi birini kolayca ekleyebilirsiniz.
|
Ve OpenAPI tabanlı düzinelerce alternatif vardır. **FastAPI** ile oluşturulmuş uygulamanıza bu alternatiflerden herhangi birini kolayca ekleyebilirsiniz.
|
||||||
|
|
||||||
Ayrıca, API'ınızla iletişim kuracak önyüz, mobil veya IoT uygulamaları gibi istemciler için otomatik olarak kod oluşturabilirsiniz.
|
Ayrıca, API'nızla iletişim kuran istemciler için otomatik olarak kod üretmekte de kullanabilirsiniz. Örneğin frontend, mobil veya IoT uygulamaları.
|
||||||
|
|
||||||
## Adım Adım Özetleyelim
|
### Uygulamanızı Yayınlayın (opsiyonel) { #deploy-your-app-optional }
|
||||||
|
|
||||||
### Adım 1: `FastAPI`yı Projemize Dahil Edelim
|
İsterseniz FastAPI uygulamanızı <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>'a deploy edebilirsiniz; henüz katılmadıysanız gidip bekleme listesine yazılın. 🚀
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
|
Zaten bir **FastAPI Cloud** hesabınız varsa (bekleme listesinden sizi davet ettiysek 😉), uygulamanızı tek komutla deploy edebilirsiniz.
|
||||||
|
|
||||||
`FastAPI`, API'niz için tüm işlevselliği sağlayan bir Python sınıfıdır.
|
Deploy etmeden önce giriş yaptığınızdan emin olun:
|
||||||
|
|
||||||
|
<div class="termy">
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ fastapi login
|
||||||
|
|
||||||
|
You are logged in to FastAPI Cloud 🚀
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Ardından uygulamanızı deploy edin:
|
||||||
|
|
||||||
|
<div class="termy">
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ fastapi deploy
|
||||||
|
|
||||||
|
Deploying to FastAPI Cloud...
|
||||||
|
|
||||||
|
✅ Deployment successful!
|
||||||
|
|
||||||
|
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Bu kadar! Artık uygulamanıza o URL üzerinden erişebilirsiniz. ✨
|
||||||
|
|
||||||
|
## Adım Adım Özetleyelim { #recap-step-by-step }
|
||||||
|
|
||||||
|
### Adım 1: `FastAPI` import edin { #step-1-import-fastapi }
|
||||||
|
|
||||||
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
|
||||||
|
|
||||||
|
`FastAPI`, API'nız için tüm işlevselliği sağlayan bir Python class'ıdır.
|
||||||
|
|
||||||
/// note | Teknik Detaylar
|
/// note | Teknik Detaylar
|
||||||
|
|
||||||
`FastAPI` doğrudan `Starlette`'i miras alan bir sınıftır.
|
`FastAPI`, doğrudan `Starlette`'ten miras alan bir class'tır.
|
||||||
|
|
||||||
<a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>'in tüm işlevselliğini `FastAPI` ile de kullanabilirsiniz.
|
<a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>'in tüm işlevselliğini `FastAPI` ile de kullanabilirsiniz.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Adım 2: Bir `FastAPI` "Örneği" Oluşturalım
|
### Adım 2: bir `FastAPI` "instance"ı oluşturun { #step-2-create-a-fastapi-instance }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
|
||||||
|
|
||||||
Burada `app` değişkeni `FastAPI` sınıfının bir örneği olacaktır.
|
Burada `app` değişkeni `FastAPI` class'ının bir "instance"ı olacaktır.
|
||||||
|
|
||||||
Bu, tüm API'yı oluşturmak için ana etkileşim noktası olacaktır.
|
Bu, tüm API'nızı oluşturmak için ana etkileşim noktası olacaktır.
|
||||||
|
|
||||||
Bu `app` değişkeni, `uvicorn` komutunda atıfta bulunulan değişkenin ta kendisidir.
|
### Adım 3: bir *path operation* oluşturun { #step-3-create-a-path-operation }
|
||||||
|
|
||||||
<div class="termy">
|
#### Path { #path }
|
||||||
|
|
||||||
```console
|
Buradaki "Path", URL'in ilk `/` işaretinden başlayarak son kısmını ifade eder.
|
||||||
$ uvicorn main:app --reload
|
|
||||||
|
|
||||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
Yani, şu şekilde bir URL'de:
|
||||||
```
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Uygulamanızı aşağıdaki gibi oluşturursanız:
|
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
|
|
||||||
|
|
||||||
Ve bunu `main.py` dosyasına yerleştirirseniz eğer `uvicorn` komutunu şu şekilde çalıştırabilirsiniz:
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
### Adım 3: Bir *Yol Operasyonu* Oluşturalım
|
|
||||||
|
|
||||||
#### <abbr title="Yol: Path">Yol</abbr>
|
|
||||||
|
|
||||||
Burada "yol" bağlantıda bulunan ilk `/` ile başlayan ve sonrasında gelen kısmı ifade eder.
|
|
||||||
|
|
||||||
Yani, şu şekilde bir bağlantıda:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
https://example.com/items/foo
|
https://example.com/items/foo
|
||||||
```
|
```
|
||||||
|
|
||||||
... yol şöyle olur:
|
...path şöyle olur:
|
||||||
|
|
||||||
```
|
```
|
||||||
/items/foo
|
/items/foo
|
||||||
@@ -199,77 +223,77 @@ https://example.com/items/foo
|
|||||||
|
|
||||||
/// info | Bilgi
|
/// info | Bilgi
|
||||||
|
|
||||||
"Yol" genellikle "<abbr title="Endpoint: Bitim Noktası">endpoint</abbr>" veya "<abbr title="Route: Yönlendirme/Yön">route</abbr>" olarak adlandırılır.
|
Bir "path" genellikle "endpoint" veya "route" olarak da adlandırılır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Bir API oluştururken, "yol", "kaynaklar" ile "endişeleri" ayırmanın ana yöntemidir.
|
Bir API oluştururken, "path", "concerns" ve "resources" ayrımını yapmanın ana yoludur.
|
||||||
|
|
||||||
#### Operasyonlar
|
#### Operation { #operation }
|
||||||
|
|
||||||
Burada "operasyon" HTTP "metodlarından" birini ifade eder.
|
Burada "Operation", HTTP "method"larından birini ifade eder.
|
||||||
|
|
||||||
Bunlardan biri:
|
Şunlardan biri:
|
||||||
|
|
||||||
* `POST`
|
* `POST`
|
||||||
* `GET`
|
* `GET`
|
||||||
* `PUT`
|
* `PUT`
|
||||||
* `DELETE`
|
* `DELETE`
|
||||||
|
|
||||||
...veya daha az kullanılan diğerleri:
|
...ve daha egzotik olanlar:
|
||||||
|
|
||||||
* `OPTIONS`
|
* `OPTIONS`
|
||||||
* `HEAD`
|
* `HEAD`
|
||||||
* `PATCH`
|
* `PATCH`
|
||||||
* `TRACE`
|
* `TRACE`
|
||||||
|
|
||||||
HTTP protokolünde, bu "metodlardan" birini (veya daha fazlasını) kullanarak her bir yol ile iletişim kurabilirsiniz.
|
HTTP protokolünde, her bir path ile bu "method"lardan biri (veya birden fazlası) ile iletişim kurabilirsiniz.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
API oluştururkan, belirli bir amaca hizmet eden belirli HTTP metodlarını kullanırsınız.
|
API oluştururken, normalde belirli bir aksiyon için bu spesifik HTTP method'larını kullanırsınız.
|
||||||
|
|
||||||
Normalde kullanılan:
|
Normalde şunları kullanırsınız:
|
||||||
|
|
||||||
* `POST`: veri oluşturmak.
|
* `POST`: veri oluşturmak için.
|
||||||
* `GET`: veri okumak.
|
* `GET`: veri okumak için.
|
||||||
* `PUT`: veriyi güncellemek.
|
* `PUT`: veriyi güncellemek için.
|
||||||
* `DELETE`: veriyi silmek.
|
* `DELETE`: veriyi silmek için.
|
||||||
|
|
||||||
Bu nedenle, OpenAPI'da HTTP metodlarından her birine "operasyon" denir.
|
Bu nedenle, OpenAPI'da HTTP method'larının her birine "operation" denir.
|
||||||
|
|
||||||
Biz de onları "**operasyonlar**" olarak adlandıracağız.
|
Biz de bunlara "**operation**" diyeceğiz.
|
||||||
|
|
||||||
#### Bir *Yol Operasyonu Dekoratörü* Tanımlayalım
|
#### Bir *path operation decorator* tanımlayın { #define-a-path-operation-decorator }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
`@app.get("/")` dekoratörü, **FastAPI**'a hemen altındaki fonksiyonun aşağıdaki durumlardan sorumlu olduğunu söyler:
|
`@app.get("/")`, **FastAPI**'a hemen altındaki fonksiyonun şuraya giden request'leri ele almakla sorumlu olduğunu söyler:
|
||||||
|
|
||||||
* <abbr title="Bir HTTP GET metodu"><code>get</code> operasyonu</abbr> ile
|
* path `/`
|
||||||
* `/` yoluna gelen istekler
|
* <abbr title="bir HTTP GET method'u"><code>get</code> operation</abbr> kullanarak
|
||||||
|
|
||||||
/// info | `@decorator` Bilgisi
|
/// info | `@decorator` Bilgisi
|
||||||
|
|
||||||
Python'da `@something` sözdizimi "<abbr title="Decorator">dekoratör</abbr>" olarak adlandırılır.
|
Python'daki `@something` söz dizimi "decorator" olarak adlandırılır.
|
||||||
|
|
||||||
Dekoratörler, dekoratif bir şapka gibi (sanırım terim buradan geliyor) fonksiyonların üzerlerine yerleştirilirler.
|
Onu bir fonksiyonun üstüne koyarsınız. Güzel, dekoratif bir şapka gibi (sanırım terim de buradan geliyor).
|
||||||
|
|
||||||
Bir "dekoratör" hemen altında bulunan fonksiyonu alır ve o fonksiyon ile bazı işlemler gerçekleştirir.
|
Bir "decorator", altındaki fonksiyonu alır ve onunla bir şey yapar.
|
||||||
|
|
||||||
Bizim durumumuzda, kullandığımız dekoratör, **FastAPI**'a altındaki fonksiyonun `/` yoluna gelen `get` metodlu isteklerden sorumlu olduğunu söyler.
|
Bizim durumumuzda bu decorator, **FastAPI**'a altındaki fonksiyonun **path** `/` ile **operation** `get`'e karşılık geldiğini söyler.
|
||||||
|
|
||||||
Bu bir **yol operasyonu dekoratörüdür**.
|
Bu, "**path operation decorator**"dır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Ayrıca diğer operasyonları da kullanabilirsiniz:
|
Diğer operation'ları da kullanabilirsiniz:
|
||||||
|
|
||||||
* `@app.post()`
|
* `@app.post()`
|
||||||
* `@app.put()`
|
* `@app.put()`
|
||||||
* `@app.delete()`
|
* `@app.delete()`
|
||||||
|
|
||||||
Daha az kullanılanları da kullanabilirsiniz:
|
Ve daha egzotik olanları:
|
||||||
|
|
||||||
* `@app.options()`
|
* `@app.options()`
|
||||||
* `@app.head()`
|
* `@app.head()`
|
||||||
@@ -278,58 +302,79 @@ Daha az kullanılanları da kullanabilirsiniz:
|
|||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
Her işlemi (HTTP metod) istediğiniz gibi kullanmakta özgürsünüz.
|
Her bir operation'ı (HTTP method'unu) istediğiniz gibi kullanmakta özgürsünüz.
|
||||||
|
|
||||||
**FastAPI** herhangi bir özel amacı veya anlamı olması konusunda ısrarcı olmaz.
|
**FastAPI** herhangi bir özel anlamı zorunlu kılmaz.
|
||||||
|
|
||||||
Buradaki bilgiler bir gereklilik değil, bir kılavuz olarak sunulmaktadır.
|
Buradaki bilgiler bir gereklilik değil, bir kılavuz olarak sunulmaktadır.
|
||||||
|
|
||||||
Mesela GraphQL kullanırkan genelde tüm işlemleri yalnızca `POST` operasyonunu kullanarak gerçekleştirirsiniz.
|
Örneğin GraphQL kullanırken, normalde tüm aksiyonları yalnızca `POST` operation'ları kullanarak gerçekleştirirsiniz.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Adım 4: **Yol Operasyonu Fonksiyonunu** Tanımlayın
|
### Adım 4: **path operation function**'ı tanımlayın { #step-4-define-the-path-operation-function }
|
||||||
|
|
||||||
Aşağıdaki, bizim **yol operasyonu fonksiyonumuzdur**:
|
Bu bizim "**path operation function**"ımız:
|
||||||
|
|
||||||
* **yol**: `/`
|
* **path**: `/`.
|
||||||
* **operasyon**: `get`
|
* **operation**: `get`.
|
||||||
* **fonksiyon**: "dekoratör"ün (`@app.get("/")`'in) altındaki fonksiyondur.
|
* **function**: "decorator"ün altındaki fonksiyondur (`@app.get("/")`'in altındaki).
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
|
||||||
|
|
||||||
Bu bir Python fonksiyonudur.
|
Bu bir Python fonksiyonudur.
|
||||||
|
|
||||||
Bu fonksiyon bir `GET` işlemi kullanılarak "`/`" bağlantısına bir istek geldiğinde **FastAPI** tarafından çağrılır.
|
**FastAPI**, "`/`" URL'ine `GET` operation kullanarak bir request aldığında bu fonksiyonu çağıracaktır.
|
||||||
|
|
||||||
Bu durumda bu fonksiyon bir `async` fonksiyondur.
|
Bu durumda, bu bir `async` fonksiyondur.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Bu fonksiyonu `async def` yerine normal bir fonksiyon olarak da tanımlayabilirsiniz.
|
Bunu `async def` yerine normal bir fonksiyon olarak da tanımlayabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
|
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
|
||||||
|
|
||||||
/// note | Not
|
/// note | Not
|
||||||
|
|
||||||
Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} sayfasını kontrol edebilirsiniz.
|
Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} sayfasına bakın.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Adım 5: İçeriği Geri Döndürün
|
### Adım 5: içeriği döndürün { #step-5-return-the-content }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
|
||||||
|
|
||||||
Bir `dict`, `list` veya `str`, `int` gibi tekil değerler döndürebilirsiniz.
|
Bir `dict`, `list`, `str`, `int` vb. tekil değerler döndürebilirsiniz.
|
||||||
|
|
||||||
Ayrıca, Pydantic modelleri de döndürebilirsiniz (bu konu ileriki aşamalarda irdelenecektir).
|
Ayrıca Pydantic modelleri de döndürebilirsiniz (bununla ilgili daha fazlasını ileride göreceksiniz).
|
||||||
|
|
||||||
Otomatik olarak JSON'a dönüştürülecek (ORM'ler vb. dahil) başka birçok nesne ve model vardır. En beğendiklerinizi kullanmayı deneyin, yüksek ihtimalle destekleniyordur.
|
Otomatik olarak JSON'a dönüştürülecek (ORM'ler vb. dahil) başka birçok nesne ve model vardır. En sevdiğiniz nesne/model'leri kullanmayı deneyin; büyük ihtimalle zaten destekleniyordur.
|
||||||
|
|
||||||
## Özet
|
### Adım 6: Deploy edin { #step-6-deploy-it }
|
||||||
|
|
||||||
* `FastAPI`'yı projemize dahil ettik.
|
Uygulamanızı tek komutla **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**'a deploy edin: `fastapi deploy`. 🎉
|
||||||
* Bir `app` örneği oluşturduk.
|
|
||||||
* Bir **yol operasyonu dekoratörü** (`@app.get("/")` gibi) yazdık.
|
#### FastAPI Cloud Hakkında { #about-fastapi-cloud }
|
||||||
* Bir **yol operasyonu fonksiyonu** (`def root(): ...` gibi) yazdık.
|
|
||||||
* Geliştirme sunucumuzu (`uvicorn main:app --reload` gibi) çalıştırdık.
|
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**, **FastAPI**'ın arkasındaki aynı yazar ve ekip tarafından geliştirilmiştir.
|
||||||
|
|
||||||
|
Minimum eforla bir API'ı **oluşturma**, **deploy etme** ve **erişme** sürecini sadeleştirir.
|
||||||
|
|
||||||
|
FastAPI ile uygulama geliştirirken yaşadığınız aynı **developer experience**'ı, onları buluta **deploy etme** aşamasına da taşır. 🎉
|
||||||
|
|
||||||
|
FastAPI Cloud, *FastAPI and friends* açık kaynak projelerinin birincil sponsoru ve finansman sağlayıcısıdır. ✨
|
||||||
|
|
||||||
|
#### Diğer cloud sağlayıcılarına deploy edin { #deploy-to-other-cloud-providers }
|
||||||
|
|
||||||
|
FastAPI açık kaynaklıdır ve standartlara dayanır. FastAPI uygulamalarını seçtiğiniz herhangi bir cloud sağlayıcısına deploy edebilirsiniz.
|
||||||
|
|
||||||
|
FastAPI uygulamalarını onlarla deploy etmek için cloud sağlayıcınızın kılavuzlarını takip edin. 🤓
|
||||||
|
|
||||||
|
## Özet { #recap }
|
||||||
|
|
||||||
|
* `FastAPI` import edin.
|
||||||
|
* Bir `app` instance'ı oluşturun.
|
||||||
|
* `@app.get("/")` gibi decorator'ları kullanarak bir **path operation decorator** yazın.
|
||||||
|
* Bir **path operation function** tanımlayın; örneğin `def root(): ...`.
|
||||||
|
* `fastapi dev` komutunu kullanarak geliştirme sunucusunu çalıştırın.
|
||||||
|
* İsterseniz `fastapi deploy` ile uygulamanızı deploy edin.
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
# Yol Parametreleri
|
# Yol Parametreleri { #path-parameters }
|
||||||
|
|
||||||
Yol "parametrelerini" veya "değişkenlerini" Python <abbr title="String Biçimleme: Format String">string biçimlemede</abbr> kullanılan sözdizimi ile tanımlayabilirsiniz.
|
Python <abbr title="String Biçimleme: Format String">string biçimlemede</abbr> kullanılan sözdizimiyle path "parametreleri"ni veya "değişkenleri"ni tanımlayabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
|
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
|
||||||
|
|
||||||
Yol parametresi olan `item_id`'nin değeri, fonksiyonunuza `item_id` argümanı olarak aktarılacaktır.
|
Path parametresi `item_id`'nin değeri, fonksiyonunuza `item_id` argümanı olarak aktarılacaktır.
|
||||||
|
|
||||||
Eğer bu örneği çalıştırıp <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> sayfasına giderseniz, şöyle bir çıktı ile karşılaşırsınız:
|
Yani, bu örneği çalıştırıp <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> adresine giderseniz, şöyle bir response görürsünüz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{"item_id":"foo"}
|
{"item_id":"foo"}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tip İçeren Yol Parametreleri
|
## Tip İçeren Yol Parametreleri { #path-parameters-with-types }
|
||||||
|
|
||||||
Standart Python tip belirteçlerini kullanarak yol parametresinin tipini fonksiyonun içerisinde tanımlayabilirsiniz.
|
Standart Python tip belirteçlerini kullanarak path parametresinin tipini fonksiyonun içinde tanımlayabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial002.py hl[7] *}
|
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
|
||||||
|
|
||||||
Bu durumda, `item_id` bir `int` olarak tanımlanacaktır.
|
Bu durumda, `item_id` bir `int` olarak tanımlanır.
|
||||||
|
|
||||||
/// check | Ek bilgi
|
/// check | Ek bilgi
|
||||||
|
|
||||||
Bu sayede, fonksiyon içerisinde hata denetimi, kod tamamlama gibi konularda editör desteğine kavuşacaksınız.
|
Bu sayede, fonksiyon içinde hata denetimi, kod tamamlama vb. konularda editör desteğine kavuşursunuz.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Veri <abbr title="Dönüşüm: serialization, parsing ve marshalling olarak da biliniyor">Dönüşümü</abbr>
|
## Veri <abbr title="also known as: endpoints, routes">conversion</abbr> { #data-conversion }
|
||||||
|
|
||||||
Eğer bu örneği çalıştırıp tarayıcınızda <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a> sayfasını açarsanız, şöyle bir yanıt ile karşılaşırsınız:
|
Bu örneği çalıştırıp tarayıcınızda <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a> adresini açarsanız, şöyle bir response görürsünüz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{"item_id":3}
|
{"item_id":3}
|
||||||
@@ -36,15 +36,15 @@ Eğer bu örneği çalıştırıp tarayıcınızda <a href="http://127.0.0.1:800
|
|||||||
|
|
||||||
/// check | Ek bilgi
|
/// check | Ek bilgi
|
||||||
|
|
||||||
Dikkatinizi çekerim ki, fonksiyonunuzun aldığı (ve döndürdüğü) değer olan `3` bir string `"3"` değil aksine bir Python `int`'idir.
|
Dikkat edin: fonksiyonunuzun aldığı (ve döndürdüğü) değer olan `3`, string `"3"` değil, bir Python `int`'idir.
|
||||||
|
|
||||||
Bu tanımlamayla birlikte, **FastAPI** size otomatik istek <abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">"ayrıştırma"</abbr> özelliği sağlar.
|
Yani, bu tip tanımıyla birlikte **FastAPI** size otomatik request <abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">"parsing"</abbr> sağlar.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Veri Doğrulama
|
## Veri Doğrulama { #data-validation }
|
||||||
|
|
||||||
Eğer tarayıcınızda <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> sayfasını açarsanız, şuna benzer güzel bir HTTP hatası ile karşılaşırsınız:
|
Ancak tarayıcınızda <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> adresine giderseniz, şuna benzer güzel bir HTTP hatası görürsünüz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -62,141 +62,135 @@ Eğer tarayıcınızda <a href="http://127.0.0.1:8000/items/foo" class="external
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Çünkü burada `item_id` yol parametresi `int` tipinde bir değer beklerken `"foo"` yani `string` tipinde bir değer almıştı.
|
çünkü path parametresi `item_id`, `int` olmayan `"foo"` değerine sahipti.
|
||||||
|
|
||||||
Aynı hata <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a> sayfasında olduğu gibi `int` yerine `float` bir değer verseydik de ortaya çıkardı.
|
Aynı hata, şu örnekte olduğu gibi `int` yerine `float` verirseniz de ortaya çıkar: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
|
||||||
|
|
||||||
/// check | Ek bilgi
|
/// check | Ek bilgi
|
||||||
|
|
||||||
Böylece, aynı Python tip tanımlaması ile birlikte, **FastAPI** veri doğrulama özelliği sağlar.
|
Yani, aynı Python tip tanımıyla birlikte **FastAPI** size veri doğrulama sağlar.
|
||||||
|
|
||||||
Dikkatinizi çekerim ki, karşılaştığınız hata, doğrulamanın geçersiz olduğu mutlak noktayı da açık bir şekilde belirtiyor.
|
Dikkat edin: hata ayrıca doğrulamanın geçmediği noktayı da açıkça belirtir.
|
||||||
|
|
||||||
Bu özellik, API'ınızla iletişime geçen kodu geliştirirken ve ayıklarken inanılmaz derecede yararlı olacaktır.
|
Bu, API'ınızla etkileşime giren kodu geliştirirken ve debug ederken inanılmaz derecede faydalıdır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Dokümantasyon
|
## Dokümantasyon { #documentation }
|
||||||
|
|
||||||
Ayrıca, tarayıcınızı <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> adresinde açarsanız, aşağıdaki gibi otomatik ve interaktif bir API dökümantasyonu ile karşılaşırsınız:
|
Tarayıcınızı <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> adresinde açtığınızda, aşağıdaki gibi otomatik ve interaktif bir API dokümantasyonu görürsünüz:
|
||||||
|
|
||||||
<img src="/img/tutorial/path-params/image01.png">
|
<img src="/img/tutorial/path-params/image01.png">
|
||||||
|
|
||||||
/// check | Ek bilgi
|
/// check | Ek bilgi
|
||||||
|
|
||||||
Üstelik, sadece aynı Python tip tanımlaması ile, **FastAPI** size otomatik ve interaktif (Swagger UI ile entegre) bir dokümantasyon sağlar.
|
Yine, sadece aynı Python tip tanımıyla **FastAPI** size otomatik ve interaktif dokümantasyon (Swagger UI entegrasyonuyla) sağlar.
|
||||||
|
|
||||||
Dikkatinizi çekerim ki, yol parametresi integer olarak tanımlanmıştır.
|
Dikkat edin: path parametresi integer olarak tanımlanmıştır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Standartlara Dayalı Avantajlar, Alternatif Dokümantasyon
|
## Standartlara Dayalı Avantajlar, Alternatif Dokümantasyon { #standards-based-benefits-alternative-documentation }
|
||||||
|
|
||||||
Oluşturulan şema <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a> standardına uygun olduğu için birçok uyumlu araç mevcuttur.
|
Üretilen şema <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a> standardından geldiği için birçok uyumlu araç vardır.
|
||||||
|
|
||||||
Bu sayede, **FastAPI**'ın bizzat kendisi <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> sayfasından erişebileceğiniz alternatif (ReDoc kullanan) bir API dokümantasyonu sağlar:
|
Bu nedenle **FastAPI**'ın kendisi, <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> adresinden erişebileceğiniz alternatif bir API dokümantasyonu (ReDoc kullanarak) sağlar:
|
||||||
|
|
||||||
<img src="/img/tutorial/path-params/image02.png">
|
<img src="/img/tutorial/path-params/image02.png">
|
||||||
|
|
||||||
Aynı şekilde, farklı diller için kod türetme araçları da dahil olmak üzere çok sayıda uyumlu araç bulunur.
|
Aynı şekilde, birçok uyumlu araç vardır. Birçok dil için kod üretme araçları da buna dahildir.
|
||||||
|
|
||||||
## Pydantic
|
## Pydantic { #pydantic }
|
||||||
|
|
||||||
Tüm veri doğrulamaları <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> tarafından arka planda gerçekleştirilir, bu sayede tüm avantajlardan faydalanabilirsiniz. Böylece, emin ellerde olduğunuzu hissedebilirsiniz.
|
Tüm veri doğrulamaları, arka planda <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> tarafından gerçekleştirilir; böylece onun tüm avantajlarından faydalanırsınız. Ve emin ellerde olduğunuzu bilirsiniz.
|
||||||
|
|
||||||
Aynı tip tanımlamalarını `str`, `float`, `bool` ve diğer karmaşık veri tipleri ile kullanma imkanınız vardır.
|
Aynı tip tanımlarını `str`, `float`, `bool` ve daha birçok karmaşık veri tipiyle kullanabilirsiniz.
|
||||||
|
|
||||||
Bunlardan birkaçı, bu eğitimin ileriki bölümlerinde irdelenmiştir.
|
Bunların birkaçı, eğitimin sonraki bölümlerinde ele alınacaktır.
|
||||||
|
|
||||||
## Sıralama Önem Arz Eder
|
## Sıralama Önemlidir { #order-matters }
|
||||||
|
|
||||||
*Yol operasyonları* tasarlarken sabit yol barındıran durumlar ile karşılaşabilirsiniz.
|
*Path operation*'lar oluştururken sabit bir path'e sahip olduğunuz durumlarla karşılaşabilirsiniz.
|
||||||
|
|
||||||
Farz edelim ki `/users/me` yolu geçerli kullanıcı hakkında bilgi almak için kullanılıyor olsun.
|
Örneğin `/users/me`'nin, geçerli kullanıcı hakkında veri almak için kullanıldığını varsayalım.
|
||||||
|
|
||||||
Benzer şekilde `/users/{user_id}` gibi tanımlanmış ve belirli bir kullanıcı hakkında veri almak için kullanıcının ID bilgisini kullanan bir yolunuz da mevcut olabilir.
|
Sonra belirli bir kullanıcı hakkında, kullanıcı ID'si ile veri almak için `/users/{user_id}` şeklinde bir path'iniz de olabilir.
|
||||||
|
|
||||||
*Yol operasyonları* sıralı bir şekilde gözden geçirildiğinden dolayı `/users/me` yolunun `/users/{user_id}` yolundan önce tanımlanmış olmasından emin olmanız gerekmektedir:
|
*Path operation*'lar sırayla değerlendirildiği için, `/users/me` için olan path'in `/users/{user_id}` olandan önce tanımlandığından emin olmanız gerekir:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
|
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
|
||||||
|
|
||||||
Aksi halde, `/users/{user_id}` yolu `"me"` değerinin `user_id` parametresi için gönderildiğini "düşünerek" `/users/me` ile de eşleşir.
|
Aksi halde, `/users/{user_id}` için olan path, `"me"` değerini `user_id` parametresi olarak aldığını "düşünerek" `/users/me` için de eşleşir.
|
||||||
|
|
||||||
Benzer şekilde, bir yol operasyonunu yeniden tanımlamanız mümkün değildir:
|
Benzer şekilde, bir path operation'ı yeniden tanımlayamazsınız:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
|
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
|
||||||
|
|
||||||
Yol, ilk kısım ile eşleştiğinden dolayı her koşulda ilk yol operasyonu kullanılacaktır.
|
Path önce eşleştiği için her zaman ilk olan kullanılır.
|
||||||
|
|
||||||
## Ön Tanımlı Değerler
|
## Ön Tanımlı Değerler { #predefined-values }
|
||||||
|
|
||||||
Eğer *yol parametresi* alan bir *yol operasyonunuz* varsa ve alabileceği *yol parametresi* değerlerinin ön tanımlı olmasını istiyorsanız, standart Python <abbr title="Enumeration">`Enum`</abbr> tipini kullanabilirsiniz.
|
Bir *path operation*'ınız *path parameter* alıyorsa ama olası geçerli *path parameter* değerlerinin önceden tanımlı olmasını istiyorsanız, standart bir Python <abbr title="Enumeration">`Enum`</abbr> kullanabilirsiniz.
|
||||||
|
|
||||||
### Bir `Enum` Sınıfı Oluşturalım
|
### Bir `Enum` Sınıfı Oluşturalım { #create-an-enum-class }
|
||||||
|
|
||||||
`Enum` sınıfını projemize dahil edip `str` ile `Enum` sınıflarını miras alan bir alt sınıf yaratalım.
|
`Enum`'u import edin ve `str` ile `Enum`'dan miras alan bir alt sınıf oluşturun.
|
||||||
|
|
||||||
`str` sınıfı miras alındığından dolayı, API dokümanı, değerlerin `string` tipinde olması gerektiğini anlayabilecek ve doğru bir şekilde işlenecektir.
|
`str`'den miras aldığınızda API dokümanları değerlerin `string` tipinde olması gerektiğini anlayabilir ve doğru şekilde render edebilir.
|
||||||
|
|
||||||
Sonrasında, sınıf içerisinde, mevcut ve geçerli değerler olacak olan sabit değerli özelliklerini oluşturalım:
|
Sonra, kullanılabilir geçerli değerler olacak sabit değerli class attribute'ları oluşturun:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
|
||||||
|
|
||||||
/// info | Bilgi
|
|
||||||
|
|
||||||
3.4 sürümünden beri <a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">enumerationlar (ya da enumlar) Python'da mevcuttur</a>.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
Merak ediyorsanız söyleyeyim, "AlexNet", "ResNet" ve "LeNet" isimleri Makine Öğrenmesi <abbr title="Teknik olarak, Derin Öğrenme model mimarileri">modellerini</abbr> temsil eder.
|
Merak ediyorsanız: "AlexNet", "ResNet" ve "LeNet", Makine Öğrenmesi <abbr title="Technically, Deep Learning model architectures">modelleri</abbr>nin sadece isimleridir.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Bir *Yol Parametresi* Tanımlayalım
|
### Bir *Path Parameter* Tanımlayalım { #declare-a-path-parameter }
|
||||||
|
|
||||||
Sonrasında, yarattığımız enum sınıfını (`ModelName`) kullanarak tip belirteci aracılığıyla bir *yol parametresi* oluşturalım:
|
Ardından oluşturduğunuz enum sınıfını (`ModelName`) kullanarak tip belirteciyle bir *path parameter* oluşturun:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[16] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
|
||||||
|
|
||||||
### Dokümana Göz Atalım
|
### Dokümana Göz Atalım { #check-the-docs }
|
||||||
|
|
||||||
*Yol parametresi* için mevcut değerler ön tanımlı olduğundan dolayı, interaktif döküman onları güzel bir şekilde gösterebilir:
|
*Path parameter* için kullanılabilir değerler ön tanımlı olduğu için, interaktif dokümanlar bunları güzelce gösterebilir:
|
||||||
|
|
||||||
<img src="/img/tutorial/path-params/image03.png">
|
<img src="/img/tutorial/path-params/image03.png">
|
||||||
|
|
||||||
### Python *Enumerationları* ile Çalışmak
|
### Python *Enumeration*'ları ile Çalışmak { #working-with-python-enumerations }
|
||||||
|
|
||||||
*Yol parametresinin* değeri bir *enumeration üyesi* olacaktır.
|
*Path parameter*'ın değeri bir *enumeration member* olacaktır.
|
||||||
|
|
||||||
#### *Enumeration Üyelerini* Karşılaştıralım
|
#### *Enumeration Member*'ları Karşılaştıralım { #compare-enumeration-members }
|
||||||
|
|
||||||
Parametreyi, yarattığınız enum olan `ModelName` içerisindeki *enumeration üyesi* ile karşılaştırabilirsiniz:
|
Bunu, oluşturduğunuz enum `ModelName` içindeki *enumeration member* ile karşılaştırabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[17] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
|
||||||
|
|
||||||
#### *Enumeration Değerini* Edinelim
|
#### *Enumeration Value*'yu Alalım { #get-the-enumeration-value }
|
||||||
|
|
||||||
`model_name.value` veya genel olarak `your_enum_member.value` tanımlarını kullanarak (bu durumda bir `str` olan) gerçek değere ulaşabilirsiniz:
|
Gerçek değeri (bu durumda bir `str`) `model_name.value` ile veya genel olarak `your_enum_member.value` ile alabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[20] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
|
||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
`"lenet"` değerine `ModelName.lenet.value` tanımı ile de ulaşabilirsiniz.
|
`"lenet"` değerine `ModelName.lenet.value` ile de erişebilirsiniz.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
#### *Enumeration Üyelerini* Döndürelim
|
#### *Enumeration Member*'ları Döndürelim { #return-enumeration-members }
|
||||||
|
|
||||||
JSON gövdesine (örneğin bir `dict`) gömülü olsalar bile *yol operasyonundaki* *enum üyelerini* döndürebilirsiniz.
|
*Path operation*'ınızdan, bir JSON body'nin içine gömülü olsalar bile (ör. bir `dict`) *enum member*'ları döndürebilirsiniz.
|
||||||
|
|
||||||
Bu üyeler istemciye iletilmeden önce kendilerine karşılık gelen değerlerine (bu durumda string) dönüştürüleceklerdir:
|
İstemciye dönmeden önce, karşılık gelen değerlerine (bu durumda string) dönüştürülürler:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
|
||||||
|
|
||||||
İstemci tarafında şuna benzer bir JSON yanıtı ile karşılaşırsınız:
|
İstemcinizde şöyle bir JSON response alırsınız:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -205,53 +199,53 @@ Bu üyeler istemciye iletilmeden önce kendilerine karşılık gelen değerlerin
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Yol İçeren Yol Parametreleri
|
## Path İçeren Path Parametreleri { #path-parameters-containing-paths }
|
||||||
|
|
||||||
Farz edelim ki elinizde `/files/{file_path}` isminde bir *yol operasyonu* var.
|
Diyelim ki `/files/{file_path}` path'ine sahip bir *path operation*'ınız var.
|
||||||
|
|
||||||
Fakat `file_path` değerinin `home/johndoe/myfile.txt` gibi bir *yol* barındırmasını istiyorsunuz.
|
Ama `file_path`'in kendisinin `home/johndoe/myfile.txt` gibi bir *path* içermesi gerekiyor.
|
||||||
|
|
||||||
Sonuç olarak, oluşturmak istediğin URL `/files/home/johndoe/myfile.txt` gibi bir şey olacaktır.
|
Böylece, o dosyanın URL'si şu şekilde olur: `/files/home/johndoe/myfile.txt`.
|
||||||
|
|
||||||
### OpenAPI Desteği
|
### OpenAPI Desteği { #openapi-support }
|
||||||
|
|
||||||
Test etmesi ve tanımlaması zor senaryolara sebebiyet vereceğinden dolayı OpenAPI, *yol* barındıran *yol parametrelerini* tanımlayacak bir çözüm sunmuyor.
|
OpenAPI, içinde bir *path* barındıracak bir *path parameter* tanımlamak için bir yöntem desteklemez; çünkü bu, test etmesi ve tanımlaması zor senaryolara yol açabilir.
|
||||||
|
|
||||||
Ancak bunu, Starlette kütüphanesinin dahili araçlarından birini kullanarak **FastAPI**'da gerçekleştirebilirsiniz.
|
Yine de, Starlette'in dahili araçlarından birini kullanarak bunu **FastAPI**'da yapabilirsiniz.
|
||||||
|
|
||||||
Parametrenin bir yol içermesi gerektiğini belirten herhangi bir doküman eklemememize rağmen dokümanlar yine de çalışacaktır.
|
Ve dokümanlar, parametrenin bir path içermesi gerektiğini söyleyen herhangi bir dokümantasyon eklemese bile çalışmaya devam eder.
|
||||||
|
|
||||||
### Yol Dönüştürücü
|
### Path Dönüştürücü { #path-convertor }
|
||||||
|
|
||||||
Direkt olarak Starlette kütüphanesinden gelen bir opsiyon sayesinde aşağıdaki gibi *yol* içeren bir *yol parametresi* bağlantısı tanımlayabilirsiniz:
|
Starlette'ten doğrudan gelen bir seçenekle, *path* içeren bir *path parameter*'ı şu URL ile tanımlayabilirsiniz:
|
||||||
|
|
||||||
```
|
```
|
||||||
/files/{file_path:path}
|
/files/{file_path:path}
|
||||||
```
|
```
|
||||||
|
|
||||||
Bu durumda, parametrenin adı `file_path` olacaktır ve son kısım olan `:path` kısmı, parametrenin herhangi bir *yol* ile eşleşmesi gerektiğini belirtecektir.
|
Bu durumda parametrenin adı `file_path`'tir ve son kısım olan `:path`, parametrenin herhangi bir *path* ile eşleşmesi gerektiğini söyler.
|
||||||
|
|
||||||
Böylece şunun gibi bir kullanım yapabilirsiniz:
|
Yani şununla kullanabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial004.py hl[6] *}
|
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
|
||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
Parametrenin başında `/home/johndoe/myfile.txt` yolunda olduğu gibi (`/`) işareti ile birlikte kullanmanız gerektiği durumlar olabilir.
|
Parametrenin başında `/home/johndoe/myfile.txt` örneğinde olduğu gibi bir eğik çizgi (`/`) ile başlaması gerekebilir.
|
||||||
|
|
||||||
Bu durumda, URL, `files` ile `home` arasında iki eğik çizgiye (`//`) sahip olup `/files//home/johndoe/myfile.txt` gibi gözükecektir.
|
Bu durumda URL, `files` ile `home` arasında çift eğik çizgi (`//`) olacak şekilde `/files//home/johndoe/myfile.txt` olur.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Özet
|
## Özet { #recap }
|
||||||
|
|
||||||
**FastAPI** ile kısa, sezgisel ve standart Python tip tanımlamaları kullanarak şunları elde edersiniz:
|
**FastAPI** ile kısa, sezgisel ve standart Python tip tanımlarını kullanarak şunları elde edersiniz:
|
||||||
|
|
||||||
* Editör desteği: hata denetimi, otomatik tamamlama, vb.
|
* Editör desteği: hata denetimleri, otomatik tamamlama vb.
|
||||||
* Veri "<abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">dönüştürme</abbr>"
|
* Veri "<abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">parsing</abbr>"
|
||||||
* Veri doğrulama
|
* Veri doğrulama
|
||||||
* API tanımlamaları ve otomatik dokümantasyon
|
* API annotation ve otomatik dokümantasyon
|
||||||
|
|
||||||
Ve sadece, bunları bir kez tanımlamanız yeterli.
|
Ve bunları sadece bir kez tanımlamanız yeterlidir.
|
||||||
|
|
||||||
Diğer frameworkler ile karşılaştırıldığında (ham performans dışında), üstte anlatılan durum muhtemelen **FastAPI**'ın göze çarpan başlıca avantajıdır.
|
Bu, (ham performans dışında) **FastAPI**'ın alternatif framework'lere kıyasla muhtemelen en görünür ana avantajıdır.
|
||||||
|
|||||||
@@ -1,83 +1,83 @@
|
|||||||
# Sorgu Parametreleri
|
# Sorgu Parametreleri { #query-parameters }
|
||||||
|
|
||||||
Fonksiyonda yol parametrelerinin parçası olmayan diğer tanımlamalar otomatik olarak "sorgu" parametresi olarak yorumlanır.
|
Fonksiyonda path parametrelerinin parçası olmayan diğer parametreleri tanımladığınızda, bunlar otomatik olarak "query" parametreleri olarak yorumlanır.
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial001.py hl[9] *}
|
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
|
||||||
|
|
||||||
Sorgu, bağlantıdaki `?` kısmından sonra gelen ve `&` işareti ile ayrılan anahtar-değer çiftlerinin oluşturduğu bir kümedir.
|
Query, bir URL'de `?` işaretinden sonra gelen ve `&` karakterleriyle ayrılan anahtar-değer çiftlerinin kümesidir.
|
||||||
|
|
||||||
Örneğin, aşağıdaki bağlantıda:
|
Örneğin, şu URL'de:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/?skip=0&limit=10
|
http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||||
```
|
```
|
||||||
|
|
||||||
...sorgu parametreleri şunlardır:
|
...query parametreleri şunlardır:
|
||||||
|
|
||||||
* `skip`: değeri `0`'dır
|
* `skip`: değeri `0`
|
||||||
* `limit`: değeri `10`'dır
|
* `limit`: değeri `10`
|
||||||
|
|
||||||
Parametreler bağlantının bir parçası oldukları için doğal olarak string olarak değerlendirilirler.
|
URL'nin bir parçası oldukları için "doğal olarak" string'tirler.
|
||||||
|
|
||||||
Fakat, Python tipleri ile tanımlandıkları zaman (yukarıdaki örnekte `int` oldukları gibi), parametreler o tiplere dönüştürülür ve o tipler çerçevesinde doğrulanırlar.
|
Ancak, bunları Python tipleriyle (yukarıdaki örnekte `int` olarak) tanımladığınızda, o tipe dönüştürülürler ve o tipe göre doğrulanırlar.
|
||||||
|
|
||||||
Yol parametreleri için geçerli olan her türlü işlem aynı şekilde sorgu parametreleri için de geçerlidir:
|
Path parametreleri için geçerli olan aynı süreç query parametreleri için de geçerlidir:
|
||||||
|
|
||||||
* Editör desteği (şüphesiz)
|
* Editör desteği (tabii ki)
|
||||||
* Veri "<abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">ayrıştırma</abbr>"
|
* Veri <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>
|
||||||
* Veri doğrulama
|
* Veri doğrulama
|
||||||
* Otomatik dokümantasyon
|
* Otomatik dokümantasyon
|
||||||
|
|
||||||
## Varsayılanlar
|
## Varsayılanlar { #defaults }
|
||||||
|
|
||||||
Sorgu parametreleri, adres yolunun sabit bir parçası olmadıklarından dolayı isteğe bağlı ve varsayılan değere sahip olabilirler.
|
Query parametreleri path'in sabit bir parçası olmadığından, opsiyonel olabilir ve varsayılan değerlere sahip olabilir.
|
||||||
|
|
||||||
Yukarıdaki örnekte `skip=0` ve `limit=10` varsayılan değere sahiplerdir.
|
Yukarıdaki örnekte varsayılan değerleri `skip=0` ve `limit=10`'dur.
|
||||||
|
|
||||||
Yani, aşağıdaki bağlantıya gitmek:
|
Yani şu URL'ye gitmek:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/
|
http://127.0.0.1:8000/items/
|
||||||
```
|
```
|
||||||
|
|
||||||
şu adrese gitmek ile aynı etkiye sahiptir:
|
şuraya gitmekle aynı olur:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/?skip=0&limit=10
|
http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||||
```
|
```
|
||||||
|
|
||||||
Ancak, mesela şöyle bir adresi ziyaret ederseniz:
|
Ancak örneğin şuraya giderseniz:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/?skip=20
|
http://127.0.0.1:8000/items/?skip=20
|
||||||
```
|
```
|
||||||
|
|
||||||
Fonksiyonunuzdaki parametre değerleri aşağıdaki gibi olacaktır:
|
Fonksiyonunuzdaki parametre değerleri şöyle olacaktır:
|
||||||
|
|
||||||
* `skip=20`: çünkü bağlantıda böyle tanımlandı.
|
* `skip=20`: çünkü URL'de siz ayarladınız
|
||||||
* `limit=10`: çünkü varsayılan değer buydu.
|
* `limit=10`: çünkü varsayılan değer oydu
|
||||||
|
|
||||||
## İsteğe Bağlı Parametreler
|
## İsteğe bağlı parametreler { #optional-parameters }
|
||||||
|
|
||||||
Aynı şekilde, varsayılan değerlerini `None` olarak atayarak isteğe bağlı parametreler tanımlayabilirsiniz:
|
Aynı şekilde, varsayılan değerlerini `None` yaparak isteğe bağlı query parametreleri tanımlayabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
|
{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
|
||||||
|
|
||||||
Bu durumda, `q` fonksiyon parametresi isteğe bağlı olacak ve varsayılan değer olarak `None` alacaktır.
|
Bu durumda, fonksiyon parametresi `q` isteğe bağlı olur ve varsayılan olarak `None` olur.
|
||||||
|
|
||||||
/// check | Ek bilgi
|
/// check | Ek bilgi
|
||||||
|
|
||||||
Ayrıca, dikkatinizi çekerim ki; **FastAPI**, `item_id` parametresinin bir yol parametresi olduğunu ve `q` parametresinin yol değil bir sorgu parametresi olduğunu fark edecek kadar beceriklidir.
|
Ayrıca, **FastAPI** path parametresi olan `item_id`'nin bir path parametresi olduğunu ve `q`'nun path olmadığını fark edecek kadar akıllıdır; dolayısıyla bu bir query parametresidir.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Sorgu Parametresi Tip Dönüşümü
|
## Sorgu parametresi tip dönüşümü { #query-parameter-type-conversion }
|
||||||
|
|
||||||
Aşağıda görüldüğü gibi dönüştürülmek üzere `bool` tipleri de tanımlayabilirsiniz:
|
`bool` tipleri de tanımlayabilirsiniz, ve bunlar dönüştürülür:
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
|
{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
|
||||||
|
|
||||||
Bu durumda, eğer şu adrese giderseniz:
|
Bu durumda, şuraya giderseniz:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/foo?short=1
|
http://127.0.0.1:8000/items/foo?short=1
|
||||||
@@ -107,38 +107,38 @@ veya
|
|||||||
http://127.0.0.1:8000/items/foo?short=yes
|
http://127.0.0.1:8000/items/foo?short=yes
|
||||||
```
|
```
|
||||||
|
|
||||||
veya adres, herhangi farklı bir harf varyasyonu içermesi durumuna rağmen (büyük harf, sadece baş harfi büyük kelime, vb.) fonksiyonunuz, `bool` tipli `short` parametresini `True` olarak algılayacaktır. Aksi halde `False` olarak algılanacaktır.
|
veya başka herhangi bir büyük/küçük harf varyasyonunda (tamamı büyük, ilk harf büyük, vb.), fonksiyonunuz `short` parametresini `bool` değeri `True` olarak görecektir. Aksi halde `False` olarak görür.
|
||||||
|
|
||||||
|
|
||||||
## Çoklu Yol ve Sorgu Parametreleri
|
## Çoklu path ve query parametreleri { #multiple-path-and-query-parameters }
|
||||||
|
|
||||||
**FastAPI** neyin ne olduğunu ayırt edebileceğinden dolayı aynı anda birden fazla yol ve sorgu parametresi tanımlayabilirsiniz.
|
Aynı anda birden fazla path parametresi ve query parametresi tanımlayabilirsiniz; **FastAPI** hangisinin hangisi olduğunu bilir.
|
||||||
|
|
||||||
Ve parametreleri, herhangi bir sıraya koymanıza da gerek yoktur.
|
Ayrıca bunları belirli bir sırayla tanımlamanız gerekmez.
|
||||||
|
|
||||||
İsimlerine göre belirleneceklerdir:
|
İsme göre tespit edilirler:
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
|
{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
|
||||||
|
|
||||||
## Zorunlu Sorgu Parametreleri
|
## Zorunlu query parametreleri { #required-query-parameters }
|
||||||
|
|
||||||
Türü yol olmayan bir parametre (şu ana kadar sadece sorgu parametrelerini gördük) için varsayılan değer tanımlarsanız o parametre zorunlu olmayacaktır.
|
Path olmayan parametreler (şimdilik sadece query parametrelerini gördük) için varsayılan değer tanımladığınızda, bu parametre zorunlu olmaz.
|
||||||
|
|
||||||
Parametre için belirli bir değer atamak istemeyip parametrenin sadece isteğe bağlı olmasını istiyorsanız değerini `None` olarak atayabilirsiniz.
|
Belirli bir değer eklemek istemiyor ama sadece opsiyonel olmasını istiyorsanız, varsayılanı `None` olarak ayarlayın.
|
||||||
|
|
||||||
Fakat, bir sorgu parametresini zorunlu yapmak istiyorsanız varsayılan bir değer atamamanız yeterli olacaktır:
|
Ancak bir query parametresini zorunlu yapmak istediğinizde, herhangi bir varsayılan değer tanımlamamanız yeterlidir:
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
|
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
|
||||||
|
|
||||||
Burada `needy` parametresi `str` tipinden oluşan zorunlu bir sorgu parametresidir.
|
Burada query parametresi `needy`, `str` tipinde zorunlu bir query parametresidir.
|
||||||
|
|
||||||
Eğer tarayıcınızda şu bağlantıyı:
|
Tarayıcınızda şöyle bir URL açarsanız:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/foo-item
|
http://127.0.0.1:8000/items/foo-item
|
||||||
```
|
```
|
||||||
|
|
||||||
...`needy` parametresini eklemeden açarsanız şuna benzer bir hata ile karşılaşırsınız:
|
...zorunlu `needy` parametresini eklemeden, şuna benzer bir hata görürsünüz:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -156,13 +156,13 @@ http://127.0.0.1:8000/items/foo-item
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`needy` zorunlu bir parametre olduğundan dolayı bağlantıda tanımlanması gerekir:
|
`needy` zorunlu bir parametre olduğundan, URL'de ayarlamanız gerekir:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||||
```
|
```
|
||||||
|
|
||||||
...bu iş görür:
|
...bu çalışır:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
@@ -171,11 +171,11 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Ve elbette, bazı parametreleri zorunlu, bazılarını varsayılan değerli ve bazılarını tamamen opsiyonel olarak tanımlayabilirsiniz:
|
Ve elbette, bazı parametreleri zorunlu, bazılarını varsayılan değerli, bazılarını da tamamen isteğe bağlı olarak tanımlayabilirsiniz:
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
|
{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
|
||||||
|
|
||||||
Bu durumda, 3 tane sorgu parametresi var olacaktır:
|
Bu durumda, 3 tane query parametresi vardır:
|
||||||
|
|
||||||
* `needy`, zorunlu bir `str`.
|
* `needy`, zorunlu bir `str`.
|
||||||
* `skip`, varsayılan değeri `0` olan bir `int`.
|
* `skip`, varsayılan değeri `0` olan bir `int`.
|
||||||
@@ -183,6 +183,6 @@ Bu durumda, 3 tane sorgu parametresi var olacaktır:
|
|||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
Ayrıca, [Yol Parametrelerinde](path-params.md#on-tanml-degerler){.internal-link target=_blank} de kullanıldığı şekilde `Enum` sınıfından faydalanabilirsiniz.
|
[Path Parametreleri](path-params.md#predefined-values){.internal-link target=_blank} ile aynı şekilde `Enum`'ları da kullanabilirsiniz.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,69 +1,73 @@
|
|||||||
# Form Verisi
|
# Form Verisi { #form-data }
|
||||||
|
|
||||||
İstek gövdesinde JSON verisi yerine form alanlarını karşılamanız gerketiğinde `Form` sınıfını kullanabilirsiniz.
|
JSON yerine form alanlarını almanız gerektiğinde `Form` kullanabilirsiniz.
|
||||||
|
|
||||||
/// info | Bilgi
|
/// info | Bilgi
|
||||||
|
|
||||||
Formları kullanmak için öncelikle <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> paketini indirmeniz gerekmektedir.
|
Formları kullanmak için önce <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> paketini kurun.
|
||||||
|
|
||||||
Örneğin `pip install python-multipart`.
|
Bir [virtual environment](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, onu etkinleştirdiğinizden emin olun ve ardından örneğin şöyle kurun:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ pip install python-multipart
|
||||||
|
```
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## `Form` Sınıfını Projenize Dahil Edin
|
## `Form`'u Import Edin { #import-form }
|
||||||
|
|
||||||
`Form` sınıfını `fastapi`'den projenize dahil edin:
|
`Form`'u `fastapi`'den import edin:
|
||||||
|
|
||||||
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
|
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
|
||||||
|
|
||||||
## `Form` Parametrelerini Tanımlayın
|
## `Form` Parametrelerini Tanımlayın { #define-form-parameters }
|
||||||
|
|
||||||
Form parametrelerini `Body` veya `Query` için yaptığınız gibi oluşturun:
|
Form parametrelerini `Body` veya `Query` için yaptığınız gibi oluşturun:
|
||||||
|
|
||||||
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
|
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
|
||||||
|
|
||||||
Örneğin, OAuth2 spesifikasyonunun kullanılabileceği ("şifre akışı" olarak adlandırılan) yollardan birinde, form alanları olarak <abbr title="Kullanıcı Adı: Username">"username"</abbr> ve <abbr title="Şifre: Password">"password"</abbr> gönderilmesi gerekir.
|
Örneğin OAuth2 spesifikasyonunun kullanılabileceği ("password flow" olarak adlandırılan) yollardan birinde, form alanları olarak bir `username` ve `password` göndermek zorunludur.
|
||||||
|
|
||||||
Bu <abbr title="Spesifikasyon: Specification">spesifikasyon</abbr> form alanlarını adlandırırken isimlerinin birebir `username` ve `password` olmasını ve JSON verisi yerine form verisi olarak gönderilmesini gerektirir.
|
<abbr title="specification - spesifikasyon">spec</abbr>, alanların adının tam olarak `username` ve `password` olmasını ve JSON değil form alanları olarak gönderilmesini gerektirir.
|
||||||
|
|
||||||
`Form` sınıfıyla tanımlama yaparken `Body`, `Query`, `Path` ve `Cookie` sınıflarında kullandığınız aynı validasyon, örnekler, isimlendirme (örneğin `username` yerine `user-name` kullanımı) ve daha fazla konfigurasyonu kullanabilirsiniz.
|
`Form` ile `Body` (ve `Query`, `Path`, `Cookie`) ile yaptığınız aynı konfigürasyonları tanımlayabilirsiniz; validasyon, örnekler, alias (örn. `username` yerine `user-name`) vb. dahil.
|
||||||
|
|
||||||
/// info | Bilgi
|
/// info | Bilgi
|
||||||
|
|
||||||
`Form` doğrudan `Body` sınıfını miras alan bir sınıftır.
|
`Form`, doğrudan `Body`'den miras alan bir sınıftır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
/// tip | İpucu
|
/// tip | İpucu
|
||||||
|
|
||||||
Form gövdelerini tanımlamak için `Form` sınıfını kullanmanız gerekir; çünkü bu olmadan parametreler sorgu parametreleri veya gövde (JSON) parametreleri olarak yorumlanır.
|
Form gövdelerini tanımlamak için `Form`'u açıkça kullanmanız gerekir; çünkü bunu yapmazsanız parametreler query parametreleri veya body (JSON) parametreleri olarak yorumlanır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## "Form Alanları" Hakkında
|
## "Form Alanları" Hakkında { #about-form-fields }
|
||||||
|
|
||||||
HTML formlarının (`<form></form>`) verileri sunucuya gönderirken JSON'dan farklı özel bir kodlama kullanır.
|
HTML formlarının (`<form></form>`) verileri sunucuya gönderme şekli normalde bu veri için JSON'dan farklı "özel" bir encoding kullanır.
|
||||||
|
|
||||||
**FastAPI** bu verilerin JSON yerine doğru şekilde okunmasını sağlayacaktır.
|
**FastAPI** bu veriyi JSON yerine doğru yerden okuyacaktır.
|
||||||
|
|
||||||
/// note | Teknik Detaylar
|
/// note | Teknik Detaylar
|
||||||
|
|
||||||
Form verileri normalde `application/x-www-form-urlencoded` medya tipiyle kodlanır.
|
Formlardan gelen veri normalde "media type" `application/x-www-form-urlencoded` kullanılarak encode edilir.
|
||||||
|
|
||||||
Ancak form içerisinde dosyalar yer aldığında `multipart/form-data` olarak kodlanır. Bir sonraki bölümde dosyaların işlenmesi hakkında bilgi edineceksiniz.
|
Ancak form dosyalar içerdiğinde `multipart/form-data` olarak encode edilir. Dosyaları ele almayı bir sonraki bölümde okuyacaksınız.
|
||||||
|
|
||||||
Form kodlama türleri ve form alanları hakkında daha fazla bilgi edinmek istiyorsanız <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web docs for <code>POST</code></a> sayfasını ziyaret edebilirsiniz.
|
Bu encoding'ler ve form alanları hakkında daha fazla okumak isterseniz, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web docs for <code>POST</code></a> sayfasına gidin.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
/// warning | Uyarı
|
/// warning | Uyarı
|
||||||
|
|
||||||
*Yol operasyonları* içerisinde birden fazla `Form` parametresi tanımlayabilirsiniz ancak bunlarla birlikte JSON verisi kabul eden `Body` alanları tanımlayamazsınız çünkü bu durumda istek gövdesi `application/json` yerine `application/x-www-form-urlencoded` ile kodlanmış olur.
|
Bir *path operation* içinde birden fazla `Form` parametresi tanımlayabilirsiniz, ancak JSON olarak almayı beklediğiniz `Body` alanlarını da ayrıca tanımlayamazsınız; çünkü bu durumda request'in body'si `application/json` yerine `application/x-www-form-urlencoded` ile encode edilmiş olur.
|
||||||
|
|
||||||
Bu **FastAPI**'ın getirdiği bir kısıtlama değildir, HTTP protokolünün bir parçasıdır.
|
Bu **FastAPI**'ın bir kısıtlaması değildir, HTTP protokolünün bir parçasıdır.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
## Özet
|
## Özet { #recap }
|
||||||
|
|
||||||
Form verisi girdi parametreleri tanımlamak için `Form` sınıfını kullanın.
|
Form verisi girdi parametrelerini tanımlamak için `Form` kullanın.
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
# Statik Dosyalar
|
# Statik Dosyalar { #static-files }
|
||||||
|
|
||||||
`StaticFiles`'ı kullanarak statik dosyaları bir yol altında sunabilirsiniz.
|
`StaticFiles` kullanarak bir dizindeki statik dosyaları otomatik olarak sunabilirsiniz.
|
||||||
|
|
||||||
## `StaticFiles` Kullanımı
|
## `StaticFiles` Kullanımı { #use-staticfiles }
|
||||||
|
|
||||||
* `StaticFiles` sınıfını projenize dahil edin.
|
* `StaticFiles`'ı import edin.
|
||||||
* Bir `StaticFiles()` örneğini belirli bir yola bağlayın.
|
* Belirli bir path'te bir `StaticFiles()` örneğini "mount" edin.
|
||||||
|
|
||||||
{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
|
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
|
||||||
|
|
||||||
/// note | Teknik Detaylar
|
/// note | Teknik Detaylar
|
||||||
|
|
||||||
Projenize dahil etmek için `from starlette.staticfiles import StaticFiles` kullanabilirsiniz.
|
`from starlette.staticfiles import StaticFiles` da kullanabilirsiniz.
|
||||||
|
|
||||||
**FastAPI**, geliştiricilere kolaylık sağlamak amacıyla `starlette.staticfiles`'ı `fastapi.staticfiles` olarak sağlar. Ancak `StaticFiles` sınıfı aslında doğrudan Starlette'den gelir.
|
**FastAPI**, geliştirici olarak size kolaylık olsun diye `starlette.staticfiles`'ı `fastapi.staticfiles` olarak da sağlar. Ancak aslında doğrudan Starlette'den gelir.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
### Bağlama (Mounting) Nedir?
|
### "Mounting" Nedir { #what-is-mounting }
|
||||||
|
|
||||||
"Bağlamak", belirli bir yola tamamen "bağımsız" bir uygulama eklemek anlamına gelir ve ardından tüm alt yollara gelen istekler bu uygulama tarafından işlenir.
|
"Mounting", belirli bir path'te tamamen "bağımsız" bir uygulama eklemek ve sonrasında tüm alt path'leri handle etmesini sağlamak demektir.
|
||||||
|
|
||||||
Bu, bir `APIRouter` kullanmaktan farklıdır çünkü bağlanmış bir uygulama tamamen bağımsızdır. Ana uygulamanızın OpenAPI ve dokümanlar, bağlanmış uygulamadan hiçbir şey içermez, vb.
|
Bu, bir `APIRouter` kullanmaktan farklıdır; çünkü mount edilen uygulama tamamen bağımsızdır. Ana uygulamanızın OpenAPI ve docs'ları, mount edilen uygulamadan hiçbir şey içermez, vb.
|
||||||
|
|
||||||
[Advanced User Guide](../advanced/index.md){.internal-link target=_blank} bölümünde daha fazla bilgi edinebilirsiniz.
|
Bununla ilgili daha fazla bilgiyi [Advanced User Guide](../advanced/index.md){.internal-link target=_blank} içinde okuyabilirsiniz.
|
||||||
|
|
||||||
## Detaylar
|
## Detaylar { #details }
|
||||||
|
|
||||||
`"/static"` ifadesi, bu "alt uygulamanın" "bağlanacağı" alt yolu belirtir. Bu nedenle, `"/static"` ile başlayan her yol, bu uygulama tarafından işlenir.
|
İlk `"/static"`, bu "alt uygulamanın" "mount" edileceği alt path'i ifade eder. Dolayısıyla `"/static"` ile başlayan herhangi bir path bunun tarafından handle edilir.
|
||||||
|
|
||||||
`directory="static"` ifadesi, statik dosyalarınızı içeren dizinin adını belirtir.
|
`directory="static"`, statik dosyalarınızı içeren dizinin adını ifade eder.
|
||||||
|
|
||||||
`name="static"` ifadesi, alt uygulamanın **FastAPI** tarafından kullanılacak ismini belirtir.
|
`name="static"`, **FastAPI**'nin dahili olarak kullanabileceği bir isim verir.
|
||||||
|
|
||||||
Bu parametrelerin hepsi "`static`"den farklı olabilir, bunları kendi uygulamanızın ihtiyaçlarına göre belirleyebilirsiniz.
|
Bu parametrelerin hepsi "`static`" ile aynı olmak zorunda değildir; kendi uygulamanızın ihtiyaçlarına ve özel detaylarına göre ayarlayın.
|
||||||
|
|
||||||
## Daha Fazla Bilgi
|
## Daha Fazla Bilgi { #more-info }
|
||||||
|
|
||||||
Daha fazla detay ve seçenek için <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Starlette'in Statik Dosyalar hakkındaki dokümantasyonunu</a> incelleyin.
|
Daha fazla detay ve seçenek için <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Starlette'in Statik Dosyalar hakkındaki dokümanlarını</a> inceleyin.
|
||||||
|
|||||||
Reference in New Issue
Block a user