Sync fastapi docs from 7cb06f36 on 2026-07-11
This commit is contained in:
@@ -7,11 +7,11 @@
|
||||
사용 방법은 다음과 같습니다:
|
||||
|
||||
* 언어별 프롬프트 `docs/{language code}/llm-prompt.md`를 준비합니다.
|
||||
* 이 문서를 원하는 대상 언어로 새로 번역합니다(예: `translate.py`의 `translate-page` 명령). 그러면 `docs/{language code}/docs/_llm-test.md` 아래에 번역이 생성됩니다.
|
||||
* 이 문서를 원하는 대상 언어로 새로 번역합니다(예: `translate.py`의 `translate-page` 명령어). 그러면 `docs/{language code}/docs/_llm-test.md` 아래에 번역이 생성됩니다.
|
||||
* 번역에서 문제가 없는지 확인합니다.
|
||||
* 필요하다면 언어별 프롬프트, 일반 프롬프트, 또는 영어 문서를 개선합니다.
|
||||
* 그런 다음 번역에서 남아 있는 문제를 수동으로 수정해 좋은 번역이 되게 합니다.
|
||||
* 좋은 번역을 둔 상태에서 다시 번역합니다. 이상적인 결과는 LLM이 더 이상 번역에 변경을 만들지 않는 것입니다. 이는 일반 프롬프트와 언어별 프롬프트가 가능한 한 최선이라는 뜻입니다(때때로 몇 가지 seemingly random 변경을 할 수 있는데, 그 이유는 [LLM은 결정론적 알고리즘이 아니기 때문](https://doublespeak.chat/#/handbook#deterministic-output)입니다).
|
||||
* 좋은 번역을 둔 상태에서 다시 번역합니다. 이상적인 결과는 LLM이 더 이상 번역에 변경을 만들지 않는 것입니다. 이는 일반 프롬프트와 언어별 프롬프트가 가능한 한 최선이라는 뜻입니다(때때로 몇 가지 겉보기에 무작위인 변경을 할 수 있는데, 그 이유는 [LLM은 결정론적 알고리즘이 아니기 때문](https://doublespeak.chat/#/handbook#deterministic-output)입니다).
|
||||
|
||||
테스트:
|
||||
|
||||
@@ -150,7 +150,7 @@ works(foo="bar") # 이건 동작합니다 🎉
|
||||
|
||||
탭과 `Info`/`Note`/`Warning`/등의 블록은 제목 번역을 수직 막대(`|`) 뒤에 추가해야 합니다.
|
||||
|
||||
`scripts/translate.py`의 일반 프롬프트에서 `### Special blocks`와 `### Tab blocks` 석션을 참고하세요.
|
||||
`scripts/translate.py`의 일반 프롬프트에서 `### Special blocks`와 `### Tab blocks` 섹션을 참고하세요.
|
||||
|
||||
////
|
||||
|
||||
@@ -240,7 +240,7 @@ works(foo="bar") # 이건 동작합니다 🎉
|
||||
|
||||
`scripts/translate.py`의 일반 프롬프트에서 `### Headings` 섹션을 참고하세요.
|
||||
|
||||
언어별 지침은 예를 들어 `docs/de/llm-prompt.md`의 `### Headings` 석션을 참고하세요.
|
||||
언어별 지침은 예를 들어 `docs/de/llm-prompt.md`의 `### Headings` 섹션을 참고하세요.
|
||||
|
||||
////
|
||||
|
||||
@@ -289,7 +289,7 @@ works(foo="bar") # 이건 동작합니다 🎉
|
||||
* 애플리케이션을 서빙하다
|
||||
* 페이지를 서빙하다
|
||||
|
||||
* 앱
|
||||
* 애플리케이션
|
||||
* 애플리케이션
|
||||
|
||||
* 요청
|
||||
@@ -490,6 +490,6 @@ works(foo="bar") # 이건 동작합니다 🎉
|
||||
|
||||
이것은 문서에서 보이는 (대부분) 기술 용어의 불완전하고 비규범적인 목록입니다. 프롬프트 설계자가 어떤 용어에 대해 LLM에 추가적인 도움이 필요한지 파악하는 데 유용할 수 있습니다. 예를 들어, 좋은 번역을 계속 덜 좋은 번역으로 되돌릴 때, 또는 언어에서 용어의 활용/변화를 처리하는 데 문제가 있을 때 도움이 됩니다.
|
||||
|
||||
예를 들어 `docs/de/llm-prompt.md`의 `### List of English terms and their preferred German translations` 석션을 참고하세요.
|
||||
예를 들어 `docs/de/llm-prompt.md`의 `### List of English terms and their preferred German translations` 섹션을 참고하세요.
|
||||
|
||||
////
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
///
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`model` 키는 OpenAPI의 일부가 아닙니다.
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
|
||||
///
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`responses` 파라미터에서 다른 미디어 타입을 명시적으로 지정하지 않는 한, FastAPI는 응답이 주요 응답 클래스와 동일한 미디어 타입(기본값 `application/json`)을 가진다고 가정합니다.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
기본 상태 코드와 별도로 추가 상태 코드를 반환하려면 `JSONResponse`와 같이 `Response`를 직접 반환하고 추가 상태 코드를 직접 설정할 수 있습니다.
|
||||
|
||||
예를 들어 항목을 업데이트할 수 있는 *경로 처리*가 있고 성공 시 200 “OK”의 HTTP 상태 코드를 반환한다고 가정해 보겠습니다.
|
||||
예를 들어 항목을 업데이트할 수 있는 *경로 처리*가 있고 성공 시 200 "OK"의 HTTP 상태 코드를 반환한다고 가정해 보겠습니다.
|
||||
|
||||
하지만 새로운 항목을 허용하기를 원할 것입니다. 그리고 항목이 이전에 존재하지 않았다면 이를 생성하고 HTTP 상태 코드 201 "Created"를 반환합니다.
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ checker(q="somequery")
|
||||
|
||||
### `yield`와 `scope`가 있는 의존성 { #dependencies-with-yield-and-scope }
|
||||
|
||||
0.121.0 버전에서 FastAPI는 `Depends(scope="function")` 지원을 추가했습니다.
|
||||
0.121.0 버전에서 FastAPI는 `yield`가 있는 의존성을 위한 `Depends(scope="function")` 지원을 추가했습니다.
|
||||
|
||||
`Depends(scope="function")`를 사용하면, `yield` 이후의 종료 코드는 *경로 처리 함수*가 끝난 직후(클라이언트에 응답이 반환되기 전)에 실행됩니다.
|
||||
|
||||
@@ -99,7 +99,7 @@ FastAPI 0.118.0 이전에는 `yield`가 있는 의존성을 사용하면, *경
|
||||
|
||||
이 동작은 0.118.0에서 되돌려져, `yield` 이후의 종료 코드가 응답이 전송된 뒤 실행되도록 변경되었습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
아래에서 보시겠지만, 이는 0.106.0 버전 이전의 동작과 매우 비슷하지만, 여러 개선 사항과 코너 케이스에 대한 버그 수정이 포함되어 있습니다.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`response_class` 매개변수는 응답의 "미디어 타입"을 정의하는 데에도 사용됩니다.
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
///
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
물론 실제 `Content-Type` 헤더, 상태 코드 등은 반환된 `Response` 객체에서 가져옵니다.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ FastAPI는 **Pydantic** 위에 구축되어 있으며, 지금까지는 Pydantic
|
||||
|
||||
이는 Pydantic 모델을 사용할 때와 같은 방식으로 동작합니다. 그리고 실제로도 내부적으로는 Pydantic을 사용해 같은 방식으로 구현됩니다.
|
||||
|
||||
/// info
|
||||
/// note | 참고
|
||||
|
||||
dataclasses는 Pydantic 모델이 할 수 있는 모든 것을 할 수는 없다는 점을 기억하세요.
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
|
||||
이 코드는 애플리케이션이 요청을 받기 **시작**하기 전에 실행되고, 요청 처리를 **끝낸 직후**에 실행되기 때문에 전체 애플리케이션의 **수명(lifespan)**을 다룹니다(잠시 후 "lifespan"이라는 단어가 중요해집니다 😉).
|
||||
|
||||
이는 전체 앱에서 사용해야 하는 **자원**을 설정하고, 요청 간에 **공유되는** 자원을 설정하고, 그리고/또는 이후에 **정리**하는 데 매우 유용할 수 있습니다. 예를 들어, 데이터베이스 연결 풀 또는 공유 머신러닝 모델을 로드하는 경우입니다.
|
||||
이는 전체 애플리케이션에서 사용해야 하는 **자원**을 설정하고, 요청 간에 **공유되는** 자원을 설정하고, 그리고/또는 이후에 **정리**하는 데 매우 유용할 수 있습니다. 예를 들어, 데이터베이스 연결 풀 또는 공유 머신러닝 모델을 로드하는 경우입니다.
|
||||
|
||||
## 사용 사례 { #use-case }
|
||||
|
||||
먼저 **사용 사례** 예시로 시작한 다음, 이를 어떻게 해결할지 살펴보겠습니다.
|
||||
|
||||
요청을 처리하는 데 사용하고 싶은 **머신러닝 모델**이 있다고 상상해 봅시다. 🤖
|
||||
요청을 처리하는 데 사용하고 싶은 몇 가지 **머신러닝 모델**이 있다고 상상해 봅시다. 🤖
|
||||
|
||||
동일한 모델이 요청 간에 공유되므로, 요청마다 모델이 하나씩 있거나 사용자마다 하나씩 있는 등의 방식이 아닙니다.
|
||||
동일한 모델들이 요청 간에 공유되므로, 요청마다 모델이 하나씩 있거나 사용자마다 하나씩 있는 등의 방식이 아닙니다.
|
||||
|
||||
모델을 로드하는 데 **상당한 시간이 걸린다고 상상해 봅시다**, 왜냐하면 모델이 **디스크에서 많은 데이터를 읽어야** 하기 때문입니다. 그래서 모든 요청마다 이를 수행하고 싶지는 않습니다.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
## Lifespan { #lifespan }
|
||||
|
||||
`FastAPI` 앱의 `lifespan` 매개변수와 "컨텍스트 매니저"를 사용하여 *시작*과 *종료* 로직을 정의할 수 있습니다(컨텍스트 매니저가 무엇인지 잠시 후에 보여드리겠습니다).
|
||||
`FastAPI` 애플리케이션의 `lifespan` 매개변수와 "컨텍스트 매니저"를 사용하여 *시작*과 *종료* 로직을 정의할 수 있습니다(컨텍스트 매니저가 무엇인지 잠시 후에 보여드리겠습니다).
|
||||
|
||||
예제로 시작한 다음 자세히 살펴보겠습니다.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
|
||||
|
||||
여기서는 `yield` 이전에 (가짜) 모델 함수를 머신러닝 모델이 들어 있는 딕셔너리에 넣어 모델을 로드하는 비용이 큰 *시작* 작업을 시뮬레이션합니다. 이 코드는 애플리케이션이 **요청을 받기 시작하기 전**, *시작* 동안에 실행됩니다.
|
||||
여기서는 `yield` 이전에 (가짜) 모델 함수를 머신러닝 모델들이 들어 있는 딕셔너리에 넣어 모델을 로드하는 비용이 큰 *시작* 작업을 시뮬레이션합니다. 이 코드는 애플리케이션이 **요청을 받기 시작하기 전**, *시작* 동안에 실행됩니다.
|
||||
|
||||
그리고 `yield` 직후에는 모델을 언로드합니다. 이 코드는 애플리케이션이 **요청 처리를 마친 후**, *종료* 직전에 실행됩니다. 예를 들어 메모리나 GPU 같은 자원을 해제할 수 있습니다.
|
||||
|
||||
@@ -80,7 +80,7 @@ async with lifespan(app):
|
||||
|
||||
위의 코드 예제에서는 직접 사용하지 않고, FastAPI에 전달하여 FastAPI가 이를 사용하도록 합니다.
|
||||
|
||||
`FastAPI` 앱의 `lifespan` 매개변수는 **비동기 컨텍스트 매니저**를 받으므로, 새 `lifespan` 비동기 컨텍스트 매니저를 전달할 수 있습니다.
|
||||
`FastAPI` 애플리케이션의 `lifespan` 매개변수는 **비동기 컨텍스트 매니저**를 받으므로, 새 `lifespan` 비동기 컨텍스트 매니저를 전달할 수 있습니다.
|
||||
|
||||
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
|
||||
|
||||
@@ -88,7 +88,7 @@ async with lifespan(app):
|
||||
|
||||
/// warning | 경고
|
||||
|
||||
*시작*과 *종료*를 처리하는 권장 방법은 위에서 설명한 대로 `FastAPI` 앱의 `lifespan` 매개변수를 사용하는 것입니다. `lifespan` 매개변수를 제공하면 `startup`과 `shutdown` 이벤트 핸들러는 더 이상 호출되지 않습니다. `lifespan`만 쓰거나 이벤트만 쓰거나 둘 중 하나이지, 둘 다는 아닙니다.
|
||||
*시작*과 *종료*를 처리하는 권장 방법은 위에서 설명한 대로 `FastAPI` 애플리케이션의 `lifespan` 매개변수를 사용하는 것입니다. `lifespan` 매개변수를 제공하면 `startup`과 `shutdown` 이벤트 핸들러는 더 이상 호출되지 않습니다. `lifespan`만 쓰거나 이벤트만 쓰거나 둘 중 하나이지, 둘 다는 아닙니다.
|
||||
|
||||
이 부분은 아마 건너뛰셔도 됩니다.
|
||||
|
||||
@@ -120,7 +120,7 @@ async with lifespan(app):
|
||||
|
||||
여기서 `shutdown` 이벤트 핸들러 함수는 텍스트 한 줄 `"Application shutdown"`을 `log.txt` 파일에 기록합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`open()` 함수에서 `mode="a"`는 "append"(추가)를 의미하므로, 기존 내용을 덮어쓰지 않고 파일에 있던 내용 뒤에 줄이 추가됩니다.
|
||||
|
||||
@@ -150,9 +150,9 @@ async with lifespan(app):
|
||||
|
||||
호기심 많은 분들을 위한 기술적인 세부사항입니다. 🤓
|
||||
|
||||
내부적으로 ASGI 기술 사양에서는 이것이 [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html)의 일부이며, `startup`과 `shutdown`이라는 이벤트를 정의합니다.
|
||||
내부적으로 ASGI 기술 사양에서는 이것이 [Lifespan 프로토콜](https://asgi.readthedocs.io/en/latest/specs/lifespan.html)의 일부이며, `startup`과 `shutdown`이라는 이벤트를 정의합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
Starlette `lifespan` 핸들러에 대해서는 [Starlette의 Lifespan 문서](https://www.starlette.dev/lifespan/)에서 더 읽어볼 수 있습니다.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**FastAPI**는 **OpenAPI** 사양을 기반으로 하므로, FastAPI의 API는 많은 도구가 이해할 수 있는 표준 형식으로 설명할 수 있습니다.
|
||||
|
||||
덕분에 여러 언어용 클라이언트 라이브러리(<abbr title="Software Development Kits - 소프트웨어 개발 키트">**SDKs**</abbr>), 최신 **문서**, 그리고 코드와 동기화된 **테스트** 또는 **자동화 워크플로**를 쉽게 생성할 수 있습니다.
|
||||
덕분에 최신 **문서**, 여러 언어용 클라이언트 라이브러리(<abbr title="Software Development Kits - 소프트웨어 개발 키트">**SDKs**</abbr>), 그리고 코드와 동기화된 **테스트** 또는 **자동화 워크플로**를 쉽게 생성할 수 있습니다.
|
||||
|
||||
이 가이드에서는 FastAPI 백엔드용 **TypeScript SDK**를 생성하는 방법을 배웁니다.
|
||||
|
||||
@@ -20,21 +20,6 @@ FastAPI는 **OpenAPI 3.1** 사양을 자동으로 생성하므로, 사용하는
|
||||
|
||||
///
|
||||
|
||||
## FastAPI 스폰서의 SDK 생성기 { #sdk-generators-from-fastapi-sponsors }
|
||||
|
||||
이 섹션에서는 FastAPI를 후원하는 회사들이 제공하는 **벤처 투자 기반** 및 **기업 지원** 솔루션을 소개합니다. 이 제품들은 고품질로 생성된 SDK에 더해 **추가 기능**과 **통합**을 제공합니다.
|
||||
|
||||
✨ [**FastAPI 후원하기**](../help-fastapi.md#sponsor-the-author) ✨를 통해, 이 회사들은 프레임워크와 그 **생태계**가 건강하고 **지속 가능**하게 유지되도록 돕습니다.
|
||||
|
||||
또한 이들의 후원은 FastAPI **커뮤니티**(여러분)에 대한 강한 헌신을 보여주며, **좋은 서비스**를 제공하는 것뿐 아니라, 견고하고 활발한 프레임워크인 FastAPI를 지원하는 데에도 관심이 있음을 나타냅니다. 🙇
|
||||
|
||||
예를 들어 다음을 사용해 볼 수 있습니다:
|
||||
|
||||
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
|
||||
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
|
||||
|
||||
이 중 일부는 오픈 소스이거나 무료 티어를 제공하므로, 비용 부담 없이 사용해 볼 수 있습니다. 다른 상용 SDK 생성기도 있으며 온라인에서 찾을 수 있습니다. 🤓
|
||||
|
||||
## TypeScript SDK 만들기 { #create-a-typescript-sdk }
|
||||
|
||||
간단한 FastAPI 애플리케이션으로 시작해 보겠습니다:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Base64와 파일 { #base64-vs-files }
|
||||
|
||||
바이너리 데이터 업로드에는 [요청 파일](../tutorial/request-files.md)을, 바이너리 데이터 전송에는 [커스텀 응답 - FileResponse](./custom-response.md#fileresponse--fileresponse-)를 사용할 수 있는지 먼저 고려하세요. JSON으로 인코딩하는 대신 말입니다.
|
||||
바이너리 데이터 업로드에는 [요청 파일](../tutorial/request-files.md)을, 바이너리 데이터 전송에는 [커스텀 응답 - FileResponse](./custom-response.md#fileresponse)를 사용할 수 있는지 먼저 고려하세요. JSON으로 인코딩하는 대신 말입니다.
|
||||
|
||||
JSON은 UTF-8로 인코딩된 문자열만 포함할 수 있으므로, 원시 바이트를 그대로 담을 수 없습니다.
|
||||
|
||||
|
||||
@@ -165,15 +165,15 @@ https://www.external.org/events/invoices/2expen51ve
|
||||
|
||||
### 콜백 라우터 추가하기 { #add-the-callback-router }
|
||||
|
||||
이 시점에서, 위에서 만든 콜백 라우터 안에 *콜백 경로 처리(들)*(즉 *external developer*가 *external API*에 구현해야 하는 것들)을 준비했습니다.
|
||||
이 시점에서, 위에서 만든 콜백 라우터 안에 *콜백 경로 처리(들)*(즉 *외부 개발자*가 *external API*에 구현해야 하는 것들)을 준비했습니다.
|
||||
|
||||
이제 *여러분의 API 경로 처리 데코레이터*에서 `callbacks` 파라미터를 사용해, 그 콜백 라우터의 `.routes` 속성(실제로는 routes/*경로 처리*의 `list`)을 전달합니다:
|
||||
이제 *여러분의 API 경로 처리 데코레이터*에서 `callbacks` 파라미터를 사용해, 그 콜백 라우터의 `.routes` 속성을 전달합니다:
|
||||
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
`callback=`에 라우터 자체(`invoices_callback_router`)를 넘기는 것이 아니라, `invoices_callback_router.routes`처럼 `.routes` 속성을 넘긴다는 점에 주목하세요.
|
||||
`callbacks=`에 라우터 자체(`invoices_callback_router`)를 넘기는 것이 아니라, `invoices_callback_router.routes`처럼 `.routes` 속성을 넘긴다는 점에 주목하세요. FastAPI는 이 라우트들을 사용하여 콜백 OpenAPI 문서를 생성합니다.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ webhook의 URL을 등록하는 방법과 실제로 그 요청을 보내는 코
|
||||
|
||||
이렇게 하면 사용자가 여러분의 **webhook** 요청을 받기 위해 **자신들의 API를 구현**하기가 훨씬 쉬워지고, 경우에 따라서는 자신의 API 코드 일부를 자동 생성할 수도 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
Webhooks는 OpenAPI 3.1.0 이상에서 사용할 수 있으며, FastAPI `0.99.0` 이상에서 지원됩니다.
|
||||
|
||||
@@ -36,7 +36,7 @@ Webhooks는 OpenAPI 3.1.0 이상에서 사용할 수 있으며, FastAPI `0.99.0`
|
||||
|
||||
여러분이 정의한 webhook은 **OpenAPI** 스키마와 자동 **docs UI**에 포함됩니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`app.webhooks` 객체는 실제로 `APIRouter`일 뿐이며, 여러 파일로 앱을 구조화할 때 사용하는 것과 동일한 타입입니다.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## OpenAPI operationId { #openapi-operationid }
|
||||
|
||||
/// warning | 경고
|
||||
/// warning
|
||||
|
||||
OpenAPI “전문가”가 아니라면, 아마 이 내용은 필요하지 않을 것입니다.
|
||||
|
||||
@@ -16,19 +16,13 @@ OpenAPI “전문가”가 아니라면, 아마 이 내용은 필요하지 않
|
||||
|
||||
### *경로 처리 함수* 이름을 operationId로 사용하기 { #using-the-path-operation-function-name-as-the-operationid }
|
||||
|
||||
API의 함수 이름을 `operationId`로 사용하고 싶다면, 모든 API를 순회하면서 `APIRoute.name`을 사용해 각 *경로 처리*의 `operation_id`를 덮어쓸 수 있습니다.
|
||||
API의 함수 이름을 `operationId`로 사용하고 싶다면, `FastAPI`에 사용자 정의 `generate_unique_id_function`을 전달할 수 있습니다.
|
||||
|
||||
모든 *경로 처리*를 추가한 뒤에 수행해야 합니다.
|
||||
이 함수는 각 `APIRoute`를 받아 그 *경로 처리*에 사용할 `operationId`를 반환합니다.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2,5:6,9] *}
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
`app.openapi()`를 수동으로 호출한다면, 그 전에 `operationId`들을 업데이트해야 합니다.
|
||||
|
||||
///
|
||||
|
||||
/// warning | 경고
|
||||
/// warning
|
||||
|
||||
이렇게 할 경우, 각 *경로 처리 함수*의 이름이 고유하도록 보장해야 합니다.
|
||||
|
||||
@@ -78,7 +72,7 @@ OpenAPI 명세에서는 이를 [Operation Object](https://github.com/OAI/OpenAPI
|
||||
|
||||
이 *경로 처리* 전용 OpenAPI 스키마는 보통 **FastAPI**가 자동으로 생성하지만, 확장할 수도 있습니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip
|
||||
|
||||
이는 저수준 확장 지점입니다.
|
||||
|
||||
@@ -163,7 +157,7 @@ OpenAPI 명세에서는 이를 [Operation Object](https://github.com/OAI/OpenAPI
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
|
||||
|
||||
/// tip | 팁
|
||||
/// tip
|
||||
|
||||
여기서는 같은 Pydantic 모델을 재사용합니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 응답 - 상태 코드 변경 { #response-change-status-code }
|
||||
|
||||
|
||||
기본 [응답 상태 코드 설정](../tutorial/response-status-code.md)이 가능하다는 걸 이미 알고 계실 겁니다.
|
||||
|
||||
하지만 경우에 따라 기본 설정과 다른 상태 코드를 반환해야 할 때가 있습니다.
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
`Response` 매개변수를 사용하지 않고 응답을 직접 반환하는 경우, FastAPI는 이를 직접 반환한다는 점에 유의하세요.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
`Response` 또는 그 하위 클래스를 반환할 수 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`JSONResponse` 자체도 `Response`의 하위 클래스입니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 응답 헤더 { #response-headers }
|
||||
|
||||
|
||||
## `Response` 매개변수 사용하기 { #use-a-response-parameter }
|
||||
|
||||
여러분은 *경로 처리 함수*에서 `Response` 타입의 매개변수를 선언할 수 있습니다 (쿠키와 같이 사용할 수 있습니다).
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
이를 통해 OAuth2 표준을 따르는 더 세밀한 권한 시스템을 OpenAPI 애플리케이션(및 API 문서)에 통합할 수 있습니다.
|
||||
|
||||
스코프를 사용하는 OAuth2는 Facebook, Google, GitHub, Microsoft, X(Twitter) 등 많은 대형 인증 제공자가 사용하는 메커니즘입니다. 이들은 이를 통해 사용자와 애플리케이션에 특정 권한을 제공합니다.
|
||||
스코프를 사용하는 OAuth2는 Facebook, Google, GitHub, Microsoft, X (Twitter) 등 많은 대형 인증 제공자가 사용하는 메커니즘입니다. 이들은 이를 통해 사용자와 애플리케이션에 특정 권한을 제공합니다.
|
||||
|
||||
Facebook, Google, GitHub, Microsoft, X(Twitter)로 “로그인”할 때마다, 해당 애플리케이션은 스코프가 있는 OAuth2를 사용하고 있습니다.
|
||||
Facebook, Google, GitHub, Microsoft, X (Twitter)로 “로그인”할 때마다, 해당 애플리케이션은 스코프가 있는 OAuth2를 사용하고 있습니다.
|
||||
|
||||
이 섹션에서는 **FastAPI** 애플리케이션에서 동일한 “스코프가 있는 OAuth2”로 인증(Authentication)과 인가(Authorization)를 관리하는 방법을 확인합니다.
|
||||
|
||||
@@ -46,7 +46,7 @@ OpenAPI(예: API 문서)에서는 “security schemes”를 정의할 수 있습
|
||||
* `instagram_basic` 는 Facebook/Instagram에서 사용합니다.
|
||||
* `https://www.googleapis.com/auth/drive` 는 Google에서 사용합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
OAuth2에서 “스코프”는 필요한 특정 권한을 선언하는 문자열일 뿐입니다.
|
||||
|
||||
@@ -126,7 +126,7 @@ OAuth2 입장에서는 그저 문자열입니다.
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
|
||||
|
||||
/// info | 기술 세부사항
|
||||
/// note | 기술 세부사항
|
||||
|
||||
`Security`는 실제로 `Depends`의 서브클래스이며, 나중에 보게 될 추가 매개변수 하나만 더 있습니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 설정과 환경 변수 { #settings-and-environment-variables }
|
||||
|
||||
|
||||
많은 경우 애플리케이션에는 외부 설정이나 구성(예: secret key, 데이터베이스 자격 증명, 이메일 서비스 자격 증명 등)이 필요할 수 있습니다.
|
||||
|
||||
이러한 설정 대부분은 데이터베이스 URL처럼 변동 가능(변경될 수 있음)합니다. 그리고 많은 설정은 secret처럼 민감할 수 있습니다.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
JSON으로 구조화할 수 있는 데이터를 스트리밍하려면 [JSON Lines 스트리밍](../tutorial/stream-json-lines.md)을 사용하세요.
|
||||
|
||||
하지만 순수 바이너리 데이터나 문자열을 스트리밍하려면 다음과 같이 하면 됩니다.
|
||||
하지만 **순수 바이너리 데이터**나 문자열을 스트리밍하려면 다음과 같이 하면 됩니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
FastAPI 0.134.0에 추가되었습니다.
|
||||
|
||||
@@ -12,21 +12,21 @@ FastAPI 0.134.0에 추가되었습니다.
|
||||
|
||||
## 사용 예시 { #use-cases }
|
||||
|
||||
예를 들어 AI LLM 서비스의 출력에서 바로 순수 문자열을 스트리밍하고 싶다면 이를 사용할 수 있습니다.
|
||||
예를 들어 **AI LLM** 서비스의 출력에서 바로 순수 문자열을 스트리밍하고 싶다면 이를 사용할 수 있습니다.
|
||||
|
||||
또한 큰 바이너리 파일을 스트리밍하는 데 사용할 수 있습니다. 한 번에 모두 메모리로 읽지 않고, 읽는 즉시 데이터 청크를 순차적으로 스트리밍합니다.
|
||||
또한 **큰 바이너리 파일**을 스트리밍하는 데 사용할 수 있습니다. 한 번에 모두 메모리로 읽지 않고, 읽는 즉시 데이터 청크를 순차적으로 스트리밍합니다.
|
||||
|
||||
이 방식으로 비디오나 오디오를 스트리밍할 수도 있으며, 처리하면서 생성된 데이터를 곧바로 전송할 수도 있습니다.
|
||||
이 방식으로 **비디오**나 **오디오**를 스트리밍할 수도 있으며, 처리하면서 생성된 데이터를 곧바로 전송할 수도 있습니다.
|
||||
|
||||
## `yield`와 함께 `StreamingResponse` 사용하기 { #a-streamingresponse-with-yield }
|
||||
|
||||
경로 처리 함수에서 `response_class=StreamingResponse`를 선언하면 `yield`를 사용해 데이터 청크를 순차적으로 보낼 수 있습니다.
|
||||
*경로 처리 함수*에서 `response_class=StreamingResponse`를 선언하면 `yield`를 사용해 데이터 청크를 순차적으로 보낼 수 있습니다.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
|
||||
|
||||
FastAPI는 각 데이터 청크를 있는 그대로 `StreamingResponse`에 전달하며, JSON 등으로 변환하려고 하지 않습니다.
|
||||
|
||||
### async가 아닌 경로 처리 함수 { #non-async-path-operation-functions }
|
||||
### async가 아닌 *경로 처리 함수* { #non-async-path-operation-functions }
|
||||
|
||||
`async`가 없는 일반 `def` 함수에서도 동일하게 `yield`를 사용할 수 있습니다.
|
||||
|
||||
@@ -40,7 +40,7 @@ FastAPI는 데이터를 Pydantic으로 JSON으로 변환하거나 어떤 방식
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
|
||||
|
||||
이는 곧 `StreamingResponse`를 사용할 때 타입 애너테이션과 무관하게, 전송 기준에 맞춰 바이트 데이터를 생성하고 인코딩할 자유와 책임이 여러분에게 있음을 의미합니다. 🤓
|
||||
이는 곧 `StreamingResponse`를 사용할 때 타입 애너테이션과 무관하게, 전송 기준에 맞춰 바이트 데이터를 생성하고 인코딩할 **자유**와 **책임**이 여러분에게 있음을 의미합니다. 🤓
|
||||
|
||||
### 바이트 스트리밍 { #stream-bytes }
|
||||
|
||||
@@ -58,7 +58,7 @@ FastAPI는 데이터를 Pydantic으로 JSON으로 변환하거나 어떤 방식
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
|
||||
|
||||
그런 다음 경로 처리 함수에서 `response_class=PNGStreamingResponse`로 이 새 클래스를 사용할 수 있습니다:
|
||||
그런 다음 *경로 처리 함수*에서 `response_class=PNGStreamingResponse`로 이 새 클래스를 사용할 수 있습니다:
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
|
||||
|
||||
@@ -90,7 +90,7 @@ FastAPI는 데이터를 Pydantic으로 JSON으로 변환하거나 어떤 방식
|
||||
|
||||
또한 디스크나 네트워크에서 읽기 때문에, 많은 경우 읽기 작업은 이벤트 루프를 막을 수 있는 블로킹 연산입니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
위의 예시는 예외적인 경우입니다. `io.BytesIO` 객체는 이미 메모리에 있으므로 읽기가 아무 것도 차단하지 않습니다.
|
||||
|
||||
@@ -98,7 +98,7 @@ FastAPI는 데이터를 Pydantic으로 JSON으로 변환하거나 어떤 방식
|
||||
|
||||
///
|
||||
|
||||
이벤트 루프가 블로킹되는 것을 피하려면 경로 처리 함수를 `async def` 대신 일반 `def`로 선언하세요. 그러면 FastAPI가 스레드풀 워커에서 실행하여 메인 루프가 막히지 않도록 합니다.
|
||||
이벤트 루프가 블로킹되는 것을 피하려면 *경로 처리 함수*를 `async def` 대신 일반 `def`로 선언하세요. 그러면 FastAPI가 스레드풀 워커에서 실행하여 메인 루프가 막히지 않도록 합니다.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ http://localhost:8000/v1/agents/multivac
|
||||
|
||||
이 설정을 사용하면 `Content-Type` 헤더가 없는 요청도 본문이 JSON으로 파싱됩니다. 이는 이전 버전의 FastAPI와 동일한 동작입니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
이 동작과 설정은 FastAPI 0.132.0에 추가되었습니다.
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ WebSocket 엔드포인트에서 `fastapi`에서 다음을 가져와 사용할
|
||||
|
||||
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
WebSocket이기 때문에 `HTTPException`을 발생시키는 것은 적절하지 않습니다. 대신 `WebSocketException`을 발생시킵니다.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## `WSGIMiddleware` 사용하기 { #using-wsgimiddleware }
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
이를 사용하려면 `a2wsgi`를 설치해야 합니다. 예: `pip install a2wsgi`
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
Hello, World from Flask!
|
||||
```
|
||||
|
||||
그리고 [http://localhost:8000/v2](http://localhost:8000/v2)로 이동하면 **FastAPI**의 응답을 볼 수 있습니다:
|
||||
그리고 [http://localhost:8000/v2](http://localhost:8000/v2)로 이동하면 FastAPI의 응답을 볼 수 있습니다:
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
### [Django REST Framework](https://www.django-rest-framework.org/) { #django-rest-framework }
|
||||
|
||||
Django REST framework는 Django를 기반으로 Web API를 구축하기 위한 유연한 toolkit으로 만들어졌고, Django의 API 기능을 개선하기 위한 목적이었습니다.
|
||||
Django REST Framework는 Django를 기반으로 Web API를 구축하기 위한 유연한 toolkit으로 만들어졌고, Django의 API 기능을 개선하기 위한 목적이었습니다.
|
||||
|
||||
Mozilla, Red Hat, Eventbrite를 포함해 많은 회사에서 사용합니다.
|
||||
|
||||
@@ -36,7 +36,7 @@ Django REST Framework는 Tom Christie가 만들었습니다. **FastAPI**의 기
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
자동 API 문서화 웹 사용자 인터페이스를 제공하기.
|
||||
|
||||
@@ -56,7 +56,7 @@ Flask는 "microframework"로, Django에 기본으로 포함된 데이터베이
|
||||
|
||||
Flask의 단순함을 고려하면 API를 구축하는 데 잘 맞는 것처럼 보였습니다. 다음으로 찾고자 했던 것은 Flask용 "Django REST Framework"였습니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
micro-framework가 되기. 필요한 도구와 구성요소를 쉽게 조합할 수 있도록 하기.
|
||||
|
||||
@@ -80,7 +80,7 @@ Requests는 매우 단순하고 직관적인 설계를 가졌고, 합리적인
|
||||
|
||||
그래서 공식 웹사이트에서 말하듯이:
|
||||
|
||||
> Requests is one of the most downloaded Python packages of all time
|
||||
> Requests는 역대 가장 많이 다운로드된 Python 패키지 중 하나입니다
|
||||
|
||||
사용 방법은 매우 간단합니다. 예를 들어 `GET` 요청을 하려면 다음처럼 작성합니다:
|
||||
|
||||
@@ -98,7 +98,7 @@ def read_url():
|
||||
|
||||
`requests.get(...)`와 `@app.get(...)`의 유사성을 확인해 보세요.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
* 단순하고 직관적인 API를 갖기.
|
||||
* HTTP method 이름(operations)을 직접, 직관적이고 명확한 방식으로 사용하기.
|
||||
@@ -118,7 +118,7 @@ def read_url():
|
||||
|
||||
그래서 2.0 버전을 이야기할 때는 "Swagger"라고 말하는 것이 일반적이고, 3+ 버전은 "OpenAPI"라고 말하는 것이 일반적입니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
커스텀 schema 대신, API 사양을 위한 열린 표준을 채택하고 사용하기.
|
||||
|
||||
@@ -147,7 +147,7 @@ API에 또 하나 크게 필요한 기능은 데이터 검증입니다. 특정
|
||||
|
||||
하지만 Python type hints가 존재하기 전에 만들어졌습니다. 그래서 각 <dfn title="데이터가 어떻게 구성되어야 하는지에 대한 정의">스키마</dfn>를 정의하려면 Marshmallow가 제공하는 특정 유틸리티와 클래스를 사용해야 합니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
데이터 타입과 검증을 제공하는 "schema"를 코드로 정의하고, 이를 자동으로 활용하기.
|
||||
|
||||
@@ -169,7 +169,7 @@ Webargs는 Marshmallow와 같은 개발자들이 만들었습니다.
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
들어오는 요청 데이터의 자동 검증을 갖기.
|
||||
|
||||
@@ -199,7 +199,7 @@ APISpec은 Marshmallow와 같은 개발자들이 만들었습니다.
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
API를 위한 열린 표준인 OpenAPI를 지원하기.
|
||||
|
||||
@@ -231,7 +231,7 @@ Flask-apispec은 Marshmallow와 같은 개발자들이 만들었습니다.
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
serialization과 validation을 정의하는 동일한 코드로부터 OpenAPI schema를 자동 생성하기.
|
||||
|
||||
@@ -251,7 +251,7 @@ Angular 2에서 영감을 받은 의존성 주입 시스템이 통합되어 있
|
||||
|
||||
중첩 모델을 잘 처리하지 못합니다. 즉, 요청의 JSON body가 내부 필드를 가진 JSON 객체이고 그 내부 필드들이 다시 중첩된 JSON 객체인 경우, 제대로 문서화하고 검증할 수 없습니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
Python 타입을 사용해 뛰어난 에디터 지원을 제공하기.
|
||||
|
||||
@@ -271,7 +271,7 @@ Python 타입을 사용해 뛰어난 에디터 지원을 제공하기.
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
미친 성능을 낼 수 있는 방법을 찾기.
|
||||
|
||||
@@ -283,11 +283,11 @@ Python 타입을 사용해 뛰어난 에디터 지원을 제공하기.
|
||||
|
||||
Falcon은 또 다른 고성능 Python framework로, 최소한으로 설계되었고 Hug 같은 다른 framework의 기반으로 동작하도록 만들어졌습니다.
|
||||
|
||||
함수가 두 개의 파라미터(하나는 "request", 하나는 "response")를 받도록 설계되어 있습니다. 그런 다음 request에서 일부를 "읽고", response에 일부를 "작성"합니다. 이 설계 때문에, 표준 Python type hints를 함수 파라미터로 사용해 요청 파라미터와 body를 선언하는 것이 불가능합니다.
|
||||
함수가 두 개의 파라미터(하나는 "요청", 하나는 "응답")를 받도록 설계되어 있습니다. 그런 다음 요청에서 일부를 "읽고", 응답에 일부를 "작성"합니다. 이 설계 때문에, 표준 Python type hints를 함수 파라미터로 사용해 요청 파라미터와 body를 선언하는 것이 불가능합니다.
|
||||
|
||||
따라서 데이터 검증, serialization, 문서화는 자동으로 되지 않고 코드로 해야 합니다. 또는 Hug처럼 Falcon 위에 framework를 얹어 구현해야 합니다. request 객체 하나와 response 객체 하나를 파라미터로 받는 Falcon의 설계에서 영감을 받은 다른 framework에서도 같은 구분이 나타납니다.
|
||||
따라서 데이터 검증, serialization, 문서화는 자동으로 되지 않고 코드로 해야 합니다. 또는 Hug처럼 Falcon 위에 framework를 얹어 구현해야 합니다. 요청 객체 하나와 응답 객체 하나를 파라미터로 받는 Falcon의 설계에서 영감을 받은 다른 framework에서도 같은 구분이 나타납니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
훌륭한 성능을 얻는 방법을 찾기.
|
||||
|
||||
@@ -313,7 +313,7 @@ Pydantic 같은 서드파티 라이브러리를 사용해 데이터 검증/seria
|
||||
|
||||
Route는 한 곳에서 선언하고, 다른 곳에 선언된 함수를 사용합니다(엔드포인트를 처리하는 함수 바로 위에 둘 수 있는 decorator를 사용하는 대신). 이는 Flask(및 Starlette)보다는 Django 방식에 가깝습니다. 코드에서 상대적으로 강하게 결합된 것들을 분리해 놓습니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
모델 속성의 "default" 값으로 데이터 타입에 대한 추가 검증을 정의하기. 이는 에디터 지원을 개선하며, 이전에는 Pydantic에 없었습니다.
|
||||
|
||||
@@ -341,7 +341,7 @@ Hug는 Timothy Crosley가 만들었습니다. Python 파일에서 import를 자
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 아이디어
|
||||
|
||||
Hug는 APIStar의 일부에 영감을 주었고, 저는 APIStar와 함께 Hug를 가장 유망한 도구 중 하나로 보았습니다.
|
||||
|
||||
@@ -385,7 +385,7 @@ APIStar는 Tom Christie가 만들었습니다. 다음을 만든 사람과 동일
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**에 영감을 준 점
|
||||
|
||||
존재하게 만들기.
|
||||
|
||||
@@ -409,7 +409,7 @@ Pydantic은 Python type hints를 기반으로 데이터 검증, serialization,
|
||||
|
||||
Marshmallow와 비교할 수 있습니다. 다만 benchmark에서 Marshmallow보다 빠릅니다. 그리고 동일한 Python type hints를 기반으로 하므로 에디터 지원도 훌륭합니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**는 이를 사용해
|
||||
|
||||
모든 데이터 검증, 데이터 serialization, 자동 모델 문서화(JSON Schema 기반)를 처리하기.
|
||||
|
||||
@@ -430,7 +430,7 @@ Starlette는 경량 <dfn title="비동기 Python 웹 애플리케이션을 구
|
||||
* 프로세스 내 백그라운드 작업.
|
||||
* 시작 및 종료 이벤트.
|
||||
* HTTPX 기반의 테스트 클라이언트.
|
||||
* CORS, GZip, Static Files, Streaming responses.
|
||||
* CORS, GZip, Static Files, 스트리밍 응답.
|
||||
* 세션 및 쿠키 지원.
|
||||
* 100% 테스트 커버리지.
|
||||
* 100% 타입 주석이 달린 코드베이스.
|
||||
@@ -452,7 +452,7 @@ ASGI는 Django 코어 팀 멤버들이 개발 중인 새로운 "표준"입니다
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**는 이를 사용해
|
||||
|
||||
핵심 웹 부분을 모두 처리하기. 그 위에 기능을 추가하기.
|
||||
|
||||
@@ -470,11 +470,11 @@ web framework가 아니라 서버입니다. 예를 들어 경로 기반 routing
|
||||
|
||||
Starlette와 **FastAPI**에서 권장하는 서버입니다.
|
||||
|
||||
/// tip | 팁
|
||||
/// tip | **FastAPI**는 이를 다음으로 권장합니다
|
||||
|
||||
**FastAPI** 애플리케이션을 실행하기 위한 주요 웹 서버.
|
||||
|
||||
또한 `--workers` 커맨드라인 옵션을 사용하면 비동기 멀티프로세스 서버로 실행할 수도 있습니다.
|
||||
또한 `--workers` 명령줄 옵션을 사용하면 비동기 멀티프로세스 서버로 실행할 수도 있습니다.
|
||||
|
||||
자세한 내용은 [배포](deployment/index.md) 섹션을 확인하세요.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 동시성과 async / await { #concurrency-and-async-await }
|
||||
|
||||
|
||||
*경로 처리 함수*에서의 `async def` 문법에 대한 세부사항과 비동기 코드, 동시성 및 병렬성에 대한 배경
|
||||
|
||||
## 바쁘신가요? { #in-a-hurry }
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
최소한의 노력으로 API를 **구축**, **배포**, **접근**하는 과정을 간소화합니다.
|
||||
|
||||
FastAPI로 앱을 빌드할 때의 동일한 **개발자 경험**을 클라우드에 **배포**하는 데에도 제공합니다. 🎉
|
||||
FastAPI로 애플리케이션을 빌드할 때의 동일한 **개발자 경험**을 클라우드에 **배포**하는 데에도 제공합니다. 🎉
|
||||
|
||||
FastAPI Cloud는 *FastAPI and friends* 오픈 소스 프로젝트의 주요 후원자이자 자금 제공자입니다. ✨
|
||||
|
||||
## 클라우드 제공업체 - 후원자들 { #cloud-providers-sponsors }
|
||||
|
||||
다른 몇몇 클라우드 제공업체들도 ✨ [**FastAPI를 후원합니다**](../help-fastapi.md#sponsor-the-author) ✨. 🙇
|
||||
다른 몇몇 클라우드 제공업체들도 ✨ [**FastAPI를 후원합니다**](https://github.com/sponsors/tiangolo) ✨. 🙇
|
||||
|
||||
가이드를 따라 하고 서비스를 사용해보기 위해 이들도 고려해볼 수 있습니다:
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ TLS Termination Proxy로 사용할 수 있는 도구는 예를 들어 다음과
|
||||
|
||||
### 시작 시 자동 실행 { #run-automatically-on-startup }
|
||||
|
||||
일반적으로 서버 프로그램(예: Uvicorn)은 서버가 시작될 때 자동으로 시작되고, **사람의 개입** 없이도 FastAPI 앱을 실행하는 프로세스가 항상 실행 중이도록(예: FastAPI 앱을 실행하는 Uvicorn) 구성하고 싶을 것입니다.
|
||||
일반적으로 서버 프로그램(예: Uvicorn)은 서버가 시작될 때 자동으로 시작되고, **사람의 개입** 없이도 FastAPI 애플리케이션을 실행하는 프로세스가 항상 실행 중이도록(예: FastAPI 애플리케이션을 실행하는 Uvicorn) 구성하고 싶을 것입니다.
|
||||
|
||||
### 별도의 프로그램 { #separate-program }
|
||||
|
||||
@@ -159,7 +159,7 @@ FastAPI로 웹 API를 만들 때 코드에 오류가 있으면, FastAPI는 보
|
||||
|
||||
///
|
||||
|
||||
애플리케이션을 재시작하는 역할은 **외부 컴포넌트**가 맡는 편이 보통 좋습니다. 그 시점에는 Uvicorn과 Python을 포함한 애플리케이션이 이미 크래시했기 때문에, 같은 앱의 같은 코드 안에서 이를 해결할 방법이 없기 때문입니다.
|
||||
애플리케이션을 재시작하는 역할은 **외부 컴포넌트**가 맡는 편이 보통 좋습니다. 그 시점에는 Uvicorn과 Python을 포함한 애플리케이션이 이미 크래시했기 때문에, 같은 애플리케이션의 같은 코드 안에서 이를 해결할 방법이 없기 때문입니다.
|
||||
|
||||
### 자동 재시작을 위한 도구 예시 { #example-tools-to-restart-automatically }
|
||||
|
||||
@@ -243,7 +243,7 @@ FastAPI 애플리케이션은 Uvicorn을 실행하는 `fastapi` 명령 같은
|
||||
|
||||
**컨테이너**, Docker, Kubernetes에 대한 일부 내용이 아직은 잘 이해되지 않아도 괜찮습니다.
|
||||
|
||||
다음 장에서 컨테이너 이미지, Docker, Kubernetes 등을 더 설명하겠습니다: [컨테이너에서 FastAPI - Docker](docker.md).
|
||||
향후 장에서 컨테이너 이미지, Docker, Kubernetes 등을 더 설명하겠습니다: [컨테이너에서 FastAPI - Docker](docker.md).
|
||||
|
||||
///
|
||||
|
||||
@@ -275,13 +275,13 @@ FastAPI 애플리케이션은 Uvicorn을 실행하는 `fastapi` 명령 같은
|
||||
|
||||
가능한 아이디어는 다음과 같습니다:
|
||||
|
||||
* 앱 컨테이너보다 먼저 실행되는 Kubernetes의 “Init Container”
|
||||
* 애플리케이션 컨테이너보다 먼저 실행되는 Kubernetes의 “Init Container”
|
||||
* 사전 단계를 실행한 다음 애플리케이션을 시작하는 bash 스크립트
|
||||
* 이 bash 스크립트를 시작/재시작하고, 오류를 감지하는 등의 방법도 여전히 필요합니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
컨테이너로 이를 처리하는 더 구체적인 예시는 다음 장에서 제공하겠습니다: [컨테이너에서 FastAPI - Docker](docker.md).
|
||||
컨테이너로 이를 처리하는 더 구체적인 예시는 향후 장에서 제공하겠습니다: [컨테이너에서 FastAPI - Docker](docker.md).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ FastAPI 애플리케이션을 배포할 때 일반적인 접근 방법은 **리
|
||||
///
|
||||
|
||||
<details>
|
||||
<summary>Dockerfile Preview 👀</summary>
|
||||
<summary>Dockerfile 미리보기 👀</summary>
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.14
|
||||
@@ -26,7 +26,7 @@ COPY ./app /code/app
|
||||
|
||||
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
||||
|
||||
# If running behind a proxy like Nginx or Traefik add --proxy-headers
|
||||
# Nginx나 Traefik 같은 프록시 뒤에서 실행한다면 --proxy-headers를 추가하세요
|
||||
# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"]
|
||||
```
|
||||
|
||||
@@ -46,7 +46,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
||||
|
||||
**컨테이너**는 **컨테이너 이미지**에서 실행됩니다.
|
||||
|
||||
컨테이너 이미지는 컨테이너에 있어야 하는 모든 파일, 환경 변수, 기본 명령/프로그램의 **정적** 버전입니다. 여기서 **정적**이라는 것은 컨테이너 **이미지**가 실행 중이거나 수행되는 것이 아니라, 패키징된 파일과 메타데이터일 뿐이라는 뜻입니다.
|
||||
컨테이너 이미지는 컨테이너에 있어야 하는 모든 파일, 환경 변수, 기본 명령어/프로그램의 **정적** 버전입니다. 여기서 **정적**이라는 것은 컨테이너 **이미지**가 실행 중이거나 수행되는 것이 아니라, 패키징된 파일과 메타데이터일 뿐이라는 뜻입니다.
|
||||
|
||||
저장된 정적 콘텐츠인 "**컨테이너 이미지**"와 달리, "**컨테이너**"는 보통 실행 중인 인스턴스, 즉 **실행되는** 대상을 의미합니다.
|
||||
|
||||
@@ -62,7 +62,7 @@ Docker는 **컨테이너 이미지**와 **컨테이너**를 생성하고 관리
|
||||
|
||||
또한 [Docker Hub](https://hub.docker.com/)에는 다양한 도구, 환경, 데이터베이스, 애플리케이션을 위한 미리 만들어진 **공식 컨테이너 이미지**가 공개되어 있습니다.
|
||||
|
||||
예를 들어, 공식 [Python Image](https://hub.docker.com/_/python)가 있습니다.
|
||||
예를 들어, 공식 [Python 이미지](https://hub.docker.com/_/python)가 있습니다.
|
||||
|
||||
그리고 데이터베이스 등 다양한 용도의 다른 이미지도 많이 있습니다. 예를 들면:
|
||||
|
||||
@@ -81,11 +81,11 @@ Docker나 Kubernetes 같은 모든 컨테이너 관리 시스템에는 이러한
|
||||
|
||||
## 컨테이너와 프로세스 { #containers-and-processes }
|
||||
|
||||
**컨테이너 이미지**는 보통 **컨테이너**가 시작될 때 실행되어야 하는 기본 프로그램/명령과 해당 프로그램에 전달할 매개변수를 메타데이터에 포함합니다. 커맨드 라인에서 실행할 때와 매우 유사합니다.
|
||||
**컨테이너 이미지**는 보통 **컨테이너**가 시작될 때 실행되어야 하는 기본 프로그램/명령어와 해당 프로그램에 전달할 매개변수를 메타데이터에 포함합니다. 커맨드 라인에서 실행할 때와 매우 유사합니다.
|
||||
|
||||
**컨테이너**가 시작되면 해당 명령/프로그램을 실행합니다(다만 오버라이드하여 다른 명령/프로그램을 실행하게 할 수도 있습니다).
|
||||
**컨테이너**가 시작되면 해당 명령어/프로그램을 실행합니다(다만 오버라이드하여 다른 명령어/프로그램을 실행하게 할 수도 있습니다).
|
||||
|
||||
컨테이너는 **메인 프로세스**(명령 또는 프로그램)가 실행되는 동안 실행됩니다.
|
||||
컨테이너는 **메인 프로세스**(명령어 또는 프로그램)가 실행되는 동안 실행됩니다.
|
||||
|
||||
컨테이너는 보통 **단일 프로세스**를 가지지만, 메인 프로세스에서 서브프로세스를 시작할 수도 있으며, 그러면 같은 컨테이너에 **여러 프로세스**가 존재하게 됩니다.
|
||||
|
||||
@@ -132,7 +132,7 @@ Successfully installed fastapi pydantic
|
||||
|
||||
</div>
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
패키지 의존성을 정의하고 설치하는 다른 형식과 도구도 있습니다.
|
||||
|
||||
@@ -218,11 +218,11 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
||||
|
||||
따라서 컨테이너 이미지 빌드 시간을 최적화하려면 `Dockerfile`의 **끝부분 근처**에 두는 것이 중요합니다.
|
||||
|
||||
6. 내부적으로 Uvicorn을 사용하는 `fastapi run`을 사용하도록 **명령**을 설정합니다.
|
||||
6. 내부적으로 Uvicorn을 사용하는 `fastapi run`을 사용하도록 **명령어**를 설정합니다.
|
||||
|
||||
`CMD`는 문자열 리스트를 받으며, 각 문자열은 커맨드 라인에서 공백으로 구분해 입력하는 항목들입니다.
|
||||
|
||||
이 명령은 **현재 작업 디렉터리**에서 실행되며, 이는 위에서 `WORKDIR /code`로 설정한 `/code` 디렉터리와 같습니다.
|
||||
이 명령어는 **현재 작업 디렉터리**에서 실행되며, 이는 위에서 `WORKDIR /code`로 설정한 `/code` 디렉터리와 같습니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
@@ -258,7 +258,7 @@ FastAPI가 정상적으로 종료(graceful shutdown)되고 [lifespan 이벤트](
|
||||
|
||||
자세한 내용은 [shell and exec form에 대한 Docker 문서](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form)를 참고하세요.
|
||||
|
||||
이는 `docker compose`를 사용할 때 꽤 눈에 띌 수 있습니다. 좀 더 기술적인 상세 내용은 Docker Compose FAQ 섹션을 참고하세요: [Why do my services take 10 seconds to recreate or stop?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop).
|
||||
이는 `docker compose`를 사용할 때 꽤 눈에 띌 수 있습니다. 좀 더 기술적인 상세 내용은 Docker Compose FAQ 섹션을 참고하세요: [왜 내 서비스는 다시 생성되거나 중지되는 데 10초가 걸리나요?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop).
|
||||
|
||||
#### 디렉터리 구조 { #directory-structure }
|
||||
|
||||
@@ -409,7 +409,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
|
||||
|
||||
2. 단일 파일 `main.py`에 있는 애플리케이션을 제공(serve)하기 위해 `fastapi run`을 사용합니다.
|
||||
|
||||
`fastapi run`에 파일을 전달하면, 이것이 패키지의 일부가 아닌 단일 파일이라는 것을 자동으로 감지하고, 어떻게 임포트해서 FastAPI 앱을 제공할지 알아냅니다. 😎
|
||||
`fastapi run`에 파일을 전달하면, 이것이 패키지의 일부가 아닌 단일 파일이라는 것을 자동으로 감지하고, 어떻게 임포트해서 FastAPI 애플리케이션을 제공할지 알아냅니다. 😎
|
||||
|
||||
## 배포 개념 { #deployment-concepts }
|
||||
|
||||
@@ -472,17 +472,17 @@ HTTPS에 사용되는 동일한 **TLS 종료 프록시** 컴포넌트가 **로
|
||||
|
||||
///
|
||||
|
||||
또한 컨테이너로 작업할 때, 이를 시작하고 관리하는 시스템은 이미 해당 **로드 밸런서**(또는 **TLS 종료 프록시**)에서 여러분의 앱이 있는 컨테이너로 **네트워크 통신**(예: HTTP 요청)을 전달하는 내부 도구를 가지고 있습니다.
|
||||
또한 컨테이너로 작업할 때, 이를 시작하고 관리하는 시스템은 이미 해당 **로드 밸런서**(또는 **TLS 종료 프록시**)에서 여러분의 애플리케이션이 있는 컨테이너로 **네트워크 통신**(예: HTTP 요청)을 전달하는 내부 도구를 가지고 있습니다.
|
||||
|
||||
### 하나의 로드 밸런서 - 여러 워커 컨테이너 { #one-load-balancer-multiple-worker-containers }
|
||||
|
||||
**Kubernetes** 같은 분산 컨테이너 관리 시스템에서는 내부 네트워킹 메커니즘을 통해, 메인 **포트**에서 대기하는 단일 **로드 밸런서**가 여러분의 앱을 실행하는 **여러 컨테이너**로 통신(요청)을 전달할 수 있습니다.
|
||||
**Kubernetes** 같은 분산 컨테이너 관리 시스템에서는 내부 네트워킹 메커니즘을 통해, 메인 **포트**에서 대기하는 단일 **로드 밸런서**가 여러분의 애플리케이션을 실행하는 **여러 컨테이너**로 통신(요청)을 전달할 수 있습니다.
|
||||
|
||||
앱을 실행하는 각 컨테이너는 보통 **프로세스 하나만** 가집니다(예: FastAPI 애플리케이션을 실행하는 Uvicorn 프로세스). 모두 같은 것을 실행하는 **동일한 컨테이너**이지만, 각자 고유한 프로세스, 메모리 등을 가집니다. 이렇게 하면 CPU의 **서로 다른 코어** 또는 **서로 다른 머신**에서 **병렬화**의 이점을 얻을 수 있습니다.
|
||||
애플리케이션을 실행하는 각 컨테이너는 보통 **프로세스 하나만** 가집니다(예: FastAPI 애플리케이션을 실행하는 Uvicorn 프로세스). 모두 같은 것을 실행하는 **동일한 컨테이너**이지만, 각자 고유한 프로세스, 메모리 등을 가집니다. 이렇게 하면 CPU의 **서로 다른 코어** 또는 **서로 다른 머신**에서 **병렬화**의 이점을 얻을 수 있습니다.
|
||||
|
||||
그리고 **로드 밸런서**가 있는 분산 컨테이너 시스템은 여러분의 앱을 실행하는 각 컨테이너에 **번갈아가며** 요청을 **분산**합니다. 따라서 각 요청은 여러분의 앱을 실행하는 여러 **복제된 컨테이너** 중 하나에서 처리될 수 있습니다.
|
||||
그리고 **로드 밸런서**가 있는 분산 컨테이너 시스템은 여러분의 애플리케이션을 실행하는 각 컨테이너에 **번갈아가며** 요청을 **분산**합니다. 따라서 각 요청은 여러분의 애플리케이션을 실행하는 여러 **복제된 컨테이너** 중 하나에서 처리될 수 있습니다.
|
||||
|
||||
또한 보통 이 **로드 밸런서**는 클러스터 내 *다른* 앱으로 가는 요청(예: 다른 도메인, 또는 다른 URL 경로 접두사 아래로 가는 요청)도 처리할 수 있으며, 그 통신을 클러스터에서 실행 중인 *그 다른* 애플리케이션의 올바른 컨테이너로 전달할 수 있습니다.
|
||||
또한 보통 이 **로드 밸런서**는 클러스터 내 *다른* 애플리케이션으로 가는 요청(예: 다른 도메인, 또는 다른 URL 경로 접두사 아래로 가는 요청)도 처리할 수 있으며, 그 통신을 클러스터에서 실행 중인 *그 다른* 애플리케이션의 올바른 컨테이너로 전달할 수 있습니다.
|
||||
|
||||
### 컨테이너당 하나의 프로세스 { #one-process-per-container }
|
||||
|
||||
@@ -556,7 +556,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
|
||||
|
||||
**여러 컨테이너**가 있고 각 컨테이너가 보통 **단일 프로세스**를 실행한다면(예: **Kubernetes** 클러스터), 복제된 워커 컨테이너를 실행하기 **전에**, 단일 컨테이너에서 단일 프로세스로 **시작 전 사전 단계**를 수행하는 **별도의 컨테이너**를 두고 싶을 가능성이 큽니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
Kubernetes를 사용한다면, 이는 아마도 [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)일 것입니다.
|
||||
|
||||
@@ -566,7 +566,7 @@ Kubernetes를 사용한다면, 이는 아마도 [Init Container](https://kuberne
|
||||
|
||||
### 단일 컨테이너 { #single-container }
|
||||
|
||||
**단일 컨테이너**에서 여러 **워커 프로세스**(또는 단일 프로세스)를 시작하는 단순한 셋업이라면, 앱이 있는 프로세스를 시작하기 직전에 같은 컨테이너에서 시작 전 사전 단계를 실행할 수 있습니다.
|
||||
**단일 컨테이너**에서 여러 **워커 프로세스**(또는 단일 프로세스)를 시작하는 단순한 셋업이라면, 애플리케이션이 있는 프로세스를 시작하기 직전에 같은 컨테이너에서 시작 전 사전 단계를 실행할 수 있습니다.
|
||||
|
||||
### 베이스 도커 이미지 { #base-docker-image }
|
||||
|
||||
@@ -582,7 +582,7 @@ Kubernetes를 사용한다면, 이는 아마도 [Init Container](https://kuberne
|
||||
|
||||
이 Docker 이미지는 Uvicorn이 죽은 워커를 관리하고 재시작하는 기능을 지원하지 않던 시기에 만들어졌습니다. 그래서 Gunicorn과 Uvicorn을 함께 사용해야 했고, Gunicorn이 Uvicorn 워커 프로세스를 관리하고 재시작하도록 하기 위해 상당한 복잡성이 추가되었습니다.
|
||||
|
||||
하지만 이제 Uvicorn(그리고 `fastapi` 명령)은 `--workers`를 지원하므로, 베이스 도커 이미지를 사용하는 대신 직접 이미지를 빌드하지 않을 이유가 없습니다(코드 양도 사실상 거의 같습니다 😅).
|
||||
하지만 이제 Uvicorn(그리고 `fastapi` 명령어)은 `--workers`를 지원하므로, 베이스 도커 이미지를 사용하는 대신 직접 이미지를 빌드하지 않을 이유가 없습니다(코드 양도 사실상 거의 같습니다 😅).
|
||||
|
||||
///
|
||||
|
||||
@@ -600,7 +600,7 @@ Kubernetes를 사용한다면, 이는 아마도 [Init Container](https://kuberne
|
||||
|
||||
## `uv`를 사용하는 도커 이미지 { #docker-image-with-uv }
|
||||
|
||||
프로젝트를 설치하고 관리하기 위해 [uv](https://github.com/astral-sh/uv)를 사용한다면, [uv Docker guide](https://docs.astral.sh/uv/guides/integration/docker/)를 따를 수 있습니다.
|
||||
프로젝트를 설치하고 관리하기 위해 [uv](https://github.com/astral-sh/uv)를 사용한다면, [uv Docker 가이드](https://docs.astral.sh/uv/guides/integration/docker/)를 따를 수 있습니다.
|
||||
|
||||
## 요약 { #recap }
|
||||
|
||||
|
||||
@@ -1,26 +1,6 @@
|
||||
# FastAPI Cloud { #fastapi-cloud }
|
||||
|
||||
**한 번의 명령**으로 FastAPI 앱을 [FastAPI Cloud](https://fastapicloud.com)에 배포할 수 있습니다. 아직이라면 대기자 명단에 등록해 보세요. 🚀
|
||||
|
||||
## 로그인하기 { #login }
|
||||
|
||||
먼저 **FastAPI Cloud** 계정이 이미 있는지 확인하세요(대기자 명단에서 초대해 드렸을 거예요 😉).
|
||||
|
||||
그다음 로그인합니다:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 배포하기 { #deploy }
|
||||
|
||||
이제 **한 번의 명령**으로 앱을 배포합니다:
|
||||
**한 번의 명령**으로 FastAPI 앱을 [FastAPI Cloud](https://fastapicloud.com)에 배포할 수 있습니다. 🚀
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -36,6 +16,8 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
</div>
|
||||
|
||||
CLI가 FastAPI 애플리케이션을 자동으로 감지하여 클라우드에 배포합니다. 로그인되어 있지 않다면, 인증을 완료할 수 있도록 브라우저가 자동으로 열립니다.
|
||||
|
||||
이게 전부입니다! 이제 해당 URL에서 앱에 접근할 수 있습니다. ✨
|
||||
|
||||
## FastAPI Cloud 소개 { #about-fastapi-cloud }
|
||||
|
||||
@@ -14,7 +14,7 @@ HTTPS는 그냥 “켜져 있거나” 아니면 “꺼져 있는” 것이라
|
||||
|
||||
이제 **개발자 관점**에서 HTTPS를 생각할 때 염두에 두어야 할 여러 가지가 있습니다:
|
||||
|
||||
* HTTPS를 사용하려면, **서버**가 **제3자**가 발급한 **"인증서(certificates)"**를 **보유**해야 합니다.
|
||||
* HTTPS를 사용하려면, **서버**가 **제3자**가 생성한 **"인증서(certificates)"**를 **보유**해야 합니다.
|
||||
* 이 인증서는 실제로 '생성'되는 것이 아니라 제3자로부터 **발급/획득**하는 것입니다.
|
||||
* 인증서에는 **유효 기간**이 있습니다.
|
||||
* 즉, **만료**됩니다.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 서버를 수동으로 실행하기 { #run-a-server-manually }
|
||||
|
||||
## `fastapi run` 명령 사용하기 { #use-the-fastapi-run-command }
|
||||
## `fastapi run` 명령어 사용하기 { #use-the-fastapi-run-command }
|
||||
|
||||
요약하면, `fastapi run`을 사용해 FastAPI 애플리케이션을 서비스하세요:
|
||||
|
||||
@@ -40,7 +40,7 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
|
||||
|
||||
대부분의 경우에는 이것으로 동작합니다. 😎
|
||||
|
||||
예를 들어 이 명령은 컨테이너나 서버 등에서 **FastAPI** 앱을 시작할 때 사용할 수 있습니다.
|
||||
예를 들어 이 명령어는 컨테이너나 서버 등에서 **FastAPI** 애플리케이션을 시작할 때 사용할 수 있습니다.
|
||||
|
||||
## ASGI 서버 { #asgi-servers }
|
||||
|
||||
@@ -48,7 +48,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** 애플리케이션(또는 다른 ASGI 애플리케이션)을 실행하기 위해 필요한 핵심 요소는 **Uvicorn** 같은 ASGI 서버 프로그램입니다. `fastapi` 명령에는 기본으로 이것이 포함되어 있습니다.
|
||||
원격 서버 머신에서 **FastAPI** 애플리케이션(또는 다른 ASGI 애플리케이션)을 실행하기 위해 필요한 핵심 요소는 **Uvicorn** 같은 ASGI 서버 프로그램입니다. `fastapi` 명령어에는 기본으로 이것이 포함되어 있습니다.
|
||||
|
||||
다음을 포함해 여러 대안이 있습니다:
|
||||
|
||||
@@ -56,7 +56,6 @@ FastAPI는 <abbr title="Asynchronous Server Gateway Interface - 비동기 서버
|
||||
* [Hypercorn](https://hypercorn.readthedocs.io/): HTTP/2 및 Trio 등 여러 기능과 호환되는 ASGI 서버.
|
||||
* [Daphne](https://github.com/django/daphne): Django Channels를 위해 만들어진 ASGI 서버.
|
||||
* [Granian](https://github.com/emmett-framework/granian): Python 애플리케이션을 위한 Rust HTTP 서버.
|
||||
* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit은 가볍고 다용도로 사용할 수 있는 웹 애플리케이션 런타임입니다.
|
||||
|
||||
## 서버 머신과 서버 프로그램 { #server-machine-and-server-program }
|
||||
|
||||
@@ -70,7 +69,7 @@ FastAPI는 <abbr title="Asynchronous Server Gateway Interface - 비동기 서버
|
||||
|
||||
## 서버 프로그램 설치하기 { #install-the-server-program }
|
||||
|
||||
FastAPI를 설치하면 프로덕션 서버인 Uvicorn이 함께 설치되며, `fastapi run` 명령으로 시작할 수 있습니다.
|
||||
FastAPI를 설치하면 프로덕션 서버인 Uvicorn이 함께 설치되며, `fastapi run` 명령어로 시작할 수 있습니다.
|
||||
|
||||
하지만 ASGI 서버를 수동으로 설치할 수도 있습니다.
|
||||
|
||||
@@ -116,7 +115,7 @@ $ uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
/// note | 참고
|
||||
|
||||
`uvicorn main:app` 명령은 다음을 가리킵니다:
|
||||
`uvicorn main:app` 명령어는 다음을 가리킵니다:
|
||||
|
||||
* `main`: 파일 `main.py`(Python "module").
|
||||
* `app`: `main.py` 안에서 `app = FastAPI()` 라인으로 생성된 객체.
|
||||
@@ -129,7 +128,7 @@ from main import app
|
||||
|
||||
///
|
||||
|
||||
각 ASGI 서버 프로그램의 대안도 비슷한 명령을 갖고 있으며, 자세한 내용은 각자의 문서를 참고하세요.
|
||||
각 ASGI 서버 프로그램의 대안도 비슷한 명령어를 갖고 있으며, 자세한 내용은 각자의 문서를 참고하세요.
|
||||
|
||||
/// warning | 경고
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
여기서는 `fastapi` 명령어를 사용하거나 `uvicorn` 명령어를 직접 사용해서, **워커 프로세스**와 함께 **Uvicorn**을 사용하는 방법을 보여드리겠습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
Docker나 Kubernetes 같은 컨테이너를 사용하고 있다면, 다음 장인 [컨테이너에서의 FastAPI - 도커](docker.md)에서 더 자세히 설명하겠습니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 에디터 지원 { #editor-support }
|
||||
|
||||
|
||||
공식 [FastAPI 확장](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode)은 FastAPI 개발 워크플로우를 강화해 줍니다. *경로 처리* 탐색 및 이동, FastAPI Cloud 배포, 실시간 로그 스트리밍을 제공합니다.
|
||||
|
||||
확장에 대한 자세한 내용은 [GitHub 저장소](https://github.com/fastapi/fastapi-vscode)의 README를 참고하세요.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 환경 변수 { #environment-variables }
|
||||
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
만약 "환경 변수"가 무엇이고, 어떻게 사용하는지 알고 계시다면, 이 챕터를 스킵하셔도 좋습니다.
|
||||
|
||||
@@ -63,7 +63,7 @@ second_user_data = {
|
||||
my_second_user: User = User(**second_user_data)
|
||||
```
|
||||
|
||||
/// note
|
||||
/// note | 참고
|
||||
|
||||
`**second_user_data`는 다음을 의미합니다:
|
||||
|
||||
@@ -172,8 +172,8 @@ FastAPI는 사용하기 매우 쉽지만, 매우 강력한 <dfn title='또한
|
||||
* HTTPX 기반 테스트 클라이언트.
|
||||
* **CORS**, GZip, 정적 파일, 스트리밍 응답.
|
||||
* **세션과 쿠키** 지원.
|
||||
* 100% test coverage.
|
||||
* 100% type annotated codebase.
|
||||
* 100% 테스트 커버리지.
|
||||
* 100% 타입 어노테이션 코드 베이스.
|
||||
|
||||
## Pydantic 기능 { #pydantic-features }
|
||||
|
||||
@@ -198,4 +198,4 @@ FastAPI는 사용하기 매우 쉽지만, 매우 강력한 <dfn title='또한
|
||||
* 깊게 **중첩된 JSON** 객체를 가질 수 있으며, 이를 모두 검증하고 주석을 달 수 있습니다.
|
||||
* **확장 가능**:
|
||||
* Pydantic은 사용자 정의 데이터 타입을 정의할 수 있게 하거나, validator decorator가 붙은 모델 메서드로 검증을 확장할 수 있습니다.
|
||||
* 100% test coverage.
|
||||
* 100% 테스트 커버리지.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 도움 { #help }
|
||||
|
||||
|
||||
FastAPI를 돕거나 FastAPI에 대한 도움을 받고 싶으신가요?
|
||||
|
||||
아주 간단하게 돕고 도움을 받을 수 있는 방법이 있습니다.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
추가적인 [Swagger UI 매개변수](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/)를 구성할 수 있습니다.
|
||||
|
||||
구성을 하려면, `FastAPI()` 앱 객체를 생성할 때 또는 `get_swagger_ui_html()` 함수에 `swagger_ui_parameters` 인수를 전달하십시오.
|
||||
구성을 하려면, `FastAPI()` 애플리케이션 객체를 생성할 때 또는 `get_swagger_ui_html()` 함수에 `swagger_ui_parameters` 인수를 전달하십시오.
|
||||
|
||||
`swagger_ui_parameters`는 Swagger UI에 직접 전달된 구성을 포함하는 딕셔너리를 받습니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 커스텀 Request 및 APIRoute 클래스 { #custom-request-and-apiroute-class }
|
||||
|
||||
|
||||
일부 경우에는 `Request`와 `APIRoute` 클래스에서 사용되는 로직을 오버라이드하고 싶을 수 있습니다.
|
||||
|
||||
특히, 이는 middleware에 있는 로직의 좋은 대안이 될 수 있습니다.
|
||||
|
||||
@@ -25,9 +25,17 @@
|
||||
* `openapi_version`: 사용되는 OpenAPI 스펙 버전. 기본값은 최신인 `3.1.0`.
|
||||
* `summary`: API에 대한 짧은 요약.
|
||||
* `description`: API 설명. markdown을 포함할 수 있으며 문서에 표시됩니다.
|
||||
* `routes`: 라우트 목록. 각각 등록된 *경로 처리*입니다. `app.routes`에서 가져옵니다.
|
||||
* `routes`: 애플리케이션의 라우트. `app.routes`에서 가져옵니다. FastAPI는 이를 사용해 등록된 *경로 처리*를 수집하며, 포함된 라우터의 것까지 포함합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// tip | 기술 세부사항
|
||||
|
||||
`app.routes`는 더 하위 수준의 라우트 트리입니다. 포함된 라우터를 위해 FastAPI가 내부적으로 사용하는 라우트 후보들을 포함할 수 있으며, 최종 `APIRoute` 객체만 있는 것은 아닙니다.
|
||||
|
||||
`app.routes`를 그대로 `get_openapi()`에 전달해도 됩니다. FastAPI가 그 라우트 트리를 순회하여 실제 유효한 경로 처리들을 수집합니다.
|
||||
|
||||
///
|
||||
|
||||
/// note | 참고
|
||||
|
||||
`summary` 파라미터는 OpenAPI 3.1.0 이상에서 사용할 수 있으며, FastAPI 0.99.0 이상에서 지원됩니다.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**FastAPI**는 **ASGI** 표준을 기반으로 하므로, ASGI와도 호환되는 어떤 **GraphQL** 라이브러리든 매우 쉽게 통합할 수 있습니다.
|
||||
|
||||
같은 애플리케이션에서 일반 FastAPI **경로 처리**와 GraphQL을 함께 조합할 수 있습니다.
|
||||
같은 애플리케이션에서 일반 FastAPI *경로 처리*와 GraphQL을 함께 조합할 수 있습니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ FastAPI 0.119.0 버전에서는 v2로의 마이그레이션을 쉽게 하기 위
|
||||
|
||||
FastAPI 0.126.0 버전에서는 Pydantic v1 지원을 중단했지만, `pydantic.v1`은 잠시 동안 계속 지원했습니다.
|
||||
|
||||
FastAPI 0.128.0 버전에서는 `pydantic.v1` 지원도 중단했으므로, FastAPI의 최신 버전은 Pydantic v2를 필요로 합니다.
|
||||
|
||||
/// warning | 경고
|
||||
|
||||
Pydantic 팀은 최신 Python 버전에서 Pydantic v1 지원을 중단했으며, 시작 버전은 **Python 3.14**입니다.
|
||||
@@ -54,6 +56,16 @@ Pydantic v2는 Pydantic v1의 모든 것을 서브모듈 `pydantic.v1`로 포함
|
||||
|
||||
### v2 안의 Pydantic v1에 대한 FastAPI 지원 { #fastapi-support-for-pydantic-v1-in-v2 }
|
||||
|
||||
/// warning | 경고
|
||||
|
||||
`pydantic.v1` 모델에 대한 이 FastAPI 지원은 **FastAPI 0.119.0**에서 추가되었고 **FastAPI 0.128.0**에서 제거되었습니다. 이는 Pydantic v2로의 마이그레이션을 위한 임시 도움 기능이었습니다.
|
||||
|
||||
현재 버전의 FastAPI에서는 앱에서 `pydantic.v1` 모델을 사용하면 오류가 발생합니다.
|
||||
|
||||
이 섹션의 나머지 부분은 해당 오래된 버전에서만 사용할 수 있는 임시 지원을 설명합니다.
|
||||
|
||||
///
|
||||
|
||||
FastAPI 0.119.0부터는 v2로의 마이그레이션을 쉽게 하기 위해, Pydantic v2 내부의 Pydantic v1에 대해서도 부분적인 지원이 있습니다.
|
||||
|
||||
따라서 Pydantic을 최신 v2로 업그레이드하고, import를 `pydantic.v1` 서브모듈을 사용하도록 바꾸면, 많은 경우 그대로 동작합니다.
|
||||
@@ -122,6 +134,12 @@ Pydantic v1 모델과 함께 `Body`, `Query`, `Form` 등 파라미터용 FastAPI
|
||||
|
||||
### 단계적으로 마이그레이션하기 { #migrate-in-steps }
|
||||
|
||||
/// warning | 경고
|
||||
|
||||
아래에 설명된 같은 앱에서 Pydantic v1과 v2 모델을 모두 사용하는 점진적 마이그레이션은 **FastAPI 0.119.0부터 0.127.x까지**에서만 동작합니다. 이는 **FastAPI 0.128.0**에서 제거되었으며, 최신 버전은 **Pydantic v2** 모델을 필요로 합니다.
|
||||
|
||||
///
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
먼저 `bump-pydantic`로 시도해 보세요. 테스트가 통과하고 잘 동작한다면, 한 번의 명령으로 끝입니다. ✨
|
||||
|
||||
@@ -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**와 일관성을 제공할 수 있습니다. 🎉
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
그런 경우에는, **FastAPI**에서 `separate_input_output_schemas=False` 파라미터로 이 기능을 비활성화할 수 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`separate_input_output_schemas` 지원은 FastAPI `0.102.0`에 추가되었습니다. 🤓
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
|
||||
|
||||
<div class="only-github" markdown="1">
|
||||
|
||||
"_[...] 저는 요즘 **FastAPI**를 많이 사용하고 있습니다. [...] 사실 우리 팀의 **마이크로소프트 ML 서비스** 전부를 바꿀 계획입니다. 그중 일부는 핵심 **Windows**와 몇몇의 **Office** 제품들이 통합되고 있습니다._"
|
||||
"_[...] 저는 요즘 **FastAPI**를 많이 사용하고 있습니다. [...] 사실 우리 팀의 **마이크로소프트 ML 서비스** 전부에 사용할 계획입니다. 그중 일부는 핵심 **Windows** 제품과 일부 **Office** 제품에 통합되고 있습니다._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div>
|
||||
|
||||
@@ -137,13 +137,13 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix**는 우리의 오픈 소스 배포판인 **위기 관리** 오케스트레이션 프레임워크를 발표할 수 있어 기쁩니다: 바로 **Dispatch**입니다! [**FastAPI**로 빌드]_"
|
||||
"_**Netflix**는 우리의 **위기 관리** 오케스트레이션 프레임워크인 **Dispatch**의 오픈 소스 공개를 발표하게 되어 기쁩니다! [**FastAPI**로 빌드]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_프로덕션 Python API를 만들고자 한다면, 저는 **FastAPI**를 강력히 추천합니다. **아름답게 설계**되었고, **사용이 간단**하며, **확장성이 매우 뛰어나** 우리의 API 우선 개발 전략에서 **핵심 구성 요소**가 되었습니다._"
|
||||
"_프로덕션 Python API를 만들고자 한다면, 저는 **FastAPI**를 강력히 추천합니다. **아름답게 설계**되었고, **사용이 간단**하며, **확장성이 매우 뛰어나** 우리의 API 우선 개발 전략에서 **핵심 구성 요소**가 되었고, 우리의 Virtual TAC Engineer와 같은 여러 자동화와 서비스들을 추진하고 있습니다._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
|
||||
|
||||
@@ -192,7 +192,7 @@ $ pip install "fastapi[standard]"
|
||||
|
||||
</div>
|
||||
|
||||
**Note**: 모든 터미널에서 동작하도록 `"fastapi[standard]"`를 따옴표로 감싸 넣었는지 확인하세요.
|
||||
**참고**: 모든 터미널에서 동작하도록 `"fastapi[standard]"`를 따옴표로 감싸 넣었는지 확인하세요.
|
||||
|
||||
## 예제 { #example }
|
||||
|
||||
@@ -237,9 +237,9 @@ async def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
**참고**:
|
||||
|
||||
잘 모르겠다면, ["급하세요?"](https://fastapi.tiangolo.com/ko/async/#in-a-hurry) 섹션을 확인해 보십시오.
|
||||
잘 모르겠다면, 문서의 [`async`와 `await`](https://fastapi.tiangolo.com/ko/async/#in-a-hurry)에 관한 _"급하세요?"_ 섹션을 확인해 보십시오.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -492,9 +492,7 @@ item: Item
|
||||
|
||||
### 앱 배포하기(선택 사항) { #deploy-your-app-optional }
|
||||
|
||||
선택적으로 FastAPI 앱을 [FastAPI Cloud](https://fastapicloud.com)에 배포할 수 있습니다. 아직이라면 대기자 명단에 등록해 보세요. 🚀
|
||||
|
||||
이미 **FastAPI Cloud** 계정이 있다면(대기자 명단에서 초대해 드렸습니다 😉), 한 번의 명령으로 애플리케이션을 배포할 수 있습니다.
|
||||
선택적으로 FastAPI 앱을 한 번의 명령어로 [FastAPI Cloud](https://fastapicloud.com)에 배포할 수 있습니다. 🚀
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -510,6 +508,8 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
</div>
|
||||
|
||||
CLI가 여러분의 FastAPI 애플리케이션을 자동으로 감지하여 클라우드에 배포합니다. 로그인되어 있지 않다면, 인증을 완료하기 위해 브라우저가 열립니다.
|
||||
|
||||
이게 전부입니다! 이제 해당 URL에서 앱에 접근할 수 있습니다. ✨
|
||||
|
||||
#### FastAPI Cloud 소개 { #about-fastapi-cloud }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Full Stack FastAPI 템플릿 { #full-stack-fastapi-template }
|
||||
|
||||
|
||||
템플릿은 일반적으로 특정 설정과 함께 제공되지만, 유연하고 커스터마이징이 가능하게 디자인 되었습니다. 이 특성들은 여러분이 프로젝트의 요구사항에 맞춰 수정, 적용을 할 수 있게 해주고, 템플릿이 완벽한 시작점이 되게 해줍니다. 🏁
|
||||
|
||||
많은 초기 설정, 보안, 데이터베이스 및 일부 API 엔드포인트가 이미 준비되어 있으므로, 여러분은 이 템플릿을 시작하는 데 사용할 수 있습니다.
|
||||
|
||||
@@ -124,7 +124,7 @@ John Doe
|
||||
|
||||
이것은 **FastAPI**와 함께 사용할 때도 주요 위치입니다.
|
||||
|
||||
### Simple 타입 { #simple-types }
|
||||
### 간단한 타입 { #simple-types }
|
||||
|
||||
`str`뿐 아니라 모든 파이썬 표준 타입을 선언할 수 있습니다.
|
||||
|
||||
@@ -287,7 +287,7 @@ Pydantic 공식 문서의 예시:
|
||||
|
||||
/// note | 참고
|
||||
|
||||
Pydantic에 대해 더 알아보려면 [문서를 확인하세요](https://docs.pydantic.dev/).
|
||||
더 알아보려면 [Pydantic 문서를 확인하세요](https://docs.pydantic.dev/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -17,16 +17,16 @@ Flask를 사용해 보셨다면, 이는 Flask의 Blueprints에 해당하는 개
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ ├── dependencies.py
|
||||
│ └── routers
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── items.py
|
||||
│ │ └── users.py
|
||||
│ └── internal
|
||||
│ ├── __init__.py
|
||||
│ └── admin.py
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ ├── dependencies.py
|
||||
│ └── routers
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── items.py
|
||||
│ │ └── users.py
|
||||
│ └── internal
|
||||
│ ├── __init__.py
|
||||
│ └── admin.py
|
||||
```
|
||||
|
||||
/// tip | 팁
|
||||
@@ -75,11 +75,11 @@ from app.routers import items
|
||||
|
||||
사용자만 처리하는 전용 파일이 `/app/routers/users.py`의 submodule이라고 해봅시다.
|
||||
|
||||
코드를 정리하기 위해 사용자와 관련된 *path operations*를 나머지 코드와 분리해 두고 싶을 것입니다.
|
||||
코드를 정리하기 위해 사용자와 관련된 *경로 처리*를 나머지 코드와 분리해 두고 싶을 것입니다.
|
||||
|
||||
하지만 이것은 여전히 같은 **FastAPI** 애플리케이션/웹 API의 일부입니다(같은 "Python Package"의 일부입니다).
|
||||
|
||||
`APIRouter`를 사용해 해당 모듈의 *path operations*를 만들 수 있습니다.
|
||||
`APIRouter`를 사용해 해당 모듈의 *경로 처리*를 만들 수 있습니다.
|
||||
|
||||
### `APIRouter` import하기 { #import-apirouter }
|
||||
|
||||
@@ -87,9 +87,9 @@ from app.routers import items
|
||||
|
||||
{* ../../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 }
|
||||
### `APIRouter`로 *경로 처리* 만들기 { #path-operations-with-apirouter }
|
||||
|
||||
그 다음 이를 사용해 *path operations*를 선언합니다.
|
||||
그 다음 이를 사용해 *경로 처리*를 선언합니다.
|
||||
|
||||
`FastAPI` 클래스를 사용할 때와 동일한 방식으로 사용합니다:
|
||||
|
||||
@@ -107,7 +107,7 @@ from app.routers import items
|
||||
|
||||
///
|
||||
|
||||
이제 이 `APIRouter`를 메인 `FastAPI` 앱에 포함(include)할 것이지만, 먼저 dependencies와 다른 `APIRouter` 하나를 확인해 보겠습니다.
|
||||
이제 이 `APIRouter`를 메인 `FastAPI` 애플리케이션에 포함(include)할 것이지만, 먼저 dependencies와 다른 `APIRouter` 하나를 확인해 보겠습니다.
|
||||
|
||||
## Dependencies { #dependencies }
|
||||
|
||||
@@ -131,7 +131,7 @@ from app.routers import items
|
||||
|
||||
애플리케이션의 "items"를 처리하는 전용 endpoint들도 `app/routers/items.py` 모듈에 있다고 해봅시다.
|
||||
|
||||
여기에는 다음에 대한 *path operations*가 있습니다:
|
||||
여기에는 다음에 대한 *경로 처리*가 있습니다:
|
||||
|
||||
* `/items/`
|
||||
* `/items/{item_id}`
|
||||
@@ -140,18 +140,18 @@ from app.routers import items
|
||||
|
||||
하지만 우리는 조금 더 똑똑하게, 코드를 약간 단순화하고 싶습니다.
|
||||
|
||||
이 모듈의 모든 *path operations*에는 다음이 동일하게 적용됩니다:
|
||||
이 모듈의 모든 *경로 처리*에는 다음이 동일하게 적용됩니다:
|
||||
|
||||
* 경로 `prefix`: `/items`.
|
||||
* `tags`: (태그 하나: `items`).
|
||||
* 추가 `responses`.
|
||||
* `dependencies`: 모두 우리가 만든 `X-Token` dependency가 필요합니다.
|
||||
|
||||
따라서 각 *path operation*마다 매번 모두 추가하는 대신, `APIRouter`에 한 번에 추가할 수 있습니다.
|
||||
따라서 각 *경로 처리*마다 매번 모두 추가하는 대신, `APIRouter`에 한 번에 추가할 수 있습니다.
|
||||
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
||||
|
||||
각 *path operation*의 경로는 다음처럼 `/`로 시작해야 하므로:
|
||||
각 *경로 처리*의 경로는 다음처럼 `/`로 시작해야 하므로:
|
||||
|
||||
```Python hl_lines="1"
|
||||
@router.get("/{item_id}")
|
||||
@@ -163,13 +163,13 @@ async def read_item(item_id: str):
|
||||
|
||||
따라서 이 경우 prefix는 `/items`입니다.
|
||||
|
||||
또한 이 router에 포함된 모든 *path operations*에 적용될 `tags` 목록과 추가 `responses`도 넣을 수 있습니다.
|
||||
또한 이 router에 포함된 모든 *경로 처리*에 적용될 `tags` 목록과 추가 `responses`도 넣을 수 있습니다.
|
||||
|
||||
그리고 router의 모든 *path operations*에 추가될 `dependencies` 목록도 추가할 수 있으며, 해당 경로들로 들어오는 각 요청마다 실행/해결됩니다.
|
||||
그리고 router의 모든 *경로 처리*에 추가될 `dependencies` 목록도 추가할 수 있으며, 해당 경로들로 들어오는 각 요청마다 실행/해결됩니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
[*path operation decorator의 dependencies*](dependencies/dependencies-in-path-operation-decorators.md)와 마찬가지로, *path operation function*에 어떤 값도 전달되지 않습니다.
|
||||
[*경로 처리 데코레이터*의 dependencies](dependencies/dependencies-in-path-operation-decorators.md)와 마찬가지로, *경로 처리 함수*에 어떤 값도 전달되지 않습니다.
|
||||
|
||||
///
|
||||
|
||||
@@ -183,14 +183,14 @@ async def read_item(item_id: str):
|
||||
* 단일 문자열 `"items"`를 포함하는 태그 목록으로 표시됩니다.
|
||||
* 이 "tags"는 자동 대화형 문서 시스템(OpenAPI 사용)에 특히 유용합니다.
|
||||
* 모두 미리 정의된 `responses`를 포함합니다.
|
||||
* 이 모든 *path operations*는 실행되기 전에 `dependencies` 목록이 평가/실행됩니다.
|
||||
* 특정 *path operation*에 dependencies를 추가로 선언하면 **그것들도 실행됩니다**.
|
||||
* router dependencies가 먼저 실행되고, 그 다음에 [decorator의 `dependencies`](dependencies/dependencies-in-path-operation-decorators.md), 그리고 일반 파라미터 dependencies가 실행됩니다.
|
||||
* 이 모든 *경로 처리*는 실행되기 전에 `dependencies` 목록이 평가/실행됩니다.
|
||||
* 특정 *경로 처리*에 dependencies를 추가로 선언하면 **그것들도 실행됩니다**.
|
||||
* router dependencies가 먼저 실행되고, 그 다음에 [데코레이터의 `dependencies`](dependencies/dependencies-in-path-operation-decorators.md), 그리고 일반 파라미터 dependencies가 실행됩니다.
|
||||
* [`scopes`가 있는 `Security` dependencies](../advanced/security/oauth2-scopes.md)도 추가할 수 있습니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
`APIRouter`에 `dependencies`를 두는 것은 예를 들어 전체 *path operations* 그룹에 인증을 요구할 때 사용할 수 있습니다. 각 경로 처리에 개별적으로 dependencies를 추가하지 않아도 됩니다.
|
||||
`APIRouter`에 `dependencies`를 두는 것은 예를 들어 전체 *경로 처리* 그룹에 인증을 요구할 때 사용할 수 있습니다. 각 경로 처리에 개별적으로 dependencies를 추가하지 않아도 됩니다.
|
||||
|
||||
///
|
||||
|
||||
@@ -232,7 +232,7 @@ from .dependencies import get_token_header
|
||||
|
||||
하지만 그 파일은 존재하지 않습니다. dependencies는 `app/dependencies.py` 파일에 있습니다.
|
||||
|
||||
우리 앱/파일 구조를 다시 떠올려 보세요:
|
||||
우리 애플리케이션/파일 구조를 다시 떠올려 보세요:
|
||||
|
||||
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
||||
|
||||
@@ -271,13 +271,13 @@ from ...dependencies import get_token_header
|
||||
|
||||
이는 `app/` 위쪽의 어떤 package(자신의 `__init__.py` 파일 등을 가진)에 대한 참조가 됩니다. 하지만 우리는 그런 것이 없습니다. 그래서 이 예시에서는 에러가 발생합니다. 🚨
|
||||
|
||||
이제 어떻게 동작하는지 알았으니, 앱이 얼마나 복잡하든 상대 import를 사용할 수 있습니다. 🤓
|
||||
이제 어떻게 동작하는지 알았으니, 애플리케이션이 얼마나 복잡하든 상대 import를 사용할 수 있습니다. 🤓
|
||||
|
||||
### 커스텀 `tags`, `responses`, `dependencies` 추가하기 { #add-some-custom-tags-responses-and-dependencies }
|
||||
|
||||
`APIRouter`에 이미 prefix `/items`와 `tags=["items"]`를 추가했기 때문에 각 *path operation*에 이를 추가하지 않습니다.
|
||||
`APIRouter`에 이미 prefix `/items`와 `tags=["items"]`를 추가했기 때문에 각 *경로 처리*에 이를 추가하지 않습니다.
|
||||
|
||||
하지만 특정 *path operation*에만 적용될 _추가_ `tags`를 더할 수도 있고, 그 *path operation* 전용의 추가 `responses`도 넣을 수 있습니다:
|
||||
하지만 특정 *경로 처리*에만 적용될 _추가_ `tags`를 더할 수도 있고, 그 *경로 처리* 전용의 추가 `responses`도 넣을 수 있습니다:
|
||||
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
|
||||
|
||||
@@ -396,9 +396,9 @@ from .routers.users import router
|
||||
|
||||
/// note | 기술 세부사항
|
||||
|
||||
내부적으로는 `APIRouter`에 선언된 각 *path operation*마다 *path operation*을 실제로 생성합니다.
|
||||
FastAPI는 메인 애플리케이션에 router를 포함해도 원래의 `APIRouter`와 그 `APIRoute`들을 활성 상태로 유지합니다.
|
||||
|
||||
즉, 내부적으로는 모든 것이 동일한 하나의 앱인 것처럼 동작합니다.
|
||||
즉, 커스텀 `APIRouter`와 `APIRoute` 서브클래스가 포함된 이후에도 계속 작동할 수 있습니다.
|
||||
|
||||
///
|
||||
|
||||
@@ -406,7 +406,7 @@ from .routers.users import router
|
||||
|
||||
router를 포함(include)할 때 성능을 걱정할 필요는 없습니다.
|
||||
|
||||
이 작업은 마이크로초 단위이며 시작 시에만 발생합니다.
|
||||
이 기능은 매우 가볍게 설계되었고 각 요청에 오버헤드를 추가하지 않도록 되어 있습니다.
|
||||
|
||||
따라서 성능에 영향을 주지 않습니다. ⚡
|
||||
|
||||
@@ -416,13 +416,13 @@ router를 포함(include)할 때 성능을 걱정할 필요는 없습니다.
|
||||
|
||||
이제 조직에서 `app/internal/admin.py` 파일을 받았다고 가정해 봅시다.
|
||||
|
||||
여기에는 조직에서 여러 프로젝트 간에 공유하는 관리자용 *path operations*가 있는 `APIRouter`가 들어 있습니다.
|
||||
여기에는 조직에서 여러 프로젝트 간에 공유하는 관리자용 *경로 처리*가 있는 `APIRouter`가 들어 있습니다.
|
||||
|
||||
이 예시에서는 매우 단순하게 만들겠습니다. 하지만 조직 내 다른 프로젝트와 공유되기 때문에, 이를 수정할 수 없어 `prefix`, `dependencies`, `tags` 등을 `APIRouter`에 직접 추가할 수 없다고 해봅시다:
|
||||
|
||||
{* ../../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`를 포함할 때 커스텀 `prefix`를 지정해 모든 *경로 처리*가 `/admin`으로 시작하게 하고, 이 프로젝트에서 이미 가진 `dependencies`로 보호하고, `tags`와 `responses`도 포함하고 싶습니다.
|
||||
|
||||
원래 `APIRouter`를 수정하지 않고도 `app.include_router()`에 파라미터를 전달해서 이를 선언할 수 있습니다:
|
||||
|
||||
@@ -430,26 +430,26 @@ router를 포함(include)할 때 성능을 걱정할 필요는 없습니다.
|
||||
|
||||
이렇게 하면 원래 `APIRouter`는 수정되지 않으므로, 조직 내 다른 프로젝트에서도 동일한 `app/internal/admin.py` 파일을 계속 공유할 수 있습니다.
|
||||
|
||||
결과적으로 우리 앱에서 `admin` 모듈의 각 *path operations*는 다음을 갖게 됩니다:
|
||||
결과적으로 우리 애플리케이션에서 `admin` 모듈의 각 *경로 처리*는 다음을 갖게 됩니다:
|
||||
|
||||
* prefix `/admin`.
|
||||
* tag `admin`.
|
||||
* dependency `get_token_header`.
|
||||
* 응답 `418`. 🍵
|
||||
|
||||
하지만 이는 우리 앱에서 그 `APIRouter`에만 영향을 주며, 이를 사용하는 다른 코드에는 영향을 주지 않습니다.
|
||||
하지만 이는 우리 애플리케이션에서 그 `APIRouter`에만 영향을 주며, 이를 사용하는 다른 코드에는 영향을 주지 않습니다.
|
||||
|
||||
따라서 다른 프로젝트들은 같은 `APIRouter`를 다른 인증 방식으로 사용할 수도 있습니다.
|
||||
|
||||
### *path operation* 포함하기 { #include-a-path-operation }
|
||||
### *경로 처리* 포함하기 { #include-a-path-operation }
|
||||
|
||||
*path operations*를 `FastAPI` 앱에 직접 추가할 수도 있습니다.
|
||||
*경로 처리*를 `FastAPI` 애플리케이션에 직접 추가할 수도 있습니다.
|
||||
|
||||
여기서는 가능하다는 것을 보여주기 위해... 그냥 해봅니다 🤷:
|
||||
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
|
||||
|
||||
그리고 `app.include_router()`로 추가한 다른 모든 *path operations*와 함께 올바르게 동작합니다.
|
||||
그리고 `app.include_router()`로 추가한 다른 모든 *경로 처리*와 함께 올바르게 동작합니다.
|
||||
|
||||
/// note | 매우 기술적인 세부사항
|
||||
|
||||
@@ -459,9 +459,9 @@ router를 포함(include)할 때 성능을 걱정할 필요는 없습니다.
|
||||
|
||||
`APIRouter`는 "mount"되는 것이 아니며, 애플리케이션의 나머지 부분과 격리되어 있지 않습니다.
|
||||
|
||||
이는 OpenAPI 스키마와 사용자 인터페이스에 그들의 *path operations*를 포함시키고 싶기 때문입니다.
|
||||
이는 OpenAPI 스키마와 사용자 인터페이스에 그들의 *경로 처리*를 포함시키기 위함입니다.
|
||||
|
||||
나머지와 독립적으로 격리해 "mount"할 수 없으므로, *path operations*는 직접 포함되는 것이 아니라 "clone"(재생성)됩니다.
|
||||
FastAPI는 원래의 router와 경로 처리를 활성 상태로 유지하고, 요청을 처리하고 OpenAPI를 생성할 때 router의 prefix, dependencies, tags, responses 및 기타 메타데이터를 결합합니다.
|
||||
|
||||
///
|
||||
|
||||
@@ -480,7 +480,7 @@ entrypoint = "app.main:app"
|
||||
from app.main import app
|
||||
```
|
||||
|
||||
이렇게 하면 `fastapi` 명령어가 여러분의 앱이 어디에 있는지 알 수 있습니다.
|
||||
이렇게 하면 `fastapi` 명령어가 여러분의 애플리케이션이 어디에 있는지 알 수 있습니다.
|
||||
|
||||
/// Note | 참고
|
||||
|
||||
@@ -498,7 +498,7 @@ $ fastapi dev app/main.py
|
||||
|
||||
## 자동 API 문서 확인하기 { #check-the-automatic-api-docs }
|
||||
|
||||
이제 앱을 실행하세요:
|
||||
이제 애플리케이션을 실행하세요:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -532,4 +532,16 @@ $ fastapi dev
|
||||
router.include_router(other_router)
|
||||
```
|
||||
|
||||
`FastAPI` 앱에 `router`를 포함하기 전에 수행해야 하며, 그래야 `other_router`의 *path operations*도 함께 포함됩니다.
|
||||
`router`를 `FastAPI` 애플리케이션에 포함하기 전이든 후든, 어느 시점에 해도 됩니다. FastAPI는 라우팅과 OpenAPI에 `other_router`의 *경로 처리*도 포함합니다.
|
||||
|
||||
나중에 router들에 추가된 *경로 처리*도 동일하게 적용됩니다. 이전에 수행한 포함을 통해서도 보이게 됩니다.
|
||||
|
||||
/// warning | 기술 세부사항
|
||||
|
||||
router를 포함한 뒤에 `router.routes`를 직접 변형하는 것은 피하세요. FastAPI는 router 포함을 실시간으로 처리하므로, 원래 router와 그 routes는 라우팅과 OpenAPI 생성의 일부로 남아 있습니다.
|
||||
|
||||
경로와 router를 추가할 때는 경로 처리 데코레이터와 `.include_router()` 같은 문서화된 API를 사용하세요.
|
||||
|
||||
`router.routes`는 최종 *경로 처리*의 평탄화된 목록이 아니라, route 정의와 포함된 router를 담는 하위 수준의 트리로 취급하고, 여기에 의존하지 마세요.
|
||||
|
||||
///
|
||||
|
||||
@@ -111,7 +111,7 @@ q: str | None = None
|
||||
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
|
||||
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`Body` 또한 `Query`, `Path` 그리고 이후에 볼 다른 것들과 마찬가지로 동일한 추가 검증과 메타데이터 매개변수를 모두 갖고 있습니다.
|
||||
|
||||
@@ -126,7 +126,7 @@ Pydantic 모델 `Item`에서 가져온 단일 `item` 본문 매개변수만 있
|
||||
하지만 추가 본문 매개변수를 선언할 때처럼, `item` 키를 가지고 그 안에 모델 내용이 들어 있는 JSON을 예상하게 하려면, `Body`의 특별한 매개변수 `embed`를 사용할 수 있습니다:
|
||||
|
||||
```Python
|
||||
item: Item = Body(embed=True)
|
||||
item: Annotated[Item, Body(embed=True)]
|
||||
```
|
||||
|
||||
다음과 같이요:
|
||||
|
||||
@@ -136,7 +136,7 @@ Pydantic 모델의 각 어트리뷰트는 타입을 갖습니다.
|
||||
}
|
||||
```
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`images` 키가 이제 이미지 객체 리스트를 갖는지 주목하세요.
|
||||
|
||||
@@ -148,7 +148,7 @@ Pydantic 모델의 각 어트리뷰트는 타입을 갖습니다.
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`Offer`가 `Item`의 리스트를 가지고, 그 `Item`이 다시 선택 사항인 `Image` 리스트를 갖는지 주목하세요
|
||||
|
||||
@@ -182,7 +182,7 @@ Pydantic 모델 대신 `dict`로 직접 작업한다면 이런 종류의 편집
|
||||
|
||||
또한 키는 어떤 타입이고 값은 다른 타입인 `dict`로 본문을 선언할 수 있습니다.
|
||||
|
||||
이렇게 하면 (Pydantic 모델을 사용하는 경우처럼) 유효한 필드/어트리뷰트 이름이 무엇인지 미리 알 필요가 없습니다.
|
||||
이렇게 하면 (Pydantic 모델을 사용하는 경우와 달리) 유효한 필드/어트리뷰트 이름이 무엇인지 미리 알 필요가 없습니다.
|
||||
|
||||
아직 모르는 키를 받으려는 경우에 유용합니다.
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
**요청** 본문을 선언하기 위해서 모든 강력함과 이점을 갖춘 [Pydantic](https://docs.pydantic.dev/) 모델을 사용합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
데이터를 보내기 위해, (좀 더 보편적인) `POST`, `PUT`, `DELETE` 혹은 `PATCH` 중에 하나를 사용하는 것이 좋습니다.
|
||||
데이터를 보내기 위해, `POST` (가장 일반적), `PUT`, `DELETE` 혹은 `PATCH` 중에 하나를 사용하는 것이 좋습니다.
|
||||
|
||||
`GET` 요청에 본문을 담아 보내는 것은 명세서에 정의되지 않은 행동입니다. 그럼에도 불구하고, 이 방식은 아주 복잡한/극한의 사용 상황에서만 FastAPI에 의해 지원됩니다.
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
## 편집기 지원 { #editor-support }
|
||||
|
||||
편집기에서, 함수 내에서 타입 힌트와 완성을 어디서나 (만약 Pydantic model 대신에 `dict`을 받을 경우 나타나지 않을 수 있습니다) 받을 수 있습니다:
|
||||
편집기에서, 함수 내에서 타입 힌트와 완성을 어디서나 (만약 Pydantic 모델 대신에 `dict`을 받을 경우 나타나지 않을 수 있습니다) 받을 수 있습니다:
|
||||
|
||||
<img src="/img/tutorial/body/image03.png">
|
||||
|
||||
@@ -141,14 +141,14 @@
|
||||
|
||||
**본문**, **경로** 그리고 **쿼리** 매개변수 모두 동시에 선언할 수도 있습니다.
|
||||
|
||||
**FastAPI**는 각각을 인지하고 데이터를 올바른 위치에 가져올 것입니다.
|
||||
**FastAPI**는 각각을 인지하고 데이터를 올바른 위치에서 가져올 것입니다.
|
||||
|
||||
{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
|
||||
|
||||
함수 매개변수는 다음을 따라서 인지하게 됩니다:
|
||||
|
||||
* 만약 매개변수가 **경로**에도 선언되어 있다면, 이는 경로 매개변수로 사용될 것입니다.
|
||||
* 만약 매개변수가 (`int`, `float`, `str`, `bool` 등과 같은) **유일한 타입**으로 되어있으면, **쿼리** 매개변수로 해석될 것입니다.
|
||||
* 만약 매개변수가 (`int`, `float`, `str`, `bool` 등과 같은) **단일 타입**으로 되어있으면, **쿼리** 매개변수로 해석될 것입니다.
|
||||
* 만약 매개변수가 **Pydantic 모델** 타입으로 선언되어 있으면, 요청 **본문**으로 해석될 것입니다.
|
||||
|
||||
/// note | 참고
|
||||
@@ -163,4 +163,4 @@ FastAPI는 `q`의 값이 필요없음을 기본 값 `= None` 때문에 알게
|
||||
|
||||
## Pydantic없이 { #without-pydantic }
|
||||
|
||||
만약 Pydantic 모델을 사용하고 싶지 않다면, **Body** 매개변수를 사용할 수도 있습니다. [Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body) 문서를 확인하세요.
|
||||
만약 Pydantic 모델을 사용하고 싶지 않다면, **Body** 매개변수를 사용할 수도 있습니다. [Body - 여러 매개변수: 본문의 단일 값](body-multiple-params.md#singular-values-in-body) 문서를 확인하세요.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<img src="/img/tutorial/cookie-param-models/image01.png">
|
||||
</div>
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
명심하세요, 내부적으로 **브라우저는 쿠키를 특별한 방식으로 처리**하기 때문에 **자바스크립트**가 쉽게 쿠키를 건드릴 수 **없습니다**.
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
|
||||
///
|
||||
|
||||
/// info
|
||||
/// note
|
||||
|
||||
쿠키를 선언하기 위해서는 `Cookie`를 사용해야 합니다. 그렇지 않으면 해당 매개변수를 쿼리 매개변수로 해석하기 때문입니다.
|
||||
|
||||
///
|
||||
|
||||
/// info
|
||||
/// note
|
||||
|
||||
**브라우저는 쿠키를** 내부적으로 특별한 방식으로 처리하기 때문에, **JavaScript**가 쉽게 쿠키를 다루도록 허용하지 않는다는 점을 염두에 두세요.
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ Python에 의해 자동으로 생성된 파일의 내부 변수 `__name__`은
|
||||
```Python
|
||||
from myapp import app
|
||||
|
||||
# Some more code
|
||||
# 추가 코드
|
||||
```
|
||||
|
||||
이 경우 `myapp.py` 내부의 자동 변수 `__name__`에는 값이 `"__main__"`이 들어가지 않습니다.
|
||||
@@ -99,7 +99,7 @@ from myapp import app
|
||||
|
||||
---
|
||||
|
||||
Pycharm을 사용하는 경우 다음을 수행할 수 있습니다
|
||||
PyCharm을 사용하는 경우 다음을 수행할 수 있습니다
|
||||
|
||||
* "Run" 메뉴를 엽니다.
|
||||
* "Debug..." 옵션을 선택합니다.
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
///
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
이 예시에서 `X-Key`와 `X-Token`이라는 커스텀 헤더를 만들어 사용했습니다.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ FastAPI는 <dfn title='때로는 "exit code", "cleanup code", "teardown code", "
|
||||
|
||||
이를 구현하려면 `return` 대신 `yield`를 사용하고, 추가로 실행할 단계 (코드)를 그 뒤에 작성하세요.
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
각 의존성마다 `yield`는 한 번만 사용해야 합니다.
|
||||
|
||||
@@ -39,7 +39,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
`async` 함수와 일반 함수 모두 사용할 수 있습니다.
|
||||
|
||||
@@ -55,7 +55,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
|
||||
|
||||
따라서, 의존성 내에서 `except SomeException`을 사용하여 특정 예외를 처리할 수 있습니다.
|
||||
|
||||
마찬가지로, `finally`를 사용하여 예외 발생 여부와 관계 없이 종료 단계까 실행되도록 할 수 있습니다.
|
||||
마찬가지로, `finally`를 사용하여 예외 발생 여부와 관계 없이 종료 단계가 실행되도록 할 수 있습니다.
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
|
||||
|
||||
@@ -87,7 +87,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
|
||||
|
||||
/// note | 기술 세부사항
|
||||
|
||||
파이썬의 [Context Managers](https://docs.python.org/3/library/contextlib.html) 덕분에 이 기능이 작동합니다.
|
||||
파이썬의 [컨텍스트 관리자](https://docs.python.org/3/library/contextlib.html) 덕분에 이 기능이 작동합니다.
|
||||
|
||||
**FastAPI**는 이를 내부적으로 사용하여 이를 달성합니다.
|
||||
|
||||
@@ -101,7 +101,7 @@ yield된 값은 *경로 처리* 및 다른 의존성들에 주입되는 값 입
|
||||
|
||||
예를 들어, `HTTPException` 같은 다른 예외를 발생시킬 수 있습니다.
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
이는 다소 고급 기술이며, 대부분의 경우 실제로는 필요하지 않을 것입니다. 예를 들어, *경로 처리 함수* 등 나머지 애플리케이션 코드 내부에서 예외 (`HTTPException` 포함)를 발생시킬 수 있기 때문입니다.
|
||||
|
||||
@@ -170,7 +170,7 @@ participant tasks as Background tasks
|
||||
end
|
||||
```
|
||||
|
||||
/// info
|
||||
/// note | 참고
|
||||
|
||||
클라이언트에는 **하나의 응답**만 전송됩니다. 이는 오류 응답 중 하나일 수도 있고, *경로 처리*에서 생성된 응답일 수도 있습니다.
|
||||
|
||||
@@ -178,7 +178,7 @@ participant tasks as Background tasks
|
||||
|
||||
///
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
*경로 처리 함수*의 코드에서 어떤 예외를 발생시키면 `HTTPException`을 포함해 `yield`를 사용하는 의존성으로 전달됩니다. 대부분의 경우 해당 예외(또는 새 예외)를 `yield`를 사용하는 의존성에서 다시 발생시켜, 제대로 처리되도록 해야 합니다.
|
||||
|
||||
@@ -234,6 +234,7 @@ participant operation as Path Operation
|
||||
`yield`를 사용하는 의존성은 시간이 지나면서 서로 다른 사용 사례를 다루고 일부 문제를 수정하기 위해 발전해 왔습니다.
|
||||
|
||||
FastAPI의 여러 버전에서 무엇이 바뀌었는지 보고 싶다면, 고급 가이드의 [고급 의존성 - `yield`, `HTTPException`, `except` 및 백그라운드 작업을 사용하는 의존성](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks)에서 더 자세히 읽을 수 있습니다.
|
||||
|
||||
## 컨텍스트 관리자 { #context-managers }
|
||||
|
||||
### "컨텍스트 관리자"란 { #what-are-context-managers }
|
||||
@@ -256,7 +257,7 @@ with open("./somefile.txt") as f:
|
||||
|
||||
### `yield`를 사용하는 의존성에서 컨텍스트 관리자 사용하기 { #using-context-managers-in-dependencies-with-yield }
|
||||
|
||||
/// warning
|
||||
/// warning | 경고
|
||||
|
||||
이것은 어느 정도 "고급" 개념입니다.
|
||||
|
||||
@@ -271,7 +272,7 @@ Python에서는 [두 가지 메서드: `__enter__()`와 `__exit__()`가 있는
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
컨텍스트 관리자를 생성하는 또 다른 방법은 다음과 같습니다:
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
그 후 위의 값을 포함한 `dict` 자료형으로 반환할 뿐입니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를 사용하기 권장합니다) 추가했습니다.
|
||||
|
||||
@@ -106,7 +106,7 @@ common_parameters --> read_users
|
||||
|
||||
이렇게 하면 공용 코드를 한번만 적어도 되며, **FastAPI**는 *경로 처리*을 위해 이에 대한 호출을 처리합니다.
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
특별한 클래스를 만들지 않아도 되며, 이러한 것 혹은 비슷한 종류를 **FastAPI**에 "등록"하기 위해 어떤 곳에 넘겨주지 않아도 됩니다.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
*경로 처리 함수*에서는 `query_or_cookie_extractor`라는 의존성 하나만 선언하고 있다는 점에 주목하세요.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 추가 데이터 자료형 { #extra-data-types }
|
||||
|
||||
|
||||
지금까지 일반적인 데이터 자료형을 사용했습니다. 예를 들면 다음과 같습니다:
|
||||
|
||||
* `int`
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* **출력 모델**은 비밀번호를 가지면 안 됩니다.
|
||||
* **데이터베이스 모델**은 아마도 해시 처리된 비밀번호를 가질 필요가 있을 것입니다.
|
||||
|
||||
/// danger
|
||||
/// danger | 위험
|
||||
|
||||
절대 사용자의 비밀번호를 평문으로 저장하지 마세요. 항상 이후에 검증 가능한 "안전한 해시(secure hash)"로 저장하세요.
|
||||
|
||||
@@ -132,7 +132,7 @@ UserInDB(
|
||||
)
|
||||
```
|
||||
|
||||
/// warning
|
||||
/// warning | 경고
|
||||
|
||||
추가적으로 제공된 함수 `fake_password_hasher`와 `fake_save_user`는 데이터 흐름을 시연하기 위한 예제일 뿐이며, 실제 보안을 제공하지 않습니다.
|
||||
|
||||
@@ -164,7 +164,7 @@ OpenAPI에서는 이를 `anyOf`로 정의합니다.
|
||||
|
||||
이를 위해 표준 Python 타입 힌트인 [`typing.Union`](https://docs.python.org/3/library/typing.html#typing.Union)을 사용할 수 있습니다:
|
||||
|
||||
/// note
|
||||
/// note | 참고
|
||||
|
||||
[`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions)을 정의할 때는 더 구체적인 타입을 먼저 포함하고, 덜 구체적인 타입을 그 뒤에 나열해야 합니다. 아래 예제에서는 `Union[PlaneItem, CarItem]`에서 더 구체적인 `PlaneItem`이 `CarItem`보다 앞에 위치합니다.
|
||||
|
||||
@@ -208,4 +208,4 @@ Pydantic 모델을 사용하지 않고, 키와 값의 타입만 선언하여 평
|
||||
|
||||
여러 Pydantic 모델을 사용하고, 각 경우에 맞게 자유롭게 상속하세요.
|
||||
|
||||
엔터티가 서로 다른 "상태"를 가져야 하는 경우, 엔터티당 단일 데이터 모델을 사용할 필요는 없습니다. 예를 들어, 사용자 "엔터티"가 `password`, `password_hash`, 그리고 비밀번호가 없는 상태를 포함할 수 있는 경우처럼 말입니다.
|
||||
엔터티가 서로 다른 "상태"를 가져야 하는 경우, 엔터티당 단일 데이터 모델을 사용할 필요는 없습니다. 예를 들어, **사용자** "엔터티"가 `password`, `password_hash`, 그리고 비밀번호가 없는 상태를 포함할 수 있는 경우처럼 말입니다.
|
||||
|
||||
@@ -54,7 +54,7 @@ $ <font color="#4E9A06">fastapi</font> dev
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
해당 줄은 로컬 머신에서 앱이 서비스되는 URL을 보여줍니다.
|
||||
해당 줄은 로컬 머신에서 애플리케이션이 서비스되는 URL을 보여줍니다.
|
||||
|
||||
### 확인하기 { #check-it }
|
||||
|
||||
@@ -143,16 +143,16 @@ OpenAPI 스키마는 포함된 두 개의 대화형 문서 시스템을 제공
|
||||
|
||||
API와 통신하는 클라이언트(프론트엔드, 모바일, IoT 애플리케이션 등)를 위해 코드를 자동으로 생성하는 데도 사용할 수 있습니다.
|
||||
|
||||
### `pyproject.toml`에 앱 `entrypoint` 구성하기 { #configure-the-app-entrypoint-in-pyproject-toml }
|
||||
### `pyproject.toml`에 애플리케이션 `entrypoint` 구성하기 { #configure-the-app-entrypoint-in-pyproject-toml }
|
||||
|
||||
다음과 같이 `pyproject.toml` 파일에서 앱이 위치한 곳을 구성할 수 있습니다:
|
||||
다음과 같이 `pyproject.toml` 파일에서 애플리케이션이 위치한 곳을 구성할 수 있습니다:
|
||||
|
||||
```toml
|
||||
[tool.fastapi]
|
||||
entrypoint = "main:app"
|
||||
```
|
||||
|
||||
해당 `entrypoint`는 `fastapi` 명령어에 다음과 같이 앱을 임포트하라고 알려줍니다:
|
||||
해당 `entrypoint`는 `fastapi` 명령어에 다음과 같이 애플리케이션을 임포트하라고 알려줍니다:
|
||||
|
||||
```python
|
||||
from main import app
|
||||
@@ -180,37 +180,27 @@ entrypoint = "backend.main:app"
|
||||
from backend.main import app
|
||||
```
|
||||
|
||||
### `fastapi dev`에 경로 지정하기 { #fastapi-dev-with-path }
|
||||
### `fastapi dev`를 경로 또는 `--entrypoint` CLI 옵션과 함께 사용하기 { #fastapi-dev-with-path-or-with-entrypoint-cli-option }
|
||||
|
||||
`fastapi dev` 명령어에 파일 경로를 전달할 수도 있으며, 그러면 사용할 FastAPI app 객체를 추정합니다:
|
||||
`fastapi dev` 명령어에 파일 경로를 전달할 수도 있으며, 그러면 사용할 FastAPI 애플리케이션 객체를 추정합니다:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
```
|
||||
|
||||
하지만 매번 `fastapi` 명령어를 호출할 때마다 올바른 경로를 전달해야 합니다.
|
||||
또는 `fastapi dev` 명령어에 `--entrypoint` 옵션을 전달할 수도 있습니다:
|
||||
|
||||
```console
|
||||
$ fastapi dev --entrypoint main:app
|
||||
```
|
||||
|
||||
하지만 매번 `fastapi` 명령어를 호출할 때마다 올바른 path\entrypoint를 전달해야 합니다.
|
||||
|
||||
또한 다른 도구들, 예를 들어 [VS Code 확장](../editor-support.md)이나 [FastAPI Cloud](https://fastapicloud.com)가 이를 찾지 못할 수 있으므로, `pyproject.toml`의 `entrypoint`를 사용하는 것을 권장합니다.
|
||||
|
||||
### 앱 배포하기(선택 사항) { #deploy-your-app-optional }
|
||||
### 애플리케이션 배포하기(선택 사항) { #deploy-your-app-optional }
|
||||
|
||||
선택적으로 FastAPI 앱을 [FastAPI Cloud](https://fastapicloud.com)에 배포할 수 있습니다. 아직 대기자 명단에 등록하지 않았다면, 등록하러 가세요. 🚀
|
||||
|
||||
이미 **FastAPI Cloud** 계정이 있다면(대기자 명단에서 초대해 드렸습니다 😉), 한 번의 명령으로 애플리케이션을 배포할 수 있습니다.
|
||||
|
||||
배포하기 전에, 로그인되어 있는지 확인하세요:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
그 다음 앱을 배포합니다:
|
||||
선택적으로 FastAPI 애플리케이션을 [FastAPI Cloud](https://fastapicloud.com)에 단 한 번의 명령어로 배포할 수 있습니다. 🚀
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -226,7 +216,9 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
</div>
|
||||
|
||||
이게 전부입니다! 이제 해당 URL에서 앱에 접근할 수 있습니다. ✨
|
||||
CLI가 여러분의 FastAPI 애플리케이션을 자동으로 감지하고 클라우드에 배포합니다. 로그인되어 있지 않다면 브라우저가 열려 인증 과정을 완료합니다.
|
||||
|
||||
이게 전부입니다! 이제 해당 URL에서 애플리케이션에 접근할 수 있습니다. ✨
|
||||
|
||||
## 단계별 요약 { #recap-step-by-step }
|
||||
|
||||
@@ -270,7 +262,7 @@ https://example.com/items/foo
|
||||
/items/foo
|
||||
```
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
"경로"는 일반적으로 "엔드포인트" 또는 "라우트"라고도 불립니다.
|
||||
|
||||
@@ -322,7 +314,7 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
|
||||
* 경로 `/`
|
||||
* <dfn title="HTTP GET 메소드"><code>get</code> 작동</dfn> 사용
|
||||
|
||||
/// info | `@decorator` 정보
|
||||
/// note | `@decorator` 정보
|
||||
|
||||
이 `@something` 문법은 파이썬에서 "데코레이터"라 부릅니다.
|
||||
|
||||
@@ -401,7 +393,7 @@ JSON으로 자동 변환되는 객체들과 모델들(ORM 등을 포함해서)
|
||||
|
||||
### 6 단계: 배포하기 { #step-6-deploy-it }
|
||||
|
||||
한 번의 명령으로 **[FastAPI Cloud](https://fastapicloud.com)**에 앱을 배포합니다: `fastapi deploy`. 🎉
|
||||
한 번의 명령어로 **[FastAPI Cloud](https://fastapicloud.com)**에 애플리케이션을 배포합니다: `fastapi deploy`. 🎉
|
||||
|
||||
#### FastAPI Cloud 소개 { #about-fastapi-cloud }
|
||||
|
||||
@@ -409,15 +401,15 @@ JSON으로 자동 변환되는 객체들과 모델들(ORM 등을 포함해서)
|
||||
|
||||
최소한의 노력으로 API를 **빌드**, **배포**, **접근**하는 과정을 간소화합니다.
|
||||
|
||||
FastAPI로 앱을 빌드할 때의 동일한 **개발자 경험**을 클라우드에 **배포**할 때도 제공합니다. 🎉
|
||||
FastAPI로 애플리케이션을 빌드할 때의 동일한 **개발자 경험**을 클라우드에 **배포**할 때도 제공합니다. 🎉
|
||||
|
||||
FastAPI Cloud는 *FastAPI와 친구들* 오픈 소스 프로젝트의 주요 스폰서이자 자금 제공자입니다. ✨
|
||||
|
||||
#### 다른 클라우드 제공업체에 배포하기 { #deploy-to-other-cloud-providers }
|
||||
|
||||
FastAPI는 오픈 소스이며 표준을 기반으로 합니다. 선택한 어떤 클라우드 제공업체에도 FastAPI 앱을 배포할 수 있습니다.
|
||||
FastAPI는 오픈 소스이며 표준을 기반으로 합니다. 선택한 어떤 클라우드 제공업체에도 FastAPI 애플리케이션을 배포할 수 있습니다.
|
||||
|
||||
클라우드 제공업체의 가이드를 따라 FastAPI 앱을 배포하세요. 🤓
|
||||
클라우드 제공업체의 가이드를 따라 FastAPI 애플리케이션을 배포하세요. 🤓
|
||||
|
||||
## 요약 { #recap }
|
||||
|
||||
@@ -425,5 +417,5 @@ FastAPI는 오픈 소스이며 표준을 기반으로 합니다. 선택한 어
|
||||
* `app` 인스턴스 생성.
|
||||
* (`@app.get("/")`처럼) **경로 처리 데코레이터** 작성.
|
||||
* (위에 있는 `def root(): ...`처럼) **경로 처리 함수** 작성.
|
||||
* `fastapi dev` 명령으로 개발 서버 실행.
|
||||
* 선택적으로 `fastapi deploy`로 앱 배포.
|
||||
* `fastapi dev` 명령어로 개발 서버 실행.
|
||||
* 선택적으로 `fastapi deploy`로 애플리케이션 배포.
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# 프론트엔드 { #frontend }
|
||||
|
||||
`app.frontend()`(또는 `router.frontend()`)로 정적 프론트엔드 애플리케이션을 제공할 수 있습니다.
|
||||
|
||||
이는 Vite를 사용하는 React, TanStack Router, Astro, Vue, Svelte, Angular, Solid 등과 같이 정적 파일을 생성하는 프론트엔드 도구에 유용합니다.
|
||||
|
||||
이러한 도구에서는 보통 다음과 같은 명령어로 프론트엔드를 빌드하는 단계가 있습니다:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
그러면 프론트엔드 파일이 들어 있는 `./dist/` 같은 디렉터리가 생성됩니다.
|
||||
|
||||
`app.frontend()`를 사용하면 이러한 프론트엔드 프레임워크에 필요한 규칙에 따라 해당 디렉터리를 제공할 수 있습니다.
|
||||
|
||||
**FastAPI**는 먼저 *경로 처리*를 확인합니다. 프론트엔드 파일은 일반 라우트와 매칭되지 않는 경우에만 확인되므로, API에는 영향을 주지 않습니다.
|
||||
|
||||
## 프론트엔드 제공하기 { #serve-a-frontend }
|
||||
|
||||
예를 들어 `npm run build`로 프론트엔드를 빌드한 후, 생성된 파일을 `dist` 같은 디렉터리에 넣습니다.
|
||||
|
||||
프로젝트 구조는 다음과 같을 수 있습니다:
|
||||
|
||||
```text
|
||||
.
|
||||
├── pyproject.toml
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ └── main.py
|
||||
└── dist
|
||||
├── index.html
|
||||
└── assets
|
||||
└── app.js
|
||||
```
|
||||
|
||||
그런 다음 `app.frontend()`로 제공합니다:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *}
|
||||
|
||||
이렇게 하면 `/assets/app.js`에 대한 요청이 `dist/assets/app.js`를 제공할 수 있습니다.
|
||||
|
||||
**FastAPI** *경로 처리*도 있다면, *경로 처리*가 우선합니다.
|
||||
|
||||
## 클라이언트 사이드 라우팅 { #client-side-routing }
|
||||
|
||||
**single-page apps**(SPAs)를 포함한 많은 프론트엔드 애플리케이션은 클라이언트 사이드 라우팅을 사용합니다. `/dashboard/settings` 같은 경로는 실제 파일이 아닐 수 있지만, 프레임워크가 이를 처리합니다.
|
||||
|
||||
따라서 해당 URL에 직접 접근하는 경우(애플리케이션 안에서 탐색하는 대신), 백엔드는 `index.html`에서 프론트엔드 애플리케이션을 제공해야 합니다. 그러면 프론트엔드 프레임워크가 클라이언트 사이드 라우팅을 처리할 수 있습니다.
|
||||
|
||||
이를 위해 `fallback="index.html"`을 사용합니다:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
|
||||
|
||||
**FastAPI**는 브라우저 탐색처럼 보이는 `GET` 및 `HEAD` 요청에만 이 fallback을 사용합니다. JavaScript, CSS, 이미지처럼 누락된 파일은 여전히 `404`를 반환합니다.
|
||||
|
||||
`POST`나 `PUT` 같은 다른 메서드의 요청이 프론트엔드 fallback에만 매칭되는 경로로 들어와도 `404`를 반환합니다. 일반 **FastAPI** *경로 처리*는 여전히 프론트엔드 라우트보다 높은 우선순위를 가집니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
기본적으로 `fallback`은 `fallback="auto"` 값을 가집니다. 대부분의 경우 `fallback`을 지정할 필요가 없습니다. 자세한 내용은 아래를 읽어보세요.
|
||||
|
||||
///
|
||||
|
||||
이는 클라이언트 사이드 라우팅을 사용하는 많은 프론트엔드 애플리케이션에서 원하는 동작입니다. 예를 들어 TanStack Router를 사용하는 React, Vue, Angular, SvelteKit, Solid 등이 있습니다.
|
||||
|
||||
## 사용자 정의 404 페이지 { #custom-404-page }
|
||||
|
||||
누락된 프론트엔드 경로에 대해 정적 `404.html` 페이지를 제공할 수도 있습니다:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial003_py310.py hl[5] *}
|
||||
|
||||
이 응답은 `404` 상태 코드를 유지합니다.
|
||||
|
||||
이 경우 **FastAPI**는 누락된 프론트엔드 경로에 대해 `index.html`을 제공하지 않습니다. 대신 `404.html` 파일을 반환합니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
기본적으로 `fallback`은 `fallback="auto"` 값을 가집니다. 이를 사용하면 `404.html` 파일이 발견될 경우 자동으로 fallback으로 사용됩니다.
|
||||
|
||||
따라서 일반적으로 `fallback` 인자를 생략할 수 있습니다.
|
||||
|
||||
///
|
||||
|
||||
이는 Astro처럼 각 페이지에 대한 정적 HTML 파일을 생성하는 프론트엔드 도구에 유용합니다.
|
||||
|
||||
## Fallback 자동 설정 { #fallback-auto }
|
||||
|
||||
기본적으로 `app.frontend()`는 `fallback="auto"`를 사용합니다.
|
||||
|
||||
프론트엔드 디렉터리에 `404.html` 파일이 있으면, 누락된 프론트엔드 경로는 상태 코드 `404`와 함께 해당 파일을 제공합니다.
|
||||
|
||||
그렇지 않고 `index.html` 파일이 있으면, 누락된 브라우저 탐색 경로는 `index.html`을 제공합니다. 이는 클라이언트 사이드 라우팅을 사용하는 많은 프론트엔드 애플리케이션이 기대하는 동작입니다.
|
||||
|
||||
따라서 대부분의 경우 `fallback` 인자를 지정하지 않고 `app.frontend("/", directory="dist")`를 사용할 수 있습니다.
|
||||
|
||||
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *}
|
||||
|
||||
## Fallback 비활성화 { #disable-fallback }
|
||||
|
||||
누락된 프론트엔드 경로에 대해 fallback 파일을 제공하고 싶지 않다면 `fallback=None`을 사용합니다:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial005_py310.py hl[5] *}
|
||||
|
||||
그러면 누락된 프론트엔드 경로는 일반 `404`를 반환합니다.
|
||||
|
||||
## 디렉터리 확인하기 { #check-directory }
|
||||
|
||||
기본적으로 `app.frontend()`는 애플리케이션이 생성될 때 디렉터리가 존재하는지 확인합니다.
|
||||
|
||||
이는 설정 오류를 일찍 발견하는 데 도움이 됩니다. 예를 들어 프론트엔드 빌드 출력 디렉터리가 없다면 **FastAPI**는 시작 시 오류를 발생시킵니다.
|
||||
|
||||
프론트엔드 파일이 나중에 생성된다면, 예를 들어 애플리케이션 객체가 생성된 후 별도의 빌드 단계에서 생성된다면, `check_dir=False`를 설정합니다:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial006_py310.py hl[5] *}
|
||||
|
||||
`check_dir=False`를 사용하면 **FastAPI**는 애플리케이션이 생성될 때 디렉터리를 확인하지 않습니다. 요청이 처리될 때 설정된 디렉터리가 여전히 없다면, 그때 **FastAPI**가 오류를 발생시킵니다.
|
||||
|
||||
## `APIRouter`와 함께 사용하기 { #use-it-with-apirouter }
|
||||
|
||||
프론트엔드 파일을 `APIRouter`에 추가하고 prefix와 함께 포함할 수도 있습니다:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial004_py310.py hl[6,7] *}
|
||||
|
||||
이 예제에서는 프론트엔드 경로가 `/app` 아래에서 제공됩니다.
|
||||
|
||||
다른 라우터에 있는 것을 포함하여, 애플리케이션의 모든 일반 *경로 처리*가 여전히 우선합니다.
|
||||
|
||||
## 정적 빌드 출력만 사용하기 { #static-build-output-only }
|
||||
|
||||
`app.frontend()`는 프론트엔드 빌드에서 이미 생성된 파일을 제공합니다.
|
||||
|
||||
서버 사이드 렌더링은 실행하지 않습니다. 각 요청마다 서버에서 동적 렌더링이 필요한 프레임워크가 아니라, 정적 파일을 생성하는 프론트엔드 프레임워크를 위한 것입니다.
|
||||
@@ -1,5 +1,6 @@
|
||||
# 오류 처리 { #handling-errors }
|
||||
|
||||
|
||||
API를 사용하는 클라이언트에 오류를 알려야 하는 상황은 많이 있습니다.
|
||||
|
||||
이 클라이언트는 프론트엔드가 있는 브라우저일 수도 있고, 다른 사람이 작성한 코드일 수도 있고, IoT 장치일 수도 있습니다.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 자습서 - 사용자 안내서 { #tutorial-user-guide }
|
||||
|
||||
|
||||
이 자습서는 **FastAPI**의 대부분의 기능을 단계별로 사용하는 방법을 보여줍니다.
|
||||
|
||||
각 섹션은 이전 섹션을 바탕으로 점진적으로 구성되지만, 주제를 분리한 구조로 되어 있어 특정 API 요구사항을 해결하기 위해 원하는 섹션으로 바로 이동할 수 있습니다.
|
||||
|
||||
@@ -11,7 +11,7 @@ OpenAPI 명세 및 자동화된 API 문서 UI에 사용되는 다음 필드를
|
||||
| `title` | `str` | API의 제목입니다. |
|
||||
| `summary` | `str` | API에 대한 짧은 요약입니다. <small>OpenAPI 3.1.0, FastAPI 0.99.0부터 사용 가능.</small> |
|
||||
| `description` | `str` | API에 대한 짧은 설명입니다. 마크다운을 사용할 수 있습니다. |
|
||||
| `version` | `string` | API의 버전입니다. OpenAPI의 버전이 아닌, 여러분의 애플리케이션의 버전을 나타냅니다. 예: `2.5.0`. |
|
||||
| `version` | `str` | API의 버전입니다. OpenAPI의 버전이 아닌, 여러분의 애플리케이션의 버전을 나타냅니다. 예: `2.5.0`. |
|
||||
| `terms_of_service` | `str` | API 이용 약관의 URL입니다. 제공하는 경우 URL 형식이어야 합니다. |
|
||||
| `contact` | `dict` | 노출된 API에 대한 연락처 정보입니다. 여러 필드를 포함할 수 있습니다. <details><summary><code>contact</code> 필드</summary><table><thead><tr><th>매개변수</th><th>타입</th><th>설명</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>연락처 인물/조직의 식별명입니다.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>연락처 정보가 담긴 URL입니다. URL 형식이어야 합니다.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>연락처 인물/조직의 이메일 주소입니다. 이메일 주소 형식이어야 합니다.</td></tr></tbody></table></details> |
|
||||
| `license_info` | `dict` | 노출된 API의 라이선스 정보입니다. 여러 필드를 포함할 수 있습니다. <details><summary><code>license_info</code> 필드</summary><table><thead><tr><th>매개변수</th><th>타입</th><th>설명</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>필수</strong> (<code>license_info</code>가 설정된 경우). API에 사용된 라이선스 이름입니다.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>API에 대한 [SPDX](https://spdx.org/licenses/) 라이선스 표현입니다. <code>identifier</code> 필드는 <code>url</code> 필드와 상호 배타적입니다. <small>OpenAPI 3.1.0, FastAPI 0.99.0부터 사용 가능.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>API에 사용된 라이선스의 URL입니다. URL 형식이어야 합니다.</td></tr></tbody></table></details> |
|
||||
@@ -26,7 +26,7 @@ OpenAPI 명세 및 자동화된 API 문서 UI에 사용되는 다음 필드를
|
||||
|
||||
///
|
||||
|
||||
이 구성을 사용하면 문서 자동화(로 생성된) API 문서는 다음과 같이 보입니다:
|
||||
이 구성을 사용하면 자동 API 문서는 다음과 같이 보입니다:
|
||||
|
||||
<img src="/img/tutorial/metadata/image01.png">
|
||||
|
||||
@@ -74,7 +74,7 @@ OpenAPI 3.1.0 및 FastAPI 0.99.0부터 `license_info`에 `url` 대신 `identifie
|
||||
|
||||
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
태그에 대한 자세한 내용은 [경로 처리 구성](path-operation-configuration.md#tags)에서 읽어보세요.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 경로 처리 설정 { #path-operation-configuration }
|
||||
|
||||
|
||||
*경로 처리 데코레이터*를 설정하기 위해 전달할 수 있는 몇 가지 매개변수가 있습니다.
|
||||
|
||||
/// warning | 경고
|
||||
@@ -72,13 +73,13 @@
|
||||
|
||||
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`response_description`은 구체적으로 응답을 지칭하며, `description`은 일반적인 *경로 처리*를 지칭합니다.
|
||||
|
||||
///
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
OpenAPI는 각 *경로 처리*가 응답에 관한 설명을 요구할 것을 명시합니다.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이를 권장하기 시작했습니다).
|
||||
|
||||
@@ -131,7 +131,7 @@ FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이
|
||||
* `lt`: `l`ess `t`han
|
||||
* `le`: `l`ess than or `e`qual
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`Query`, `Path`, 그리고 나중에 보게 될 다른 클래스들은 공통 `Param` 클래스의 서브클래스입니다.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
위의 예시에서, `item_id`는 `int`로 선언되었습니다.
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
이 기능은 함수 내에서 오류 검사, 자동완성 등의 편집기 기능을 활용할 수 있게 해줍니다.
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
{"item_id":3}
|
||||
```
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
함수가 받은(반환도 하는) 값은 문자열 `"3"`이 아니라 파이썬 `int` 형인 `3`입니다.
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
`int` 대신 `float`을 제공하면(예: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)) 동일한 오류가 나타납니다.
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
즉, 파이썬 타입 선언을 하면 **FastAPI**는 데이터 검증을 합니다.
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
<img src="/img/tutorial/path-params/image01.png">
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
다시 한 번, 동일한 파이썬 타입 선언만으로 **FastAPI**는 자동 대화형 문서(Swagger UI 통합)를 제공합니다.
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ FastAPI는 `q`의 기본값이 `= None`이기 때문에 필수가 아님을 압
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
FastAPI는 0.95.0 버전에서 `Annotated` 지원을 추가했고(그리고 이를 권장하기 시작했습니다).
|
||||
|
||||
@@ -382,7 +382,7 @@ Pydantic에는 [BeforeValidator](https://docs.pydantic.dev/latest/concepts/valid
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
이는 Pydantic 2 이상 버전에서 사용할 수 있습니다. 😎
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 쿼리 매개변수 { #query-parameters }
|
||||
|
||||
|
||||
경로 매개변수의 일부가 아닌 다른 함수 매개변수를 선언하면 "쿼리" 매개변수로 자동 해석합니다.
|
||||
|
||||
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
|
||||
@@ -65,7 +66,7 @@ http://127.0.0.1:8000/items/?skip=20
|
||||
|
||||
이 경우 함수 매개변수 `q`는 선택적이며 기본값으로 `None` 값이 됩니다.
|
||||
|
||||
/// check
|
||||
/// tip | 팁
|
||||
|
||||
또한 **FastAPI**는 `item_id`가 경로 매개변수이고 `q`는 경로 매개변수가 아니라서 쿼리 매개변수라는 것을 알 정도로 충분히 똑똑하다는 점도 확인하세요.
|
||||
|
||||
@@ -181,7 +182,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
* `skip`, 기본값이 `0`인 `int`.
|
||||
* `limit`, 선택적인 `int`.
|
||||
|
||||
/// tip
|
||||
/// tip | 팁
|
||||
|
||||
[경로 매개변수](path-params.md#predefined-values)와 마찬가지로 `Enum`을 사용할 수 있습니다.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
`File`을 사용하여 클라이언트가 업로드할 파일들을 정의할 수 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
업로드된 파일을 전달받기 위해 먼저 [`python-multipart`](https://github.com/Kludex/python-multipart)를 설치해야합니다.
|
||||
|
||||
@@ -28,7 +28,7 @@ $ pip install python-multipart
|
||||
|
||||
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`File` 은 `Form` 으로부터 직접 상속된 클래스입니다.
|
||||
|
||||
@@ -151,11 +151,11 @@ HTML의 폼들(`<form></form>`)이 서버에 데이터를 전송하는 방식은
|
||||
|
||||
그들은 "폼 데이터"를 사용하여 전송된 동일한 "폼 필드"에 연결됩니다.
|
||||
|
||||
이 기능을 사용하기 위해 , `bytes` 의 `List` 또는 `UploadFile` 를 선언하기 바랍니다:
|
||||
이 기능을 사용하려면 `bytes` 또는 `UploadFile`의 `list`를 선언하기 바랍니다:
|
||||
|
||||
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
|
||||
|
||||
선언한대로, `bytes` 의 `list` 또는 `UploadFile` 들을 전송받을 것입니다.
|
||||
선언한 대로, `bytes` 또는 `UploadFile`의 `list`를 받게 됩니다.
|
||||
|
||||
/// note | 기술 세부사항
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
FastAPI에서 **Pydantic 모델**을 이용하여 **폼 필드**를 선언할 수 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
폼을 사용하려면, 먼저 [`python-multipart`](https://github.com/Kludex/python-multipart)를 설치하세요.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
`File` 과 `Form` 을 사용하여 파일과 폼 필드를 동시에 정의할 수 있습니다.
|
||||
|
||||
/// info
|
||||
/// note
|
||||
|
||||
업로드된 파일 및/또는 폼 데이터를 받으려면 먼저 [`python-multipart`](https://github.com/Kludex/python-multipart)를 설치해야 합니다.
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# 폼 데이터 { #form-data }
|
||||
|
||||
|
||||
JSON 대신 폼 필드를 받아야 하는 경우 `Form`을 사용할 수 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
폼을 사용하려면, 먼저 [`python-multipart`](https://github.com/Kludex/python-multipart)를 설치하세요.
|
||||
|
||||
@@ -30,9 +31,9 @@ $ pip install python-multipart
|
||||
|
||||
<dfn title="사양">사양</dfn>에서는 필드 이름이 `username` 및 `password`로 정확하게 명명되어야 하고, JSON이 아닌 폼 필드로 전송해야 합니다.
|
||||
|
||||
`Form`을 사용하면 유효성 검사, 예제, 별칭(예: `username` 대신 `user-name`) 등을 포함하여 `Body`(및 `Query`, `Path`, `Cookie`)와 동일한 구성을 선언할 수 있습니다.
|
||||
`Form`을 사용하면 유효성 검사, 예제, 별칭(예: `user-name` 대신 `username`) 등을 포함하여 `Body`(및 `Query`, `Path`, `Cookie`)와 동일한 구성을 선언할 수 있습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`Form`은 `Body`에서 직접 상속되는 클래스입니다.
|
||||
|
||||
@@ -56,7 +57,7 @@ HTML 폼(`<form></form>`)이 데이터를 서버로 보내는 방식은 일반
|
||||
|
||||
그러나 폼에 파일이 포함된 경우, `multipart/form-data`로 인코딩합니다. 다음 장에서 파일 처리에 대해 읽을 겁니다.
|
||||
|
||||
이러한 인코딩 및 폼 필드에 대해 더 읽고 싶다면, [`POST`에 대한 <abbr title="Mozilla Developer Network - Mozilla 개발자 네트워크">MDN</abbr> 웹 문서를 참조하세요](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
|
||||
이러한 인코딩 및 폼 필드에 대해 더 읽고 싶다면, [`POST`에 대한 <abbr title="Mozilla Developer Network - 모질라 개발자 네트워크">MDN</abbr> 웹 문서를 참조하세요](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ FastAPI는 이 `response_model`을 사용해 데이터 문서화, 검증 등을
|
||||
|
||||
{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`EmailStr`을 사용하려면 먼저 [`email-validator`](https://github.com/JoshData/python-email-validator)를 설치하세요.
|
||||
|
||||
@@ -202,11 +202,11 @@ FastAPI는 Pydantic을 내부적으로 여러 방식으로 사용하여, 클래
|
||||
|
||||
하지만 유효한 Pydantic 타입이 아닌 다른 임의의 객체(예: 데이터베이스 객체)를 반환하고, 함수에서 그렇게 어노테이션하면, FastAPI는 그 타입 어노테이션으로부터 Pydantic 응답 모델을 만들려고 시도하다가 실패합니다.
|
||||
|
||||
또한, 유효한 Pydantic 타입이 아닌 타입이 하나 이상 포함된 여러 타입 간의 <dfn title="여러 타입 간의 union은 '이 타입들 중 아무거나'를 의미합니다.">union</dfn>이 있는 경우에도 동일합니다. 예를 들어, 아래는 실패합니다 💥:
|
||||
또한, 유효한 Pydantic 타입이 아닌 타입이 하나 이상 포함된 여러 타입 간의 <dfn title="여러 타입 간의 유니온은 '이 타입들 중 아무거나'를 의미합니다.">유니온</dfn>이 있는 경우에도 동일합니다. 예를 들어, 아래는 실패합니다 💥:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
|
||||
|
||||
...이는 타입 어노테이션이 Pydantic 타입이 아니고, 단일 `Response` 클래스/서브클래스도 아니며, `Response`와 `dict` 간 union(둘 중 아무거나)이기 때문에 실패합니다.
|
||||
...이는 타입 어노테이션이 Pydantic 타입이 아니고, 단일 `Response` 클래스/서브클래스도 아니며, `Response`와 `dict` 간 유니온(둘 중 아무거나)이기 때문에 실패합니다.
|
||||
|
||||
### 응답 모델 비활성화 { #disable-response-model }
|
||||
|
||||
@@ -251,7 +251,7 @@ FastAPI는 Pydantic을 내부적으로 여러 방식으로 사용하여, 클래
|
||||
}
|
||||
```
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
다음도 사용할 수 있습니다:
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 응답 상태 코드 { #response-status-code }
|
||||
|
||||
|
||||
응답 모델을 지정하는 것과 같은 방법으로, 어떤 *경로 처리*에서든 `status_code` 매개변수를 사용하여 응답에 사용할 HTTP 상태 코드를 선언할 수도 있습니다:
|
||||
|
||||
* `@app.get()`
|
||||
@@ -12,13 +13,13 @@
|
||||
|
||||
/// note | 참고
|
||||
|
||||
`status_code` 는 "데코레이터" 메소드(`get`, `post` 등)의 매개변수입니다. 모든 매개변수들과 본문처럼 *경로 처리 함수*가 아닙니다.
|
||||
`status_code` 는 "데코레이터" 메소드(`get`, `post` 등)의 매개변수입니다. 다른 매개변수나 본문과 달리, *경로 처리 함수*의 매개변수가 아닙니다.
|
||||
|
||||
///
|
||||
|
||||
`status_code` 매개변수는 HTTP 상태 코드를 숫자로 입력받습니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`status_code` 는 파이썬의 [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus) 와 같은 `IntEnum` 을 입력받을 수도 있습니다.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 요청 예제 데이터 선언 { #declare-request-example-data }
|
||||
|
||||
여러분의 앱이 받을 수 있는 데이터 예제를 선언할 수 있습니다.
|
||||
여러분의 애플리케이션이 받을 수 있는 데이터 예제를 선언할 수 있습니다.
|
||||
|
||||
여기 이를 위한 몇 가지 방식이 있습니다.
|
||||
|
||||
@@ -24,7 +24,7 @@ JSON 스키마를 확장하고 여러분의 별도의 자체 데이터를 추가
|
||||
|
||||
///
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
(FastAPI 0.99.0부터 쓰이기 시작한) OpenAPI 3.1.0은 **JSON 스키마** 표준의 일부인 `examples`에 대한 지원을 추가했습니다.
|
||||
|
||||
@@ -155,7 +155,7 @@ OpenAPI는 또한 `example`과 `examples` 필드를 명세서의 다른 부분
|
||||
* `File()`
|
||||
* `Form()`
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
이 예전 OpenAPI-특화 `examples` 매개변수는 이제 FastAPI `0.103.0`부터 `openapi_examples`입니다.
|
||||
|
||||
@@ -171,7 +171,7 @@ OpenAPI는 또한 `example`과 `examples` 필드를 명세서의 다른 부분
|
||||
|
||||
JSON 스키마의 새로운 `examples` 필드는 예제의 **단순한 `list`**일 뿐이며, (위에서 상술한 것처럼) OpenAPI의 다른 곳에 존재하는 추가 메타데이터가 있는 dict가 아닙니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
더 쉽고 새로운 JSON 스키마와의 통합과 함께 OpenAPI 3.1.0가 배포되었지만, 잠시동안 자동 문서 생성을 제공하는 도구인 Swagger UI는 OpenAPI 3.1.0을 지원하지 않았습니다 (5.0.0 버전부터 지원합니다 🎉).
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 보안 - 첫 단계 { #security-first-steps }
|
||||
|
||||
|
||||
어떤 도메인에 **backend** API가 있다고 가정해 보겠습니다.
|
||||
|
||||
그리고 다른 도메인에 **frontend**가 있거나, 같은 도메인의 다른 경로에 있거나(또는 모바일 애플리케이션에 있을 수도 있습니다).
|
||||
@@ -24,7 +25,7 @@
|
||||
|
||||
## 실행하기 { #run-it }
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
[`python-multipart`](https://github.com/Kludex/python-multipart) 패키지는 `pip install "fastapi[standard]"` 명령을 실행하면 **FastAPI**와 함께 자동으로 설치됩니다.
|
||||
|
||||
@@ -60,7 +61,7 @@ $ fastapi dev
|
||||
|
||||
<img src="/img/tutorial/security/image01.png">
|
||||
|
||||
/// check | Authorize 버튼!
|
||||
/// tip | Authorize 버튼!
|
||||
|
||||
반짝이는 새 "Authorize" 버튼이 이미 있습니다.
|
||||
|
||||
@@ -118,7 +119,7 @@ OAuth2는 backend 또는 API가 사용자를 인증하는 서버와 독립적일
|
||||
|
||||
이 예제에서는 **OAuth2**의 **Password** 플로우와 **Bearer** token을 사용합니다. 이를 위해 `OAuth2PasswordBearer` 클래스를 사용합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
"bearer" token만이 유일한 선택지는 아닙니다.
|
||||
|
||||
@@ -148,7 +149,7 @@ OAuth2는 backend 또는 API가 사용자를 인증하는 서버와 독립적일
|
||||
|
||||
곧 실제 경로 처리를 만들 것입니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
엄격한 "Pythonista"라면 `token_url` 대신 `tokenUrl` 같은 파라미터 이름 스타일이 마음에 들지 않을 수도 있습니다.
|
||||
|
||||
@@ -176,7 +177,7 @@ oauth2_scheme(some, parameters)
|
||||
|
||||
**FastAPI**는 이 의존성을 사용해 OpenAPI 스키마(및 자동 API 문서)에 "security scheme"를 정의할 수 있다는 것을 알게 됩니다.
|
||||
|
||||
/// info | 기술 세부사항
|
||||
/// note | 기술 세부사항
|
||||
|
||||
**FastAPI**는 (의존성에 선언된) `OAuth2PasswordBearer` 클래스를 사용해 OpenAPI에서 보안 스킴을 정의할 수 있다는 것을 알고 있습니다. 이는 `OAuth2PasswordBearer`가 `fastapi.security.oauth2.OAuth2`를 상속하고, 이것이 다시 `fastapi.security.base.SecurityBase`를 상속하기 때문입니다.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
Pydantic을 사용해 본문을 선언하는 것과 같은 방식으로, 다른 곳에서도 어디서든 사용할 수 있습니다:
|
||||
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *}
|
||||
|
||||
## `get_current_user` 의존성 생성하기 { #create-a-get-current-user-dependency }
|
||||
|
||||
@@ -52,7 +52,7 @@ Pydantic을 사용해 본문을 선언하는 것과 같은 방식으로, 다른
|
||||
|
||||
///
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
이 의존성 시스템이 설계된 방식은 모두 `User` 모델을 반환하는 서로 다른 의존성(서로 다른 "dependables")을 가질 수 있도록 합니다.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# 패스워드(해싱 포함)를 사용하는 OAuth2, JWT 토큰을 사용하는 Bearer { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
|
||||
|
||||
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON 웹 토큰">JWT</abbr> 토큰과 안전한 패스워드 해싱을 사용해 애플리케이션을 실제로 안전하게 만들겠습니다.
|
||||
|
||||
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON Web Tokens - JSON 웹 토큰">JWT</abbr> 토큰과 안전한 패스워드 해싱을 사용해 애플리케이션을 실제로 안전하게 만들겠습니다.
|
||||
|
||||
이 코드는 실제로 애플리케이션에서 사용할 수 있으며, 패스워드 해시를 데이터베이스에 저장하는 등의 작업에 활용할 수 있습니다.
|
||||
|
||||
@@ -42,7 +43,7 @@ $ pip install pyjwt
|
||||
|
||||
</div>
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
RSA나 ECDSA 같은 전자 서명 알고리즘을 사용할 계획이라면, cryptography 라이브러리 의존성인 `pyjwt[crypto]`를 설치해야 합니다.
|
||||
|
||||
@@ -213,7 +214,7 @@ JWT는 사용자를 식별하고 사용자가 API에서 직접 작업을 수행
|
||||
Username: `johndoe`
|
||||
Password: `secret`
|
||||
|
||||
/// check | 확인
|
||||
/// tip | 팁
|
||||
|
||||
코드 어디에도 평문 패스워드 "`secret`"은 없고, 해시된 버전만 있다는 점에 유의하십시오.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
**FastAPI** 보안 유틸리티를 사용하여 `username` 및 `password`를 가져올 것입니다.
|
||||
|
||||
OAuth2는 (우리가 사용하고 있는) "패스워드 플로우"을 사용할 때 클라이언트/유저가 `username` 및 `password` 필드를 폼 데이터로 보내야 함을 지정합니다.
|
||||
OAuth2는 (우리가 사용하고 있는) "패스워드 플로우"를 사용할 때 클라이언트/유저가 `username` 및 `password` 필드를 폼 데이터로 보내야 함을 지정합니다.
|
||||
|
||||
그리고 사양에는 필드의 이름을 그렇게 지정해야 한다고 나와 있습니다. 따라서 `user-name` 또는 `email`은 작동하지 않습니다.
|
||||
|
||||
@@ -32,7 +32,7 @@ OAuth2는 (우리가 사용하고 있는) "패스워드 플로우"을 사용할
|
||||
* `instagram_basic`은 페이스북/인스타그램에서 사용합니다.
|
||||
* `https://www.googleapis.com/auth/drive`는 Google에서 사용합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
OAuth2에서 "범위"는 필요한 특정 권한을 선언하는 문자열입니다.
|
||||
|
||||
@@ -72,7 +72,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
|
||||
* `client_id`(선택적으로 사용) (예제에서는 필요하지 않습니다).
|
||||
* `client_secret`(선택적으로 사용) (예제에서는 필요하지 않습니다).
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`OAuth2PasswordRequestForm`은 `OAuth2PasswordBearer`와 같이 **FastAPI**에 대한 특수 클래스가 아닙니다.
|
||||
|
||||
@@ -104,7 +104,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
|
||||
|
||||
### 패스워드 확인하기 { #check-the-password }
|
||||
|
||||
이 시점에서 데이터베이스의 사용자 데이터 형식을 확인했지만 암호를 확인하지 않았습니다.
|
||||
이 시점에서 데이터베이스의 사용자 데이터는 있지만, 아직 패스워드는 확인하지 않았습니다.
|
||||
|
||||
먼저 데이터를 Pydantic `UserInDB` 모델에 넣겠습니다.
|
||||
|
||||
@@ -144,9 +144,9 @@ UserInDB(
|
||||
)
|
||||
```
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`**user_dict`에 대한 자세한 설명은 [**추가 모델** 문서](../extra-models.md#about-user-in-dict)를 다시 확인해보세요.
|
||||
`**user_dict`에 대한 자세한 설명은 [**추가 모델** 문서](../extra-models.md#about-user-in-model-dump)를 다시 확인해보세요.
|
||||
|
||||
///
|
||||
|
||||
@@ -196,7 +196,7 @@ UserInDB(
|
||||
|
||||
{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
여기서 반환하는 값이 `Bearer`인 추가 헤더 `WWW-Authenticate`도 사양의 일부입니다.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
이는 [JSON Lines 스트리밍](stream-json-lines.md)과 비슷하지만, 브라우저가 기본적으로 [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)를 통해 지원하는 `text/event-stream` 형식을 사용합니다.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
FastAPI 0.135.0에 추가되었습니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# SQL (관계형) 데이터베이스 { #sql-relational-databases }
|
||||
|
||||
|
||||
**FastAPI**에서 SQL(관계형) 데이터베이스 사용은 필수가 아닙니다. 하지만 여러분이 원하는 **어떤 데이터베이스든** 사용할 수 있습니다.
|
||||
|
||||
여기서는 [SQLModel](https://sqlmodel.tiangolo.com/)을 사용하는 예제를 살펴보겠습니다.
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
`StaticFiles`를 사용하면 디렉터리에서 정적 파일을 자동으로 제공할 수 있습니다.
|
||||
|
||||
/// tip | 팁
|
||||
|
||||
프론트엔드를 호스팅해야 한다면 대신 `app.frontend()`를 사용하세요. 자세한 내용은 [프론트엔드](frontend.md)에서 확인하세요.
|
||||
|
||||
`app.frontend()`는 내부적으로 `StaticFiles`를 사용하며, 클라이언트 사이드 라우팅 처리와 같은 프론트엔드를 위한 여러 추가 이점이 있습니다.
|
||||
|
||||
///
|
||||
|
||||
## `StaticFiles` 사용 { #use-staticfiles }
|
||||
|
||||
* `StaticFiles`를 임포트합니다.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
연속된 데이터를 "**스트림**"으로 보내고 싶다면 **JSON Lines**를 사용할 수 있습니다.
|
||||
|
||||
/// info
|
||||
/// note
|
||||
|
||||
FastAPI 0.134.0에 추가되었습니다.
|
||||
|
||||
@@ -48,7 +48,7 @@ sequenceDiagram
|
||||
|
||||
JSON 배열(Python의 list에 해당)과 매우 비슷하지만, 항목들을 `[]`로 감싸고 항목 사이에 `,`를 넣는 대신, 줄마다 하나의 JSON 객체가 있고, 새 줄 문자로 구분됩니다.
|
||||
|
||||
/// info
|
||||
/// note
|
||||
|
||||
핵심은 애플리케이션이 각 줄을 차례로 생성하는 동안, 클라이언트는 이전 줄을 소비할 수 있다는 점입니다.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
## `TestClient` 사용하기 { #using-testclient }
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`TestClient` 사용하려면, 우선 [`httpx`](https://www.python-httpx.org)를 설치해야 합니다.
|
||||
|
||||
@@ -62,7 +62,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
|
||||
|
||||
그리고 **FastAPI** 애플리케이션도 여러 파일이나 모듈 등으로 구성될 수 있습니다.
|
||||
|
||||
### **FastAPI** app 파일 { #fastapi-app-file }
|
||||
### **FastAPI** 애플리케이션 파일 { #fastapi-app-file }
|
||||
|
||||
[더 큰 애플리케이션](bigger-applications.md)에 묘사된 파일 구조를 가지고 있는 것으로 가정해봅시다.
|
||||
|
||||
@@ -73,7 +73,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
|
||||
│ └── main.py
|
||||
```
|
||||
|
||||
`main.py` 파일 안에 **FastAPI** app 을 만들었습니다:
|
||||
`main.py` 파일 안에 **FastAPI** 애플리케이션이 있습니다:
|
||||
|
||||
|
||||
{* ../../docs_src/app_testing/app_a_py310/main.py *}
|
||||
@@ -101,7 +101,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
|
||||
|
||||
이제 위의 예시를 확장하고 더 많은 세부 사항을 추가하여 다양한 부분을 어떻게 테스트하는지 살펴보겠습니다.
|
||||
|
||||
### 확장된 **FastAPI** app 파일 { #extended-fastapi-app-file }
|
||||
### 확장된 **FastAPI** 애플리케이션 파일 { #extended-fastapi-app-file }
|
||||
|
||||
이전과 같은 파일 구조를 계속 사용해 보겠습니다.
|
||||
|
||||
@@ -113,7 +113,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
|
||||
│ └── test_main.py
|
||||
```
|
||||
|
||||
이제 **FastAPI** 앱이 있는 `main.py` 파일에 몇 가지 다른 **경로 처리**가 추가된 경우를 생각해봅시다.
|
||||
이제 **FastAPI** 애플리케이션이 있는 `main.py` 파일에 몇 가지 다른 **경로 처리**가 추가된 경우를 생각해봅시다.
|
||||
|
||||
오류를 반환할 수 있는 `GET` 작업이 있습니다.
|
||||
|
||||
@@ -144,7 +144,7 @@ FastAPI 애플리케이션에 요청을 보내는 것 외에도 테스트에서
|
||||
|
||||
백엔드로 데이터를 어떻게 보내는지 정보를 더 얻으려면 (`httpx` 혹은 `TestClient`를 이용해서) [HTTPX 문서](https://www.python-httpx.org)를 확인하세요.
|
||||
|
||||
/// info | 정보
|
||||
/// note | 참고
|
||||
|
||||
`TestClient`는 Pydantic 모델이 아니라 JSON으로 변환될 수 있는 데이터를 받습니다.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 가상 환경 { #virtual-environments }
|
||||
|
||||
|
||||
Python 프로젝트를 작업할 때는 **가상 환경**(또는 이와 유사한 메커니즘)을 사용해 각 프로젝트마다 설치하는 패키지를 분리하는 것이 좋습니다.
|
||||
|
||||
/// note | 참고
|
||||
|
||||
Reference in New Issue
Block a user