🌐 Update translations for ko (update-all and add-missing) (#14923)

* Update all and add missing

* 🎨 Auto format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Motov Yurii 2026-02-14 09:57:01 +01:00 committed by GitHub
parent 82d90c51b4
commit 01e2e1088c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
93 changed files with 548 additions and 620 deletions

View File

@ -35,7 +35,7 @@
//// tab | 테스트
어제 제 친구가 이렇게 썼습니다: "If you spell incorrectly correctly, you have spelled it incorrectly". 이에 저는 이렇게 답했습니다: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"".
어제 제 친구가 이렇게 썼습니다: "If you spell incorrectly correctly, you have spelled it incorrectly". 이에 저는 이렇게 답했습니다: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'".
/// note | 참고
@ -256,15 +256,15 @@ works(foo="bar") # 이건 동작합니다 🎉
//// tab | 테스트
* 당신
* 당신
* 여러분
* 여러분
* 예: (e.g.)
* 등 (etc.)
* `int`로서의 `foo`
* `str`로서의 `bar`
* `list`로서의 `baz`
* `foo`로서의 `int`
* `bar`로서의 `str`
* `baz`로서의 `list`
* 튜토리얼 - 사용자 가이드
* 고급 사용자 가이드

View File

@ -26,7 +26,7 @@
예를 들어, 상태 코드 `404`와 Pydantic 모델 `Message`를 사용하는 다른 응답을 선언하려면 다음과 같이 작성할 수 있습니다:
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
/// note | 참고
@ -203,7 +203,7 @@
또한 `response_model`을 사용하는 상태 코드 `200` 응답을 선언하되, 커스텀 `example`을 포함할 수도 있습니다:
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
이 모든 내용은 OpenAPI에 결합되어 포함되고, API 문서에 표시됩니다:

View File

@ -1,14 +1,14 @@
# 추가 상태 코드 { #additional-status-codes }
기본적으로 **FastAPI**는 응답을 `JSONResponse`를 사용하여 반환하며, *경로 작업(path operation)*에서 반환한 내용을 해당 `JSONResponse` 안에 넣어 반환합니다.
기본적으로 **FastAPI**는 응답을 `JSONResponse`를 사용하여 반환하며, *경로 처리*에서 반환한 내용을 해당 `JSONResponse` 안에 넣어 반환합니다.
기본 상태 코드 또는 *경로 작업*에서 설정한 상태 코드를 사용합니다.
기본 상태 코드 또는 *경로 처리*에서 설정한 상태 코드를 사용합니다.
## 추가 상태 코드 { #additional-status-codes_1 }
기본 상태 코드와 별도로 추가 상태 코드를 반환하려면 `JSONResponse`와 같이 `Response`를 직접 반환하고 추가 상태 코드를 직접 설정할 수 있습니다.
예를 들어 항목을 업데이트할 수 있는 *경로 작업*이 있고 성공 시 200 “OK”의 HTTP 상태 코드를 반환한다고 가정해 보겠습니다.
예를 들어 항목을 업데이트할 수 있는 *경로 처리*가 있고 성공 시 200 “OK”의 HTTP 상태 코드를 반환한다고 가정해 보겠습니다.
하지만 새로운 항목을 허용하기를 원할 것입니다. 그리고 항목이 이전에 존재하지 않았다면 이를 생성하고 HTTP 상태 코드 201 "Created"를 반환합니다.
@ -16,7 +16,7 @@
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
/// warning | 경고
/// warning
위의 예제처럼 `Response`를 직접 반환하면 바로 반환됩니다.

View File

@ -18,7 +18,7 @@ Python에는 클래스의 인스턴스를 "호출 가능"하게 만드는 방법
이를 위해 `__call__` 메서드를 선언합니다:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
이 경우, **FastAPI**는 추가 매개변수와 하위 의존성을 확인하기 위해 `__call__`을 사용하게 되며,
나중에 *경로 처리 함수*에서 매개변수에 값을 전달할 때 이를 호출하게 됩니다.
@ -27,7 +27,7 @@ Python에는 클래스의 인스턴스를 "호출 가능"하게 만드는 방법
이제 `__init__`을 사용하여 의존성을 "매개변수화"할 수 있는 인스턴스의 매개변수를 선언할 수 있습니다:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
이 경우, **FastAPI**는 `__init__`에 전혀 관여하지 않으며, 우리는 이 메서드를 코드에서 직접 사용하게 됩니다.
@ -35,7 +35,7 @@ Python에는 클래스의 인스턴스를 "호출 가능"하게 만드는 방법
다음과 같이 이 클래스의 인스턴스를 생성할 수 있습니다:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
이렇게 하면 `checker.fixed_content` 속성에 `"bar"`라는 값을 담아 의존성을 "매개변수화"할 수 있습니다.
@ -51,7 +51,7 @@ checker(q="somequery")
...그리고 이때 반환되는 값을 *경로 처리 함수*의 의존성 값으로, `fixed_content_included` 매개변수에 전달합니다:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
/// tip | 팁

View File

@ -0,0 +1,61 @@
# 고급 Python 타입 { #advanced-python-types }
Python 타입을 다룰 때 유용할 수 있는 몇 가지 추가 아이디어를 소개합니다.
## `Union` 또는 `Optional` 사용 { #using-union-or-optional }
어떤 이유로 코드에서 `|`를 사용할 수 없다면, 예를 들어 타입 어노테이션이 아니라 `response_model=` 같은 곳이라면, 파이프 문자(`|`) 대신 `typing``Union`을 사용할 수 있습니다.
예를 들어, 어떤 값이 `str` 또는 `None`이 될 수 있다고 선언할 수 있습니다:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing`에는 `None`이 될 수 있음을 선언하는 축약형으로 `Optional`도 있습니다.
아주 개인적인 관점에서의 팁입니다:
- 🚨 `Optional[SomeType]` 사용은 피하세요
- 대신 ✨ **`Union[SomeType, None]`를 사용하세요** ✨.
둘은 동등하며 내부적으로도 같습니다. 하지만 단어 "optional"은 값이 선택 사항이라는 인상을 주는 반면, 실제 의미는 "값이 `None`이 될 수 있다"는 뜻입니다. 값이 선택 사항이 아니라 여전히 필수인 경우에도 그렇습니다.
`Union[SomeType, None]`가 의미를 더 명확하게 드러낸다고 생각합니다.
이는 단지 단어와 명칭의 문제입니다. 하지만 이런 단어가 여러분과 팀원이 코드를 어떻게 생각하는지에 영향을 줄 수 있습니다.
예를 들어, 다음 함수를 보세요:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
매개변수 `name``Optional[str]`로 정의되어 있지만, 사실 선택적이지 않습니다. 이 매개변수 없이 함수를 호출할 수 없습니다:
```Python
say_hi() # 이런, 에러가 발생합니다! 😱
```
`name` 매개변수는 기본값이 없기 때문에 여전히 필수입니다(선택적이 아님). 대신, `name`에는 `None`을 전달할 수 있습니다:
```Python
say_hi(name=None) # 작동합니다. None은 유효합니다 🎉
```
좋은 소식은, 대부분의 경우 타입의 합집합을 정의할 때 그냥 `|`를 사용할 수 있다는 점입니다:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
그래서 보통은 `Optional``Union` 같은 이름에 대해 걱정하지 않으셔도 됩니다. 😎

View File

@ -32,11 +32,11 @@
`main.py` 파일은 다음과 같습니다:
{* ../../docs_src/async_tests/app_a_py39/main.py *}
{* ../../docs_src/async_tests/app_a_py310/main.py *}
`test_main.py` 파일에는 `main.py`에 대한 테스트가 있으며, 이제 다음과 같이 보일 수 있습니다:
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
## 실행하기 { #run-it }
@ -56,7 +56,7 @@ $ pytest
`@pytest.mark.anyio` 마커는 pytest에게 이 테스트 함수가 비동기로 호출되어야 한다고 알려줍니다:
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
/// tip | 팁
@ -66,7 +66,7 @@ $ pytest
그 다음 앱으로 `AsyncClient`를 만들고, `await`를 사용해 비동기 요청을 보낼 수 있습니다.
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
이는 다음과 동등합니다:

View File

@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
예를 들어, *경로 처리* `/items/`를 정의했다고 해봅시다:
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
클라이언트가 `/items`로 접근하면, 기본적으로 `/items/`로 리디렉션됩니다.
@ -115,7 +115,7 @@ sequenceDiagram
코드는 모두 `/app`만 있다고 가정하고 작성되어 있는데도 말입니다.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
그리고 프록시는 요청을 앱 서버(아마 FastAPI CLI를 통해 실행되는 Uvicorn)로 전달하기 전에, 동적으로 **경로 접두사**를 **"제거"**합니다. 그래서 애플리케이션은 여전히 `/app`에서 서비스된다고 믿게 되고, 코드 전체를 `/api/v1` 접두사를 포함하도록 수정할 필요가 없어집니다.
@ -193,7 +193,7 @@ ASGI 사양은 이 사용 사례를 위해 `root_path`를 정의합니다.
여기서는 데모 목적을 위해 메시지에 포함하고 있습니다.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
그 다음 Uvicorn을 다음과 같이 시작하면:
@ -220,7 +220,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
또는 `--root-path` 같은 커맨드 라인 옵션(또는 동등한 방법)을 제공할 수 없는 경우, FastAPI 앱을 생성할 때 `root_path` 파라미터를 설정할 수 있습니다:
{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
`FastAPI``root_path`를 전달하는 것은 Uvicorn이나 Hypercorn에 커맨드 라인 옵션 `--root-path`를 전달하는 것과 동일합니다.
@ -400,7 +400,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
예:
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
다음과 같은 OpenAPI 스키마를 생성합니다:
@ -455,7 +455,7 @@ OpenAPI 사양에서 `servers` 속성은 선택 사항입니다.
**FastAPI**가 `root_path`를 사용한 자동 server를 포함하지 않게 하려면, `root_path_in_servers=False` 파라미터를 사용할 수 있습니다:
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
그러면 OpenAPI 스키마에 포함되지 않습니다.

View File

@ -30,7 +30,7 @@
하지만 반환하는 내용이 **JSON으로 직렬화 가능**하다고 확신하는 경우, 해당 내용을 응답 클래스에 직접 전달할 수 있으며, FastAPI가 반환 내용을 `jsonable_encoder`를 통해 처리한 뒤 응답 클래스에 전달하는 오버헤드를 피할 수 있습니다.
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
/// info | 정보
@ -55,7 +55,7 @@
* `HTMLResponse`를 임포트 합니다.
* *경로 처리 데코레이터*의 `response_class` 매개변수로 `HTMLResponse`를 전달합니다.
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info | 정보
@ -73,7 +73,7 @@
위의 예제와 동일하게 `HTMLResponse`를 반환하는 코드는 다음과 같을 수 있습니다:
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning | 경고
@ -97,7 +97,7 @@
예를 들어, 다음과 같이 작성할 수 있습니다:
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
이 예제에서, `generate_html_response()` 함수는 HTML을 `str`로 반환하는 대신 이미 `Response`를 생성하고 반환합니다.
@ -136,7 +136,7 @@
FastAPI (실제로는 Starlette)가 자동으로 Content-Length 헤더를 포함시킵니다. 또한 `media_type`에 기반하여 Content-Type 헤더를 포함하며, 텍스트 타입의 경우 문자 집합을 추가 합니다.
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@ -146,7 +146,7 @@ FastAPI (실제로는 Starlette)가 자동으로 Content-Length 헤더를 포함
텍스트 또는 바이트를 받아 일반 텍스트 응답을 반환합니다.
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@ -180,7 +180,7 @@ FastAPI (실제로는 Starlette)가 자동으로 Content-Length 헤더를 포함
///
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// tip | 팁
@ -194,14 +194,14 @@ HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 30
`RedirectResponse`를 직접 반환할 수 있습니다.
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
또는 `response_class` 매개변수에서 사용할 수도 있습니다:
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
이 경우, *경로 처리* 함수에서 URL을 직접 반환할 수 있습니다.
@ -211,13 +211,13 @@ HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 30
`status_code` 매개변수를 `response_class` 매개변수와 함께 사용할 수도 있습니다:
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
비동기 제너레이터 또는 일반 제너레이터/이터레이터를 받아 응답 본문을 스트리밍 합니다.
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### 파일과 같은 객체를 사용한 `StreamingResponse` { #using-streamingresponse-with-file-like-objects }
@ -227,7 +227,7 @@ HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 30
이 방식은 클라우드 스토리지, 비디오 처리 등의 다양한 라이브러리와 함께 사용할 수 있습니다.
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
1. 이것이 제너레이터 함수입니다. `yield` 문을 포함하고 있으므로 "제너레이터 함수"입니다.
2. `with` 블록을 사용함으로써, 제너레이터 함수가 완료된 후 파일과 같은 객체가 닫히도록 합니다. 즉, 응답 전송이 끝난 후 닫힙니다.
@ -256,11 +256,11 @@ HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 30
파일 응답에는 적절한 `Content-Length`, `Last-Modified`, 및 `ETag` 헤더가 포함됩니다.
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
또한 `response_class` 매개변수를 사용할 수도 있습니다:
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
이 경우, 경로 처리 함수에서 파일 경로를 직접 반환할 수 있습니다.
@ -274,7 +274,7 @@ HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 30
`CustomORJSONResponse`를 생성할 수 있습니다. 여기서 핵심은 `Response.render(content)` 메서드를 생성하여 내용을 `bytes`로 반환하는 것입니다:
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
이제 다음 대신:
@ -300,7 +300,7 @@ HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 30
아래 예제에서 **FastAPI**는 모든 *경로 처리*에서 기본적으로 `JSONResponse` 대신 `ORJSONResponse`를 사용합니다.
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip | 팁

View File

@ -64,7 +64,7 @@ dataclass는 자동으로 Pydantic dataclass로 변환됩니다.
6. 여기서는 dataclasses 리스트인 `items`를 포함하는 딕셔너리를 반환합니다.
FastAPI는 여전히 데이터를 JSON으로 <abbr title="converting the data to a format that can be transmitted - 데이터를 전송 가능한 형식으로 변환하는 것">serializing</abbr>할 수 있습니다.
FastAPI는 여전히 데이터를 JSON으로 <dfn title="데이터를 전송 가능한 형식으로 변환하는 것">직렬화</dfn>할 수 있습니다.
7. 여기서 `response_model``Author` dataclasses 리스트에 대한 타입 애너테이션을 사용합니다.

View File

@ -30,7 +30,7 @@
`yield`를 사용해 비동기 함수 `lifespan()`을 다음과 같이 생성합니다:
{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
여기서는 `yield` 이전에 (가짜) 모델 함수를 머신러닝 모델이 들어 있는 딕셔너리에 넣어 모델을 로드하는 비용이 큰 *시작* 작업을 시뮬레이션합니다. 이 코드는 애플리케이션이 **요청을 받기 시작하기 전**, *시작* 동안에 실행됩니다.
@ -48,7 +48,7 @@
먼저 주목할 점은 `yield`를 사용하여 비동기 함수를 정의하고 있다는 것입니다. 이는 `yield`를 사용하는 의존성과 매우 유사합니다.
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
함수의 첫 번째 부분, 즉 `yield` 이전의 코드는 애플리케이션이 시작되기 **전에** 실행됩니다.
@ -60,7 +60,7 @@
이는 함수를 "**비동기 컨텍스트 매니저**"라고 불리는 것으로 변환합니다.
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
파이썬에서 **컨텍스트 매니저**는 `with` 문에서 사용할 수 있는 것입니다. 예를 들어, `open()`은 컨텍스트 매니저로 사용할 수 있습니다:
@ -82,7 +82,7 @@ async with lifespan(app):
`FastAPI` 앱의 `lifespan` 매개변수는 **비동기 컨텍스트 매니저**를 받으므로, 새 `lifespan` 비동기 컨텍스트 매니저를 전달할 수 있습니다.
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
## 대체 이벤트(사용 중단) { #alternative-events-deprecated }
@ -104,7 +104,7 @@ async with lifespan(app):
애플리케이션이 시작되기 전에 실행되어야 하는 함수를 추가하려면, `"startup"` 이벤트로 선언합니다:
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
이 경우, `startup` 이벤트 핸들러 함수는 "database"(그냥 `dict`) 항목을 일부 값으로 초기화합니다.
@ -116,7 +116,7 @@ async with lifespan(app):
애플리케이션이 종료될 때 실행되어야 하는 함수를 추가하려면, `"shutdown"` 이벤트로 선언합니다:
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
여기서 `shutdown` 이벤트 핸들러 함수는 텍스트 한 줄 `"Application shutdown"``log.txt` 파일에 기록합니다.

View File

@ -40,7 +40,7 @@ FastAPI는 **OpenAPI 3.1** 사양을 자동으로 생성하므로, 사용하는
간단한 FastAPI 애플리케이션으로 시작해 보겠습니다:
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
*path operation*에서 요청 페이로드와 응답 페이로드에 사용하는 모델을 `Item`, `ResponseMessage` 모델로 정의하고 있다는 점에 주목하세요.
@ -98,7 +98,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
예를 들어 **items** 섹션과 **users** 섹션이 있고, 이를 태그로 분리할 수 있습니다:
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
### 태그로 TypeScript 클라이언트 생성하기 { #generate-a-typescript-client-with-tags }
@ -145,7 +145,7 @@ FastAPI는 각 *path operation*에 대해 **유일 ID**를 사용하며, 이는
그 다음 이 커스텀 함수를 `generate_unique_id_function` 매개변수로 **FastAPI**에 전달할 수 있습니다:
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
### 커스텀 Operation ID로 TypeScript 클라이언트 생성하기 { #generate-a-typescript-client-with-custom-operation-ids }
@ -167,7 +167,7 @@ OpenAPI 전반에서는 operation ID가 **유일**하다는 것을 보장하기
OpenAPI JSON을 `openapi.json` 파일로 다운로드한 뒤, 아래와 같은 스크립트로 **접두사 태그를 제거**할 수 있습니다:
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
//// tab | Node.js

View File

@ -1,4 +1,4 @@
# 심화 사용자 안내서 - 도입부 { #advanced-user-guide }
# 심화 사용자 안내서 { #advanced-user-guide }
## 추가 기능 { #additional-features }

View File

@ -8,7 +8,7 @@
## ASGI middleware 추가하기 { #adding-asgi-middlewares }
**FastAPI**는 Starlette를 기반으로 하고 <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> 사양을 구현하므로, 어떤 ASGI middleware든 사용할 수 있습니다.
**FastAPI**는 Starlette를 기반으로 하고 <abbr title="Asynchronous Server Gateway Interface - 비동기 서버 게이트웨이 인터페이스">ASGI</abbr> 사양을 구현하므로, 어떤 ASGI middleware든 사용할 수 있습니다.
ASGI 사양을 따르기만 하면, FastAPI나 Starlette를 위해 만들어진 middleware가 아니어도 동작합니다.
@ -57,13 +57,13 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
`http` 또는 `ws`로 들어오는 모든 요청은 대신 보안 스킴으로 리디렉션됩니다.
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
HTTP Host Header 공격을 방어하기 위해, 들어오는 모든 요청에 올바르게 설정된 `Host` 헤더가 있어야 하도록 강제합니다.
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
다음 인자들을 지원합니다:
@ -78,7 +78,7 @@ HTTP Host Header 공격을 방어하기 위해, 들어오는 모든 요청에
이 middleware는 일반 응답과 스트리밍 응답을 모두 처리합니다.
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
다음 인자들을 지원합니다:

View File

@ -1,8 +1,8 @@
# OpenAPI 콜백 { #openapi-callbacks }
다른 사람이 만든 *external API*(아마도 당신의 API를 *사용*할 동일한 개발자)가 요청을 트리거하도록 만드는 *경로 처리*를 가진 API를 만들 수 있습니다.
다른 사람이 만든 *external API*(아마도 여러분의 API를 *사용*할 동일한 개발자)가 요청을 트리거하도록 만드는 *경로 처리*를 가진 API를 만들 수 있습니다.
당신의 API 앱이 *external API*를 호출할 때 일어나는 과정을 "callback"이라고 합니다. 외부 개발자가 작성한 소프트웨어가 당신의 API로 요청을 보낸 다음, 당신의 API가 다시 *external API*로 요청을 보내 *되돌려 호출*하기 때문입니다(아마도 같은 개발자가 만든 API일 것입니다).
여러분의 API 앱이 *external API*를 호출할 때 일어나는 과정을 "callback"이라고 합니다. 외부 개발자가 작성한 소프트웨어가 여러분의 API로 요청을 보낸 다음, 여러분의 API가 다시 *external API*로 요청을 보내 *되돌려 호출*하기 때문입니다(아마도 같은 개발자가 만든 API일 것입니다).
이 경우, 그 *external API*가 어떤 형태여야 하는지 문서화하고 싶을 수 있습니다. 어떤 *경로 처리*를 가져야 하는지, 어떤 body를 기대하는지, 어떤 응답을 반환해야 하는지 등입니다.
@ -14,14 +14,14 @@
이 청구서는 `id`, `title`(선택 사항), `customer`, `total`을 갖습니다.
당신의 API 사용자(외부 개발자)는 POST 요청으로 당신의 API에서 청구서를 생성합니다.
여러분의 API 사용자(외부 개발자)는 POST 요청으로 여러분의 API에서 청구서를 생성합니다.
그 다음 당신의 API는(가정해 보면):
그 다음 여러분의 API는(가정해 보면):
* 청구서를 외부 개발자의 고객에게 전송합니다.
* 돈을 수금합니다.
* API 사용자(외부 개발자)의 API로 다시 알림을 보냅니다.
* 이는 (당신의 API에서) 그 외부 개발자가 제공하는 어떤 *external API*로 POST 요청을 보내는 방식으로 수행됩니다(이것이 "callback"입니다).
* 이는 (여러분의 API에서) 그 외부 개발자가 제공하는 어떤 *external API*로 POST 요청을 보내는 방식으로 수행됩니다(이것이 "callback"입니다).
## 일반적인 **FastAPI** 앱 { #the-normal-fastapi-app }
@ -43,7 +43,7 @@
## 콜백 문서화하기 { #documenting-the-callback }
실제 콜백 코드는 당신의 API 앱에 크게 의존합니다.
실제 콜백 코드는 여러분의 API 앱에 크게 의존합니다.
그리고 앱마다 많이 달라질 수 있습니다.
@ -54,11 +54,11 @@ callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
```
하지만 콜백에서 가장 중요한 부분은, 당신의 API 사용자(외부 개발자)가 콜백 요청 body로 *당신의 API*가 보낼 데이터 등에 맞춰 *external API*를 올바르게 구현하도록 보장하는 것입니다.
하지만 콜백에서 가장 중요한 부분은, 여러분의 API 사용자(외부 개발자)가 콜백 요청 body로 *여러분의 API*가 보낼 데이터 등에 맞춰 *external API*를 올바르게 구현하도록 보장하는 것입니다.
그래서 다음으로 할 일은, *당신의 API*에서 보내는 콜백을 받기 위해 그 *external API*가 어떤 형태여야 하는지 문서화하는 코드를 추가하는 것입니다.
그래서 다음으로 할 일은, *여러분의 API*에서 보내는 콜백을 받기 위해 그 *external API*가 어떤 형태여야 하는지 문서화하는 코드를 추가하는 것입니다.
그 문서는 당신의 API에서 `/docs`의 Swagger UI에 표시되며, 외부 개발자들이 *external API*를 어떻게 만들어야 하는지 알 수 있게 해줍니다.
그 문서는 여러분의 API에서 `/docs`의 Swagger UI에 표시되며, 외부 개발자들이 *external API*를 어떻게 만들어야 하는지 알 수 있게 해줍니다.
이 예시는 콜백 자체(한 줄 코드로도 될 수 있음)를 구현하지 않고, 문서화 부분만 구현합니다.
@ -76,11 +76,11 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
하지만 **FastAPI**로 API의 자동 문서를 쉽게 생성하는 방법은 이미 알고 있습니다.
따라서 그와 같은 지식을 사용해 *external API*가 어떻게 생겨야 하는지 문서화할 것입니다... 즉 외부 API가 구현해야 하는 *경로 처리(들)*(당신의 API가 호출할 것들)을 만들어서 말입니다.
따라서 그와 같은 지식을 사용해 *external API*가 어떻게 생겨야 하는지 문서화할 것입니다... 즉 외부 API가 구현해야 하는 *경로 처리(들)*(여러분의 API가 호출할 것들)을 만들어서 말입니다.
/// tip | 팁
콜백을 문서화하는 코드를 작성할 때는, 자신이 그 *외부 개발자*라고 상상하는 것이 유용할 수 있습니다. 그리고 지금은 *당신의 API*가 아니라 *external API*를 구현하고 있다고 생각해 보세요.
콜백을 문서화하는 코드를 작성할 때는, 자신이 그 *외부 개발자*라고 상상하는 것이 유용할 수 있습니다. 그리고 지금은 *여러분의 API*가 아니라 *external API*를 구현하고 있다고 생각해 보세요.
이 관점(외부 개발자의 관점)을 잠시 채택하면, 그 *external API*를 위해 파라미터, body용 Pydantic 모델, 응답 등을 어디에 두어야 하는지가 더 명확하게 느껴질 수 있습니다.
@ -105,12 +105,12 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
일반적인 *경로 처리*와의 주요 차이점은 2가지입니다:
* 실제 코드를 가질 필요가 없습니다. 당신의 앱은 이 코드를 절대 호출하지 않기 때문입니다. 이는 *external API*를 문서화하는 데만 사용됩니다. 따라서 함수는 그냥 `pass`만 있어도 됩니다.
* *path*에는 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>(자세한 내용은 아래 참고)이 포함될 수 있으며, 이를 통해 *당신의 API*로 보내진 원래 요청의 파라미터와 일부 값을 변수로 사용할 수 있습니다.
* 실제 코드를 가질 필요가 없습니다. 여러분의 앱은 이 코드를 절대 호출하지 않기 때문입니다. 이는 *external API*를 문서화하는 데만 사용됩니다. 따라서 함수는 그냥 `pass`만 있어도 됩니다.
* *path*에는 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>(자세한 내용은 아래 참고)이 포함될 수 있으며, 이를 통해 *여러분의 API*로 보내진 원래 요청의 파라미터와 일부 값을 변수로 사용할 수 있습니다.
### 콜백 경로 표현식 { #the-callback-path-expression }
콜백 *path*는 *당신의 API*로 보내진 원래 요청의 일부를 포함할 수 있는 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>을 가질 수 있습니다.
콜백 *path*는 *여러분의 API*로 보내진 원래 요청의 일부를 포함할 수 있는 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>을 가질 수 있습니다.
이 경우, 다음 `str`입니다:
@ -118,7 +118,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
"{$callback_url}/invoices/{$request.body.id}"
```
따라서 당신의 API 사용자(외부 개발자)가 *당신의 API*로 다음 요청을 보내고:
따라서 여러분의 API 사용자(외부 개발자)가 *여러분의 API*로 다음 요청을 보내고:
```
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
@ -134,7 +134,7 @@ JSON body가 다음과 같다면:
}
```
그러면 *당신의 API*는 청구서를 처리하고, 나중에 어느 시점에서 `callback_url`(즉 *external API*)로 콜백 요청을 보냅니다:
그러면 *여러분의 API*는 청구서를 처리하고, 나중에 어느 시점에서 `callback_url`(즉 *external API*)로 콜백 요청을 보냅니다:
```
https://www.external.org/events/invoices/2expen51ve
@ -167,7 +167,7 @@ https://www.external.org/events/invoices/2expen51ve
이 시점에서, 위에서 만든 콜백 라우터 안에 *콜백 경로 처리(들)*(즉 *external developer*가 *external API*에 구현해야 하는 것들)을 준비했습니다.
이제 *당신의 API 경로 처리 데코레이터*에서 `callbacks` 파라미터를 사용해, 그 콜백 라우터의 `.routes` 속성(실제로는 routes/*경로 처리*의 `list`)을 전달합니다:
이제 *여러분의 API 경로 처리 데코레이터*에서 `callbacks` 파라미터를 사용해, 그 콜백 라우터의 `.routes` 속성(실제로는 routes/*경로 처리*의 `list`)을 전달합니다:
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}

View File

@ -32,7 +32,7 @@ Webhooks는 OpenAPI 3.1.0 이상에서 사용할 수 있으며, FastAPI `0.99.0`
**FastAPI** 애플리케이션을 만들면, *경로 처리*를 정의하는 것과 같은 방식으로(예: `@app.webhooks.post()`), *webhooks*를 정의하는 데 사용할 수 있는 `webhooks` 속성이 있습니다.
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
여러분이 정의한 webhook은 **OpenAPI** 스키마와 자동 **docs UI**에 포함됩니다.

View File

@ -12,7 +12,7 @@ OpenAPI “전문가”가 아니라면, 아마 이 내용은 필요하지 않
각 작업마다 고유하도록 보장해야 합니다.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### *경로 처리 함수* 이름을 operationId로 사용하기 { #using-the-path-operation-function-name-as-the-operationid }
@ -20,7 +20,7 @@ API의 함수 이름을 `operationId`로 사용하고 싶다면, 모든 API를
모든 *경로 처리*를 추가한 뒤에 수행해야 합니다.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip | 팁
@ -40,7 +40,7 @@ API의 함수 이름을 `operationId`로 사용하고 싶다면, 모든 API를
생성된 OpenAPI 스키마(따라서 자동 문서화 시스템)에서 특정 *경로 처리*를 제외하려면, `include_in_schema` 매개변수를 `False`로 설정하세요:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## docstring에서 고급 설명 가져오기 { #advanced-description-from-docstring }
@ -92,7 +92,7 @@ OpenAPI 명세에서는 이를 <a href="https://github.com/OAI/OpenAPI-Specifica
예를 들어 `openapi_extra`는 [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions)를 선언하는 데 도움이 될 수 있습니다:
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
자동 API 문서를 열면, 해당 특정 *경로 처리*의 하단에 확장이 표시됩니다.
@ -139,9 +139,9 @@ OpenAPI 명세에서는 이를 <a href="https://github.com/OAI/OpenAPI-Specifica
그럴 때 `openapi_extra`를 사용할 수 있습니다:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
이 예시에서는 어떤 Pydantic 모델도 선언하지 않았습니다. 사실 요청 바디는 JSON으로 <abbr title="converted from some plain format, like bytes, into Python objects - bytes 같은 일반 형식에서 Python 객체로 변환">parsed</abbr>되지도 않고, `bytes`로 직접 읽습니다. 그리고 함수 `magic_data_reader()`가 어떤 방식으로든 이를 파싱하는 역할을 담당합니다.
이 예시에서는 어떤 Pydantic 모델도 선언하지 않았습니다. 사실 요청 바디는 JSON으로 <dfn title="bytes 같은 일반 형식에서 Python 객체로 변환">파싱</dfn>되지도 않고, `bytes`로 직접 읽습니다. 그리고 함수 `magic_data_reader()`가 어떤 방식으로든 이를 파싱하는 역할을 담당합니다.
그럼에도 불구하고, 요청 바디에 대해 기대하는 스키마를 선언할 수 있습니다.
@ -153,7 +153,7 @@ OpenAPI 명세에서는 이를 <a href="https://github.com/OAI/OpenAPI-Specifica
예를 들어 이 애플리케이션에서는 Pydantic 모델에서 JSON Schema를 추출하는 FastAPI의 통합 기능도, JSON에 대한 자동 검증도 사용하지 않습니다. 실제로 요청 콘텐츠 타입을 JSON이 아니라 YAML로 선언합니다:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
그럼에도 기본 통합 기능을 사용하지 않더라도, YAML로 받고자 하는 데이터에 대한 JSON Schema를 수동으로 생성하기 위해 Pydantic 모델을 여전히 사용합니다.
@ -161,7 +161,7 @@ OpenAPI 명세에서는 이를 <a href="https://github.com/OAI/OpenAPI-Specifica
그리고 코드에서 YAML 콘텐츠를 직접 파싱한 뒤, 다시 같은 Pydantic 모델을 사용해 YAML 콘텐츠를 검증합니다:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip | 팁

View File

@ -20,7 +20,7 @@
그리고 이 *임시* 응답 객체에서 `status_code`를 설정할 수 있습니다.
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
그리고 평소처럼 필요한 어떤 객체든 반환할 수 있습니다(`dict`, 데이터베이스 모델 등).

View File

@ -6,7 +6,7 @@
그런 다음 해당 *임시* 응답 객체에서 쿠키를 설정할 수 있습니다.
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
그런 다음 일반적으로 하듯이 필요한 어떤 객체든 반환할 수 있습니다(`dict`, 데이터베이스 모델 등).
@ -24,7 +24,7 @@
그런 다음 쿠키를 설정하고 반환하면 됩니다:
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip | 팁

View File

@ -54,7 +54,7 @@ Pydantic 모델로 데이터 변환을 수행하지 않으며, 내용을 다른
XML 내용을 문자열에 넣고, 이를 `Response`에 넣어 반환할 수 있습니다:
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## 참고 사항 { #notes }

View File

@ -6,7 +6,7 @@
그런 다음, 여러분은 해당 *임시* 응답 객체에서 헤더를 설정할 수 있습니다.
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
그 후, 일반적으로 사용하듯이 필요한 객체(`dict`, 데이터베이스 모델 등)를 반환할 수 있습니다.
@ -20,15 +20,15 @@
`Response`를 직접 반환할 때에도 헤더를 추가할 수 있습니다.
[응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 설명한 대로 응답을 생성하고, 헤더를 추가 매개변수로 전달하세요.
[응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 설명한 대로 응답을 생성하고, 헤더를 추가 매개변수로 전달하세요:
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
/// note | 기술 세부사항
`from starlette.responses import Response``from starlette.responses import JSONResponse`를 사용할 수도 있습니다.
**FastAPI**는 해당 *임시* 응답에서 헤더(쿠키와 상태 코드도 포함)를 추출하여, 여러분이 반환한 값을 포함하는 최종 응답에 `response_model`로 필터링된 값을 넣습니다.
**FastAPI**는 개발자인 여러분의 편의를 위해 `starlette.responses`와 동일한 것을 `fastapi.responses`로도 제공합니다. 하지만 사용 가능한 대부분의 응답은 Starlette에서 직접 제공합니다.
그리고 `Response`는 헤더와 쿠키를 설정하는 데 자주 사용될 수 있으므로, **FastAPI**는 `fastapi.Response`로도 이를 제공합니다.

View File

@ -20,7 +20,7 @@ HTTP Basic Auth에서는 애플리케이션이 사용자명과 비밀번호가
* `HTTPBasicCredentials` 타입의 객체를 반환합니다:
* 전송된 `username``password`를 포함합니다.
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
처음으로 URL을 열어보면(또는 문서에서 "Execute" 버튼을 클릭하면) 브라우저가 사용자명과 비밀번호를 물어봅니다:
@ -40,13 +40,13 @@ dependency를 사용해 사용자명과 비밀번호가 올바른지 확인하
그런 다음 `secrets.compare_digest()`를 사용해 `credentials.username``"stanleyjobson"`이고 `credentials.password``"swordfish"`인지 확실히 확인할 수 있습니다.
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
이는 다음과 비슷합니다:
```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# Return some error
# 어떤 오류를 반환
...
```
@ -104,4 +104,4 @@ Python은 두 문자열이 같지 않다는 것을 알아차리기 전까지 `st
자격 증명이 올바르지 않다고 판단되면, 상태 코드 401(자격 증명이 제공되지 않았을 때와 동일)을 사용하는 `HTTPException`을 반환하고 브라우저가 로그인 프롬프트를 다시 표시하도록 `WWW-Authenticate` 헤더를 추가하세요:
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}

View File

@ -54,7 +54,7 @@ Pydantic 모델과 같은 방식으로, 타입 어노테이션(그리고 필요
다양한 데이터 타입, `Field()`로 추가 검증 등 Pydantic 모델에서 사용하는 동일한 검증 기능과 도구를 모두 사용할 수 있습니다.
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
/// tip | 팁
@ -70,7 +70,7 @@ Pydantic 모델과 같은 방식으로, 타입 어노테이션(그리고 필요
이제 애플리케이션에서 새 `settings` 객체를 사용할 수 있습니다:
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
### 서버 실행하기 { #run-the-server }
@ -104,11 +104,11 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
예를 들어 `config.py` 파일을 다음처럼 만들 수 있습니다:
{* ../../docs_src/settings/app01_py39/config.py *}
{* ../../docs_src/settings/app01_py310/config.py *}
그리고 `main.py` 파일에서 이를 사용합니다:
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
/// tip | 팁
@ -126,7 +126,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
이전 예시에서 이어서, `config.py` 파일은 다음과 같을 수 있습니다:
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
이제는 기본 인스턴스 `settings = Settings()`를 생성하지 않는다는 점에 유의하세요.
@ -134,7 +134,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
이제 새로운 `config.Settings()`를 반환하는 의존성을 생성합니다.
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
/// tip | 팁
@ -146,13 +146,13 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
그 다음 *경로 처리 함수*에서 이를 의존성으로 요구하고, 필요한 어디서든 사용할 수 있습니다.
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
### 설정과 테스트 { #settings-and-testing }
그 다음, `get_settings`에 대한 의존성 override를 만들어 테스트 중에 다른 설정 객체를 제공하기가 매우 쉬워집니다:
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
의존성 override에서는 새 `Settings` 객체를 생성할 때 `admin_email`의 새 값을 설정하고, 그 새 객체를 반환합니다.
@ -193,11 +193,11 @@ APP_NAME="ChimichangApp"
그리고 `config.py`를 다음처럼 업데이트합니다:
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
/// tip | 팁
`model_config` 속성은 Pydantic 설정을 위한 것입니다. 자세한 내용은 <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a> 참고하세요.
`model_config` 속성은 Pydantic 설정을 위한 것입니다. 자세한 내용은 <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a> 참고하세요.
///
@ -226,11 +226,11 @@ def get_settings():
하지만 위에 `@lru_cache` 데코레이터를 사용하고 있으므로, `Settings` 객체는 최초 호출 시 딱 한 번만 생성됩니다. ✔️
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
그 다음 요청들에서 의존성으로 `get_settings()`가 다시 호출될 때마다, `get_settings()`의 내부 코드를 실행해서 새 `Settings` 객체를 만드는 대신, 첫 호출에서 반환된 동일한 객체를 계속 반환합니다.
#### `lru_cache` Technical Details { #lru-cache-technical-details }
#### `lru_cache` 기술 세부사항 { #lru-cache-technical-details }
`@lru_cache`는 데코레이션한 함수가 매번 다시 계산하는 대신, 첫 번째에 반환된 동일한 값을 반환하도록 함수를 수정합니다(즉, 매번 함수 코드를 실행하지 않습니다).

View File

@ -10,7 +10,7 @@
먼저, 메인 최상위 **FastAPI** 애플리케이션과 그 *경로 처리*를 생성합니다:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
### 하위 응용프로그램 { #sub-application }
@ -18,7 +18,7 @@
이 하위 응용프로그램은 또 다른 표준 FastAPI 애플리케이션이지만, "마운트"될 애플리케이션입니다:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
### 하위 응용프로그램 마운트 { #mount-the-sub-application }
@ -26,7 +26,7 @@
이 경우 `/subapi` 경로에 마운트됩니다:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
### 자동 API 문서 확인 { #check-the-automatic-api-docs }

View File

@ -27,7 +27,7 @@ $ pip install jinja2
* 템플릿을 반환할 *경로 처리*에 `Request` 매개변수를 선언합니다.
* 생성한 `templates`를 사용하여 `TemplateResponse`를 렌더링하고 반환합니다. 템플릿의 이름, 요청 객체 및 Jinja2 템플릿 내에서 사용될 키-값 쌍이 포함된 "컨텍스트" 딕셔너리도 전달합니다.
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
/// note | 참고

View File

@ -2,11 +2,11 @@
테스트에서 `lifespan`을 실행해야 하는 경우, `with` 문과 함께 `TestClient`를 사용할 수 있습니다:
{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
["공식 Starlette 문서 사이트에서 테스트에서 라이프스팬 실행하기."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)에 대한 자세한 내용을 더 읽을 수 있습니다.
더 이상 권장되지 않는 `startup``shutdown` 이벤트의 경우, 다음과 같이 `TestClient`를 사용할 수 있습니다:
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}

View File

@ -4,10 +4,10 @@
이를 위해 `with` 문에서 `TestClient`를 사용하여 WebSocket에 연결합니다:
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
/// note | 참고
자세한 내용은 Starlette의 <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">testing WebSockets</a> 문서를 확인하세요.
자세한 내용은 Starlette의 <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">WebSocket 테스트</a> 문서를 확인하세요.
///

View File

@ -29,7 +29,7 @@
이를 위해서는 요청에 직접 접근해야 합니다.
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
*경로 처리 함수* 매개변수를 `Request` 타입으로 선언하면 **FastAPI**가 해당 매개변수에 `Request`를 전달하는 것을 알게 됩니다.

View File

@ -24,7 +24,7 @@ $ pip install websockets
그리고 백엔드와 WebSockets을 사용해 통신하려면 아마도 프런트엔드의 유틸리티를 사용할 것입니다.
또는 네이티브 코드로 WebSocket 백엔드와 직접 통신하는 네이티브 모바일 응용 프로그램을 가질 수도 있습니다.
또는 네이티브 코드로 WebSocket 백엔드와 직접 통신하는 네이티브 모바일 애플리케이션을 가질 수도 있습니다.
혹은 WebSocket 엔드포인트와 통신할 수 있는 다른 방법이 있을 수도 있습니다.
@ -38,13 +38,13 @@ $ pip install websockets
그러나 이는 WebSockets의 서버 측에 집중하고 동작하는 예제를 제공하는 가장 간단한 방법입니다:
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
## `websocket` 생성하기 { #create-a-websocket }
**FastAPI** 응용 프로그램에서 `websocket`을 생성합니다:
**FastAPI** 애플리케이션에서 `websocket`을 생성합니다:
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
/// note | 기술 세부사항
@ -58,13 +58,13 @@ $ pip install websockets
WebSocket 경로에서 메시지를 대기(`await`)하고 전송할 수 있습니다.
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
여러분은 이진 데이터, 텍스트, JSON 데이터를 받을 수 있고 전송할 수 있습니다.
## 시도해보기 { #try-it }
파일 이름이 `main.py`라고 가정하고 다음으로 응용 프로그램을 실행합니다:
파일 이름이 `main.py`라고 가정하고 다음으로 애플리케이션을 실행합니다:
<div class="termy">
@ -86,7 +86,7 @@ $ fastapi dev main.py
<img src="/img/tutorial/websockets/image02.png">
그리고 WebSockets가 포함된 **FastAPI** 응용 프로그램이 응답을 돌려줄 것입니다:
그리고 WebSockets가 포함된 **FastAPI** 애플리케이션이 응답을 돌려줄 것입니다:
<img src="/img/tutorial/websockets/image03.png">
@ -121,7 +121,7 @@ WebSocket이기 때문에 `HTTPException`을 발생시키는 것은 적절하지
### 종속성을 가진 WebSockets 시도해보기 { #try-the-websockets-with-dependencies }
파일 이름이 `main.py`라고 가정하고 다음으로 응용 프로그램을 실행합니다:
파일 이름이 `main.py`라고 가정하고 다음으로 애플리케이션을 실행합니다:
<div class="termy">
@ -154,7 +154,7 @@ $ fastapi dev main.py
WebSocket 연결이 닫히면, `await websocket.receive_text()``WebSocketDisconnect` 예외를 발생시킵니다. 그러면 이 예제처럼 이를 잡아 처리할 수 있습니다.
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
테스트해보기:

View File

@ -18,7 +18,7 @@
그리고 해당 경로에 마운트합니다.
{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
/// note | 참고

View File

@ -137,7 +137,7 @@ Flask REST framework는 여러 개가 있지만, 시간을 들여 조사해 본
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
API 시스템에 필요한 주요 기능 중 하나는 데이터 "<abbr title="also called marshalling, conversion - 마샬링, 변환이라고도 합니다">serialization</abbr>"입니다. 이는 코드(Python)에서 데이터를 가져와 네트워크로 전송할 수 있는 형태로 변환하는 것을 의미합니다. 예를 들어 데이터베이스의 데이터를 담은 객체를 JSON 객체로 변환하거나, `datetime` 객체를 문자열로 변환하는 등의 작업입니다.
API 시스템에 필요한 주요 기능 중 하나는 데이터 "<dfn title="마샬링, 변환이라고도 함">직렬화</dfn>"입니다. 이는 코드(Python)에서 데이터를 가져와 네트워크로 전송할 수 있는 형태로 변환하는 것을 의미합니다. 예를 들어 데이터베이스의 데이터를 담은 객체를 JSON 객체로 변환하거나, `datetime` 객체를 문자열로 변환하는 등의 작업입니다.
API에 또 하나 크게 필요한 기능은 데이터 검증입니다. 특정 파라미터를 기준으로 데이터가 유효한지 확인하는 것입니다. 예를 들어 어떤 필드가 `int`인지, 임의의 문자열이 아닌지 확인하는 식입니다. 이는 특히 들어오는 데이터에 유용합니다.
@ -145,7 +145,7 @@ API에 또 하나 크게 필요한 기능은 데이터 검증입니다. 특정
이런 기능들을 제공하기 위해 Marshmallow가 만들어졌습니다. 훌륭한 라이브러리이며, 저도 이전에 많이 사용했습니다.
하지만 Python type hints가 존재하기 전에 만들어졌습니다. 그래서 각 <abbr title="the definition of how data should be formed - 데이터가 어떻게 구성되어야 하는지에 대한 정의">schema</abbr>를 정의하려면 Marshmallow가 제공하는 특정 유틸리티와 클래스를 사용해야 합니다.
하지만 Python type hints가 존재하기 전에 만들어졌습니다. 그래서 각 <dfn title="데이터가 어떻게 구성되어야 하는지에 대한 정의">스키마</dfn>를 정의하려면 Marshmallow가 제공하는 특정 유틸리티와 클래스를 사용해야 합니다.
/// check | **FastAPI**에 영감을 준 것
@ -155,7 +155,7 @@ API에 또 하나 크게 필요한 기능은 데이터 검증입니다. 특정
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
API에 필요한 또 다른 큰 기능은 들어오는 요청에서 데이터를 <abbr title="reading and converting to Python data - 읽어서 Python 데이터로 변환하기">parsing</abbr>하는 것입니다.
API에 필요한 또 다른 큰 기능은 들어오는 요청에서 데이터를 <dfn title="읽어서 Python 데이터로 변환하기">파싱</dfn>하는 것입니다.
Webargs는 Flask를 포함한 여러 framework 위에서 이를 제공하기 위해 만들어진 도구입니다.
@ -419,7 +419,7 @@ Marshmallow와 비교할 수 있습니다. 다만 benchmark에서 Marshmallow보
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
Starlette는 경량 <abbr title="The new standard for building asynchronous Python web applications - 비동기 Python 웹 애플리케이션을 구축하기 위한 새로운 표준">ASGI</abbr> framework/toolkit으로, 고성능 asyncio 서비스를 만들기에 이상적입니다.
Starlette는 경량 <dfn title="비동기 Python 웹 애플리케이션을 구축하기 위한 새로운 표준">ASGI</dfn> framework/toolkit으로, 고성능 asyncio 서비스를 만들기에 이상적입니다.
매우 단순하고 직관적입니다. 쉽게 확장할 수 있도록 설계되었고, 모듈식 component를 갖습니다.

View File

@ -14,7 +14,7 @@ FastAPI 애플리케이션을 배포할 때 일반적인 접근 방법은 **리
<summary>Dockerfile Preview 👀</summary>
```Dockerfile
FROM python:3.9
FROM python:3.14
WORKDIR /code
@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None):
```{ .dockerfile .annotate }
# (1)!
FROM python:3.9
FROM python:3.14
# (2)!
WORKDIR /code
@ -390,7 +390,7 @@ FastAPI가 단일 파일(예: `./app` 디렉터리 없이 `main.py`만 있는
그런 다음 `Dockerfile`에서 해당 파일을 복사하도록 경로만 맞게 변경하면 됩니다:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
FROM python:3.14
WORKDIR /code
@ -454,7 +454,7 @@ Traefik은 Docker, Kubernetes 등과 통합되어 있어, 이를 사용해 컨
## 복제 - 프로세스 개수 { #replication-number-of-processes }
**Kubernetes**, Docker Swarm Mode, Nomad 등의 복잡한 시스템으로 여러 머신에 분산된 컨테이너를 관리하는 <abbr title="어떤 방식으로 연결되어 함께 동작하도록 구성된 머신의 그룹">클러스터</abbr>를 사용한다면, 각 컨테이너에서(**워커를 사용하는 Uvicorn** 같은) **프로세스 매니저**를 쓰는 대신, **클러스터 레벨**에서 **복제를 처리**하고 싶을 가능성이 큽니다.
**Kubernetes**, Docker Swarm Mode, Nomad 등의 복잡한 시스템으로 여러 머신에 분산된 컨테이너를 관리하는 <dfn title="어떤 방식으로 연결되어 함께 동작하도록 구성된 머신의 그룹">클러스터</dfn>를 사용한다면, 각 컨테이너에서(**워커를 사용하는 Uvicorn** 같은) **프로세스 매니저**를 쓰는 대신, **클러스터 레벨**에서 **복제를 처리**하고 싶을 가능성이 큽니다.
Kubernetes 같은 분산 컨테이너 관리 시스템은 보통 들어오는 요청에 대한 **로드 밸런싱**을 지원하면서도, **컨테이너 복제**를 처리하는 통합된 방법을 가지고 있습니다. 모두 **클러스터 레벨**에서요.
@ -499,7 +499,7 @@ HTTPS에 사용되는 동일한 **TLS 종료 프록시** 컴포넌트가 **로
그런 경우에는 `--workers` 커맨드 라인 옵션을 사용해 실행할 워커 수를 설정할 수 있습니다:
```{ .dockerfile .annotate }
FROM python:3.9
FROM python:3.14
WORKDIR /code

View File

@ -15,7 +15,7 @@ HTTPS는 그냥 “켜져 있거나” 아니면 “꺼져 있는” 것이라
이제 **개발자 관점**에서 HTTPS를 생각할 때 염두에 두어야 할 여러 가지가 있습니다:
* HTTPS를 사용하려면, **서버**가 **제3자**가 발급한 **"인증서(certificates)"**를 **보유**해야 합니다.
* 이 인증서는 실제로 제3자가 “생성”해 주는 것이고, 서버가 만드는 것이 아니라 제3자로부터 **발급/획득**하는 것입니다.
* 이 인증서는 실제로 '생성'되는 것이 아니라 제3자로부터 **발급/획득**하는 것입니다.
* 인증서에는 **유효 기간**이 있습니다.
* 즉, **만료**됩니다.
* 그리고 나면 제3자로부터 다시 **갱신**해서 **재발급/재획득**해야 합니다.
@ -65,7 +65,7 @@ Let's Encrypt 이전에는 이러한 **HTTPS 인증서**가 신뢰할 수 있는
아마도 시작은 **도메인 이름**을 **획득**하는 것일 겁니다. 그 다음 DNS 서버(아마 같은 클라우드 제공업체)에서 이를 설정합니다.
대개 클라우드 서버(가상 머신) 같은 것을 사용하게 되고, 거기에는 <abbr title="That doesn't change - 변하지 않음">fixed</abbr> **공개 IP 주소**가 있습니다.
대개 클라우드 서버(가상 머신) 같은 것을 사용하게 되고, 거기에는 <dfn title="시간이 지나도 변하지 않음. 동적이지 않음">고정</dfn> **공개 IP 주소**가 있습니다.
DNS 서버(들)에서 **도메인**이 서버의 **공개 IP 주소**를 가리키도록 레코드(“`A record`”)를 설정합니다.

View File

@ -46,7 +46,7 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
이제 조금 더 자세히 살펴보겠습니다.
FastAPI는 <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr>라고 불리는, Python 웹 프레임워크와 서버를 만들기 위한 표준을 사용합니다. FastAPI는 ASGI 웹 프레임워크입니다.
FastAPI는 <abbr title="Asynchronous Server Gateway Interface - 비동기 서버 게이트웨이 인터페이스">ASGI</abbr>라고 불리는, Python 웹 프레임워크와 서버를 만들기 위한 표준을 사용합니다. FastAPI는 ASGI 웹 프레임워크입니다.
원격 서버 머신에서 **FastAPI** 애플리케이션(또는 다른 ASGI 애플리케이션)을 실행하기 위해 필요한 핵심 요소는 **Uvicorn** 같은 ASGI 서버 프로그램입니다. `fastapi` 명령에는 기본으로 이것이 포함되어 있습니다.

View File

@ -9,13 +9,13 @@
* 메모리
* 시작하기 전의 이전 단계
지금까지 문서의 모든 튜토리얼을 참고하면서, `fastapi` 명령처럼 Uvicorn을 실행하는 **서버 프로그램**을 사용해 **단일 프로세스**로 실행해 왔을 가능성이 큽니다.
지금까지 문서의 모든 튜토리얼을 참고하면서, `fastapi` 명령처럼 Uvicorn을 실행하는 **서버 프로그램**을 사용해 **단일 프로세스**로 실행해 왔을 가능성이 큽니다.
애플리케이션을 배포할 때는 **다중 코어**를 활용하고 더 많은 요청을 처리할 수 있도록 **프로세스 복제**를 하고 싶을 가능성이 큽니다.
이전 장의 [배포 개념들](concepts.md){.internal-link target=_blank}에서 본 것처럼, 사용할 수 있는 전략이 여러 가지 있습니다.
여기서는 `fastapi` 명령을 사용하거나 `uvicorn` 명령을 직접 사용해서, **워커 프로세스**와 함께 **Uvicorn**을 사용하는 방법을 보여드리겠습니다.
여기서는 `fastapi` 명령어를 사용하거나 `uvicorn` 명령어를 직접 사용해서, **워커 프로세스**와 함께 **Uvicorn**을 사용하는 방법을 보여드리겠습니다.
/// info | 정보
@ -27,11 +27,11 @@ Docker나 Kubernetes 같은 컨테이너를 사용하고 있다면, 다음 장
## 여러 워커 { #multiple-workers }
`--workers` 커맨드라인 옵션으로 여러 워커를 시작할 수 있습니다:
`--workers` 명령어 옵션으로 여러 워커를 시작할 수 있습니다:
//// tab | `fastapi`
`fastapi` 명령 사용한다면:
`fastapi` 명령어를 사용한다면:
<div class="termy">
@ -81,7 +81,7 @@ $ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration
//// tab | `uvicorn`
`uvicorn` 명령 직접 사용하는 편이 좋다면:
`uvicorn` 명령어를 직접 사용하는 편이 좋다면:
<div class="termy">
@ -132,7 +132,7 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
## 요약 { #recap }
`fastapi` 또는 `uvicorn` 명령에서 `--workers` CLI 옵션을 사용해 여러 워커 프로세스를 실행하면, **멀티 코어 CPU**를 활용해 **여러 프로세스를 병렬로 실행**할 수 있습니다.
`fastapi` 또는 `uvicorn` 명령에서 `--workers` CLI 옵션을 사용해 여러 워커 프로세스를 실행하면, **멀티 코어 CPU**를 활용해 **여러 프로세스를 병렬로 실행**할 수 있습니다.
다른 배포 개념들을 직접 처리하면서 **자체 배포 시스템**을 구축하는 경우, 이러한 도구와 아이디어를 활용할 수 있습니다.

View File

@ -34,7 +34,7 @@ fastapi[standard]>=0.112.0,<0.113.0
## 이용 가능한 버전들 { #available-versions }
사용 가능한 버전(예: 현재 최신 버전이 무엇인지 확인하기 위해)은 [Release Notes](../release-notes.md){.internal-link target=_blank}에서 확인할 수 있습니다.
사용 가능한 버전(예: 현재 최신 버전이 무엇인지 확인하기 위해)은 [릴리스 노트](../release-notes.md){.internal-link target=_blank}에서 확인할 수 있습니다.
## 버전들에 대해 { #about-versions }
@ -66,7 +66,7 @@ fastapi>=0.45.0,<0.46.0
앱에 테스트를 추가해야 합니다.
**FastAPI**에서는 매우 쉽습니다(Starlette 덕분에). 문서를 확인해 보세요: [Testing](../tutorial/testing.md){.internal-link target=_blank}
**FastAPI**에서는 매우 쉽습니다(Starlette 덕분에). 문서를 확인해 보세요: [테스트](../tutorial/testing.md){.internal-link target=_blank}
테스트를 갖춘 뒤에는 **FastAPI** 버전을 더 최신 버전으로 업그레이드하고, 테스트를 실행하여 모든 코드가 올바르게 동작하는지 확인하세요.

View File

@ -19,10 +19,10 @@
<div class="termy">
```console
// You could create an env var MY_NAME with
// 환경 변수 MY_NAME을 다음과 같이 생성할 수 있습니다
$ export MY_NAME="Wade Wilson"
// Then you could use it with other programs, like
// 그런 다음 다른 프로그램과 함께 사용할 수 있습니다. 예:
$ echo "Hello $MY_NAME"
Hello Wade Wilson
@ -37,10 +37,10 @@ Hello Wade Wilson
<div class="termy">
```console
// Create an env var MY_NAME
// 환경 변수 MY_NAME 생성
$ $Env:MY_NAME = "Wade Wilson"
// Use it with other programs, like
// 다른 프로그램과 함께 사용하기. 예:
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
@ -78,20 +78,20 @@ print(f"Hello {name} from Python")
<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
```
@ -105,20 +105,20 @@ Hello Wade Wilson from Python
<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
```
@ -136,14 +136,14 @@ Hello Wade Wilson from Python
<div class="termy">
```console
// Create an env var MY_NAME in line for this program call
// 이 프로그램 호출을 위해 같은 줄에서 환경 변수 MY_NAME 생성
$ 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

View File

@ -6,7 +6,7 @@
### 개방형 표준을 기반으로 { #based-on-open-standards }
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>: <abbr title="또한 다음으로도 불립니다: 엔드포인트, 라우트">path</abbr> <abbr title="HTTP 메소드(POST, GET, PUT, DELETE 등)로도 알려져 있습니다">operations</abbr>, 매개변수, 요청 본문, 보안 등의 선언을 포함하여 API를 생성합니다.
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>: <dfn title="또한 다음으로도 불림: 엔드포인트, 라우트">경로</dfn> <dfn title="HTTP 메소드(POST, GET, PUT, DELETE 등)로도 알려짐">처리</dfn>, 매개변수, 요청 본문, 보안 등의 선언을 포함하여 API를 생성합니다.
* <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a>를 사용한 자동 데이터 모델 문서화(OpenAPI 자체가 JSON Schema를 기반으로 하기 때문입니다).
* 단순히 떠올려서 덧붙인 레이어가 아니라, 세심한 검토를 거친 뒤 이러한 표준을 중심으로 설계되었습니다.
* 이는 또한 다양한 언어로 자동 **클라이언트 코드 생성**을 사용할 수 있게 해줍니다.
@ -136,7 +136,7 @@ Python 개발자 설문조사에서 <a href="https://www.jetbrains.com/research/
### 의존성 주입 { #dependency-injection }
FastAPI는 사용하기 매우 쉽지만, 매우 강력한 <abbr title='또한 다음으로도 불립니다: "컴포넌트", "자원", "서비스", "제공자"'><strong>Dependency Injection</strong></abbr> 시스템을 포함하고 있습니다.
FastAPI는 사용하기 매우 쉽지만, 매우 강력한 <dfn title='또한 다음으로도 불림: "컴포넌트", "자원", "서비스", "제공자"'><strong>의존성 주입</strong></dfn> 시스템을 포함하고 있습니다.
* 의존성도 의존성을 가질 수 있어, 의존성의 계층 또는 **의존성의 "그래프"**를 생성합니다.
* 모든 것이 프레임워크에 의해 **자동으로 처리됩니다**.
@ -153,8 +153,8 @@ FastAPI는 사용하기 매우 쉽지만, 매우 강력한 <abbr title='또한
### 테스트됨 { #tested }
* 100% <abbr title="자동으로 테스트되는 코드의 양">test coverage</abbr>.
* 100% <abbr title="Python 타입 어노테이션으로, 이를 통해 편집기와 외부 도구가 더 나은 지원을 제공할 수 있습니다">type annotated</abbr> 코드 베이스.
* 100% <dfn title="자동으로 테스트되는 코드의 양">테스트 커버리지</dfn>.
* 100% <dfn title="Python 타입 어노테이션으로, 이를 통해 편집기와 외부 도구가 더 나은 지원을 제공할 수 있습니다">타입 어노테이션</dfn> 코드 베이스.
* 프로덕션 애플리케이션에서 사용됩니다.
## Starlette 기능 { #starlette-features }
@ -190,7 +190,7 @@ FastAPI는 사용하기 매우 쉽지만, 매우 강력한 <abbr title='또한
* **No brainfuck**:
* 새로운 스키마 정의 마이크로 언어를 배울 필요가 없습니다.
* Python 타입을 알고 있다면 Pydantic 사용법도 알고 있는 것입니다.
* 여러분의 **<abbr title="Integrated Development Environment - 통합 개발 환경: 코드 편집기와 비슷합니다">IDE</abbr>/<abbr title="코드 오류를 확인하는 프로그램">linter</abbr>/뇌**와 잘 어울립니다:
* 여러분의 **<abbr title="Integrated Development Environment - 통합 개발 환경: 코드 편집기와 비슷합니다">IDE</abbr>/<dfn title="코드 오류를 확인하는 프로그램">린터</dfn>/뇌**와 잘 어울립니다:
* pydantic 데이터 구조는 여러분이 정의한 클래스 인스턴스일 뿐이므로, 자동 완성, 린팅, mypy, 그리고 직관까지도 검증된 데이터와 함께 제대로 작동합니다.
* **복잡한 구조**를 검증합니다:
* 계층적인 Pydantic 모델, Python `typing``List``Dict` 등을 사용합니다.

View File

@ -8,10 +8,10 @@ FastAPI 버전 `0.122.0`부터는 더 적절한 HTTP 상태 코드 `401 Unauthor
예를 들어, 기본값인 `401 Unauthorized` 오류 대신 `403 Forbidden` 오류를 반환하는 `HTTPBearer`의 서브클래스를 만들 수 있습니다:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
/// tip | 팁
함수는 예외를 `raise`하는 것이 아니라 예외 인스턴스를 `return`다는 점에 유의하세요. 예외를 발생시키는(`raise`) 작업은 내부 코드의 나머지 부분에서 수행됩니다.
함수는 예외를 `return`하는 것이지 `raise`하지 않는다는 점에 유의하세요. 예외를 발생시키는(`raise`) 작업은 내부 코드의 나머지 부분에서 수행됩니다.
///

View File

@ -4,7 +4,7 @@
## 보안, API 및 docs에 대해서 { #about-security-apis-and-docs }
프로덕션에서, 문서화된 사용자 인터페이스(UI)를 숨기는 것이 API를 보호하는 방법이 *되어서는 안 됩니다*.
프로덕션에서, 문서화된 사용자 인터페이스(UI)를 숨기는 것이 API를 보호하는 방법이 되어서는 안 됩니다.
이는 API에 추가적인 보안을 제공하지 않으며, *경로 처리*는 여전히 동일한 위치에서 사용 할 수 있습니다.
@ -29,7 +29,7 @@ API를 보호하고 싶다면, 예를 들어 다음과 같은 더 나은 방법
예를 들어:
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
여기서 `openapi_url` 설정을 기본값인 `"/openapi.json"`으로 선언합니다.

View File

@ -18,7 +18,7 @@ FastAPI는 이 구성을 **JSON** 형식으로 변환하여 JavaScript와 호환
그러나 `syntaxHighlight``False`로 설정하여 구문 강조 기능을 비활성화할 수 있습니다:
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
...그럼 Swagger UI에서 더 이상 구문 강조 기능이 표시되지 않습니다:
@ -28,7 +28,7 @@ FastAPI는 이 구성을 **JSON** 형식으로 변환하여 JavaScript와 호환
동일한 방식으로 `"syntaxHighlight.theme"` 키를 사용하여 구문 강조 테마를 설정할 수 있습니다 (중간에 점이 포함된 것을 참고하십시오).
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
이 설정은 구문 강조 색상 테마를 변경합니다:
@ -42,11 +42,11 @@ FastAPI는 대부분의 사용 사례에 적합한 몇 가지 기본 구성 매
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
`swagger_ui_parameters` 인수에 다른 값을 설정하여 이러한 기본값 중 일부를 재정의할 수 있습니다.
`swagger_ui_parameters` 인수에 다른 값을 설정하여 이러한 기본값 중 어느 것이든 재정의할 수 있습니다.
예를 들어, `deepLinking`을 비활성화하려면 `swagger_ui_parameters`에 다음 설정을 전달할 수 있습니다:
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
## 기타 Swagger UI 매개변수 { #other-swagger-ui-parameters }

View File

@ -8,7 +8,7 @@ API 문서는 **Swagger UI**와 **ReDoc**을 사용하며, 각각 JavaScript와
## JavaScript와 CSS용 커스텀 CDN { #custom-cdn-for-javascript-and-css }
예를 들어 다른 <abbr title="Content Delivery Network">CDN</abbr>을 사용하고 싶다고 해봅시다. 예를 들면 `https://unpkg.com/`을 사용하려는 경우입니다.
예를 들어 다른 <abbr title="Content Delivery Network - 콘텐츠 전송 네트워크">CDN</abbr>을 사용하고 싶다고 해봅시다. 예를 들면 `https://unpkg.com/`을 사용하려는 경우입니다.
이는 예를 들어 특정 국가에서 일부 URL을 제한하는 경우에 유용할 수 있습니다.
@ -18,7 +18,7 @@ API 문서는 **Swagger UI**와 **ReDoc**을 사용하며, 각각 JavaScript와
비활성화하려면 `FastAPI` 앱을 생성할 때 해당 URL을 `None`으로 설정하세요:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
### 커스텀 문서 포함하기 { #include-the-custom-docs }
@ -34,7 +34,7 @@ FastAPI 내부 함수를 재사용해 문서용 HTML 페이지를 생성하고,
ReDoc도 마찬가지입니다...
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
/// tip | 팁
@ -50,7 +50,7 @@ Swagger UI가 이 과정을 백그라운드에서 처리해 주지만, 이를
이제 모든 것이 제대로 동작하는지 테스트할 수 있도록 *경로 처리*를 하나 만드세요:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
### 테스트하기 { #test-it }
@ -118,7 +118,7 @@ JavaScript와 CSS를 자체 호스팅하는 것은 예를 들어, 오프라인
* `StaticFiles`를 import합니다.
* 특정 경로에 `StaticFiles()` 인스턴스를 "마운트(mount)"합니다.
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
### 정적 파일 테스트하기 { #test-the-static-files }
@ -144,7 +144,7 @@ JavaScript와 CSS를 자체 호스팅하는 것은 예를 들어, 오프라인
비활성화하려면 `FastAPI` 앱을 생성할 때 해당 URL을 `None`으로 설정하세요:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
### 정적 파일을 위한 커스텀 문서 포함하기 { #include-the-custom-docs-for-static-files }
@ -160,7 +160,7 @@ JavaScript와 CSS를 자체 호스팅하는 것은 예를 들어, 오프라인
ReDoc도 마찬가지입니다...
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
/// tip | 팁
@ -176,7 +176,7 @@ Swagger UI가 이 과정을 백그라운드에서 처리해 주지만, 이를
이제 모든 것이 제대로 동작하는지 테스트할 수 있도록 *경로 처리*를 하나 만드세요:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
### 정적 파일 UI 테스트하기 { #test-static-files-ui }

View File

@ -43,19 +43,19 @@
먼저, 평소처럼 **FastAPI** 애플리케이션을 모두 작성합니다:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
### OpenAPI 스키마 생성하기 { #generate-the-openapi-schema }
그다음 `custom_openapi()` 함수 안에서, 동일한 유틸리티 함수를 사용해 OpenAPI 스키마를 생성합니다:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
### OpenAPI 스키마 수정하기 { #modify-the-openapi-schema }
이제 OpenAPI 스키마의 `info` "object"에 커스텀 `x-logo`를 추가하여 ReDoc 확장을 더할 수 있습니다:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
### OpenAPI 스키마 캐시하기 { #cache-the-openapi-schema }
@ -65,13 +65,13 @@
스키마는 한 번만 생성되고, 이후 요청에서는 같은 캐시된 스키마가 사용됩니다.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
### 메서드 오버라이드하기 { #override-the-method }
이제 `.openapi()` 메서드를 새 함수로 교체할 수 있습니다.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
### 확인하기 { #check-it }

View File

@ -35,7 +35,7 @@
다음은 Strawberry를 FastAPI와 통합하는 방법에 대한 간단한 미리보기입니다:
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
<a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry 문서</a>에서 Strawberry에 대해 더 알아볼 수 있습니다.

View File

@ -22,7 +22,7 @@ Pydantic v1을 사용하는 오래된 FastAPI 앱이 있다면, 여기서는 이
## 공식 가이드 { #official-guide }
Pydantic에는 v1에서 v2로의 공식 <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">Migration Guide</a>가 있습니다.
Pydantic에는 v1에서 v2로의 공식 <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">마이그레이션 가이드</a>가 있습니다.
여기에는 무엇이 바뀌었는지, 검증이 이제 어떻게 더 정확하고 엄격해졌는지, 가능한 주의사항 등도 포함되어 있습니다.
@ -30,7 +30,7 @@ Pydantic에는 v1에서 v2로의 공식 <a href="https://docs.pydantic.dev/lates
## 테스트 { #tests }
앱에 대한 [tests](../tutorial/testing.md){.internal-link target=_blank}가 있는지 확인하고, 지속적 통합(CI)에서 테스트를 실행하세요.
앱에 대한 [테스트](../tutorial/testing.md){.internal-link target=_blank}가 있는지 확인하고, 지속적 통합(CI)에서 테스트를 실행하세요.
이렇게 하면 업그레이드를 진행하면서도 모든 것이 기대한 대로 계속 동작하는지 확인할 수 있습니다.

View File

@ -72,7 +72,7 @@
하지만 `Item-Output`에서는 `description`**필수이며**, 빨간 별표가 있습니다.
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image04.png">
<img src="/img/tutorial/separate-openapi_schemas/image04.png">
</div>
**Pydantic v2**의 이 기능 덕분에 API 문서는 더 **정밀**해지고, 자동 생성된 클라이언트와 SDK가 있다면 그것들도 더 정밀해져서 더 나은 **developer experience**와 일관성을 제공할 수 있습니다. 🎉

View File

@ -40,7 +40,7 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
* **빠름**: (Starlette과 Pydantic 덕분에) **NodeJS** 및 **Go**와 대등할 정도로 매우 높은 성능. [사용 가능한 가장 빠른 파이썬 프레임워크 중 하나](#performance).
* **빠른 코드 작성**: 약 200%에서 300%까지 기능 개발 속도 증가. *
* **적은 버그**: 사람(개발자)에 의한 에러 약 40% 감소. *
* **직관적**: 훌륭한 편집기 지원. 모든 곳에서 <abbr title="다른 말로는: auto-complete, autocompletion, IntelliSense">자동완성</abbr>. 적은 디버깅 시간.
* **직관적**: 훌륭한 편집기 지원. <dfn title="다른 말로는: 자동 완성, 자동완성, IntelliSense">자동완성</dfn>이 모든 곳에서 동작. 적은 디버깅 시간.
* **쉬움**: 쉽게 사용하고 배우도록 설계. 적은 문서 읽기 시간.
* **짧음**: 코드 중복 최소화. 각 매개변수 선언의 여러 기능. 적은 버그.
* **견고함**: 준비된 프로덕션 용 코드를 얻으십시오. 자동 대화형 문서와 함께.
@ -368,7 +368,7 @@ item: Item
* 데이터 검증:
* 데이터가 유효하지 않을 때 자동으로 생성하는 명확한 에러.
* 깊이 중첩된 JSON 객체에 대한 유효성 검사.
* 입력 데이터 <abbr title="다른 말로는: serialization, parsing, marshalling">변환</abbr>: 네트워크에서 파이썬 데이터 및 타입으로 전송. 읽을 수 있는 것들:
* 입력 데이터 <dfn title="다른 말로는: 직렬화, 파싱, 마샬링">변환</dfn>: 네트워크에서 파이썬 데이터 및 타입으로 전송. 읽을 수 있는 것들:
* JSON.
* 경로 매개변수.
* 쿼리 매개변수.
@ -376,7 +376,7 @@ item: Item
* 헤더.
* 폼(Forms).
* 파일.
* 출력 데이터 <abbr title="다른 말로는: serialization, parsing, marshalling">변환</abbr>: 파이썬 데이터 및 타입을 네트워크 데이터로 전환(JSON 형식으로):
* 출력 데이터 <dfn title="다른 말로는: 직렬화, 파싱, 마샬링">변환</dfn>: 파이썬 데이터 및 타입을 네트워크 데이터로 전환(JSON 형식으로):
* 파이썬 타입 변환 (`str`, `int`, `float`, `bool`, `list`, 등).
* `datetime` 객체.
* `UUID` 객체.
@ -439,7 +439,7 @@ item: Item
* 서로 다른 장소에서 **매개변수** 선언: **헤더**, **쿠키**, **폼 필드** 그리고 **파일**.
* `maximum_length` 또는 `regex`처럼 **유효성 제약**하는 방법.
* 강력하고 사용하기 쉬운 **<abbr title="다른 말로는: components, resources, providers, services, injectables">의존성 주입</abbr>** 시스템.
* 강력하고 사용하기 쉬운 **<dfn title="다른 말로는: 컴포넌트, 리소스, 프로바이더, 서비스, 인젝터블">의존성 주입</dfn>** 시스템.
* **OAuth2** 지원을 포함한 **JWT tokens** 및 **HTTP Basic**을 갖는 보안과 인증.
* (Pydantic 덕분에) **깊은 중첩 JSON 모델**을 선언하는데 더 진보한 (하지만 마찬가지로 쉬운) 기술.
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> 및 기타 라이브러리와의 **GraphQL** 통합.
@ -524,7 +524,7 @@ Starlette이 사용하는:
* <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://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()`과 함께 form <abbr title="HTTP 요청에서 파이썬 데이터로 가는 문자열 변환">"parsing"</abbr> 지원을 원하면 필요.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()`과 함께 form <dfn title="HTTP 요청에서 온 문자열을 파이썬 데이터로 변환">"파싱"</dfn> 지원을 원하면 필요.
FastAPI가 사용하는:

View File

@ -2,7 +2,7 @@
템플릿은 일반적으로 특정 설정과 함께 제공되지만, 유연하고 커스터마이징이 가능하게 디자인 되었습니다. 이 특성들은 여러분이 프로젝트의 요구사항에 맞춰 수정, 적용을 할 수 있게 해주고, 템플릿이 완벽한 시작점이 되게 해줍니다. 🏁
많은 초기 설정, 보안, 데이터베이스 및 일부 API 엔드포인트가 이미 준비되어 있으므로, 여러분은 이 템플릿을 (프로젝트를) 시작하는 데 사용할 수 있습니다.
많은 초기 설정, 보안, 데이터베이스 및 일부 API 엔드포인트가 이미 준비되어 있으므로, 여러분은 이 템플릿을 시작하는 데 사용할 수 있습니다.
GitHub 저장소: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Full Stack FastAPI 템플릿</a>

View File

@ -2,7 +2,7 @@
파이썬은 선택적으로 "타입 힌트(type hints)"(“type annotations”라고도 함)를 지원합니다.
이러한 **"타입 힌트"** 또는 애너테이션은 변수의 <abbr title="for example: str, int, float, bool">타입</abbr>을 선언할 수 있게 해주는 특수한 구문입니다.
이러한 **"타입 힌트"** 또는 애너테이션은 변수의 <dfn title="예: str, int, float, bool">타입</dfn>을 선언할 수 있게 해주는 특수한 구문입니다.
변수의 타입을 선언하면 에디터와 도구가 더 나은 지원을 제공할 수 있습니다.
@ -22,7 +22,7 @@
간단한 예제로 시작해봅시다:
{* ../../docs_src/python_types/tutorial001_py39.py *}
{* ../../docs_src/python_types/tutorial001_py310.py *}
이 프로그램을 호출하면 다음이 출력됩니다:
@ -34,9 +34,9 @@ John Doe
* `first_name``last_name`를 받습니다.
* `title()`로 각각의 첫 글자를 대문자로 변환합니다.
* 가운데에 공백을 두고 <abbr title="Puts them together, as one. With the contents of one after the other.">연결</abbr>합니다.
* 가운데에 공백을 두고 <dfn title="서로를 하나로 합칩니다. 하나의 내용 뒤에 다른 것의 내용을 이어 붙입니다.">연결</dfn>합니다.
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
### 수정하기 { #edit-it }
@ -80,7 +80,7 @@ John Doe
이것들이 "타입 힌트"입니다:
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
이것은 다음처럼 기본값을 선언하는 것과는 다릅니다:
@ -108,7 +108,7 @@ John Doe
이 함수를 확인해보세요. 이미 타입 힌트가 있습니다:
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
에디터가 변수의 타입을 알고 있기 때문에, 자동완성만 되는 게 아니라 오류 검사도 할 수 있습니다:
@ -116,7 +116,7 @@ John Doe
이제 고쳐야 한다는 것을 알고, `age``str(age)`로 문자열로 바꿉니다:
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
## 타입 선언 { #declaring-types }
@ -135,29 +135,32 @@ John Doe
* `bool`
* `bytes`
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
### 타입 매개변수가 있는 Generic(제네릭) 타입 { #generic-types-with-type-parameters }
### `typing` 모듈 { #typing-module }
`dict`, `list`, `set`, `tuple`처럼 다른 값을 담을 수 있는 데이터 구조가 있습니다. 그리고 내부 값에도 각자의 타입이 있을 수 있습니다.
몇 가지 추가적인 사용 사례에서는 표준 라이브러리의 `typing` 모듈에서 무언가를 import해야 할 수 있습니다. 예를 들어 어떤 값이 "아무 타입"일 수 있다고 선언하려면, `typing``Any`를 사용할 수 있습니다:
이렇게 내부 타입을 가지는 타입을 "**generic**" 타입이라고 부릅니다. 그리고 내부 타입까지 포함해 선언할 수도 있습니다.
```python
from typing import Any
이런 타입과 내부 타입을 선언하려면 표준 파이썬 모듈 `typing`을 사용할 수 있습니다. 이 모듈은 이러한 타입 힌트를 지원하기 위해 존재합니다.
#### 더 최신 버전의 Python { #newer-versions-of-python }
def some_function(data: Any):
print(data)
```
`typing`을 사용하는 문법은 Python 3.6부터 최신 버전까지, Python 3.9, Python 3.10 등을 포함한 모든 버전과 **호환**됩니다.
### Generic(제네릭) 타입 { #generic-types }
파이썬이 발전함에 따라 **더 최신 버전**에서는 이러한 타입 애너테이션 지원이 개선되며, 많은 경우 타입 애너테이션을 선언하기 위해 `typing` 모듈을 import해서 사용할 필요조차 없게 됩니다.
일부 타입은 대괄호 안에 "타입 매개변수"를 받아 내부 타입을 정의할 수 있습니다. 예를 들어 "문자열의 리스트"는 `list[str]`로 선언합니다.
프로젝트에서 더 최신 버전의 파이썬을 선택할 수 있다면, 그 추가적인 단순함을 활용할 수 있습니다.
이렇게 타입 매개변수를 받을 수 있는 타입을 **Generic types** 또는 **Generics**라고 부릅니다.
이 문서 전체에는 각 파이썬 버전과 호환되는 예제가 있습니다(차이가 있을 때).
대괄호와 내부 타입을 사용해 동일한 내장 타입들을 제네릭으로 사용할 수 있습니다:
예를 들어 "**Python 3.6+**"는 Python 3.6 이상(3.7, 3.8, 3.9, 3.10 등 포함)과 호환된다는 뜻입니다. 그리고 "**Python 3.9+**"는 Python 3.9 이상(3.10 등 포함)과 호환된다는 뜻입니다.
**최신 버전의 Python**을 사용할 수 있다면, 최신 버전용 예제를 사용하세요. 예를 들어 "**Python 3.10+**"처럼, 가장 **좋고 가장 단순한 문법**을 갖게 됩니다.
* `list`
* `tuple`
* `set`
* `dict`
#### List { #list }
@ -169,7 +172,7 @@ John Doe
`list`는 내부 타입을 포함하는 타입이므로, 그 타입들을 대괄호 안에 넣습니다:
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
/// info | 정보
@ -195,7 +198,7 @@ John Doe
`tuple``set`도 동일하게 선언할 수 있습니다:
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
이는 다음을 의미합니다:
@ -210,7 +213,7 @@ John Doe
두 번째 타입 매개변수는 `dict`의 값을 위한 것입니다:
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
이는 다음을 의미합니다:
@ -222,44 +225,20 @@ John Doe
변수가 **여러 타입 중 어떤 것이든** 될 수 있다고 선언할 수 있습니다. 예를 들어 `int` 또는 `str`입니다.
Python 3.6 이상(3.10 포함)에서는 `typing``Union` 타입을 사용하고, 대괄호 안에 허용할 수 있는 타입들을 넣을 수 있습니다.
이를 정의하려면 두 타입을 <dfn title='“비트 단위 OR 연산자”라고도 하지만, 여기서는 그 의미와 관련이 없습니다'>세로 막대(`|`)</dfn>로 구분해 사용합니다.
Python 3.10에는 가능한 타입들을 <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>세로 막대(`|`)</abbr>로 구분해 넣을 수 있는 **새 문법**도 있습니다.
//// tab | Python 3.10+
이는 두 타입 집합의 합집합(union) 안의 어느 것이든 될 수 있다는 뜻이므로 "유니온"이라고 부릅니다.
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
```
////
두 경우 모두 이는 `item``int` 또는 `str`일 수 있다는 뜻입니다.
이는 `item``int` 또는 `str`일 수 있다는 뜻입니다.
#### `None`일 수도 있음 { #possibly-none }
값이 `str` 같은 타입일 수도 있지만, `None`일 수도 있다고 선언할 수 있습니다.
Python 3.6 이상(3.10 포함)에서는 `typing` 모듈에서 `Optional`을 import해서 사용하여 선언할 수 있습니다.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009_py39.py!}
```
그냥 `str` 대신 `Optional[str]`을 사용하면, 값이 항상 `str`이라고 가정하고 있지만 실제로는 `None`일 수도 있는 상황에서 에디터가 오류를 감지하도록 도와줍니다.
`Optional[Something]`은 사실 `Union[Something, None]`의 축약이며, 서로 동등합니다.
또한 이는 Python 3.10에서 `Something | None`을 사용할 수 있다는 의미이기도 합니다:
//// tab | Python 3.10+
```Python hl_lines="1"
@ -268,96 +247,7 @@ Python 3.6 이상(3.10 포함)에서는 `typing` 모듈에서 `Optional`을 impo
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009_py39.py!}
```
////
//// tab | Python 3.9+ alternative
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
```
////
#### `Union` 또는 `Optional` 사용하기 { #using-union-or-optional }
Python 3.10 미만 버전을 사용한다면, 아주 **주관적인** 관점에서의 팁입니다:
* 🚨 `Optional[SomeType]` 사용을 피하세요
* 대신 ✨ **`Union[SomeType, None]`을 사용하세요** ✨.
둘은 동등하고 내부적으로는 같은 것이지만, `Optional`이라는 단어가 값이 선택 사항인 것처럼 보일 수 있기 때문에 `Optional` 대신 `Union`을 권장합니다. 실제 의미는 값이 선택 사항이라는 뜻이 아니라, "값이 `None`일 수 있다"는 뜻이기 때문입니다. 선택 사항이 아니고 여전히 필수인 경우에도요.
`Union[SomeType, None]`이 의미를 더 명확하게 드러낸다고 생각합니다.
이건 단지 단어와 이름의 문제입니다. 하지만 그런 단어들이 여러분과 팀원이 코드에 대해 생각하는 방식에 영향을 줄 수 있습니다.
예로, 이 함수를 봅시다:
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
매개변수 `name``Optional[str]`로 정의되어 있지만, **선택 사항이 아닙니다**. 매개변수 없이 함수를 호출할 수 없습니다:
```Python
say_hi() # Oh, no, this throws an error! 😱
```
기본값이 없기 때문에 `name` 매개변수는 **여전히 필수입니다**(*optional*이 아님). 그럼에도 `name`은 값으로 `None`을 허용합니다:
```Python
say_hi(name=None) # This works, None is valid 🎉
```
좋은 소식은 Python 3.10을 사용하면, 타입의 유니온을 정의하기 위해 간단히 `|`를 사용할 수 있어서 이런 걱정을 할 필요가 없다는 점입니다:
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
그러면 `Optional`이나 `Union` 같은 이름에 대해 걱정할 필요도 없습니다. 😎
#### Generic(제네릭) 타입 { #generic-types }
대괄호 안에 타입 매개변수를 받는 이러한 타입들은 **Generic types** 또는 **Generics**라고 부릅니다. 예를 들면:
//// tab | Python 3.10+
대괄호와 내부 타입을 사용해, 동일한 내장 타입들을 제네릭으로 사용할 수 있습니다:
* `list`
* `tuple`
* `set`
* `dict`
그리고 이전 파이썬 버전과 마찬가지로 `typing` 모듈의 다음도 사용할 수 있습니다:
* `Union`
* `Optional`
* ...그 밖의 것들.
Python 3.10에서는 제네릭 `Union``Optional`을 사용하는 대안으로, 타입 유니온을 선언하기 위해 <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>세로 막대(`|`)</abbr>를 사용할 수 있는데, 훨씬 더 좋고 단순합니다.
////
//// tab | Python 3.9+
대괄호와 내부 타입을 사용해, 동일한 내장 타입들을 제네릭으로 사용할 수 있습니다:
* `list`
* `tuple`
* `set`
* `dict`
그리고 `typing` 모듈의 제네릭들:
* `Union`
* `Optional`
* ...그 밖의 것들.
////
그냥 `str` 대신 `str | None`을 사용하면, 값이 항상 `str`이라고 가정하고 있지만 실제로는 `None`일 수도 있는 상황에서 에디터가 오류를 감지하도록 도와줍니다.
### 타입으로서의 클래스 { #classes-as-types }
@ -365,11 +255,11 @@ Python 3.10에서는 제네릭 `Union`과 `Optional`을 사용하는 대안으
이름을 가진 `Person` 클래스가 있다고 해봅시다:
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
그러면 `Person` 타입의 변수를 선언할 수 있습니다:
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
그리고 다시, 에디터의 모든 지원을 받을 수 있습니다:
@ -405,19 +295,13 @@ Pydantic 공식 문서의 예시:
이 모든 것은 [자습서 - 사용자 안내서](tutorial/index.md){.internal-link target=_blank}에서 실제로 많이 보게 될 것입니다.
/// tip | 팁
Pydantic은 기본값 없이 `Optional` 또는 `Union[Something, None]`을 사용할 때 특별한 동작이 있습니다. 이에 대해서는 Pydantic 문서의 <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a>에서 더 읽을 수 있습니다.
///
## 메타데이터 애너테이션이 있는 타입 힌트 { #type-hints-with-metadata-annotations }
파이썬에는 `Annotated`를 사용해 이러한 타입 힌트에 **추가 <abbr title="Data about the data, in this case, information about the type, e.g. a description.">메타데이터</abbr>**를 넣을 수 있는 기능도 있습니다.
파이썬에는 `Annotated`를 사용해 이러한 타입 힌트에 **추가 <dfn title="데이터에 대한 데이터, 여기서는 타입에 대한 정보(예: 설명)">메타데이터</dfn>**를 넣을 수 있는 기능도 있습니다.
Python 3.9부터 `Annotated` 표준 라이브러리의 일부이므로, `typing`에서 import할 수 있습니다.
`Annotated``typing`에서 import할 수 있습니다.
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
파이썬 자체는 이 `Annotated`로 아무것도 하지 않습니다. 그리고 에디터와 다른 도구들에게는 타입이 여전히 `str`입니다.

View File

@ -1,3 +1,3 @@
# 리소스 { #resources }
추가 리소스, 외부 링크. ✈️
추가 리소스, 외부 링크, 그리고 더 많은 자료. ✈️

View File

@ -0,0 +1,11 @@
/// details | 🌐 AI와 사람이 함께한 번역
이 번역은 사람의 안내를 받아 AI가 만들었습니다. 🤝
원문의 의미를 오해하거나 부자연스러워 보이는 등 오류가 있을 수 있습니다. 🤖
[AI LLM을 더 잘 안내하는 데 도움을 주세요](https://fastapi.tiangolo.com/ko/contributing/#translations).
[영문 버전](ENGLISH_VERSION_URL)
///

View File

@ -15,7 +15,7 @@ FastAPI에서는 응답을 반환한 *후에* 실행할 백그라운드 작업
먼저 `BackgroundTasks`를 임포트하고, `BackgroundTasks` 타입 선언으로 *경로 처리 함수*에 매개변수를 정의합니다:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
**FastAPI**가 `BackgroundTasks` 타입의 객체를 생성하고 해당 매개변수로 전달합니다.
@ -31,13 +31,13 @@ FastAPI에서는 응답을 반환한 *후에* 실행할 백그라운드 작업
그리고 쓰기 작업은 `async``await`를 사용하지 않으므로, 일반 `def`로 함수를 정의합니다:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## 백그라운드 작업 추가 { #add-the-background-task }
*경로 처리 함수* 내부에서 `.add_task()` 메서드로 작업 함수를 *백그라운드 작업* 객체에 전달합니다:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
`.add_task()`는 다음 인자를 받습니다:

View File

@ -58,17 +58,17 @@ from app.routers import items
```bash
.
├── app # "app" is a Python package
│   ├── __init__.py # this file makes "app" a "Python package"
│   ├── main.py # "main" module, e.g. import app.main
│   ├── dependencies.py # "dependencies" module, e.g. import app.dependencies
│   └── routers # "routers" is a "Python subpackage"
│   │ ├── __init__.py # makes "routers" a "Python subpackage"
│   │ ├── items.py # "items" submodule, e.g. import app.routers.items
│   │ └── users.py # "users" submodule, e.g. import app.routers.users
│   └── internal # "internal" is a "Python subpackage"
│   ├── __init__.py # makes "internal" a "Python subpackage"
│   └── admin.py # "admin" submodule, e.g. import app.internal.admin
├── app # 'app'은 Python 패키지입니다
│   ├── __init__.py # 이 파일로 'app'이 'Python 패키지'가 됩니다
│   ├── main.py # 'main' 모듈, 예: import app.main
│   ├── dependencies.py # 'dependencies' 모듈, 예: import app.dependencies
│   └── routers # 'routers'는 'Python 하위 패키지'입니다
│   │ ├── __init__.py # 이 파일로 'routers'가 'Python 하위 패키지'가 됩니다
│   │ ├── items.py # 'items' 서브모듈, 예: import app.routers.items
│   │ └── users.py # 'users' 서브모듈, 예: import app.routers.users
│   └── internal # 'internal'은 'Python 하위 패키지'입니다
│   ├── __init__.py # 이 파일로 'internal'이 'Python 하위 패키지'가 됩니다
│   └── admin.py # 'admin' 서브모듈, 예: import app.internal.admin
```
## `APIRouter` { #apirouter }
@ -85,7 +85,7 @@ from app.routers import items
`FastAPI` 클래스와 동일한 방식으로 import하고 "instance"를 생성합니다:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### `APIRouter`*path operations* 만들기 { #path-operations-with-apirouter }
@ -93,7 +93,7 @@ from app.routers import items
`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_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
`APIRouter`는 "미니 `FastAPI`" 클래스라고 생각할 수 있습니다.
@ -117,7 +117,7 @@ from app.routers import items
이제 간단한 dependency를 사용해 커스텀 `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_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | 팁
@ -149,7 +149,7 @@ from app.routers import items
따라서 각 *path operation*마다 매번 모두 추가하는 대신, `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_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
각 *path operation*의 경로는 다음처럼 `/`로 시작해야 하므로:
@ -208,7 +208,7 @@ async def read_item(item_id: str):
그래서 dependencies에 대해 `..`를 사용하는 상대 import를 사용합니다:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
#### 상대 import가 동작하는 방식 { #how-relative-imports-work }
@ -279,7 +279,7 @@ from ...dependencies import get_token_header
하지만 특정 *path operation*에만 적용될 _추가_ `tags`를 더할 수도 있고, 그 *path operation* 전용의 추가 `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_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | 팁
@ -305,13 +305,13 @@ from ...dependencies import get_token_header
또한 각 `APIRouter`의 dependencies와 결합될 [global dependencies](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_py310/main.py hl[1,3,7] title["app/main.py"] *}
### `APIRouter` import하기 { #import-the-apirouter }
이제 `APIRouter`가 있는 다른 submodule들을 import합니다:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
`app/routers/users.py``app/routers/items.py` 파일은 같은 Python package `app`에 속한 submodule들이므로, 점 하나 `.`를 사용해 "상대 import"로 가져올 수 있습니다.
@ -374,13 +374,13 @@ from .routers.users import router
따라서 같은 파일에서 둘 다 사용할 수 있도록 submodule들을 직접 import합니다:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
### `users``items``APIRouter` 포함하기 { #include-the-apirouters-for-users-and-items }
이제 submodule `users``items``router`를 포함해 봅시다:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
/// info | 정보
@ -394,7 +394,7 @@ from .routers.users import router
그 router의 모든 route가 애플리케이션의 일부로 포함됩니다.
/// note Technical Details | 기술 세부사항
/// note | 기술 세부사항
내부적으로는 `APIRouter`에 선언된 각 *path operation*마다 *path operation*을 실제로 생성합니다.
@ -420,13 +420,13 @@ router를 포함(include)할 때 성능을 걱정할 필요는 없습니다.
이 예시에서는 매우 단순하게 만들겠습니다. 하지만 조직 내 다른 프로젝트와 공유되기 때문에, 이를 수정할 수 없어 `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_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
하지만 `APIRouter`를 포함할 때 커스텀 `prefix`를 지정해 모든 *path operations*가 `/admin`으로 시작하게 하고, 이 프로젝트에서 이미 가진 `dependencies`로 보호하고, `tags``responses`도 포함하고 싶습니다.
원래 `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_py310/main.py hl[14:17] title["app/main.py"] *}
이렇게 하면 원래 `APIRouter`는 수정되지 않으므로, 조직 내 다른 프로젝트에서도 동일한 `app/internal/admin.py` 파일을 계속 공유할 수 있습니다.
@ -447,11 +447,11 @@ router를 포함(include)할 때 성능을 걱정할 필요는 없습니다.
여기서는 가능하다는 것을 보여주기 위해... 그냥 해봅니다 🤷:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
그리고 `app.include_router()`로 추가한 다른 모든 *path operations*와 함께 올바르게 동작합니다.
/// info | 정보
/// info | 매우 기술적인 세부사항
**참고**: 이는 매우 기술적인 세부사항이라 아마 **그냥 건너뛰어도 됩니다**.

View File

@ -48,8 +48,8 @@
/// warning | 경고
별도 키가 전달된 `Field` 또한 여러분의 플리케이션의 OpenAPI 스키마에 나타날 것입니다.
이런 키가 OpenAPI 명세서, [the OpenAPI validator](https://validator.swagger.io/)같은 몇몇 OpenAPI 도구들에 포함되지 못할 수 있으며, 여러분이 생성한 스키마와 호환되지 않을 수 있습니다.
별도 키가 전달된 `Field` 또한 여러분의 플리케이션의 OpenAPI 스키마에 나타날 것입니다.
이런 키가 OpenAPI 명세서의 일부가 아닐 수도 있으므로, [OpenAPI validator](https://validator.swagger.io/) 같은 몇몇 OpenAPI 도구들은 여러분이 생성한 스키마와 호환되지 않을 수 있습니다.
///

View File

@ -106,13 +106,6 @@
q: str | None = None
```
또는 Python 3.9에서는:
```Python
q: Union[str, None] = None
```
예를 들어:
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}

View File

@ -164,7 +164,7 @@ images: list[Image]
이를 아래처럼:
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
## 어디서나 편집기 지원 { #editor-support-everywhere }
@ -194,7 +194,7 @@ Pydantic 모델 대신 `dict`로 직접 작업한다면 이런 종류의 편집
이 경우, `int` 키와 `float` 값을 가진 한 어떤 `dict`든 받아들입니다:
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
/// tip | 팁

View File

@ -74,7 +74,7 @@
* 매개변수 `item`에 포함된 수신 데이터를 제공합니다.
* 함수 내에서 매개변수를 `Item` 타입으로 선언했기 때문에, 모든 어트리뷰트와 그에 대한 타입에 대한 편집기 지원(완성 등)을 또한 받을 수 있습니다.
* 여러분의 모델을 위한 <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 }
@ -141,7 +141,7 @@
**본문**, **경로** 그리고 **쿼리** 매개변수 모두 동시에 선언할 수도 있습니다.
**FastAPI**는 각각을 인지하고 데이터를 바른 위치에 가져올 것입니다.
**FastAPI**는 각각을 인지하고 데이터를 바른 위치에 가져올 것입니다.
{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
@ -153,9 +153,9 @@
/// note | 참고
FastAPI는 `q`의 값이 필요없음을 알게 될 것입니다. 기본 값이 `= None`이기 때문입니다.
FastAPI는 `q`의 값이 필요없음을 기본 값 `= None` 때문에 알게 됩니다.
Python 3.10+의 `str | None` 또는 Python 3.9+의 `Union[str, None]`에 있는 `Union`은 FastAPI가 `q` 값이 필수가 아님을 판단하기 위해 사용하지 않습니다. 기본 값이 `= None`이기 때문에 필수가 아님을 알게 됩니다.
`str | None`은 FastAPI가 값이 필수인지 아닌지를 판단하기 위해 사용하지 않습니다. 기본 값이 `= None`이므로 필수가 아님을 알게 됩니다.
하지만 타입 어노테이션을 추가하면 편집기가 더 나은 지원을 제공하고 오류를 감지할 수 있습니다.

View File

@ -46,7 +46,7 @@
일부 특별한 사용 사례(흔하지는 않겠지만)에서는 수신하려는 쿠키를 **제한**할 수 있습니다.
이제 API는 자신의 <abbr title="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</abbr>를 제어할 수 있는 권한을 갖게 되었습니다. 🤪🍪
이제 API는 자신의 <dfn title="혹시라도 오해할까 봐 하는 농담입니다. 쿠키 동의와는 아무 관련이 없지만, 이제 API도 불쌍한 쿠키를 거절할 수 있다는 점이 웃기네요. 쿠키 하나 드세요. 🍪">쿠키 동의</dfn>를 제어할 수 있는 권한을 갖게 되었습니다. 🤪🍪
Pydantic의 모델 구성을 사용하여 추가(`extra`) 필드를 금지(`forbid`)할 수 있습니다:
@ -54,9 +54,9 @@ Pydantic의 모델 구성을 사용하여 추가(`extra`) 필드를 금지(`forb
클라이언트가 **추가 쿠키**를 보내려고 시도하면, **오류** 응답을 받게 됩니다.
동의를 얻기 위해 애쓰는 불쌍한 쿠키 배너(팝업)들, <abbr title="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API가 거부</abbr>하는데도. 🍪
동의를 얻기 위해 애쓰는 불쌍한 쿠키 배너(팝업)들, <dfn title="이것도 농담입니다. 신경 쓰지 마세요. 쿠키와 함께 커피 한 잔 하세요. ☕">API가 거부</dfn>하는데도. 🍪
예를 들어, 클라이언트가 `good-list-please` 값으로 `santa_tracker` 쿠키를 보내려고 하면 클라이언트는 `santa_tracker` <abbr title="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">쿠키가 허용되지 않는다</abbr>**오류** 응답을 받게 됩니다:
예를 들어, 클라이언트가 `good-list-please` 값으로 `santa_tracker` 쿠키를 보내려고 하면 클라이언트는 `santa_tracker` <dfn title="산타는 쿠키가 부족한 것을 못마땅해합니다. 🎅 좋아요, 이제 더 이상 쿠키 농담은 하지 않겠습니다.">쿠키가 허용되지 않는다</dfn>**오류** 응답을 받게 됩니다:
```json
{
@ -73,4 +73,4 @@ Pydantic의 모델 구성을 사용하여 추가(`extra`) 필드를 금지(`forb
## 요약 { #summary }
**Pydantic 모델**을 사용하여 **FastAPI**에서 <abbr title="Have a last cookie before you go. 🍪">**쿠키**</abbr>를 선언할 수 있습니다. 😎
**Pydantic 모델**을 사용하여 **FastAPI**에서 <dfn title="가시기 전에 마지막 쿠키 하나 드세요. 🍪">**쿠키**</dfn>를 선언할 수 있습니다. 😎

View File

@ -24,13 +24,13 @@
///
/// info | 정보
/// info
쿠키를 선언하기 위해서는 `Cookie`를 사용해야 합니다. 그렇지 않으면 해당 매개변수를 쿼리 매개변수로 해석하기 때문입니다.
///
/// info | 정보
/// info
**브라우저는 쿠키를** 내부적으로 특별한 방식으로 처리하기 때문에, **JavaScript**가 쉽게 쿠키를 다루도록 허용하지 않는다는 점을 염두에 두세요.

View File

@ -46,7 +46,7 @@
* 특정 HTTP 메서드(`POST`, `PUT`) 또는 와일드카드 `"*"`를 사용한 모든 메서드.
* 특정 HTTP 헤더 또는 와일드카드 `"*"`를 사용한 모든 헤더.
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
`CORSMiddleware` 구현에서 사용하는 기본 매개변수는 기본적으로 제한적이므로, 브라우저가 Cross-Domain 컨텍스트에서 특정 출처, 메서드 또는 헤더를 사용할 수 있도록 하려면 이를 명시적으로 활성화해야 합니다.
@ -78,7 +78,7 @@
## 더 많은 정보 { #more-info }
<abbr title="Cross-Origin Resource Sharing 교차-출처 리소스 공유">CORS</abbr>에 대한 더 많은 정보는 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS 문서</a>를 참고하세요.
<abbr title="Cross-Origin Resource Sharing - 교차-출처 리소스 공유">CORS</abbr>에 대한 더 많은 정보는 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS 문서</a>를 참고하세요.
/// note | 기술 세부사항

View File

@ -6,7 +6,7 @@
FastAPI 애플리케이션에서 `uvicorn`을 직접 임포트하여 실행합니다:
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
### `__name__ == "__main__"` 에 대하여 { #about-name-main }

View File

@ -101,7 +101,7 @@ FastAPI가 실제로 확인하는 것은 그것이 "호출 가능(callable)"(함
위 코드에서 `CommonQueryParams`를 두 번 작성하는 방식에 주목하세요:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated 미사용
/// tip | 팁
@ -137,7 +137,7 @@ FastAPI는 여기에서 선언된 매개변수들을 추출하고, 실제로 이
이 경우 첫 번째 `CommonQueryParams`는 다음에서:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, ...
@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated 미사용
/// tip | 팁
@ -163,7 +163,7 @@ commons: CommonQueryParams ...
실제로는 이렇게만 작성해도 됩니다:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated 미사용
/// tip | 팁
@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams)
하지만 `CommonQueryParams`를 두 번 작성하는 코드 반복이 있다는 것을 볼 수 있습니다:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated 미사용
/// tip | 팁
@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
다음처럼 작성하는 대신:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated 미사용
/// tip | 팁
@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
...이렇게 작성합니다:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends()]
@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated 미사용
/// tip | 팁

View File

@ -1,28 +1,28 @@
# 경로 작동 데코레이터에서의 의존성 { #dependencies-in-path-operation-decorators }
# 경로 처리 데코레이터에서의 의존성 { #dependencies-in-path-operation-decorators }
몇몇 경우에는, *경로 작동 함수* 안에서 의존성의 반환 값이 필요하지 않습니다.
몇몇 경우에는, *경로 처리 함수* 안에서 의존성의 반환 값이 필요하지 않습니다.
또는 의존성이 값을 반환하지 않습니다.
그러나 여전히 실행/해결될 필요가 있습니다.
그런 경우에, `Depends`를 사용하여 *경로 작동 함수*의 매개변수로 선언하는 것보다 *경로 작동 데코레이터*에 `dependencies``list`를 추가할 수 있습니다.
그런 경우에, `Depends`를 사용하여 *경로 처리 함수*의 매개변수로 선언하는 대신 *경로 처리 데코레이터*에 `dependencies``list`를 추가할 수 있습니다.
## *경로 작동 데코레이터*에 `dependencies` 추가하기 { #add-dependencies-to-the-path-operation-decorator }
## *경로 처리 데코레이터*에 `dependencies` 추가하기 { #add-dependencies-to-the-path-operation-decorator }
*경로 작동 데코레이터*는 `dependencies`라는 선택적인 인자를 받습니다.
*경로 처리 데코레이터*는 선택적인 인자 `dependencies`를 받습니다.
`Depends()`로 된 `list`이어야합니다:
`Depends()`로 된 `list`이어야 합니다:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
이러한 의존성들은 기존 의존성들과 같은 방식으로 실행/해결됩니다. 그러나 값은 (무엇이든 반환한다면) *경로 작동 함수*에 제공되지 않습니다.
이러한 의존성들은 기존 의존성들과 같은 방식으로 실행/해결됩니다. 그러나 값은 (무엇이든 반환한다면) *경로 처리 함수*에 제공되지 않습니다.
/// tip | 팁
일부 편집기에서는 사용되지 않는 함수 매개변수를 검사하고 오류로 표시합니다.
*경로 작동 데코레이터*에서 이러한 `dependencies`를 사용하면 편집기/도구 오류를 피하면서도 실행되도록 할 수 있습니다.
*경로 처리 데코레이터*에서 이러한 `dependencies`를 사용하면 편집기/도구 오류를 피하면서도 실행되도록 할 수 있습니다.
또한 코드에서 사용되지 않는 매개변수를 보고 불필요하다고 생각할 수 있는 새로운 개발자의 혼란을 방지하는데 도움이 될 수 있습니다.
@ -44,13 +44,13 @@
(헤더같은) 요청 요구사항이나 하위-의존성을 선언할 수 있습니다:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
### 오류 발생시키기 { #raise-exceptions }
다음 의존성은 기존 의존성과 동일하게 예외를 `raise`할 수 있습니다:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
### 값 반환하기 { #return-values }
@ -58,12 +58,12 @@
그래서 이미 다른 곳에서 사용된 (값을 반환하는) 일반적인 의존성을 재사용할 수 있고, 비록 값은 사용되지 않지만 의존성은 실행될 것입니다:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
## *경로 작동* 모음에 대한 의존성 { #dependencies-for-a-group-of-path-operations }
## *경로 처리* 모음에 대한 의존성 { #dependencies-for-a-group-of-path-operations }
나중에 여러 파일을 가지고 있을 수 있는 더 큰 애플리케이션을 구조화하는 법([더 큰 애플리케이션 - 여러 파일들](../../tutorial/bigger-applications.md){.internal-link target=_blank})을 읽을 때, *경로 작동* 모음에 대한 단일 `dependencies` 매개변수를 선언하는 법에 대해서 배우게 될 것입니다.
나중에 여러 파일을 가지고 있을 수 있는 더 큰 애플리케이션을 구조화하는 법([더 큰 애플리케이션 - 여러 파일들](../../tutorial/bigger-applications.md){.internal-link target=_blank})을 읽을 때, *경로 처리* 모음에 대한 단일 `dependencies` 매개변수를 선언하는 법에 대해서 배우게 될 것입니다.
## 전역 의존성 { #global-dependencies }
다음으로 각 *경로 작동*에 적용되도록 `FastAPI` 애플리케이션 전체에 의존성을 추가하는 법을 볼 것입니다.
다음으로 각 *경로 처리*에 적용되도록 `FastAPI` 애플리케이션 전체에 의존성을 추가하는 법을 볼 것입니다.

View File

@ -1,6 +1,6 @@
# `yield`를 사용하는 의존성 { #dependencies-with-yield }
FastAPI는 <abbr title='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc. 때로는 "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" 등으로도 불립니다'>작업 완료 후 추가 단계를 수행하는</abbr> 의존성을 지원합니다.
FastAPI는 <dfn title='때로는 "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" 등으로도 불립니다'>작업 완료 후 추가 단계</dfn>를 수행하는 의존성을 지원합니다.
이를 구현하려면 `return` 대신 `yield`를 사용하고, 추가로 실행할 단계 (코드)를 그 뒤에 작성하세요.
@ -29,15 +29,15 @@ FastAPI는 <abbr title='sometimes also called "exit code", "cleanup code", "tear
응답을 생성하기 전에는 `yield`문을 포함하여 그 이전의 코드만이 실행됩니다:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입니다:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
`yield`문 다음의 코드는 응답을 생성한 후 실행됩니다:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
/// tip | 팁
@ -57,7 +57,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
마찬가지로, `finally`를 사용하여 예외 발생 여부와 관계 없이 종료 단계까 실행되도록 할 수 있습니다.
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
## `yield`를 사용하는 하위 의존성 { #sub-dependencies-with-yield }
@ -67,7 +67,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
예를 들어, `dependency_c``dependency_b`에 의존할 수 있고, `dependency_b``dependency_a`에 의존할 수 있습니다.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
이들 모두는 `yield`를 사용할 수 있습니다.
@ -75,7 +75,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
그리고, `dependency_b`는 종료 코드를 위해 `dependency_a`의 값 (여기서는 `dep_a`로 명명) 이 사용 가능해야 합니다.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
같은 방식으로, `yield`를 사용하는 의존성과 `return`을 사용하는 의존성을 함께 사용할 수 있으며, 이들 중 일부가 다른 것들에 의존할 수 있습니다.
@ -109,7 +109,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
///
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
예외를 잡고 그에 기반해 사용자 정의 응답을 생성하려면, [사용자 정의 예외 처리기](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}를 생성하세요.
@ -117,7 +117,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
`yield`를 사용하는 의존성에서 `except`를 사용하여 예외를 포착하고 예외를 다시 발생시키지 않거나 (또는 새 예외를 발생시키지 않으면), FastAPI는 일반적인 Python에서와 마찬가지로 예외가 있었다는 것을 알아차릴 수 없습니다:
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
이 경우, `HTTPException`이나 유사한 예외를 발생시키지 않기 때문에 클라이언트는 마땅히 *HTTP 500 Internal Server Error* 응답을 보게 되지만, 서버에는 어떤 오류였는지에 대한 **로그**나 다른 표시가 **전혀 남지 않게 됩니다**. 😱
@ -127,7 +127,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
`raise`를 사용하여 동일한 예외를 다시 발생시킬 수 있습니다:
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
이제 클라이언트는 동일한 *HTTP 500 Internal Server Error* 응답을 받게 되지만, 서버 로그에는 사용자 정의 `InternalError`가 기록됩니다. 😎
@ -190,7 +190,7 @@ participant tasks as Background tasks
하지만 *경로 처리 함수*에서 반환한 뒤에는 더 이상 해당 의존성이 필요 없다는 것을 알고 있다면, `Depends(scope="function")`을 사용하여 FastAPI에 *경로 처리 함수*가 반환된 후, 하지만 **응답이 전송되기 전에** 의존성을 종료(닫기)해야 한다고 알려줄 수 있습니다.
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
`Depends()`는 다음이 될 수 있는 `scope` 매개변수를 받습니다:
@ -269,7 +269,7 @@ Python에서는 다음을 통해 컨텍스트 관리자를 생성할 수 있습
**FastAPI**의 `yield`가 있는 의존성 내에서
`with` 또는 `async with`문을 사용하여 이들을 활용할 수 있습니다:
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
/// tip | 팁

View File

@ -2,12 +2,11 @@
몇몇 유형의 애플리케이션에서는 애플리케이션 전체에 의존성을 추가하고 싶을 수 있습니다.
[*경로 처리 데코레이터*에 `dependencies` 추가하기](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}와 유사한 방법으로 `FastAPI` 애플리케이션에 그것들을 추가할 수 있습니다.
[*경로 처리 데코레이터*에 `dependencies` 추가하기](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}와 유사한 방법으로 `FastAPI` 애플리케이션에 그것들을 추가할 수 있습니다.
그런 경우에, 애플리케이션의 모든 *경로 처리*에 적용될 것입니다:
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
그리고 [*경로 처리 데코레이터*에 `dependencies` 추가하기](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 섹션의 모든 아이디어는 여전히 적용되지만, 이 경우에는 앱의 모든 *경로 처리*에 적용됩니다.

View File

@ -1,6 +1,6 @@
# 의존성 { #dependencies }
**FastAPI**는 아주 강력하지만 직관적인 **<abbr title="also known as components, resources, providers, services, injectables">의존성 주입</abbr>** 시스템을 가지고 있습니다.
**FastAPI**는 아주 강력하지만 직관적인 **<dfn title="컴포넌트, 리소스, 제공자, 서비스, 인젝터블로도 알려져 있음">의존성 주입</dfn>** 시스템을 가지고 있습니다.
이는 사용하기 아주 쉽게 설계했으며, 어느 개발자나 다른 컴포넌트와 **FastAPI**를 쉽게 통합할 수 있도록 만들었습니다.
@ -47,7 +47,7 @@
* 선택적인 쿼리 매개변수 `q`, `str`을 자료형으로 가집니다.
* 선택적인 쿼리 매개변수 `skip`, `int`를 자료형으로 가지며 기본 값은 `0`입니다.
* 선택적인 쿼리 매개변수 `limit` that is an `int`, and by default is `100`.
* 선택적인 쿼리 매개변수 `limit`, `int`를 자료형으로 가지며 기본 값은 `100`입니다.
그 후 위의 값을 포함한 `dict` 자료형으로 반환할 뿐입니다.
@ -71,7 +71,7 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
비록 `Body`, `Query` 등을 사용하는 것과 같은 방식으로 여러분의 함수의 매개변수에 있는 `Depends` 사용하지만, `Depends`는 약간 다르게 작동합니다.
비록 `Depends`를 함수의 매개변수에서 `Body`, `Query` 등을 사용하는 것과 같은 방식으로 사용하지만, `Depends`는 약간 다르게 작동합니다.
`Depends`에 단일 매개변수만 전달했습니다.

View File

@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
같은 *경로 처리*에 대해 의존성 중 하나가 여러 번 선언되는 경우(예: 여러 의존성이 공통 하위 의존성을 갖는 경우), **FastAPI**는 그 하위 의존성을 요청당 한 번만 호출해야 한다는 것을 알고 있습니다.
그리고 같은 요청에 대해 동일한 의존성을 여러 번 호출하는 대신, 반환값을 <abbr title="계산/생성된 값을 저장해 두었다가, 다시 계산하지 않고 재사용하기 위한 유틸리티/시스템.">"cache"</abbr>에 저장하고, 그 요청에서 해당 값이 필요한 모든 "dependants"에 전달합니다.
그리고 같은 요청에 대해 동일한 의존성을 여러 번 호출하는 대신, 반환값을 <dfn title="계산/생성된 값을 저장해 두었다가, 다시 계산하지 않고 재사용하기 위한 유틸리티/시스템.">"캐시"</dfn>에 저장하고, 그 요청에서 해당 값이 필요한 모든 "dependants"에 전달합니다.
고급 시나리오로, 같은 요청에서 "cached" 값을 쓰는 대신 매 단계마다(아마도 여러 번) 의존성이 호출되어야 한다는 것을 알고 있다면, `Depends`를 사용할 때 `use_cache=False` 파라미터를 설정할 수 있습니다:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
////
//// tab | Python 3.9+ 비 Annotated
//// tab | Python 3.10+ 비 Annotated
/// tip | 팁

View File

@ -12,7 +12,7 @@ JSON 호환 가능 데이터만 수신하는 `fake_db` 데이터베이스가 존
예를 들면, `datetime` 객체는 JSON과 호환되지 않으므로 이 데이터베이스는 이를 받지 않습니다.
따라서 `datetime` 객체는 <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO format</a>의 데이터를 포함하는 `str`로 변환되어야 합니다.
따라서 `datetime` 객체는 <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO 형식</a>의 데이터를 포함하는 `str`로 변환되어야 합니다.
같은 방식으로 이 데이터베이스는 Pydantic 모델(속성이 있는 객체)을 받지 않고, `dict`만을 받습니다.

View File

@ -8,11 +8,11 @@
* **출력 모델**은 비밀번호를 가지면 안 됩니다.
* **데이터베이스 모델**은 아마도 해시 처리된 비밀번호를 가질 필요가 있을 것입니다.
/// danger | 위험
/// danger
절대 사용자의 비밀번호를 평문으로 저장하지 마세요. 항상 이후에 검증 가능한 "안전한 해시(secure hash)"로 저장하세요.
만약 이게 무엇인지 모르겠다면, [security chapters](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}에서 "password hash"가 무엇인지 배울 수 있습니다.
만약 이게 무엇인지 모르겠다면, [보안 장](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}에서 "password hash"가 무엇인지 배울 수 있습니다.
///
@ -132,7 +132,7 @@ UserInDB(
)
```
/// warning | 경고
/// warning
추가적으로 제공된 함수 `fake_password_hasher``fake_save_user`는 데이터 흐름을 시연하기 위한 예제일 뿐이며, 실제 보안을 제공하지 않습니다.
@ -164,7 +164,7 @@ OpenAPI에서는 이를 `anyOf`로 정의합니다.
이를 위해 표준 Python 타입 힌트인 <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>을 사용할 수 있습니다:
/// note | 참고
/// note
<a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>을 정의할 때는 더 구체적인 타입을 먼저 포함하고, 덜 구체적인 타입을 그 뒤에 나열해야 합니다. 아래 예제에서는 `Union[PlaneItem, CarItem]`에서 더 구체적인 `PlaneItem``CarItem`보다 앞에 위치합니다.
@ -190,9 +190,9 @@ some_variable: PlaneItem | CarItem
마찬가지로, 객체 리스트 형태의 응답을 선언할 수도 있습니다.
이를 위해 표준 Python의 `typing.List`를 사용하세요(또는 Python 3.9 이상에서는 단순히 `list`를 사용할 수 있습니다):
이를 위해 표준 Python의 `list`를 사용하세요:
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
## 임의의 `dict` 응답 { #response-with-arbitrary-dict }
@ -200,9 +200,9 @@ Pydantic 모델을 사용하지 않고, 키와 값의 타입만 선언하여 평
이는 Pydantic 모델에 필요한 유효한 필드/속성 이름을 사전에 알 수 없는 경우에 유용합니다.
이 경우, `typing.Dict`를 사용할 수 있습니다(또는 Python 3.9 이상에서는 단순히 `dict`를 사용할 수 있습니다):
이 경우, `dict`를 사용할 수 있습니다:
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
## 요약 { #recap }

View File

@ -2,7 +2,7 @@
가장 단순한 FastAPI 파일은 다음과 같이 보일 것입니다:
{* ../../docs_src/first_steps/tutorial001_py39.py *}
{* ../../docs_src/first_steps/tutorial001_py310.py *}
위 코드를 `main.py`에 복사합니다.
@ -104,7 +104,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
#### OpenAPI와 JSON 스키마 { #openapi-and-json-schema }
OpenAPI는 당신의 API에 대한 API 스키마를 정의합니다. 또한 이 스키마는 JSON 데이터 스키마의 표준인 **JSON 스키마**를 사용하여 당신의 API가 보내고 받는 데이터의 정의(또는 "스키마")를 포함합니다.
OpenAPI는 여러분의 API에 대한 API 스키마를 정의합니다. 또한 이 스키마는 JSON 데이터 스키마의 표준인 **JSON 스키마**를 사용하여 여러분의 API가 보내고 받는 데이터의 정의(또는 "스키마")를 포함합니다.
#### `openapi.json` 확인 { #check-the-openapi-json }
@ -183,9 +183,9 @@ Deploying to FastAPI Cloud...
### 1 단계: `FastAPI` 임포트 { #step-1-import-fastapi }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
`FastAPI`당신의 API를 위한 모든 기능을 제공하는 파이썬 클래스입니다.
`FastAPI`여러분의 API를 위한 모든 기능을 제공하는 파이썬 클래스입니다.
/// note | 기술 세부사항
@ -197,11 +197,11 @@ Deploying to FastAPI Cloud...
### 2 단계: `FastAPI` "인스턴스" 생성 { #step-2-create-a-fastapi-instance }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
여기에서 `app` 변수는 `FastAPI` 클래스의 "인스턴스"가 됩니다.
이것은 당신의 모든 API를 생성하기 위한 상호작용의 주요 지점이 될 것입니다.
이것은 여러분의 모든 API를 생성하기 위한 상호작용의 주요 지점이 될 것입니다.
### 3 단계: *경로 처리* 생성 { #step-3-create-a-path-operation }
@ -266,12 +266,12 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
#### *경로 처리 데코레이터* 정의 { #define-a-path-operation-decorator }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
`@app.get("/")`은 **FastAPI**에게 바로 아래에 있는 함수가 다음으로 이동하는 요청을 처리한다는 것을 알려줍니다:
* 경로 `/`
* <abbr title="an HTTP GET method"><code>get</code> operation</abbr> 사용
* <dfn title="HTTP GET 메소드"><code>get</code> 작동</dfn> 사용
/// info | `@decorator` 정보
@ -320,7 +320,7 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
* **작동**: 은 `get`입니다.
* **함수**: 는 "데코레이터" 아래에 있는 함수입니다 (`@app.get("/")` 아래).
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
이것은 파이썬 함수입니다.
@ -332,7 +332,7 @@ URL "`/`"에 대한 `GET` 작동을 사용하는 요청을 받을 때마다 **Fa
`async def`을 이용하는 대신 일반 함수로 정의할 수 있습니다:
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
/// note | 참고
@ -342,7 +342,7 @@ URL "`/`"에 대한 `GET` 작동을 사용하는 요청을 받을 때마다 **Fa
### 5 단계: 콘텐츠 반환 { #step-5-return-the-content }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
`dict`, `list`, 단일값을 가진 `str`, `int` 등을 반환할 수 있습니다.

View File

@ -25,7 +25,7 @@ API를 사용하는 클라이언트에 오류를 알려야 하는 상황은 많
### `HTTPException` 가져오기 { #import-httpexception }
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
### 코드에서 `HTTPException` 발생시키기 { #raise-an-httpexception-in-your-code }
@ -39,7 +39,7 @@ Python 예외이므로 `return` 하는 것이 아니라 `raise` 합니다.
이 예시에서는, 클라이언트가 존재하지 않는 ID로 항목을 요청하면 상태 코드 `404`로 예외를 발생시킵니다:
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
### 결과 응답 { #the-resulting-response }
@ -77,7 +77,7 @@ HTTP 오류에 커스텀 헤더를 추가할 수 있으면 유용한 상황이
하지만 고급 시나리오에서 필요하다면 커스텀 헤더를 추가할 수 있습니다:
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
## 커스텀 예외 핸들러 설치하기 { #install-custom-exception-handlers }
@ -89,7 +89,7 @@ HTTP 오류에 커스텀 헤더를 추가할 수 있으면 유용한 상황이
`@app.exception_handler()`로 커스텀 예외 핸들러를 추가할 수 있습니다:
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
여기서 `/unicorns/yolo`를 요청하면, *경로 처리*가 `UnicornException``raise`합니다.
@ -127,7 +127,7 @@ HTTP 오류에 커스텀 헤더를 추가할 수 있으면 유용한 상황이
예외 핸들러는 `Request`와 예외를 받습니다.
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
이제 `/items/foo`로 이동하면, 다음과 같은 기본 JSON 오류 대신:
@ -159,7 +159,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
예를 들어, 이런 오류들에 대해 JSON 대신 일반 텍스트 응답을 반환하고 싶을 수 있습니다:
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
/// note | 기술 세부사항
@ -183,7 +183,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
앱을 개발하는 동안 body를 로그로 남기고 디버그하거나, 사용자에게 반환하는 등으로 사용할 수 있습니다.
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
이제 다음처럼 유효하지 않은 item을 보내보세요:
@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
예외를 사용하면서 **FastAPI**의 동일한 기본 예외 핸들러도 함께 사용하고 싶다면, `fastapi.exception_handlers`에서 기본 예외 핸들러를 가져와 재사용할 수 있습니다:
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
이 예시에서는 매우 표현력 있는 메시지로 오류를 출력만 하고 있지만, 요지는 이해하셨을 겁니다. 예외를 사용한 뒤 기본 예외 핸들러를 그대로 재사용할 수 있습니다.

View File

@ -2,7 +2,7 @@
관련 있는 **헤더 매개변수** 그룹이 있는 경우, **Pydantic 모델**을 생성하여 선언할 수 있습니다.
이를 통해 **여러 위치**에서 **모델을 재사용** 수 있고 모든 매개변수에 대한 유효성 검사 및 메타데이터를 한 번에 선언할 수도 있습니다. 😎
이를 통해 **여러 위치**에서 **모델을 재사용** 수 있고 모든 매개변수에 대한 유효성 검사 및 메타데이터를 한 번에 선언할 수도 있습니다. 😎
/// note | 참고
@ -36,7 +36,7 @@ Pydantic의 모델 구성을 사용하여 추가(`extra`) 필드를 금지(`forb
클라이언트가 **추가 헤더**를 보내려고 시도하면, **오류** 응답을 받게 됩니다.
예를 들어, 클라이언트가 `plumbus` 값으로 `tool` 헤더를 보내려고 하면, 클라이언트는 헤더 매개변수 `tool`이 허용 되지 않는다는 **오류** 응답을 받게 됩니다:
예를 들어, 클라이언트가 `plumbus` 값으로 `tool` 헤더를 보내려고 하면, 클라이언트는 헤더 매개변수 `tool`이 허용되지 않는다는 **오류** 응답을 받게 됩니다:
```json
{

View File

@ -18,7 +18,7 @@ OpenAPI 명세 및 자동화된 API 문서 UI에 사용되는 다음 필드를
다음과 같이 설정할 수 있습니다:
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
/// tip | 팁
@ -36,7 +36,7 @@ OpenAPI 3.1.0 및 FastAPI 0.99.0부터 `license_info`에 `url` 대신 `identifie
예:
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
## 태그에 대한 메타데이터 { #metadata-for-tags }
@ -58,7 +58,7 @@ OpenAPI 3.1.0 및 FastAPI 0.99.0부터 `license_info`에 `url` 대신 `identifie
태그에 대한 메타데이터를 생성하고 이를 `openapi_tags` 매개변수로 전달하세요:
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
설명 안에 마크다운을 사용할 수 있다는 점에 유의하세요. 예를 들어 "login"은 굵게(**login**) 표시되고, "fancy"는 기울임꼴(_fancy_)로 표시됩니다.
@ -72,7 +72,7 @@ OpenAPI 3.1.0 및 FastAPI 0.99.0부터 `license_info`에 `url` 대신 `identifie
`tags` 매개변수를 *경로 처리* (및 `APIRouter`)와 함께 사용하여 이를 서로 다른 태그에 할당하세요:
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
/// info | 정보
@ -100,7 +100,7 @@ OpenAPI 3.1.0 및 FastAPI 0.99.0부터 `license_info`에 `url` 대신 `identifie
예를 들어, 이를 `/api/v1/openapi.json`에서 제공하도록 설정하려면:
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
OpenAPI 스키마를 완전히 비활성화하려면 `openapi_url=None`으로 설정할 수 있으며, 이를 사용하여 문서화 사용자 인터페이스도 비활성화됩니다.
@ -117,4 +117,4 @@ OpenAPI 스키마를 완전히 비활성화하려면 `openapi_url=None`으로
예를 들어, Swagger UI를 `/documentation`에서 제공하고 ReDoc을 비활성화하려면:
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}

View File

@ -15,7 +15,7 @@
`yield`를 사용하는 의존성이 있다면, exit 코드는 미들웨어 *후에* 실행됩니다.
백그라운드 작업(뒤에서 보게 될 [Background Tasks](background-tasks.md){.internal-link target=_blank} 섹션에서 다룹니다)이 있다면, 모든 미들웨어 *후에* 실행됩니다.
백그라운드 작업(뒤에서 보게 될 [백그라운드 작업](background-tasks.md){.internal-link target=_blank} 섹션에서 다룹니다)이 있다면, 모든 미들웨어 *후에* 실행됩니다.
///
@ -31,7 +31,7 @@
* 그런 다음 해당 *경로 처리*가 생성한 `response`를 반환합니다.
* 그런 다음 반환하기 전에 `response`를 추가로 수정할 수 있습니다.
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
/// tip | 팁
@ -57,7 +57,7 @@
예를 들어, 요청을 처리하고 응답을 생성하는 데 걸린 시간을 초 단위로 담는 사용자 정의 헤더 `X-Process-Time`을 추가할 수 있습니다:
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
/// tip | 팁
@ -92,4 +92,4 @@ app.add_middleware(MiddlewareB)
다른 미들웨어에 대한 더 많은 정보는 나중에 [숙련된 사용자 안내서: 향상된 미들웨어](../advanced/middleware.md){.internal-link target=_blank}에서 확인할 수 있습니다.
다음 섹션에서 미들웨어로 <abbr title="Cross-Origin Resource Sharing">CORS</abbr>를 처리하는 방법을 보게 될 것입니다.
다음 섹션에서 미들웨어로 <abbr title="Cross-Origin Resource Sharing - 교차 출처 리소스 공유">CORS</abbr>를 처리하는 방법을 보게 될 것입니다.

View File

@ -46,7 +46,7 @@
**FastAPI**는 일반 문자열과 동일한 방식으로 이를 지원합니다:
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
## 요약과 설명 { #summary-and-description }
@ -56,7 +56,7 @@
## 독스트링으로 만든 설명 { #description-from-docstring }
설명은 보통 길어지고 여러 줄에 걸쳐있기 때문에, *경로 처리* 설명을 함수 <abbr title="문서화에 사용되는 함수 내부 첫 표현식의 여러 줄 문자열(어떤 변수에도 할당되지 않음)">docstring</abbr>에 선언할 수 있으며, **FastAPI**는 그곳에서 이를 읽습니다.
설명은 보통 길어지고 여러 줄에 걸쳐있기 때문에, *경로 처리* 설명을 함수 <dfn title="문서화에 사용되는 함수 내부 첫 표현식의 여러 줄 문자열(어떤 변수에도 할당되지 않음)">독스트링</dfn>에 선언할 수 있으며, **FastAPI**는 그곳에서 이를 읽습니다.
독스트링에는 <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>을 작성할 수 있으며, (독스트링의 들여쓰기를 고려하여) 올바르게 해석되고 표시됩니다.
@ -90,9 +90,9 @@ OpenAPI는 각 *경로 처리*가 응답에 관한 설명을 요구할 것을
## *경로 처리* 지원중단하기 { #deprecate-a-path-operation }
*경로 처리*를 제거하지 않고 <abbr title="구식이며 사용하지 않는 것이 권장됨">deprecated</abbr>로 표시해야 한다면, `deprecated` 매개변수를 전달하면 됩니다:
*경로 처리*를 제거하지 않고 <dfn title="구식이며 사용하지 않는 것이 권장됨">지원중단</dfn>로 표시해야 한다면, `deprecated` 매개변수를 전달하면 됩니다:
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
대화형 문서에서 지원중단으로 명확하게 표시됩니다:

View File

@ -54,11 +54,11 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
따라서 함수를 다음과 같이 선언할 수 있습니다:
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
하지만 `Annotated`를 사용하면 이 문제가 없다는 점을 기억하세요. `Query()``Path()`에 함수 매개변수 기본값을 사용하지 않기 때문에, 순서는 중요하지 않습니다.
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
## 필요한 대로 매개변수 정렬하기, 트릭 { #order-the-parameters-as-you-need-tricks }
@ -83,13 +83,13 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
파이썬은 `*`으로 아무것도 하지 않지만, 뒤따르는 모든 매개변수는 키워드 인자(키-값 쌍)로 호출되어야 함을 알게 됩니다. 이는 <abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>로도 알려져 있습니다. 기본값이 없더라도 마찬가지입니다.
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
### `Annotated`를 쓰면 더 좋습니다 { #better-with-annotated }
`Annotated`를 사용하면 함수 매개변수 기본값을 사용하지 않기 때문에 이 문제가 발생하지 않으며, 아마 `*`도 사용할 필요가 없다는 점을 기억하세요.
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
## 숫자 검증: 크거나 같음 { #number-validations-greater-than-or-equal }
@ -97,7 +97,7 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
여기서 `ge=1`인 경우, `item_id``1`보다 "`g`reater than or `e`qual"(크거나 같은) 정수형 숫자여야 합니다.
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
## 숫자 검증: 크거나 및 작거나 같음 { #number-validations-greater-than-and-less-than-or-equal }
@ -106,7 +106,7 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
* `gt`: `g`reater `t`han
* `le`: `l`ess than or `e`qual
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
## 숫자 검증: 부동소수, 크거나 및 작거나 { #number-validations-floats-greater-than-and-less-than }
@ -118,7 +118,7 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
<abbr title="less than"><code>lt</code></abbr> 역시 마찬가지입니다.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
## 요약 { #recap }

View File

@ -2,7 +2,7 @@
파이썬의 포맷 문자열 리터럴에서 사용되는 문법을 이용하여 경로 "매개변수" 또는 "변수"를 선언할 수 있습니다:
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
경로 매개변수 `item_id`의 값은 함수의 `item_id` 인자로 전달됩니다.
@ -16,7 +16,7 @@
파이썬 표준 타입 어노테이션을 사용하여 함수에 있는 경로 매개변수의 타입을 선언할 수 있습니다:
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
위의 예시에서, `item_id``int`로 선언되었습니다.
@ -26,7 +26,7 @@
///
## 데이터 <abbr title="다음으로도 알려져 있습니다: 직렬화, 파싱, 마샬링">변환</abbr> { #data-conversion }
## 데이터 <dfn title="다음으로도 알려져 있습니다: 직렬화, 파싱, 마샬링">변환</dfn> { #data-conversion }
이 예제를 실행하고 <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>을 열면, 다음 응답을 볼 수 있습니다:
@ -38,7 +38,7 @@
함수가 받은(반환도 하는) 값은 문자열 `"3"`이 아니라 파이썬 `int` 형인 `3`입니다.
즉, 타입 선언을 하면 **FastAPI**는 자동으로 요청을 <abbr title="HTTP 요청에서 전달되는 문자열을 파이썬 데이터로 변환">"파싱"</abbr>합니다.
즉, 타입 선언을 하면 **FastAPI**는 자동으로 요청을 <dfn title="HTTP 요청에서 전달되는 문자열을 파이썬 데이터로 변환">"파싱"</dfn>합니다.
///
@ -116,21 +116,21 @@
사용자 ID를 이용해 특정 사용자의 정보를 가져오는 경로 `/users/{user_id}`도 있습니다.
*경로 처리*는 순차적으로 평가되기 때문에 `/users/{user_id}` 이전에 `/users/me`에 대한 경로가 먼저 선언되었는지 확인해야 합니다:
*경로 처리*는 순차적으로 평가되기 때문에 `/users/me`에 대한 경로가 `/users/{user_id}` 이전에 먼저 선언되었는지 확인해야 합니다:
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
그렇지 않으면 `/users/{user_id}`에 대한 경로가 `/users/me`에도 매칭되어, 매개변수 `user_id``"me"` 값이 들어왔다고 "생각하게" 됩니다.
마찬가지로, 경로 처리를 재정의할 수는 없습니다:
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
경로가 먼저 매칭되기 때문에 첫 번째 것이 항상 사용됩니다.
## 사전정의 값 { #predefined-values }
만약 *경로 매개변수*를 받는 *경로 처리*가 있지만, 가능한 유효한 *경로 매개변수* 값들을 미리 정의하고 싶다면 파이썬 표준 <abbr title="열거형(Enumeration)">`Enum`</abbr>을 사용할 수 있습니다.
만약 *경로 매개변수*를 받는 *경로 처리*가 있지만, 가능한 유효한 *경로 매개변수* 값들을 미리 정의하고 싶다면 파이썬 표준 <abbr title="열거형">`Enum`</abbr>을 사용할 수 있습니다.
### `Enum` 클래스 생성 { #create-an-enum-class }
@ -140,11 +140,11 @@
가능한 값들에 해당하는 고정된 값의 클래스 어트리뷰트들을 만듭니다:
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
/// tip | 팁
혹시 궁금하다면, "AlexNet", "ResNet", 그리고 "LeNet"은 그저 머신 러닝 <abbr title="기술적으로는 딥 러닝 모델 아키텍처">모델</abbr>들의 이름입니다.
혹시 궁금하다면, "AlexNet", "ResNet", 그리고 "LeNet"은 그저 머신 러닝 <dfn title="기술적으로는 딥 러닝 모델 아키텍처">모델</dfn>들의 이름입니다.
///
@ -152,7 +152,7 @@
생성한 열거형 클래스(`ModelName`)를 사용하는 타입 어노테이션으로 *경로 매개변수*를 만듭니다:
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
### 문서 확인 { #check-the-docs }
@ -168,13 +168,13 @@
생성한 열거형 `ModelName`의 *열거형 멤버*와 비교할 수 있습니다:
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
#### *열거형 값* 가져오기 { #get-the-enumeration-value }
`model_name.value` 또는 일반적으로 `your_enum_member.value`를 이용하여 실제 값(위 예시의 경우 `str`)을 가져올 수 있습니다:
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
/// tip | 팁
@ -188,7 +188,7 @@
클라이언트에 반환하기 전에 해당 값(이 경우 문자열)으로 변환됩니다:
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
클라이언트는 아래와 같은 JSON 응답을 얻게 됩니다:
@ -227,7 +227,7 @@ Starlette의 옵션을 직접 이용하여 다음과 같은 URL을 사용함으
따라서 다음과 같이 사용할 수 있습니다:
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
/// tip | 팁
@ -242,7 +242,7 @@ Starlette의 옵션을 직접 이용하여 다음과 같은 URL을 사용함으
**FastAPI**를 이용하면 짧고 직관적인 표준 파이썬 타입 선언을 사용하여 다음을 얻을 수 있습니다:
* 편집기 지원: 오류 검사, 자동완성 등
* 데이터 "<abbr title="HTTP 요청에서 전달되는 문자열을 파이썬 데이터로 변환">parsing</abbr>"
* 데이터 "<dfn title="HTTP 요청에서 전달되는 문자열을 파이썬 데이터로 변환">파싱</dfn>"
* 데이터 검증
* API 주석(Annotation)과 자동 문서

View File

@ -2,7 +2,7 @@
**FastAPI**를 사용하면 매개변수에 대한 추가 정보 및 검증을 선언할 수 있습니다.
응용 프로그램을 예로 들어보겠습니다:
애플리케이션을 예로 들어보겠습니다:
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
@ -41,46 +41,22 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
## `q` 매개변수의 타입에 `Annotated` 사용하기 { #use-annotated-in-the-type-for-the-q-parameter }
이전에 [Python Types Intro](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}에서 `Annotated`를 사용해 매개변수에 메타데이터를 추가할 수 있다고 말씀드린 것을 기억하시나요?
이전에 [Python 타입 소개](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}에서 `Annotated`를 사용해 매개변수에 메타데이터를 추가할 수 있다고 말씀드린 것을 기억하시나요?
이제 FastAPI에서 사용할 차례입니다. 🚀
다음과 같은 타입 어노테이션이 있었습니다:
//// tab | Python 3.10+
```Python
q: str | None = None
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
여기서 `Annotated`로 감싸서 다음과 같이 만듭니다:
//// tab | Python 3.10+
```Python
q: Annotated[str | None] = None
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
두 버전 모두 같은 의미로, `q``str` 또는 `None`이 될 수 있는 매개변수이며 기본값은 `None`입니다.
이제 재미있는 부분으로 넘어가 봅시다. 🎉
@ -109,7 +85,7 @@ q: Annotated[Union[str, None]] = None
## 대안(이전 방식): 기본값으로 `Query` 사용 { #alternative-old-query-as-the-default-value }
이전 FastAPI 버전(<abbr title="before 2023-03">0.95.0</abbr> 이전)에서는 `Annotated`에 넣는 대신, 매개변수의 기본값으로 `Query`를 사용해야 했습니다. 주변에서 이 방식을 사용하는 코드를 볼 가능성이 높기 때문에 설명해 드리겠습니다.
이전 FastAPI 버전(<dfn title="2023-03 이전">0.95.0</dfn> 이전)에서는 `Annotated`에 넣는 대신, 매개변수의 기본값으로 `Query`를 사용해야 했습니다. 주변에서 이 방식을 사용하는 코드를 볼 가능성이 높기 때문에 설명해 드리겠습니다.
/// tip | 팁
@ -192,7 +168,7 @@ FastAPI 없이도 **다른 곳에서** 같은 함수를 **호출**할 수 있고
## 정규식 추가 { #add-regular-expressions }
매개변수와 일치해야 하는 <abbr title="문자열에 대한 검색 패턴을 정의하는 문자들의 순열인 정규 표현식(regular expression), regex 또는 regexp입니다.">정규 표현식</abbr> `pattern`을 정의할 수 있습니다:
매개변수와 일치해야 하는 <dfn title="정규 표현식(regex 또는 regexp)은 문자열에 대한 검색 패턴을 정의하는 문자 시퀀스입니다.">정규 표현식</dfn> `pattern`을 정의할 수 있습니다:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@ -212,7 +188,7 @@ FastAPI 없이도 **다른 곳에서** 같은 함수를 **호출**할 수 있고
`q` 쿼리 매개변수에 `min_length``3`으로 설정하고, 기본값을 `"fixedquery"`로 선언하고 싶다고 해봅시다:
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
/// note | 참고
@ -242,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
따라서 `Query`를 사용하면서 값을 필수로 선언해야 할 때는, 기본값을 선언하지 않으면 됩니다:
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### 필수지만 `None` 가능 { #required-can-be-none }
@ -293,7 +269,7 @@ http://localhost:8000/items/?q=foo&q=bar
제공된 값이 없으면 기본 `list` 값을 정의할 수도 있습니다:
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
다음으로 이동하면:
@ -316,7 +292,7 @@ http://localhost:8000/items/
`list[str]` 대신 `list`를 직접 사용할 수도 있습니다:
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
/// note | 참고
@ -372,7 +348,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
이제는 더 이상 이 매개변수를 마음에 들어하지 않는다고 가정해 봅시다.
이 매개변수를 사용하는 클라이언트가 있기 때문에 한동안은 남겨둬야 하지만, 문서에서 <abbr title="obsolete, recommended not to use it 구식이며, 사용하지 않는 것을 추천">deprecated</abbr>로 명확하게 보여주고 싶습니다.
이 매개변수를 사용하는 클라이언트가 있기 때문에 한동안은 남겨둬야 하지만, 문서에서 <dfn title="구식이며, 사용하지 않기를 권장함">사용 중단됨</dfn>로 명확하게 보여주고 싶습니다.
그렇다면 `deprecated=True` 매개변수를 `Query`로 전달합니다:
@ -402,7 +378,7 @@ Pydantic에는 <a href="https://docs.pydantic.dev/latest/concepts/validators/#fi
///
예를 들어, 이 커스텀 validator는 <abbr title="ISBN means International Standard Book Number 국제 표준 도서 번호">ISBN</abbr> 도서 번호의 경우 아이템 ID가 `isbn-`으로 시작하고, <abbr title="IMDB (Internet Movie Database) is a website with information about movies 영화에 대한 정보를 제공하는 웹사이트">IMDB</abbr> 영화 URL ID의 경우 `imdb-`로 시작하는지 확인합니다:
예를 들어, 이 커스텀 validator는 <abbr title="International Standard Book Number - 국제 표준 도서 번호">ISBN</abbr> 도서 번호의 경우 아이템 ID가 `isbn-`으로 시작하고, <abbr title="Internet Movie Database - 인터넷 영화 데이터베이스: 영화에 대한 정보를 제공하는 웹사이트">IMDB</abbr> 영화 URL ID의 경우 `imdb-`로 시작하는지 확인합니다:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@ -436,9 +412,9 @@ Pydantic에는 <a href="https://docs.pydantic.dev/latest/concepts/validators/#fi
#### 임의의 항목 { #a-random-item }
`data.items()`를 사용하면 각 딕셔너리 항목의 키와 값을 담은 튜플로 구성된 <abbr title="리스트, 세트 등처럼 for 루프로 순회할 수 있는 것">iterable object</abbr>를 얻습니다.
`data.items()`를 사용하면 각 딕셔너리 항목의 키와 값을 담은 튜플로 구성된 <dfn title="리스트, 세트 등처럼 for 루프로 순회할 수 있는 것">이터러블 객체</dfn>를 얻습니다.
iterable object`list(data.items())`로 적절한 `list`로 변환합니다.
이터러블 객체`list(data.items())`로 적절한 `list`로 변환합니다.
그 다음 `random.choice()`로 리스트에서 **무작위 값**을 얻어 `(id, name)` 형태의 튜플을 얻습니다. 예를 들어 `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")` 같은 값이 될 것입니다.

View File

@ -2,7 +2,7 @@
경로 매개변수의 일부가 아닌 다른 함수 매개변수를 선언하면 "쿼리" 매개변수로 자동 해석합니다.
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
쿼리는 URL에서 `?` 후에 나오고 `&`으로 구분되는 키-값 쌍의 집합입니다.
@ -24,7 +24,7 @@ URL의 일부이므로 "자연스럽게" 문자열입니다.
경로 매개변수에 적용된 동일한 프로세스가 쿼리 매개변수에도 적용됩니다:
* (당연히) 편집기 지원
* 데이터 <abbr title="converting the string that comes from an HTTP request into Python data">"파싱"</abbr>
* 데이터 <dfn title="HTTP 요청에서 온 문자열을 Python 데이터로 변환하는 것">"파싱"</dfn>
* 데이터 검증
* 자동 문서화
@ -128,7 +128,7 @@ http://127.0.0.1:8000/items/foo?short=yes
그러나 쿼리 매개변수를 필수로 만들려면 단순히 기본값을 선언하지 않으면 됩니다:
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
여기 쿼리 매개변수 `needy``str`형인 필수 쿼리 매개변수입니다.

View File

@ -20,13 +20,13 @@ $ pip install python-multipart
`fastapi` 에서 `File``UploadFile` 을 임포트 합니다:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
## `File` 매개변수 정의 { #define-file-parameters }
`Body``Form` 과 동일한 방식으로 파일의 매개변수를 생성합니다:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
/// info | 정보
@ -54,7 +54,7 @@ File의 본문을 선언할 때, 매개변수가 쿼리 매개변수 또는 본
`File` 매개변수를 `UploadFile` 타입으로 정의합니다:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
`UploadFile` 을 사용하는 것은 `bytes` 과 비교해 다음과 같은 장점이 있습니다:
@ -121,7 +121,7 @@ HTML의 폼들(`<form></form>`)이 서버에 데이터를 전송하는 방식은
하지만 파일이 포함된 경우, `multipart/form-data`로 인코딩됩니다. `File`을 사용하였다면, **FastAPI**는 본문의 적합한 부분에서 파일을 가져와야 한다는 것을 인지합니다.
인코딩과 폼 필드에 대해 더 알고싶다면, <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>를 참고하기 바랍니다.
인코딩과 폼 필드에 대해 더 알고싶다면, <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>를 참고하기 바랍니다.
///
@ -143,7 +143,7 @@ HTML의 폼들(`<form></form>`)이 서버에 데이터를 전송하는 방식은
추가 메타데이터를 설정하기 위해 예를 들어 `UploadFile`과 함께 `File()`을 사용할 수도 있습니다:
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
## 다중 파일 업로드 { #multiple-file-uploads }
@ -153,7 +153,7 @@ HTML의 폼들(`<form></form>`)이 서버에 데이터를 전송하는 방식은
이 기능을 사용하기 위해 , `bytes``List` 또는 `UploadFile` 를 선언하기 바랍니다:
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
선언한대로, `bytes``list` 또는 `UploadFile` 들을 전송받을 것입니다.
@ -169,7 +169,7 @@ HTML의 폼들(`<form></form>`)이 서버에 데이터를 전송하는 방식은
이전과 같은 방식으로 `UploadFile`에 대해서도 `File()`을 사용해 추가 매개변수를 설정할 수 있습니다:
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
## 요약 { #recap }

View File

@ -24,7 +24,7 @@ $ pip install python-multipart
**폼 필드**로 받고 싶은 필드를 **Pydantic 모델**로 선언한 다음, 매개변수를 `Form`으로 선언하면 됩니다:
{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
**FastAPI**는 요청에서 받은 **폼 데이터**에서 **각 필드**에 대한 데이터를 **추출**하고 정의한 Pydantic 모델을 줍니다.
@ -48,7 +48,7 @@ $ pip install python-multipart
Pydantic의 모델 구성을 사용하여 `extra` 필드를 `forbid`할 수 있습니다:
{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
클라이언트가 추가 데이터를 보내려고 하면 **오류** 응답을 받게 됩니다.

View File

@ -16,13 +16,13 @@ $ pip install python-multipart
## `File``Form` 임포트 { #import-file-and-form }
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
## `File``Form` 매개변수 정의 { #define-file-and-form-parameters }
`Body``Query`와 동일한 방식으로 파일과 폼의 매개변수를 생성합니다:
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
파일과 폼 필드는 폼 데이터로 업로드되며, 파일과 폼 필드를 받게 됩니다.

View File

@ -18,17 +18,17 @@ $ pip install python-multipart
`fastapi`에서 `Form`을 임포트합니다:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
## `Form` 매개변수 정의하기 { #define-form-parameters }
`Body` 또는 `Query`와 동일한 방식으로 폼 매개변수를 만듭니다:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
예를 들어, OAuth2 사양을 사용할 수 있는 방법 중 하나("패스워드 플로우"라고 함)로 `username``password`를 폼 필드로 보내야 합니다.
<abbr title="specification">spec</abbr>에서는 필드 이름이 `username``password`로 정확하게 명명되어야 하고, JSON이 아닌 폼 필드로 전송해야 합니다.
<dfn title="사양">사양</dfn>에서는 필드 이름이 `username``password`로 정확하게 명명되어야 하고, JSON이 아닌 폼 필드로 전송해야 합니다.
`Form`을 사용하면 유효성 검사, 예제, 별칭(예: `username` 대신 `user-name`) 등을 포함하여 `Body`(및 `Query`, `Path`, `Cookie`)와 동일한 구성을 선언할 수 있습니다.
@ -56,7 +56,7 @@ HTML 폼(`<form></form>`)이 데이터를 서버로 보내는 방식은 일반
그러나 폼에 파일이 포함된 경우, `multipart/form-data`로 인코딩합니다. 다음 장에서 파일 처리에 대해 읽을 겁니다.
이러한 인코딩 및 폼 필드에 대해 더 읽고 싶다면, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><code>POST</code>에 대한 <abbr title="Mozilla Developer Network">MDN</abbr> 웹 문서를 참조하세요</a>.
이러한 인코딩 및 폼 필드에 대해 더 읽고 싶다면, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla 개발자 네트워크">MDN</abbr> 웹 문서를 참조하세요 <code>POST</code>에 대한</a>.
///

View File

@ -183,7 +183,7 @@ FastAPI는 Pydantic을 내부적으로 여러 방식으로 사용하여, 클래
가장 흔한 경우는 [고급 문서에서 나중에 설명하는 대로 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_py310.py hl[8,10:11] *}
이 간단한 경우는 반환 타입 어노테이션이 `Response` 클래스(또는 그 서브클래스)이기 때문에 FastAPI에서 자동으로 처리됩니다.
@ -193,7 +193,7 @@ FastAPI는 Pydantic을 내부적으로 여러 방식으로 사용하여, 클래
타입 어노테이션에 `Response`의 서브클래스를 사용할 수도 있습니다:
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
이는 `RedirectResponse``Response`의 서브클래스이기 때문에 동작하며, FastAPI가 이 간단한 경우를 자동으로 처리합니다.
@ -201,7 +201,7 @@ FastAPI는 Pydantic을 내부적으로 여러 방식으로 사용하여, 클래
하지만 유효한 Pydantic 타입이 아닌 다른 임의의 객체(예: 데이터베이스 객체)를 반환하고, 함수에서 그렇게 어노테이션하면, FastAPI는 그 타입 어노테이션으로부터 Pydantic 응답 모델을 만들려고 시도하다가 실패합니다.
또한, 유효한 Pydantic 타입이 아닌 타입이 하나 이상 포함된 여러 타입 간의 <abbr title='여러 타입 간 union은 "이 타입들 중 아무거나"를 의미합니다.'>union</abbr>이 있는 경우에도 동일합니다. 예를 들어, 아래는 실패합니다 💥:
또한, 유효한 Pydantic 타입이 아닌 타입이 하나 이상 포함된 여러 타입 간의 <dfn title="여러 타입 간의 union은 '이 타입들 중 아무거나'를 의미합니다.">union</dfn>이 있는 경우에도 동일합니다. 예를 들어, 아래는 실패합니다 💥:
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}

View File

@ -8,7 +8,7 @@
* `@app.delete()`
* 등
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
/// note | 참고
@ -43,7 +43,7 @@ FastAPI는 이를 알고 있으며, 응답 본문이 없다고 명시하는 Open
/// note | 참고
만약 HTTP 상태 코드가 무엇인지 이미 알고 있다면, 다음 션으로 넘어가세요.
만약 HTTP 상태 코드가 무엇인지 이미 알고 있다면, 다음 션으로 넘어가세요.
///
@ -66,7 +66,7 @@ HTTP에서는 응답의 일부로 3자리 숫자 상태 코드를 보냅니다.
/// tip | 팁
각 상태 코드와 어떤 코드가 어떤 용도인지 더 알고 싶다면 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr>의 HTTP 상태 코드에 관한 문서</a>를 확인하세요.
각 상태 코드와 어떤 코드가 어떤 용도인지 더 알고 싶다면 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - 모질라 개발자 네트워크">MDN</abbr>의 HTTP 상태 코드에 관한 문서</a>를 확인하세요.
///
@ -74,7 +74,7 @@ HTTP에서는 응답의 일부로 3자리 숫자 상태 코드를 보냅니다.
이전 예시를 다시 확인해보겠습니다:
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
`201` 은 "생성됨"을 위한 상태 코드입니다.
@ -82,7 +82,7 @@ HTTP에서는 응답의 일부로 3자리 숫자 상태 코드를 보냅니다.
`fastapi.status` 의 편의 변수를 사용할 수 있습니다.
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
이것들은 단지 편의를 위한 것으로, 동일한 숫자를 갖고 있지만, 이를 통해 편집기의 자동완성 기능으로 찾을 수 있습니다:

View File

@ -74,7 +74,7 @@ Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를
이와 같이 하면 예제들은 그 본문 데이터의 내부 **JSON 스키마**의 일부가 될 것입니다.
그럼에도 불구하고, 지금 <abbr title="2023-08-26">이 문서를 작성하는 시간</abbr>에, 문서 UI를 보여주는 역할을 맡은 Swagger UI는 **JSON 스키마** 속 데이터를 위한 여러 예제의 표현을 지원하지 않습니다. 하지만 해결 방안을 밑에서 읽어보세요.
그럼에도 불구하고, 지금 <dfn title="2023-08-26">이 문서를 작성하는 시간</dfn>에, 문서 UI를 보여주는 역할을 맡은 Swagger UI는 **JSON 스키마** 속 데이터를 위한 여러 예제의 표현을 지원하지 않습니다. 하지만 해결 방안을 밑에서 읽어보세요.
### OpenAPI-특화 `examples` { #openapi-specific-examples }

View File

@ -20,7 +20,7 @@
예제를 파일 `main.py`에 복사하세요:
{* ../../docs_src/security/tutorial001_an_py39.py *}
{* ../../docs_src/security/tutorial001_an_py310.py *}
## 실행하기 { #run-it }
@ -132,7 +132,7 @@ OAuth2는 backend 또는 API가 사용자를 인증하는 서버와 독립적일
`OAuth2PasswordBearer` 클래스의 인스턴스를 만들 때 `tokenUrl` 파라미터를 전달합니다. 이 파라미터에는 클라이언트(사용자의 브라우저에서 실행되는 frontend)가 token을 받기 위해 `username``password`를 보낼 URL이 들어 있습니다.
{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
/// tip | 팁
@ -170,7 +170,7 @@ oauth2_scheme(some, parameters)
이제 `Depends``oauth2_scheme`를 의존성에 전달할 수 있습니다.
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
이 의존성은 `str`을 제공하고, 그 값은 *경로 처리 함수*의 파라미터 `token`에 할당됩니다.

View File

@ -2,7 +2,7 @@
이전 장에서 (의존성 주입 시스템을 기반으로 한) 보안 시스템은 *경로 처리 함수*에 `str``token`을 제공했습니다:
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
하지만 이는 여전히 그다지 유용하지 않습니다.

View File

@ -1,6 +1,6 @@
# 패스워드(해싱 포함)를 사용하는 OAuth2, JWT 토큰을 사용하는 Bearer { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON Web Tokens">JWT</abbr> 토큰과 안전한 패스워드 해싱을 사용해 애플리케이션을 실제로 안전하게 만들겠습니다.
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON 웹 토큰">JWT</abbr> 토큰과 안전한 패스워드 해싱을 사용해 애플리케이션을 실제로 안전하게 만들겠습니다.
이 코드는 실제로 애플리케이션에서 사용할 수 있으며, 패스워드 해시를 데이터베이스에 저장하는 등의 작업에 활용할 수 있습니다.
@ -42,7 +42,7 @@ $ pip install pyjwt
</div>
/// info
/// info | 정보
RSA나 ECDSA 같은 전자 서명 알고리즘을 사용할 계획이라면, cryptography 라이브러리 의존성인 `pyjwt[crypto]`를 설치해야 합니다.
@ -84,7 +84,7 @@ $ pip install "pwdlib[argon2]"
</div>
/// tip
/// tip | 팁
`pwdlib`를 사용하면 **Django**, **Flask** 보안 플러그인 또는 다른 여러 도구로 생성한 패스워드를 읽을 수 있도록 설정할 수도 있습니다.
@ -100,7 +100,7 @@ $ pip install "pwdlib[argon2]"
권장 설정으로 PasswordHash 인스턴스를 생성합니다. 이는 패스워드를 해싱하고 검증하는 데 사용됩니다.
/// tip
/// tip | 팁
pwdlib는 bcrypt 해싱 알고리즘도 지원하지만 레거시 알고리즘은 포함하지 않습니다. 오래된 해시로 작업해야 한다면 passlib 라이브러리를 사용하는 것을 권장합니다.
@ -116,9 +116,13 @@ pwdlib는 bcrypt 해싱 알고리즘도 지원하지만 레거시 알고리즘
그리고 사용자를 인증하고 반환하는 또 다른 함수도 생성합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
/// note
`authenticate_user`가 데이터베이스에 존재하지 않는 사용자이름으로 호출되더라도, 여전히 `verify_password`를 더미 해시에 대해 실행합니다.
이렇게 하면 사용자이름이 유효하든 아니든 엔드포인트가 응답하는 데 걸리는 시간이 대략 동일해져, 기존 사용자이름을 열거하는 데 악용될 수 있는 **타이밍 공격**을 방지합니다.
/// note | 참고
새로운 (가짜) 데이터베이스 `fake_users_db`를 확인하면, 이제 해시 처리된 패스워드가 어떻게 생겼는지 볼 수 있습니다: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
@ -152,7 +156,7 @@ JWT 토큰을 서명하는 데 사용될 알고리즘을 위한 변수 `ALGORITH
새 액세스 토큰을 생성하기 위한 유틸리티 함수를 생성합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
## 의존성 업데이트 { #update-the-dependencies }
@ -162,7 +166,7 @@ JWT 토큰을 서명하는 데 사용될 알고리즘을 위한 변수 `ALGORITH
토큰이 유효하지 않다면 즉시 HTTP 오류를 반환합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
## `/token` *경로 처리* 업데이트 { #update-the-token-path-operation }
@ -170,7 +174,7 @@ JWT 토큰을 서명하는 데 사용될 알고리즘을 위한 변수 `ALGORITH
실제 JWT 액세스 토큰을 생성하여 반환합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
### JWT "주체(subject)" `sub`에 대한 기술 세부사항 { #technical-details-about-the-jwt-subject-sub }
@ -209,7 +213,7 @@ JWT는 사용자를 식별하고 사용자가 API에서 직접 작업을 수행
Username: `johndoe`
Password: `secret`
/// check
/// check | 확인
코드 어디에도 평문 패스워드 "`secret`"은 없고, 해시된 버전만 있다는 점에 유의하십시오.
@ -234,7 +238,7 @@ Password: `secret`
<img src="/img/tutorial/security/image10.png">
/// note
/// note | 참고
`Bearer `로 시작하는 값을 가진 `Authorization` 헤더에 주목하십시오.

View File

@ -162,7 +162,7 @@ UserInDB(
/// tip | 팁
다음 장에서는 패스워드 해싱 및 <abbr title="JSON Web Tokens">JWT</abbr> 토큰을 사용하여 실제 보안 구현을 볼 수 있습니다.
다음 장에서는 패스워드 해싱 및 <abbr title="JSON Web Tokens - JSON 웹 토큰">JWT</abbr> 토큰을 사용하여 실제 보안 구현을 볼 수 있습니다.
하지만 지금은 필요한 세부 정보에 집중하겠습니다.
@ -286,4 +286,4 @@ UserInDB(
유일한 오점은 아직 실제로 "안전"하지 않다는 것입니다.
다음 장에서는 안전한 패스워드 해싱 라이브러리와 <abbr title="JSON Web Tokens">JWT</abbr> 토큰을 사용하는 방법을 살펴보겠습니다.
다음 장에서는 안전한 패스워드 해싱 라이브러리와 <abbr title="JSON Web Tokens - JSON 웹 토큰">JWT</abbr> 토큰을 사용하는 방법을 살펴보겠습니다.

View File

@ -8,7 +8,7 @@
/// tip | 팁
다른 SQL 또는 NoSQL 데이터베이스 라이브러리를 사용할 수도 있습니다 (일부는 <abbr title="Object Relational Mapper: a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">"ORMs"</abbr>이라고도 불립니다), FastAPI는 특정 라이브러리의 사용을 강요하지 않습니다. 😎
다른 SQL 또는 NoSQL 데이터베이스 라이브러리를 사용할 수도 있습니다 (일부는 <abbr title="Object Relational Mapper - 객체-관계 매퍼: 일부 클래스는 SQL 테이블을, 인스턴스는 해당 테이블의 행을 나타내는 라이브러리를 가리키는 용어">"ORMs"</abbr>이라고도 불립니다), FastAPI는 특정 라이브러리의 사용을 강요하지 않습니다. 😎
///

View File

@ -7,7 +7,7 @@
* `StaticFiles`를 임포트합니다.
* 특정 경로에 `StaticFiles()` 인스턴스를 "마운트"합니다.
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
/// note | 기술 세부사항

View File

@ -2,7 +2,7 @@
<a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a> 덕분에 **FastAPI** 애플리케이션을 테스트하는 일은 쉽고 즐거운 일이 되었습니다.
Starlette<a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>를 기반으로 하며, 이는 Requests를 기반으로 설계되었기 때문에 매우 친숙하고 직관적입니다.
<a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>를 기반으로 하며, 이는 Requests를 기반으로 설계되었기 때문에 매우 친숙하고 직관적입니다.
이를 사용하면 **FastAPI**에서 <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a>를 직접 사용할 수 있습니다.
@ -30,7 +30,7 @@ $ pip install httpx
표준적인 파이썬 표현식으로 확인이 필요한 곳에 간단한 `assert` 문장을 작성하세요(역시 표준적인 `pytest` 관례입니다).
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
/// tip | 팁
@ -42,7 +42,7 @@ $ pip install httpx
///
/// note Technical Details | 기술 세부사항
/// note | 기술 세부사항
`from starlette.testclient import TestClient` 역시 사용할 수 있습니다.
@ -76,7 +76,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
`main.py` 파일 안에 **FastAPI** app 을 만들었습니다:
{* ../../docs_src/app_testing/app_a_py39/main.py *}
{* ../../docs_src/app_testing/app_a_py310/main.py *}
### 테스트 파일 { #testing-file }
@ -92,7 +92,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
파일들이 동일한 패키지에 위치해 있으므로, 상대 임포트를 사용하여 `main` 모듈(`main.py`)에서 `app` 객체를 임포트 해올 수 있습니다.
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
...그리고 이전에 작성했던 것과 같은 테스트 코드를 작성할 수 있습니다.
@ -115,7 +115,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
이제 **FastAPI** 앱이 있는 `main.py` 파일에 몇 가지 다른 **경로 처리**가 추가된 경우를 생각해봅시다.
단일 오류를 반환할 수 있는 `GET` 작업이 있습니다.
오류를 반환할 수 있는 `GET` 작업이 있습니다.
여러 다른 오류를 반환할 수 있는 `POST` 작업이 있습니다.

View File

@ -37,15 +37,15 @@ Python 설치까지 포함해 **모든 것을 관리해주는 도구**를 도입
<div class="termy">
```console
// Go to the home directory
// 홈 디렉터리로 이동
$ cd
// Create a directory for all your code projects
// 모든 코드 프로젝트를 위한 디렉터리 생성
$ mkdir code
// Enter into that code directory
// 그 code 디렉터리로 이동
$ cd code
// Create a directory for this project
// 이 프로젝트를 위한 디렉터리 생성
$ mkdir awesome-project
// Enter into that project directory
// 그 프로젝트 디렉터리로 이동
$ cd awesome-project
```
@ -53,7 +53,7 @@ $ cd awesome-project
## 가상 환경 생성 { #create-a-virtual-environment }
Python 프로젝트를 **처음 시작할 때**, **<abbr title="다른 옵션도 있지만, 이것은 간단한 가이드라인입니다">프로젝트 내부</abbr>**에 가상 환경을 생성하세요.
Python 프로젝트를 **처음 시작할 때**, 가상 환경을 **<dfn title="다른 옵션도 있지만, 이것은 간단한 가이드라인입니다">프로젝트 내부</dfn>**에 생성하세요.
/// tip
@ -166,7 +166,7 @@ $ source .venv/Scripts/activate
해당 환경에 **새 패키지**를 설치할 때마다, 환경을 다시 **활성화**하세요.
이렇게 하면 해당 패키지가 설치한 **터미널(<abbr title="command line interface">CLI</abbr>) 프로그램**을 사용할 때, 전역으로 설치되어 있을 수도 있는(아마 필요한 버전과는 다른 버전인) 다른 프로그램이 아니라 가상 환경에 있는 것을 사용하게 됩니다.
이렇게 하면 해당 패키지가 설치한 **터미널(<abbr title="command line interface - 명령줄 인터페이스">CLI</abbr>) 프로그램**을 사용할 때, 전역으로 설치되어 있을 수도 있는(아마 필요한 버전과는 다른 버전인) 다른 프로그램이 아니라 가상 환경에 있는 것을 사용하게 됩니다.
///
@ -557,7 +557,7 @@ Python을 설치하면 컴퓨터에 몇몇 파일이 들어 있는 디렉터리
<div class="termy">
```console
// Don't run this now, it's just an example 🤓
// 지금은 실행하지 마세요, 예시일 뿐입니다 🤓
$ pip install "fastapi[standard]"
---> 100%
```
@ -811,7 +811,7 @@ $ cd ~/code/prisoner-of-azkaban
$ python main.py
// Error importing sirius, it's not installed 😱
// sirius 임포트 오류, 설치되어 있지 않습니다 😱
Traceback (most recent call last):
File "main.py", line 1, in <module>
import sirius
@ -826,13 +826,13 @@ Traceback (most recent call last):
```console
$ cd ~/code/prisoner-of-azkaban
// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎
// 비활성화를 위해 이전 디렉터리에 있을 필요는 없습니다. 어디서든, 다른 프로젝트로 이동한 뒤에도 할 수 있습니다 😎
$ deactivate
// Activate the virtual environment in prisoner-of-azkaban/.venv 🚀
// prisoner-of-azkaban/.venv의 가상 환경을 활성화하세요 🚀
$ source .venv/bin/activate
// Now when you run python, it will find the package sirius installed in this virtual environment
// 이제 python을 실행하면, 이 가상 환경에 설치된 sirius 패키지를 찾습니다
$ python main.py
I solemnly swear 🐺