mirror of https://github.com/tiangolo/fastapi.git
Merge branch 'master' into fix-duplicate-special-dependency-handling
This commit is contained in:
commit
f78d00b17b
|
|
@ -64,7 +64,7 @@ jobs:
|
|||
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
|
||||
# TODO: Use v3 when it's fixed, probably in v3.11
|
||||
# https://github.com/cloudflare/wrangler-action/issues/307
|
||||
uses: cloudflare/wrangler-action@v3.11
|
||||
uses: cloudflare/wrangler-action@v3.12
|
||||
# uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
||||
run: python -m build
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@v1.11.0
|
||||
uses: pypa/gh-action-pypi-publish@v1.12.2
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ repos:
|
|||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.7.1
|
||||
rev: v0.7.2
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ hide:
|
|||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Korean translation for `/docs/ko/docs/environment-variables.md`. PR [#12526](https://github.com/fastapi/fastapi/pull/12526) by [@Tolerblanc](https://github.com/Tolerblanc).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/history-design-future.md`. PR [#12646](https://github.com/fastapi/fastapi/pull/12646) by [@saeye](https://github.com/saeye).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/advanced/advanced-dependencies.md`. PR [#12675](https://github.com/fastapi/fastapi/pull/12675) by [@kim-sangah](https://github.com/kim-sangah).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/how-to/conditional-openapi.md`. PR [#12731](https://github.com/fastapi/fastapi/pull/12731) by [@sptcnl](https://github.com/sptcnl).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/advanced/using_request_directly.md`. PR [#12738](https://github.com/fastapi/fastapi/pull/12738) by [@kwang1215](https://github.com/kwang1215).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/advanced/testing-events.md`. PR [#12741](https://github.com/fastapi/fastapi/pull/12741) by [@9zimin9](https://github.com/9zimin9).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/security/index.md`. PR [#12743](https://github.com/fastapi/fastapi/pull/12743) by [@kim-sangah](https://github.com/kim-sangah).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/path-operation-advanced-configuration.md`. PR [#12762](https://github.com/fastapi/fastapi/pull/12762) by [@Joao-Pedro-P-Holanda](https://github.com/Joao-Pedro-P-Holanda).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/advanced/wsgi.md`. PR [#12659](https://github.com/fastapi/fastapi/pull/12659) by [@Limsunoh](https://github.com/Limsunoh).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/websockets.md`. PR [#12703](https://github.com/fastapi/fastapi/pull/12703) by [@devfernandoa](https://github.com/devfernandoa).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/security/simple-oauth2.md`. PR [#12520](https://github.com/fastapi/fastapi/pull/12520) by [@LidiaDomingos](https://github.com/LidiaDomingos).
|
||||
|
|
@ -43,6 +51,10 @@ hide:
|
|||
|
||||
### Internal
|
||||
|
||||
* ⬆ Bump pypa/gh-action-pypi-publish from 1.12.0 to 1.12.2. PR [#12788](https://github.com/fastapi/fastapi/pull/12788) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump pypa/gh-action-pypi-publish from 1.11.0 to 1.12.0. PR [#12781](https://github.com/fastapi/fastapi/pull/12781) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump cloudflare/wrangler-action from 3.11 to 3.12. PR [#12777](https://github.com/fastapi/fastapi/pull/12777) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#12766](https://github.com/fastapi/fastapi/pull/12766) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
|
||||
* ⬆ Bump pypa/gh-action-pypi-publish from 1.10.3 to 1.11.0. PR [#12721](https://github.com/fastapi/fastapi/pull/12721) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Update pre-commit requirement from <4.0.0,>=2.17.0 to >=2.17.0,<5.0.0. PR [#12749](https://github.com/fastapi/fastapi/pull/12749) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump typer from 0.12.3 to 0.12.5. PR [#12748](https://github.com/fastapi/fastapi/pull/12748) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,179 @@
|
|||
# 고급 의존성
|
||||
|
||||
## 매개변수화된 의존성
|
||||
|
||||
지금까지 본 모든 의존성은 고정된 함수 또는 클래스입니다.
|
||||
|
||||
하지만 여러 개의 함수나 클래스를 선언하지 않고도 의존성에 매개변수를 설정해야 하는 경우가 있을 수 있습니다.
|
||||
|
||||
예를 들어, `q` 쿼리 매개변수가 특정 고정된 내용을 포함하고 있는지 확인하는 의존성을 원한다고 가정해 봅시다.
|
||||
|
||||
이때 해당 고정된 내용을 매개변수화할 수 있길 바랍니다.
|
||||
|
||||
## "호출 가능한" 인스턴스
|
||||
|
||||
Python에는 클래스의 인스턴스를 "호출 가능"하게 만드는 방법이 있습니다.
|
||||
|
||||
클래스 자체(이미 호출 가능함)가 아니라 해당 클래스의 인스턴스에 대해 호출 가능하게 하는 것입니다.
|
||||
|
||||
이를 위해 `__call__` 메서드를 선언합니다:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | 참고
|
||||
|
||||
가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
이 경우, **FastAPI**는 추가 매개변수와 하위 의존성을 확인하기 위해 `__call__`을 사용하게 되며,
|
||||
나중에 *경로 연산 함수*에서 매개변수에 값을 전달할 때 이를 호출하게 됩니다.
|
||||
|
||||
## 인스턴스 매개변수화하기
|
||||
|
||||
이제 `__init__`을 사용하여 의존성을 "매개변수화"할 수 있는 인스턴스의 매개변수를 선언할 수 있습니다:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | 참고
|
||||
|
||||
가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
이 경우, **FastAPI**는 `__init__`에 전혀 관여하지 않으며, 우리는 이 메서드를 코드에서 직접 사용하게 됩니다.
|
||||
|
||||
## 인스턴스 생성하기
|
||||
|
||||
다음과 같이 이 클래스의 인스턴스를 생성할 수 있습니다:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | 참고
|
||||
|
||||
가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
이렇게 하면 `checker.fixed_content` 속성에 `"bar"`라는 값을 담아 의존성을 "매개변수화"할 수 있습니다.
|
||||
|
||||
## 인스턴스를 의존성으로 사용하기
|
||||
|
||||
그런 다음, `Depends(FixedContentQueryChecker)` 대신 `Depends(checker)`에서 이 `checker` 인스턴스를 사용할 수 있으며,
|
||||
클래스 자체가 아닌 인스턴스 `checker`가 의존성이 됩니다.
|
||||
|
||||
의존성을 해결할 때 **FastAPI**는 이 `checker`를 다음과 같이 호출합니다:
|
||||
|
||||
```Python
|
||||
checker(q="somequery")
|
||||
```
|
||||
|
||||
...그리고 이때 반환되는 값을 *경로 연산 함수*의 `fixed_content_included` 매개변수로 전달합니다:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | 참고
|
||||
|
||||
가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// tip | 참고
|
||||
|
||||
이 모든 과정이 복잡하게 느껴질 수 있습니다. 그리고 지금은 이 방법이 얼마나 유용한지 명확하지 않을 수도 있습니다.
|
||||
|
||||
이 예시는 의도적으로 간단하게 만들었지만, 전체 구조가 어떻게 작동하는지 보여줍니다.
|
||||
|
||||
보안 관련 장에서는 이와 같은 방식으로 구현된 편의 함수들이 있습니다.
|
||||
|
||||
이 모든 과정을 이해했다면, 이러한 보안 도구들이 내부적으로 어떻게 작동하는지 이미 파악한 것입니다.
|
||||
|
||||
///
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# 이벤트 테스트: 시작 - 종료
|
||||
|
||||
테스트에서 이벤트 핸들러(`startup` 및 `shutdown`)를 실행해야 하는 경우, `with` 문과 함께 `TestClient`를 사용할 수 있습니다.
|
||||
|
||||
```Python hl_lines="9-12 20-24"
|
||||
{!../../docs_src/app_testing/tutorial003.py!}
|
||||
```
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# `Request` 직접 사용하기
|
||||
|
||||
지금까지 요청에서 필요한 부분을 각 타입으로 선언하여 사용해 왔습니다.
|
||||
|
||||
다음과 같은 곳에서 데이터를 가져왔습니다:
|
||||
|
||||
* 경로의 파라미터로부터.
|
||||
* 헤더.
|
||||
* 쿠키.
|
||||
* 기타 등등.
|
||||
|
||||
이렇게 함으로써, **FastAPI**는 데이터를 검증하고 변환하며, API에 대한 문서를 자동화로 생성합니다.
|
||||
|
||||
하지만 `Request` 객체에 직접 접근해야 하는 상황이 있을 수 있습니다.
|
||||
|
||||
## `Request` 객체에 대한 세부 사항
|
||||
|
||||
**FastAPI**는 실제로 내부에 **Starlette**을 사용하며, 그 위에 여러 도구를 덧붙인 구조입니다. 따라서 여러분이 필요할 때 Starlette의 <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request`</a> 객체를 직접 사용할 수 있습니다.
|
||||
|
||||
`Request` 객체에서 데이터를 직접 가져오는 경우(예: 본문을 읽기)에는 FastAPI가 해당 데이터를 검증하거나 변환하지 않으며, 문서화(OpenAPI를 통한 문서 자동화(로 생성된) API 사용자 인터페이스)도 되지 않습니다.
|
||||
|
||||
그러나 다른 매개변수(예: Pydantic 모델을 사용한 본문)는 여전히 검증, 변환, 주석 추가 등이 이루어집니다.
|
||||
|
||||
하지만 특정한 경우에는 `Request` 객체에 직접 접근하는 것이 유용할 수 있습니다.
|
||||
|
||||
## `Request` 객체를 직접 사용하기
|
||||
|
||||
여러분이 클라이언트의 IP 주소/호스트 정보를 *경로 작동 함수* 내부에서 가져와야 한다고 가정해 보겠습니다.
|
||||
|
||||
이를 위해서는 요청에 직접 접근해야 합니다.
|
||||
|
||||
```Python hl_lines="1 7-8"
|
||||
{!../../docs_src/using_request_directly/tutorial001.py!}
|
||||
```
|
||||
|
||||
*경로 작동 함수* 매개변수를 `Request` 타입으로 선언하면 **FastAPI**가 해당 매개변수에 `Request` 객체를 전달하는 것을 알게 됩니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
이 경우, 요청 매개변수와 함께 경로 매개변수를 선언한 것을 볼 수 있습니다.
|
||||
|
||||
따라서, 경로 매개변수는 추출되고 검증되며 지정된 타입으로 변환되고 OpenAPI로 주석이 추가됩니다.
|
||||
|
||||
이와 같은 방식으로, 다른 매개변수들을 평소처럼 선언하면서, 부가적으로 `Request`도 가져올 수 있습니다.
|
||||
|
||||
///
|
||||
|
||||
## `Request` 설명서
|
||||
|
||||
여러분은 `Request` 객체에 대한 더 자세한 내용을 <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">공식 Starlette 설명서 사이트</a>에서 읽어볼 수 있습니다.
|
||||
|
||||
/// note | 기술 세부사항
|
||||
|
||||
`from starlette.requests import Request`를 사용할 수도 있습니다.
|
||||
|
||||
**FastAPI**는 여러분(개발자)를 위한 편의를 위해 이를 직접 제공하지만, 실제로는 Starlette에서 가져온 것입니다.
|
||||
|
||||
///
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
# 환경 변수
|
||||
|
||||
/// tip | "팁"
|
||||
|
||||
만약 "환경 변수"가 무엇이고, 어떻게 사용하는지 알고 계시다면, 이 챕터를 스킵하셔도 좋습니다.
|
||||
|
||||
///
|
||||
|
||||
환경 변수는 파이썬 코드의 **바깥**인, **운영 체제**에 존재하는 변수입니다. 파이썬 코드나 다른 프로그램에서 읽을 수 있습니다.
|
||||
|
||||
환경 변수는 애플리케이션 **설정**을 처리하거나, 파이썬의 **설치** 과정의 일부로 유용합니다.
|
||||
|
||||
## 환경 변수를 만들고 사용하기
|
||||
|
||||
파이썬 없이도, **셸 (터미널)** 에서 환경 변수를 **생성** 하고 사용할 수 있습니다.
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// You could create an env var MY_NAME with
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// Then you could use it with other programs, like
|
||||
$ echo "Hello $MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Create an env var MY_NAME
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// Use it with other programs, like
|
||||
$ echo "Hello $Env:MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
## 파이썬에서 환경 변수 읽기
|
||||
|
||||
파이썬 **바깥**인 터미널에서(다른 도구로도 가능) 환경 변수를 생성도 할 수도 있고, 이를 **파이썬에서 읽을 수 있습니다.**
|
||||
|
||||
예를 들어 다음과 같은 `main.py` 파일이 있다고 합시다:
|
||||
|
||||
```Python hl_lines="3"
|
||||
import os
|
||||
|
||||
name = os.getenv("MY_NAME", "World")
|
||||
print(f"Hello {name} from Python")
|
||||
```
|
||||
|
||||
/// tip | "팁"
|
||||
|
||||
<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> 의 두 번째 인자는 반환할 기본값입니다.
|
||||
|
||||
여기서는 `"World"`를 넣었기에 기본값으로써 사용됩니다. 넣지 않으면 `None` 이 기본값으로 사용됩니다.
|
||||
|
||||
///
|
||||
|
||||
그러면 해당 파이썬 프로그램을 다음과 같이 호출할 수 있습니다:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Here we don't set the env var yet
|
||||
$ python main.py
|
||||
|
||||
// As we didn't set the env var, we get the default value
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// But if we create an environment variable first
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// And then call the program again
|
||||
$ python main.py
|
||||
|
||||
// Now it can read the environment variable
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Here we don't set the env var yet
|
||||
$ python main.py
|
||||
|
||||
// As we didn't set the env var, we get the default value
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// But if we create an environment variable first
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// And then call the program again
|
||||
$ python main.py
|
||||
|
||||
// Now it can read the environment variable
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
환경변수는 코드 바깥에서 설정될 수 있지만, 코드에서 읽을 수 있고, 나머지 파일과 함께 저장(`git`에 커밋)할 필요가 없으므로, 구성이나 **설정** 에 사용하는 것이 일반적입니다.
|
||||
|
||||
**특정 프로그램 호출**에 대해서만 사용할 수 있는 환경 변수를 만들 수도 있습니다. 해당 프로그램에서만 사용할 수 있고, 해당 프로그램이 실행되는 동안만 사용할 수 있습니다.
|
||||
|
||||
그렇게 하려면 프로그램 바로 앞, 같은 줄에 환경 변수를 만들어야 합니다:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Create an env var MY_NAME in line for this program call
|
||||
$ MY_NAME="Wade Wilson" python main.py
|
||||
|
||||
// Now it can read the environment variable
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
|
||||
// The env var no longer exists afterwards
|
||||
$ python main.py
|
||||
|
||||
Hello World from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | "팁"
|
||||
|
||||
<a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a> 에서 좀 더 자세히 알아볼 수 있습니다.
|
||||
|
||||
///
|
||||
|
||||
## 타입과 검증
|
||||
|
||||
이 환경변수들은 오직 **텍스트 문자열**로만 처리할 수 있습니다. 텍스트 문자열은 파이썬 외부에 있으며 다른 프로그램 및 나머지 시스템(Linux, Windows, macOS 등 다른 운영 체제)과 호환되어야 합니다.
|
||||
|
||||
즉, 파이썬에서 환경 변수로부터 읽은 **모든 값**은 **`str`**이 되고, 다른 타입으로의 변환이나 검증은 코드에서 수행해야 합니다.
|
||||
|
||||
**애플리케이션 설정**을 처리하기 위한 환경 변수 사용에 대한 자세한 내용은 [고급 사용자 가이드 - 설정 및 환경 변수](./advanced/settings.md){.internal-link target=\_blank} 에서 확인할 수 있습니다.
|
||||
|
||||
## `PATH` 환경 변수
|
||||
|
||||
**`PATH`**라고 불리는, **특별한** 환경변수가 있습니다. 운영체제(Linux, Windows, macOS 등)에서 실행할 프로그램을 찾기위해 사용됩니다.
|
||||
|
||||
변수 `PATH`의 값은 Linux와 macOS에서는 콜론 `:`, Windows에서는 세미콜론 `;`으로 구분된 디렉토리로 구성된 긴 문자열입니다.
|
||||
|
||||
예를 들어, `PATH` 환경 변수는 다음과 같습니다:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
이는 시스템이 다음 디렉토리에서 프로그램을 찾아야 함을 의미합니다:
|
||||
|
||||
- `/usr/local/bin`
|
||||
- `/usr/bin`
|
||||
- `/bin`
|
||||
- `/usr/sbin`
|
||||
- `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
|
||||
```
|
||||
|
||||
이는 시스템이 다음 디렉토리에서 프로그램을 찾아야 함을 의미합니다:
|
||||
|
||||
- `C:\Program Files\Python312\Scripts`
|
||||
- `C:\Program Files\Python312`
|
||||
- `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
터미널에 **명령어**를 입력하면 운영 체제는 `PATH` 환경 변수에 나열된 **각 디렉토리**에서 프로그램을 **찾습니다.**
|
||||
|
||||
예를 들어 터미널에 `python`을 입력하면 운영 체제는 해당 목록의 **첫 번째 디렉토리**에서 `python`이라는 프로그램을 찾습니다.
|
||||
|
||||
찾으면 **사용합니다**. 그렇지 않으면 **다른 디렉토리**에서 계속 찾습니다.
|
||||
|
||||
### 파이썬 설치와 `PATH` 업데이트
|
||||
|
||||
파이썬을 설치할 때, 아마 `PATH` 환경 변수를 업데이트 할 것이냐고 물어봤을 겁니다.
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
파이썬을 설치하고 그것이 `/opt/custompython/bin` 디렉토리에 있다고 가정해 보겠습니다.
|
||||
|
||||
`PATH` 환경 변수를 업데이트하도록 "예"라고 하면 설치 관리자가 `/opt/custompython/bin`을 `PATH` 환경 변수에 추가합니다.
|
||||
|
||||
다음과 같이 보일 수 있습니다:
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
|
||||
```
|
||||
|
||||
이렇게 하면 터미널에 `python`을 입력할 때, 시스템이 `/opt/custompython/bin`(마지막 디렉토리)에서 파이썬 프로그램을 찾아 사용합니다.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
파이썬을 설치하고 그것이 `C:\opt\custompython\bin` 디렉토리에 있다고 가정해 보겠습니다.
|
||||
|
||||
`PATH` 환경 변수를 업데이트하도록 "예"라고 하면 설치 관리자가 `C:\opt\custompython\bin`을 `PATH` 환경 변수에 추가합니다.
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
|
||||
```
|
||||
|
||||
이렇게 하면 터미널에 `python`을 입력할 때, 시스템이 `C:\opt\custompython\bin`(마지막 디렉토리)에서 파이썬 프로그램을 찾아 사용합니다.
|
||||
|
||||
////
|
||||
|
||||
그래서, 다음과 같이 입력한다면:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
시스템은 `/opt/custompython/bin`에서 `python` 프로그램을 **찾아** 실행합니다.
|
||||
|
||||
다음과 같이 입력하는 것과 거의 같습니다:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ /opt/custompython/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
시스템은 `C:\opt\custompython\bin\python`에서 `python` 프로그램을 **찾아** 실행합니다.
|
||||
|
||||
다음과 같이 입력하는 것과 거의 같습니다:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ C:\opt\custompython\bin\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
이 정보는 [가상 환경](virtual-environments.md){.internal-link target=\_blank} 에 대해 알아볼 때 유용할 것입니다.
|
||||
|
||||
## 결론
|
||||
|
||||
이 문서를 읽고 **환경 변수**가 무엇이고 파이썬에서 어떻게 사용하는지 기본적으로 이해하셨을 겁니다.
|
||||
|
||||
또한 <a href="https://ko.wikipedia.org/wiki/환경_변수" class="external-link" target="_blank">환경 변수에 대한 위키피디아(한국어)</a>에서 이에 대해 자세히 알아볼 수 있습니다.
|
||||
|
||||
많은 경우에서, 환경 변수가 어떻게 유용하고 적용 가능한지 바로 명확하게 알 수는 없습니다. 하지만 개발할 때 다양한 시나리오에서 계속 나타나므로 이에 대해 아는 것이 좋습니다.
|
||||
|
||||
예를 들어, 다음 섹션인 [가상 환경](virtual-environments.md)에서 이 정보가 필요합니다.
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# 역사, 디자인 그리고 미래
|
||||
|
||||
어느 날, [한 FastAPI 사용자](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920)가 이렇게 물었습니다:
|
||||
|
||||
> 이 프로젝트의 역사를 알려 주실 수 있나요? 몇 주 만에 멋진 결과를 낸 것 같아요. [...]
|
||||
|
||||
여기서 그 역사에 대해 간단히 설명하겠습니다.
|
||||
|
||||
---
|
||||
|
||||
## 대안
|
||||
|
||||
저는 여러 해 동안 머신러닝, 분산 시스템, 비동기 작업, NoSQL 데이터베이스 같은 복잡한 요구사항을 가진 API를 개발하며 여러 팀을 이끌어 왔습니다.
|
||||
|
||||
이 과정에서 많은 대안을 조사하고, 테스트하며, 사용해야 했습니다. **FastAPI**의 역사는 그 이전에 나왔던 여러 도구의 역사와 밀접하게 연관되어 있습니다.
|
||||
|
||||
[대안](alternatives.md){.internal-link target=_blank} 섹션에서 언급된 것처럼:
|
||||
|
||||
> **FastAPI**는 이전에 나왔던 많은 도구들의 노력 없이는 존재하지 않았을 것입니다.
|
||||
>
|
||||
> 이전에 개발된 여러 도구들이 이 프로젝트에 영감을 주었습니다.
|
||||
>
|
||||
> 저는 오랫동안 새로운 프레임워크를 만드는 것을 피하고자 했습니다. 처음에는 **FastAPI**가 제공하는 기능들을 다양한 프레임워크와 플러그인, 도구들을 조합해 해결하려 했습니다.
|
||||
>
|
||||
> 하지만 결국에는 이 모든 기능을 통합하는 도구가 필요해졌습니다. 이전 도구들로부터 최고의 아이디어들을 모으고, 이를 최적의 방식으로 조합해야만 했습니다. 이는 :term:Python 3.6+ 타입 힌트 <type hints>와 같은, 이전에는 사용할 수 없었던 언어 기능이 가능했기 때문입니다.
|
||||
|
||||
---
|
||||
|
||||
## 조사
|
||||
|
||||
여러 대안을 사용해 보며 다양한 도구에서 배운 점들을 모아 저와 개발팀에게 가장 적합한 방식을 찾았습니다.
|
||||
|
||||
예를 들어, 표준 :term:Python 타입 힌트 <type hints>에 기반하는 것이 이상적이라는 점이 명확했습니다.
|
||||
|
||||
또한, 이미 존재하는 표준을 활용하는 것이 가장 좋은 접근법이라 판단했습니다.
|
||||
|
||||
그래서 **FastAPI**의 코드를 작성하기 전에 몇 달 동안 OpenAPI, JSON Schema, OAuth2 명세를 연구하며 이들의 관계와 겹치는 부분, 차이점을 이해했습니다.
|
||||
|
||||
---
|
||||
|
||||
## 디자인
|
||||
|
||||
그 후, **FastAPI** 사용자가 될 개발자로서 사용하고 싶은 개발자 "API"를 디자인했습니다.
|
||||
|
||||
[Python Developer Survey](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools)에 따르면 약 80%의 Python 개발자가 PyCharm, VS Code, Jedi 기반 편집기 등에서 개발합니다. 이 과정에서 여러 아이디어를 테스트했습니다.
|
||||
|
||||
대부분의 다른 편집기도 유사하게 동작하기 때문에, **FastAPI**의 이점은 거의 모든 편집기에서 누릴 수 있습니다.
|
||||
|
||||
이 과정을 통해 코드 중복을 최소화하고, 모든 곳에서 자동 완성, 타입 검사, 에러 확인 기능이 제공되는 최적의 방식을 찾아냈습니다.
|
||||
|
||||
이 모든 것은 개발자들에게 최고의 개발 경험을 제공하기 위해 설계되었습니다.
|
||||
|
||||
---
|
||||
|
||||
## 필요조건
|
||||
|
||||
여러 대안을 테스트한 후, [Pydantic](https://docs.pydantic.dev/)을 사용하기로 결정했습니다.
|
||||
|
||||
이후 저는 **Pydantic**이 JSON Schema와 완벽히 호환되도록 개선하고, 다양한 제약 조건 선언을 지원하며, 여러 편집기에서의 자동 완성과 타입 검사 기능을 향상하기 위해 기여했습니다.
|
||||
|
||||
또한, 또 다른 주요 필요조건이었던 [Starlette](https://www.starlette.io/)에도 기여했습니다.
|
||||
|
||||
---
|
||||
|
||||
## 개발
|
||||
|
||||
**FastAPI**를 개발하기 시작할 즈음에는 대부분의 준비가 이미 완료된 상태였습니다. 설계가 정의되었고, 필요조건과 도구가 준비되었으며, 표준과 명세에 대한 지식도 충분했습니다.
|
||||
|
||||
---
|
||||
|
||||
## 미래
|
||||
|
||||
현시점에서 **FastAPI**가 많은 사람들에게 유용하다는 것이 명백해졌습니다.
|
||||
|
||||
여러 용도에 더 적합한 도구로서 기존 대안보다 선호되고 있습니다.
|
||||
이미 많은 개발자와 팀들이 **FastAPI**에 의존해 프로젝트를 진행 중입니다 (저와 제 팀도 마찬가지입니다).
|
||||
|
||||
하지만 여전히 개선해야 할 점과 추가할 기능들이 많이 남아 있습니다.
|
||||
|
||||
**FastAPI**는 밝은 미래로 나아가고 있습니다.
|
||||
그리고 [여러분의 도움](help-fastapi.md){.internal-link target=_blank}은 큰 힘이 됩니다.
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# 조건부적인 OpenAPI
|
||||
|
||||
필요한 경우, 설정 및 환경 변수를 사용하여 환경에 따라 조건부로 OpenAPI를 구성하고 완전히 비활성화할 수도 있습니다.
|
||||
|
||||
## 보안, API 및 docs에 대해서
|
||||
|
||||
프로덕션에서, 문서화된 사용자 인터페이스(UI)를 숨기는 것이 API를 보호하는 방법이 *되어서는 안 됩니다*.
|
||||
|
||||
이는 API에 추가적인 보안을 제공하지 않으며, *경로 작업*은 여전히 동일한 위치에서 사용 할 수 있습니다.
|
||||
|
||||
코드에 보안 결함이 있다면, 그 결함은 여전히 존재할 것입니다.
|
||||
|
||||
문서를 숨기는 것은 API와 상호작용하는 방법을 이해하기 어렵게 만들며, 프로덕션에서 디버깅을 더 어렵게 만들 수 있습니다. 이는 단순히 <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">'모호성에 의한 보안'</a>의 한 형태로 간주될 수 있습니다.
|
||||
|
||||
API를 보호하고 싶다면, 예를 들어 다음과 같은 더 나은 방법들이 있습니다:
|
||||
|
||||
* 요청 본문과 응답에 대해 잘 정의된 Pydantic 모델을 사용하도록 하세요.
|
||||
|
||||
* 종속성을 사용하여 필요한 권한과 역할을 구성하세요.
|
||||
|
||||
* 평문 비밀번호를 절대 저장하지 말고, 오직 암호화된 비밀번호만 저장하세요.
|
||||
|
||||
* Passlib과 JWT 토큰과 같은 잘 알려진 암호화 도구들을 구현하고 사용하세요.
|
||||
|
||||
* 필요한 곳에 OAuth2 범위를 사용하여 더 세분화된 권한 제어를 추가하세요.
|
||||
|
||||
* 등등....
|
||||
|
||||
그럼에도 불구하고, 특정 환경(예: 프로덕션)에서 또는 환경 변수의 설정에 따라 API 문서를 비활성화해야 하는 매우 특정한 사용 사례가 있을 수 있습니다.
|
||||
|
||||
## 설정 및 환경변수의 조건부 OpenAPI
|
||||
|
||||
동일한 Pydantic 설정을 사용하여 생성된 OpenAPI 및 문서 UI를 쉽게 구성할 수 있습니다.
|
||||
|
||||
예를 들어:
|
||||
|
||||
{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
|
||||
|
||||
여기서 `openapi_url` 설정을 기본값인 `"/openapi.json"`으로 선언합니다.
|
||||
|
||||
그런 뒤, 우리는 `FastAPI` 앱을 만들 때 그것을 사용합니다.
|
||||
|
||||
환경 변수 `OPENAPI_URL`을 빈 문자열로 설정하여 OpenAPI(문서 UI 포함)를 비활성화할 수도 있습니다. 예를 들어:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ OPENAPI_URL= uvicorn main:app
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
그리고 `/openapi.json`, `/docs` 또는 `/redoc`의 URL로 이동하면 `404 Not Found`라는 오류가 다음과 같이 표시됩니다:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"detail": "Not Found"
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# 고급 보안
|
||||
|
||||
## 추가 기능
|
||||
|
||||
[자습서 - 사용자 가이드: 보안](../../tutorial/security/index.md){.internal-link target=_blank} 문서에서 다룬 내용 외에도 보안 처리를 위한 몇 가지 추가 기능이 있습니다.
|
||||
|
||||
/// tip
|
||||
|
||||
다음 섹션은 **반드시 "고급"** 기능은 아닙니다.
|
||||
|
||||
그리고 여러분의 사용 사례에 따라, 적합한 해결책이 그 중 하나에 있을 가능성이 있습니다.
|
||||
|
||||
///
|
||||
|
||||
## 먼저 자습서 읽기
|
||||
|
||||
다음 섹션은 이미 [자습서 - 사용자 가이드: 보안](../../tutorial/security/index.md){.internal-link target=_blank} 문서를 읽었다고 가정합니다.
|
||||
|
||||
이 섹션들은 모두 동일한 개념을 바탕으로 하며, 추가 기능을 제공합니다.
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
# Configuração Avançada da Operação de Rota
|
||||
|
||||
## operationId do OpenAPI
|
||||
|
||||
/// warning | Aviso
|
||||
|
||||
Se você não é um "especialista" no OpenAPI, você provavelmente não precisa disso.
|
||||
|
||||
///
|
||||
|
||||
Você pode definir o `operationId` do OpenAPI que será utilizado na sua *operação de rota* com o parâmetro `operation_id`.
|
||||
|
||||
Você precisa ter certeza que ele é único para cada operação.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
|
||||
|
||||
### Utilizando o nome da *função de operação de rota* como o operationId
|
||||
|
||||
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 `operationId` em cada *operação de rota* utilizando o `APIRoute.name` dela.
|
||||
|
||||
Você deve fazer isso depois de adicionar todas as suas *operações de rota*.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *}
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Se você chamar `app.openapi()` manualmente, os `operationId`s devem ser atualizados antes dessa chamada.
|
||||
|
||||
///
|
||||
|
||||
/// warning | Aviso
|
||||
|
||||
Se você fizer isso, você tem que ter certeza de que cada uma das suas *funções de operação de rota* tem um nome único.
|
||||
|
||||
Mesmo que elas estejam em módulos (arquivos Python) diferentes.
|
||||
|
||||
///
|
||||
|
||||
## Excluir do OpenAPI
|
||||
|
||||
Para excluir uma *operação de rota* do esquema OpenAPI gerado (e por consequência, dos sistemas de documentação automáticos), utilize o parâmetro `include_in_schema` e defina ele como `False`:
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
|
||||
|
||||
## Descrição avançada a partir de docstring
|
||||
|
||||
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 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 do texto.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
|
||||
|
||||
## Respostas Adicionais
|
||||
|
||||
Você provavelmente já viu como declarar o `response_model` e `status_code` para uma *operação de rota*.
|
||||
|
||||
Isso define os metadados sobre a resposta principal da *operação de rota*.
|
||||
|
||||
Você também pode declarar respostas adicionais, com seus modelos, códigos de status, etc.
|
||||
|
||||
Existe um capítulo inteiro da nossa documentação sobre isso, você pode ler em [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
## Extras do OpenAPI
|
||||
|
||||
Quando você declara uma *operação de rota* na sua aplicação, o **FastAPI** irá gerar os metadados relevantes da *operação de rota* automaticamente para serem incluídos no esquema do OpenAPI.
|
||||
|
||||
/// note | Nota
|
||||
|
||||
Na especificação do OpenAPI, isso é chamado de um <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Objeto de Operação</a>.
|
||||
|
||||
///
|
||||
|
||||
Ele possui toda a informação sobre a *operação de rota* e é usado para gerar a documentação automaticamente.
|
||||
|
||||
Ele inclui os atributos `tags`, `parameters`, `requestBody`, `responses`, etc.
|
||||
|
||||
Esse esquema específico para uma *operação de rota* normalmente é gerado automaticamente pelo **FastAPI**, mas você também pode estender ele.
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Esse é um ponto de extensão de baixo nível.
|
||||
|
||||
Caso você só precise declarar respostas adicionais, uma forma conveniente de fazer isso é com [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
|
||||
Você pode estender o esquema do OpenAPI para uma *operação de rota* utilizando o parâmetro `openapi_extra`.
|
||||
|
||||
### Extensões do OpenAPI
|
||||
|
||||
Esse parâmetro `openapi_extra` pode ser útil, por exemplo, para declarar [Extensões do OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
|
||||
|
||||
Se você abrir os documentos criados automaticamente para a API, sua extensão aparecerá no final da *operação de rota* específica.
|
||||
|
||||
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
|
||||
|
||||
E se você olhar o esquema OpenAPI resultante (na rota `/openapi.json` da sua API), você verá que a sua extensão também faz parte da *operação de rota* específica:
|
||||
|
||||
```JSON hl_lines="22"
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "FastAPI",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"paths": {
|
||||
"/items/": {
|
||||
"get": {
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-aperture-labs-portal": "blue"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Esquema de *operação de rota* do OpenAPI personalizado
|
||||
|
||||
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 para o esquema gerado automaticamente.
|
||||
|
||||
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`:
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.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="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.
|
||||
|
||||
### Tipo de conteúdo do OpenAPI personalizado
|
||||
|
||||
Utilizando esse mesmo truque, você pode utilizar um modelo Pydantic para definir o esquema JSON 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 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 esquema JSON 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
|
||||
|
||||
```Python hl_lines="17-22 24"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
```Python hl_lines="17-22 24"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info | Informação
|
||||
|
||||
Na versão 1 do Pydantic, o método para obter o esquema JSON 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 esquema JSON 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
|
||||
|
||||
```Python hl_lines="26-33"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
```Python hl_lines="26-33"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// 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
|
||||
|
||||
Aqui reutilizamos o mesmo modelo do Pydantic.
|
||||
|
||||
Mas da mesma forma, nós poderíamos ter validado de alguma outra forma.
|
||||
|
||||
///
|
||||
Loading…
Reference in New Issue