committed by
GitHub
65 changed files with 749 additions and 2917 deletions
@ -64,7 +64,7 @@ jobs: |
|||
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }} |
|||
# TODO: Use v3 when it's fixed, probably in v3.11 |
|||
# https://github.com/cloudflare/wrangler-action/issues/307 |
|||
uses: cloudflare/[email protected]3 |
|||
uses: cloudflare/[email protected]4 |
|||
# uses: cloudflare/wrangler-action@v3 |
|||
with: |
|||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} |
|||
|
@ -0,0 +1,313 @@ |
|||
# 사용자 정의 응답 - HTML, Stream, 파일, 기타 |
|||
|
|||
기본적으로, **FastAPI** 응답을 `JSONResponse`를 사용하여 반환합니다. |
|||
|
|||
이를 재정의 하려면 [응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 본 것처럼 `Response`를 직접 반환하면 됩니다. |
|||
|
|||
그러나 `Response` (또는 `JSONResponse`와 같은 하위 클래스)를 직접 반환하면, 데이터가 자동으로 변환되지 않으며 (심지어 `response_model`을 선언했더라도), 문서화가 자동으로 생성되지 않습니다(예를 들어, 생성된 OpenAPI의 일부로 HTTP 헤더 `Content-Type`에 특정 "미디어 타입"을 포함하는 경우). |
|||
|
|||
하지만 *경로 작업 데코레이터*에서 `response_class` 매개변수를 사용하여 원하는 `Response`(예: 모든 `Response` 하위 클래스)를 선언할 수도 있습니다. |
|||
|
|||
*경로 작업 함수*에서 반환하는 내용은 해당 `Response`안에 포함됩니다. |
|||
|
|||
그리고 만약 그 `Response`가 `JSONResponse`와 `UJSONResponse`의 경우 처럼 JSON 미디어 타입(`application/json`)을 가지고 있다면, *경로 작업 데코레이터*에서 선언한 Pydantic의 `response_model`을 사용해 자동으로 변환(및 필터링) 됩니다. |
|||
|
|||
/// note | 참고 |
|||
|
|||
미디어 타입이 없는 응답 클래스를 사용하는 경우, FastAPI는 응답에 내용이 없을 것으로 예상하므로 생성된 OpenAPI 문서에서 응답 형식을 문서화하지 않습니다. |
|||
|
|||
/// |
|||
|
|||
## `ORJSONResponse` 사용하기 |
|||
|
|||
예를 들어, 성능을 극대화하려는 경우, <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">orjson</a>을 설치하여 사용하고 응답을 `ORJSONResponse`로 설정할 수 있습니다. |
|||
|
|||
사용하고자 하는 `Response` 클래스(하위 클래스)를 임포트한 후, **경로 작업 데코레이터*에서 선언하세요. |
|||
|
|||
대규모 응답의 경우, 딕셔너리를 반환하는 것보다 `Response`를 반환하는 것이 훨씬 빠릅니다. |
|||
|
|||
이유는 기본적으로, FastAPI가 내부의 모든 항목을 검사하고 JSON으로 직렬화할 수 있는지 확인하기 때문입니다. 이는 사용자 안내서에서 설명된 [JSON 호환 가능 인코더](../tutorial/encoder.md){.internal-link target=_blank}를 사용하는 방식과 동일합니다. 이를 통해 데이터베이스 모델과 같은 **임의의 객체**를 반환할 수 있습니다. |
|||
|
|||
하지만 반환하는 내용이 **JSON으로 직렬화 가능**하다고 확신하는 경우, 해당 내용을 응답 클래스에 직접 전달할 수 있으며, FastAPI가 반환 내용을 `jsonable_encoder`를 통해 처리한 뒤 응답 클래스에 전달하는 오버헤드를 피할 수 있습니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} |
|||
|
|||
/// info | 정보 |
|||
|
|||
`response_class` 매개변수는 응답의 "미디어 타입"을 정의하는 데에도 사용됩니다. |
|||
|
|||
이 경우, HTTP 헤더 `Content-Type`은 `application/json`으로 설정됩니다. |
|||
|
|||
그리고 이는 OpenAPI에 그대로 문서화됩니다. |
|||
|
|||
/// |
|||
|
|||
/// tip | 팁 |
|||
|
|||
`ORJSONResponse`는 FastAPI에서만 사용할 수 있고 Starlette에서는 사용할 수 없습니다. |
|||
|
|||
/// |
|||
|
|||
## HTML 응답 |
|||
|
|||
**FastAPI**에서 HTML 응답을 직접 반환하려면 `HTMLResponse`를 사용하세요. |
|||
|
|||
* `HTMLResponse`를 임포트 합니다. |
|||
* *경로 작업 데코레이터*의 `response_class` 매개변수로 `HTMLResponse`를 전달합니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} |
|||
|
|||
/// info | 정보 |
|||
|
|||
`response_class` 매개변수는 응답의 "미디어 타입"을 정의하는 데에도 사용됩니다. |
|||
|
|||
이 경우, HTTP 헤더 `Content-Type`은 `text/html`로 설정됩니다. |
|||
|
|||
그리고 이는 OpenAPI에 그대로 문서화 됩니다. |
|||
|
|||
/// |
|||
|
|||
### `Response` 반환하기 |
|||
|
|||
[응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 본 것 처럼, *경로 작업*에서 응답을 직접 반환하여 재정의할 수도 있습니다. |
|||
|
|||
위의 예제와 동일하게 `HTMLResponse`를 반환하는 코드는 다음과 같을 수 있습니다: |
|||
|
|||
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *} |
|||
|
|||
/// warning | 경고 |
|||
|
|||
*경로 작업 함수*에서 직접 반환된 `Response`는 OpenAPI에 문서화되지 않습니다(예를들어, `Content-Type`이 문서화되지 않음) 자동 대화형 문서에서도 표시되지 않습니다. |
|||
|
|||
/// |
|||
|
|||
/// info | 정보 |
|||
|
|||
물론 실제 `Content-Type` 헤더, 상태 코드 등은 반환된 `Response` 객체에서 가져옵니다. |
|||
|
|||
/// |
|||
|
|||
### OpenAPI에 문서화하고 `Response` 재정의 하기 |
|||
|
|||
함수 내부에서 응답을 재정의하면서 동시에 OpenAPI에서 "미디어 타입"을 문서화하고 싶다면, `response_class` 매게변수를 사용하면서 `Response` 객체를 반환할 수 있습니다. |
|||
|
|||
이 경우 `response_class`는 OpenAPI *경로 작업*을 문서화하는 데만 사용되고, 실제로는 여러분이 반환한 `Response`가 그대로 사용됩니다. |
|||
|
|||
### `HTMLResponse`직접 반환하기 |
|||
|
|||
예를 들어, 다음과 같이 작성할 수 있습니다: |
|||
|
|||
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *} |
|||
|
|||
이 예제에서, `generate_html_response()` 함수는 HTML을 `str`로 반환하는 대신 이미 `Response`를 생성하고 반환합니다. |
|||
|
|||
`generate_html_response()`를 호출한 결과를 반환함으로써, 기본적인 **FastAPI** 기본 동작을 재정의 하는 `Response`를 이미 반환하고 있습니다. |
|||
|
|||
하지만 `response_class`에 `HTMLResponse`를 함께 전달했기 때문에, FastAPI는 이를 OpenAPI 및 대화형 문서에서 `text/html`로 HTML을 문서화 하는 방법을 알 수 있습니다. |
|||
|
|||
<img src="/img/tutorial/custom-response/image01.png"> |
|||
|
|||
## 사용 가능한 응답들 |
|||
|
|||
다음은 사용할 수 있는 몇가지 응답들 입니다. |
|||
|
|||
`Response`를 사용하여 다른 어떤 것도 반환 할수 있으며, 직접 하위 클래스를 만들 수도 있습니다. |
|||
|
|||
/// note | 기술 세부사항 |
|||
|
|||
`from starlette.responses import HTMLResponse`를 사용할 수도 있습니다. |
|||
|
|||
**FastAPI**는 개발자인 여러분의 편의를 위해 `starlette.responses`를 `fastapi.responses`로 제공 하지만, 대부분의 사용 가능한 응답은 Starlette에서 직접 가져옵니다. |
|||
|
|||
/// |
|||
|
|||
### `Response` |
|||
|
|||
기본 `Response` 클래스는 다른 모든 응답 클래스의 부모 클래스 입니다. |
|||
|
|||
이 클래스를 직접 반환할 수 있습니다. |
|||
|
|||
다음 매개변수를 받을 수 있습니다: |
|||
|
|||
* `content` - `str` 또는 `bytes`. |
|||
* `status_code` - HTTP 상태코드를 나타내는 `int`. |
|||
* `headers` - 문자열로 이루어진 `dict`. |
|||
* `media_type` - 미디어 타입을 나타내는 `str` 예: `"text/html"`. |
|||
|
|||
FastAPI (실제로는 Starlette)가 자동으로 `Content-Length` 헤더를 포함시킵니다. 또한 `media_type`에 기반하여 `Content-Type` 헤더를 포함하며, 텍스트 타입의 경우 문자 집합을 추가 합니다. |
|||
|
|||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} |
|||
|
|||
### `HTMLResponse` |
|||
|
|||
텍스트 또는 바이트를 받아 HTML 응답을 반환합니다. 위에서 설명한 내용과 같습니다. |
|||
|
|||
### `PlainTextResponse` |
|||
|
|||
텍스트 또는 바이트를 받아 일반 텍스트 응답을 반환합니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} |
|||
|
|||
### `JSONResponse` |
|||
|
|||
데이터를 받아 `application/json`으로 인코딩된 응답을 반환합니다. |
|||
|
|||
이는 위에서 설명했듯이 **FastAPI**에서 기본적으로 사용되는 응답 형식입니다. |
|||
|
|||
### `ORJSONResponse` |
|||
|
|||
<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>을 사용하여 빠른 JSON 응답을 제공하는 대안입니다. 위에서 설명한 내용과 같습니다. |
|||
|
|||
/// info | 정보 |
|||
|
|||
이를 사용하려면 `orjson`을 설치해야합니다. 예: `pip install orjson`. |
|||
|
|||
/// |
|||
|
|||
### `UJSONResponse` |
|||
|
|||
<a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>을 사용한 또 다른 JSON 응답 형식입니다. |
|||
|
|||
/// info | 정보 |
|||
|
|||
이 응답을 사용하려면 `ujson`을 설치해야합니다. 예: 'pip install ujson`. |
|||
|
|||
/// |
|||
|
|||
/// warning | 경고 |
|||
|
|||
`ujson` 은 일부 예외 경우를 처리하는 데 있어 Python 내장 구현보다 덜 엄격합니다. |
|||
|
|||
/// |
|||
|
|||
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *} |
|||
|
|||
/// tip | 팁 |
|||
|
|||
`ORJSONResponse`가 더 빠른 대안일 가능성이 있습니다. |
|||
|
|||
/// |
|||
|
|||
### `RedirectResponse` |
|||
|
|||
HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 307(임시 리디렉션)으로 설정됩니다. |
|||
|
|||
`RedirectResponse`를 직접 반환할 수 있습니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *} |
|||
|
|||
--- |
|||
|
|||
또는 `response_class` 매개변수에서 사용할 수도 있습니다: |
|||
|
|||
|
|||
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *} |
|||
|
|||
이 경우, *경로 작업* 함수에서 URL을 직접 반환할 수 있습니다. |
|||
|
|||
이 경우, 사용되는 `status_code`는 `RedirectResponse`의 기본값인 `307` 입니다. |
|||
|
|||
--- |
|||
|
|||
`status_code` 매개변수를 `response_class` 매개변수와 함께 사용할 수도 있습니다: |
|||
|
|||
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} |
|||
|
|||
### `StreamingResponse` |
|||
|
|||
비동기 제너레이터 또는 일반 제너레이터/이터레이터를 받아 응답 본문을 스트리밍 합니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} |
|||
|
|||
#### 파일과 같은 객체를 사용한 `StreamingResponse` |
|||
|
|||
파일과 같은 객체(예: `open()`으로 반환된 객체)가 있는 경우, 해당 파일과 같은 객체를 반복(iterate)하는 제너레이터 함수를 만들 수 있습니다. |
|||
|
|||
이 방식으로, 파일 전체를 메모리에 먼저 읽어들일 필요 없이, 제너레이터 함수를 `StreamingResponse`에 전달하여 반환할 수 있습니다. |
|||
|
|||
이 방식은 클라우드 스토리지, 비디오 처리 등의 다양한 라이브러리와 함께 사용할 수 있습니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *} |
|||
|
|||
1. 이것이 제너레이터 함수입니다. `yield` 문을 포함하고 있으므로 "제너레이터 함수"입니다. |
|||
2. `with` 블록을 사용함으로써, 제너레이터 함수가 완료된 후 파일과 같은 객체가 닫히도록 합니다. 즉, 응답 전송이 끝난 후 닫힙니다. |
|||
3. 이 `yield from`은 함수가 `file_like`라는 객체를 반복(iterate)하도록 합니다. 반복된 각 부분은 이 제너레이터 함수(`iterfile`)에서 생성된 것처럼 `yield` 됩니다. |
|||
|
|||
이렇게 하면 "생성(generating)" 작업을 내부적으로 다른 무언가에 위임하는 제너레이터 함수가 됩니다. |
|||
|
|||
이 방식을 사용하면 `with` 블록 안에서 파일을 열 수 있어, 작업이 완료된 후 파일과 같은 객체가 닫히는 것을 보장할 수 있습니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
여기서 표준 `open()`을 사용하고 있기 때문에 `async`와 `await`를 지원하지 않습니다. 따라서 경로 작업은 일반 `def`로 선언합니다. |
|||
|
|||
/// |
|||
|
|||
### `FileResponse` |
|||
|
|||
파일을 비동기로 스트리밍하여 응답합니다. |
|||
|
|||
다른 응답 유형과는 다른 인수를 사용하여 객체를 생성합니다: |
|||
|
|||
* `path` - 스트리밍할 파일의 경로. |
|||
* `headers` - 딕셔너리 형식의 사용자 정의 헤더. |
|||
* `media_type` - 미디어 타입을 나타내는 문자열. 설정되지 않은 경우 파일 이름이나 경로를 사용하여 추론합니다. |
|||
* `filename` - 설정된 경우 응답의 `Content-Disposition`에 포함됩니다. |
|||
|
|||
파일 응답에는 적절한 `Content-Length`, `Last-Modified`, 및 `ETag` 헤더가 포함됩니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *} |
|||
|
|||
또한 `response_class` 매개변수를 사용할 수도 있습니다: |
|||
|
|||
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *} |
|||
|
|||
이 경우, 경로 작업 함수에서 파일 경로를 직접 반환할 수 있습니다. |
|||
|
|||
## 사용자 정의 응답 클래스 |
|||
|
|||
`Response`를 상속받아 사용자 정의 응답 클래스를 생성하고 사용할 수 있습니다. |
|||
|
|||
예를 들어, 포함된 `ORJSONResponse` 클래스에서 사용되지 않는 설정으로 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">orjson</a>을 사용하고 싶다고 가정해봅시다. |
|||
|
|||
만약 들여쓰기 및 포맷된 JSON을 반환하고 싶다면, `orjson.OPT_INDENT_2` 옵션을 사용할 수 있습니다. |
|||
|
|||
`CustomORJSONResponse`를 생성할 수 있습니다. 여기서 핵심은 `Response.render(content)` 메서드를 생성하여 내용을 `bytes`로 반환하는 것입니다: |
|||
|
|||
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *} |
|||
|
|||
이제 다음 대신: |
|||
|
|||
```json |
|||
{"message": "Hello World"} |
|||
``` |
|||
|
|||
이 응답은 이렇게 반환됩니다: |
|||
|
|||
```json |
|||
{ |
|||
"message": "Hello World" |
|||
} |
|||
``` |
|||
|
|||
물론 JSON 포맷팅보다 더 유용하게 활용할 방법을 찾을 수 있을 것입니다. 😉 |
|||
|
|||
## 기본 응답 클래스 |
|||
|
|||
**FastAPI** 클래스 객체 또는 `APIRouter`를 생성할 때 기본적으로 사용할 응답 클래스를 지정할 수 있습니다. |
|||
|
|||
이를 정의하는 매개변수는 `default_response_class`입니다. |
|||
|
|||
아래 예제에서 **FastAPI**는 모든 경로 작업에서 기본적으로 `JSONResponse` 대신 `ORJSONResponse`를 사용합니다. |
|||
|
|||
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *} |
|||
|
|||
/// tip | 팁 |
|||
|
|||
여전히 이전처럼 *경로 작업*에서 `response_class`를 재정의할 수 있습니다. |
|||
|
|||
/// |
|||
|
|||
## 추가 문서화 |
|||
|
|||
OpenAPI에서 `responses`를 사용하여 미디어 타입 및 기타 세부 정보를 선언할 수도 있습니다: [OpenAPI에서 추가 응답](additional-responses.md){.internal-link target=_blank}. |
@ -1,162 +1,269 @@ |
|||
* # FastAPI 지원 - 도움말 받기 |
|||
# FastAPI 지원 - 도움 받기 |
|||
|
|||
**FastAPI** 가 마음에 드시나요? |
|||
**FastAPI** 가 마음에 드시나요? |
|||
|
|||
FastAPI, 다른 사용자, 개발자를 응원하고 싶으신가요? |
|||
FastAPI, 다른 사용자, 개발자를 응원하고 싶으신가요? |
|||
|
|||
혹은 **FastAPI** 에 대해 도움이 필요하신가요? |
|||
혹은 **FastAPI** 에 대해 도움이 필요하신가요? |
|||
|
|||
아주 간단하게 응원할 수 있습니다 (몇 번의 클릭만으로). |
|||
아주 간단하게 응원할 수 있습니다 (몇 번의 클릭만으로). |
|||
|
|||
또한 도움을 받을 수 있는 방법도 몇 가지 있습니다. |
|||
또한 도움을 받을 수 있는 방법도 몇 가지 있습니다. |
|||
|
|||
## 뉴스레터 구독 |
|||
## 뉴스레터 구독 |
|||
|
|||
[**FastAPI와 친구** 뉴스레터](https://github.com/fastapi/fastapi/blob/master/newsletter)를 구독하여 최신 정보를 유지할 수 있습니다{.internal-link target=_blank}: |
|||
[**FastAPI and friends** 뉴스레터](newsletter.md){.internal-link target=\_blank}를 구독하여 최신 정보를 유지할 수 있습니다: |
|||
|
|||
- FastAPI 와 그 친구들에 대한 뉴스 🚀 |
|||
- 가이드 📝 |
|||
- 특징 ✨ |
|||
- 획기적인 변화 🚨 |
|||
- 팁과 요령 ✅ |
|||
* FastAPI and friends에 대한 뉴스 🚀 |
|||
* 가이드 📝 |
|||
* 기능 ✨ |
|||
* 획기적인 변화 🚨 |
|||
* 팁과 요령 ✅ |
|||
|
|||
## 트위터에서 FastAPI 팔로우하기 |
|||
## 트위터에서 FastAPI 팔로우하기 |
|||
|
|||
[Follow @fastapi on **Twitter**](https://twitter.com/fastapi) 를 팔로우하여 **FastAPI** 에 대한 최신 뉴스를 얻을 수 있습니다. 🐦 |
|||
<a href="https://twitter.com/fastapi" class="external-link" target="_blank">**Twitter**의 @fastapi를 팔로우</a>하여 **FastAPI** 에 대한 최신 뉴스를 얻을 수 있습니다. 🐦 |
|||
|
|||
## Star **FastAPI** in GitHub |
|||
## Star **FastAPI** in GitHub |
|||
|
|||
GitHub에서 FastAPI에 "star"를 붙일 수 있습니다(오른쪽 상단의 star 버튼을 클릭): https://github.com/fastapi/fastapi. ⭐️ |
|||
GitHub에서 FastAPI에 "star"를 붙일 수 있습니다 (오른쪽 상단의 star 버튼을 클릭): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️ |
|||
|
|||
스타를 늘림으로써, 다른 사용자들이 좀 더 쉽게 찾을 수 있고, 많은 사람들에게 유용한 것임을 나타낼 수 있습니다. |
|||
스타를 늘림으로써, 다른 사용자들이 좀 더 쉽게 찾을 수 있고, 많은 사람들에게 유용한 것임을 나타낼 수 있습니다. |
|||
|
|||
## GitHub 저장소에서 릴리즈 확인 |
|||
## GitHub 저장소에서 릴리즈 확인 |
|||
|
|||
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): https://github.com/fastapi/fastapi. 👀 |
|||
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀 |
|||
|
|||
여기서 "Releases only"을 선택할 수 있습니다. |
|||
여기서 "Releases only"을 선택할 수 있습니다. |
|||
|
|||
이렇게하면, **FastAPI** 의 버그 수정 및 새로운 기능의 구현 등의 새로운 자료 (최신 버전)이 있을 때마다 (이메일) 통지를 받을 수 있습니다. |
|||
이렇게하면, **FastAPI** 의 버그 수정 및 새로운 기능의 구현 등의 새로운 자료 (최신 버전)이 있을 때마다 (이메일) 통지를 받을 수 있습니다. |
|||
|
|||
## 개발자와의 연결 |
|||
## 개발자와의 연결 |
|||
|
|||
개발자인 [me (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com/) 와 연락을 취할 수 있습니다. |
|||
<a href="https://tiangolo.com" class="external-link" target="_blank">개발자(Sebastián Ramírez / `tiangolo`)</a>와 연락을 취할 수 있습니다. |
|||
|
|||
여러분은 할 수 있습니다: |
|||
여러분은 할 수 있습니다: |
|||
|
|||
- [**GitHub**에서 팔로우하기](https://github.com/tiangolo). |
|||
- 당신에게 도움이 될 저의 다른 오픈소스 프로젝트를 확인하십시오. |
|||
- 새로운 오픈소스 프로젝트를 만들었을 때 확인하려면 팔로우 하십시오. |
|||
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">**GitHub**에서 팔로우하기.</a>. |
|||
* 당신에게 도움이 될 저의 다른 오픈소스 프로젝트를 확인하십시오. |
|||
* 새로운 오픈소스 프로젝트를 만들었을 때 확인하려면 팔로우 하십시오. |
|||
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">**Twitter**</a> 또는 <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>에서 팔로우하기. |
|||
* FastAPI의 사용 용도를 알려주세요 (그것을 듣는 것을 좋아합니다). |
|||
* 발표나 새로운 툴 출시 소식을 받아보십시오. |
|||
* <a href="https://twitter.com/fastapi" class="external-link" target="_blank">**Twitter**의 @fastapi를 팔로우</a> (별도 계정에서) 할 수 있습니다. |
|||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**LinkedIn**에서 팔로우하기.</a>. |
|||
* 새로운 툴의 발표나 출시 소식을 받아보십시오. (단, Twitter를 더 자주 사용합니다 🤷♂). |
|||
* <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> 또는 <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>에서 제가 작성한 내용을 읽어 보십시오 (또는 팔로우). |
|||
* 다른 기사나 아이디어들을 읽고, 제가 만들어왔던 툴에 대해서도 읽으십시오. |
|||
* 새로운 기사를 읽기 위해 팔로우 하십시오. |
|||
|
|||
- [**Twitter**에서 팔로우하기](https://twitter.com/tiangolo). |
|||
- FastAPI의 사용 용도를 알려주세요 (그것을 듣는 것을 좋아합니다). |
|||
- 발표 또는 새로운 툴 출시할 때 들으십시오. |
|||
- [follow @fastapi on Twitter](https://twitter.com/fastapi) (별도 계정에서) 할 수 있습니다. |
|||
## **FastAPI**에 대한 트윗 |
|||
|
|||
- [**Linkedin**에서의 연결](https://www.linkedin.com/in/tiangolo/). |
|||
- 새로운 툴의 발표나 릴리스를 들을 수 있습니다 (단, Twitter를 더 자주 사용합니다 🤷♂). |
|||
<a href="https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI**에 대해 트윗</a> 하고 FastAPI가 마음에 드는 이유를 알려주세요. 🎉 |
|||
|
|||
- [**Dev.to**](https://dev.to/tiangolo) 또는 [**Medium**](https://medium.com/@tiangolo)에서 제가 작성한 내용을 읽어 보십시오(또는 팔로우). |
|||
- 다른 기사나 아이디어들을 읽고, 제가 만들어왔던 툴에 대해서도 읽으십시오. |
|||
- 새로운 기사를 읽기 위해 팔로우 하십시오. |
|||
**FastAPI**가 어떻게 사용되고 있는지, 어떤 점이 마음에 들었는지, 어떤 프로젝트/회사에서 사용하고 있는지 등에 대해 듣고 싶습니다. |
|||
|
|||
## **FastAPI**에 대한 트윗 |
|||
## FastAPI에 투표하기 |
|||
|
|||
[**FastAPI**에 대해 트윗](https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi) 하고 FastAPI가 마음에 드는 이유를 알려주세요. 🎉 |
|||
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Slant에서 **FastAPI** 에 대해 투표하십시오</a>. |
|||
* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">AlternativeTo에서 **FastAPI** 에 대해 투표하십시오</a>. |
|||
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">StackShare에서 **FastAPI** 에 대해 투표하십시오</a>. |
|||
|
|||
**FastAPI**가 어떻게 사용되고 있는지, 어떤 점이 마음에 들었는지, 어떤 프로젝트/회사에서 사용하고 있는지 등에 대해 듣고 싶습니다. |
|||
## GitHub의 이슈로 다른사람 돕기 |
|||
|
|||
## FastAPI에 투표하기 |
|||
다른 사람들의 질문에 도움을 줄 수 있습니다: |
|||
|
|||
- [Slant에서 **FastAPI** 에 대해 투표하십시오](https://www.slant.co/options/34241/~fastapi-review). |
|||
- [AlternativeTo**FastAPI** 에 대해 투표하십시오](https://alternativeto.net/software/fastapi/). |
|||
* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub 디스커션</a> |
|||
* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub 이슈</a> |
|||
|
|||
## GitHub의 이슈로 다른사람 돕기 |
|||
많은 경우, 여러분은 이미 그 질문에 대한 답을 알고 있을 수도 있습니다. 🤓 |
|||
|
|||
[존재하는 이슈](https://github.com/fastapi/fastapi/issues)를 확인하고 그것을 시도하고 도와줄 수 있습니다. 대부분의 경우 이미 답을 알고 있는 질문입니다. 🤓 |
|||
만약 많은 사람들의 문제를 도와준다면, 공식적인 [FastAPI 전문가](fastapi-people.md#fastapi-experts){.internal-link target=\_blank} 가 될 것입니다. 🎉 |
|||
|
|||
많은 사람들의 문제를 도와준다면, 공식적인 [FastAPI 전문가](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/fastapi-people.md#experts) 가 될 수 있습니다{.internal-link target=_blank}. 🎉 |
|||
가장 중요한 점은: 친절하려고 노력하는 것입니다. 사람들은 좌절감을 안고 오며, 많은 경우 최선의 방식으로 질문하지 않을 수도 있습니다. 하지만 최대한 친절하게 대하려고 노력하세요. 🤗 |
|||
|
|||
## GitHub 저장소 보기 |
|||
**FastAPI** 커뮤니티의 목표는 친절하고 환영하는 것입니다. 동시에, 괴롭힘이나 무례한 행동을 받아들이지 마세요. 우리는 서로를 돌봐야 합니다. |
|||
|
|||
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): https://github.com/fastapi/fastapi. 👀 |
|||
--- |
|||
|
|||
"Releases only" 대신 "Watching"을 선택하면 다른 사용자가 새로운 issue를 생성할 때 알림이 수신됩니다. |
|||
다른 사람들의 질문 (디스커션 또는 이슈에서) 해결을 도울 수 있는 방법은 다음과 같습니다. |
|||
|
|||
그런 다음 이런 issues를 해결 할 수 있도록 도움을 줄 수 있습니다. |
|||
### 질문 이해하기 |
|||
|
|||
## 이슈 생성하기 |
|||
* 질문하는 사람이 가진 **목적**과 사용 사례를 이해할 수 있는지 확인하세요. |
|||
|
|||
GitHub 저장소에 [새로운 이슈 생성](https://github.com/fastapi/fastapi/issues/new/choose) 을 할 수 있습니다, 예를들면 다음과 같습니다: |
|||
* 질문 (대부분은 질문입니다)이 **명확**한지 확인하세요. |
|||
|
|||
- **질문**을 하거나 **문제**에 대해 질문합니다. |
|||
- 새로운 **기능**을 제안 합니다. |
|||
* 많은 경우, 사용자가 가정한 해결책에 대한 질문을 하지만, 더 **좋은** 해결책이 있을 수 있습니다. 문제와 사용 사례를 더 잘 이해하면 더 나은 **대안적인 해결책**을 제안할 수 있습니다. |
|||
|
|||
**참고**: 만약 이슈를 생성한다면, 저는 여러분에게 다른 사람들을 도와달라고 부탁할 것입니다. 😉 |
|||
* 질문을 이해할 수 없다면, 더 **자세한 정보**를 요청하세요. |
|||
|
|||
## Pull Request를 만드십시오 |
|||
### 문제 재현하기 |
|||
|
|||
Pull Requests를 이용하여 소스코드에 [컨트리뷰트](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/contributing.md){.internal-link target=_blank} 할 수 있습니다. 예를 들면 다음과 같습니다: |
|||
대부분의 경우, 질문은 질문자의 **원본 코드**와 관련이 있습니다. |
|||
|
|||
- 문서에서 찾은 오타를 수정할 때. |
|||
많은 경우, 코드의 일부만 복사해서 올리지만, 그것만으로는 **문제를 재현**하기에 충분하지 않습니다. |
|||
|
|||
- FastAPI를 [편집하여](https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml) 작성했거나 찾은 문서, 비디오 또는 팟캐스트를 공유할 때. |
|||
* 질문자에게 <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">최소한의 재현 가능한 예제</a>를 제공해달라고 요청하세요. 이렇게 하면 코드를 **복사-붙여넣기**하여 직접 실행하고, 동일한 오류나 동작을 확인하거나 사용 사례를 더 잘 이해할 수 있습니다. |
|||
|
|||
- 해당 섹션의 시작 부분에 링크를 추가했는지 확인하십시오. |
|||
* 너그러운 마음이 든다면, 문제 설명만을 기반으로 직접 **예제를 만들어**볼 수도 있습니다. 하지만, 이는 시간이 많이 걸릴 수 있으므로, 먼저 질문을 명확히 해달라고 요청하는 것이 좋습니다. |
|||
|
|||
- 당신의 언어로 [문서 번역하는데](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/contributing.md#translations){.internal-link target=_blank} 기여할 때. |
|||
### 해결책 제안하기 |
|||
|
|||
- 또한 다른 사용자가 만든 번역을 검토하는데 도움을 줄 수도 있습니다. |
|||
* 질문을 충분히 이해한 후에는 가능한 **답변**을 제공할 수 있습니다. |
|||
|
|||
- 새로운 문서의 섹션을 제안할 때. |
|||
* 많은 경우, 질문자의 **근본적인 문제나 사용 사례**를 이해하는 것이 중요합니다. 그들이 시도하는 방법보다 더 나은 해결책이 있을 수 있기 때문입니다. |
|||
|
|||
- 기존 문제/버그를 수정할 때. |
|||
### 해결 요청하기 |
|||
|
|||
- 새로운 feature를 추가할 때. |
|||
질문자가 답변을 확인하고 나면, 당신이 문제를 해결했을 가능성이 높습니다. 축하합니다, **당신은 영웅입니다**! 🦸 |
|||
|
|||
## 채팅에 참여하십시오 |
|||
* 이제 문제를 해결했다면, 질문자에게 다음을 요청할 수 있습니다. |
|||
|
|||
👥 [디스코드 채팅 서버](https://discord.gg/VQjSZaeJmf) 👥 에 가입하고 FastAPI 커뮤니티에서 다른 사람들과 어울리세요. |
|||
* GitHub 디스커션에서: 댓글을 **답변**으로 표시하도록 요청하세요. |
|||
* GitHub 이슈에서: 이슈를 **닫아달라고** 요청하세요. |
|||
|
|||
/// tip |
|||
## GitHub 저장소 보기 |
|||
|
|||
질문이 있는 경우, [GitHub 이슈 ](https://github.com/fastapi/fastapi/issues/new/choose) 에서 질문하십시오, [FastAPI 전문가](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/fastapi-people.md#experts) 의 도움을 받을 가능성이 높습니다{.internal-link target=_blank} . |
|||
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀 |
|||
|
|||
/// |
|||
"Releases only" 대신 "Watching"을 선택하면, 새로운 이슈나 질문이 생성될 때 알림을 받을 수 있습니다. 또한, 특정하게 새로운 이슈, 디스커션, PR 등만 알림 받도록 설정할 수도 있습니다. |
|||
|
|||
``` |
|||
다른 일반적인 대화에서만 채팅을 사용하십시오. |
|||
``` |
|||
그런 다음 이런 이슈들을 해결 할 수 있도록 도움을 줄 수 있습니다. |
|||
|
|||
기존 [지터 채팅](https://gitter.im/fastapi/fastapi) 이 있지만 채널과 고급기능이 없어서 대화를 하기가 조금 어렵기 때문에 지금은 디스코드가 권장되는 시스템입니다. |
|||
## 이슈 생성하기 |
|||
|
|||
### 질문을 위해 채팅을 사용하지 마십시오 |
|||
GitHub 저장소에 <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">새로운 이슈 생성</a>을 할 수 있습니다, 예를들면 다음과 같습니다: |
|||
|
|||
채팅은 더 많은 "자유로운 대화"를 허용하기 때문에, 너무 일반적인 질문이나 대답하기 어려운 질문을 쉽게 질문을 할 수 있으므로, 답변을 받지 못할 수 있습니다. |
|||
* **질문**을 하거나 **문제**에 대해 질문합니다. |
|||
* 새로운 **기능**을 제안 합니다. |
|||
|
|||
GitHub 이슈에서의 템플릿은 올바른 질문을 작성하도록 안내하여 더 쉽게 좋은 답변을 얻거나 질문하기 전에 스스로 문제를 해결할 수도 있습니다. 그리고 GitHub에서는 시간이 조금 걸리더라도 항상 모든 것에 답할 수 있습니다. 채팅 시스템에서는 개인적으로 그렇게 할 수 없습니다. 😅 |
|||
**참고**: 만약 이슈를 생성한다면, 저는 여러분에게 다른 사람들을 도와달라고 부탁할 것입니다. 😉 |
|||
|
|||
채팅 시스템에서의 대화 또한 GitHub에서 처럼 쉽게 검색할 수 없기 때문에 대화 중에 질문과 답변이 손실될 수 있습니다. 그리고 GitHub 이슈에 있는 것만 [FastAPI 전문가](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/fastapi-people.md#experts)가 되는 것으로 간주되므로{.internal-link target=_blank} , GitHub 이슈에서 더 많은 관심을 받을 것입니다. |
|||
## Pull Requests 리뷰하기 |
|||
|
|||
반면, 채팅 시스템에는 수천 명의 사용자가 있기 때문에, 거의 항상 대화 상대를 찾을 가능성이 높습니다. 😄 |
|||
다른 사람들의 pull request를 리뷰하는 데 도움을 줄 수 있습니다. |
|||
|
|||
## 개발자 스폰서가 되십시오 |
|||
다시 한번 말하지만, 최대한 친절하게 리뷰해 주세요. 🤗 |
|||
|
|||
[GitHub 스폰서](https://github.com/sponsors/tiangolo) 를 통해 개발자를 경제적으로 지원할 수 있습니다. |
|||
--- |
|||
|
|||
감사하다는 말로 커피를 ☕️ 한잔 사줄 수 있습니다. 😄 |
|||
Pull Rrquest를 리뷰할 때 고려해야 할 사항과 방법은 다음과 같습니다: |
|||
|
|||
또한 FastAPI의 실버 또는 골드 스폰서가 될 수 있습니다. 🏅🎉 |
|||
### 문제 이해하기 |
|||
|
|||
## FastAPI를 강화하는 도구의 스폰서가 되십시오 |
|||
* 먼저, 해당 pull request가 해결하려는 **문제를 이해하는지** 확인하세요. GitHub 디스커션 또는 이슈에서 더 긴 논의가 있었을 수도 있습니다. |
|||
|
|||
문서에서 보았듯이, FastAPI는 Starlette과 Pydantic 라는 거인의 어깨에 타고 있습니다. |
|||
* Pull request가 필요하지 않을 가능성도 있습니다. **다른 방식**으로 문제를 해결할 수 있다면, 그 방법을 제안하거나 질문할 수 있습니다. |
|||
|
|||
다음의 스폰서가 될 수 있습니다 |
|||
### 스타일에 너무 신경 쓰지 않기 |
|||
|
|||
- [Samuel Colvin (Pydantic)](https://github.com/sponsors/samuelcolvin) |
|||
- [Encode (Starlette, Uvicorn)](https://github.com/sponsors/encode) |
|||
* 커밋 메시지 스타일 같은 것에 너무 신경 쓰지 않아도 됩니다. 저는 직접 커밋을 수정하여 squash and merge를 수행할 것입니다. |
|||
|
|||
------ |
|||
* 코드 스타일 규칙도 걱정할 필요 없습니다. 이미 자동화된 도구들이 이를 검사하고 있습니다. |
|||
|
|||
감사합니다! 🚀 |
|||
스타일이나 일관성 관련 요청이 필요한 경우, 제가 직접 요청하거나 필요한 변경 사항을 추가 커밋으로 수정할 것입니다. |
|||
|
|||
### 코드 확인하기 |
|||
|
|||
* 코드를 읽고, **논리적으로 타당**한지 확인한 후 로컬에서 실행하여 문제가 해결되는지 확인하세요. |
|||
|
|||
* 그런 다음, 확인했다고 **댓글**을 남겨 주세요. 그래야 제가 검토했음을 알 수 있습니다. |
|||
|
|||
/// info |
|||
|
|||
불행히도, 제가 단순히 여러 개의 승인만으로 PR을 신뢰할 수는 없습니다. |
|||
|
|||
3개, 5개 이상의 승인이 달린 PR이 실제로는 깨져 있거나, 버그가 있거나, 주장하는 문제를 해결하지 못하는 경우가 여러 번 있었습니다. 😅 |
|||
|
|||
따라서, 정말로 코드를 읽고 실행한 뒤, 댓글로 확인 내용을 남겨 주는 것이 매우 중요합니다. 🤓 |
|||
|
|||
/// |
|||
|
|||
* PR을 더 단순하게 만들 수 있다면 그렇게 요청할 수 있지만, 너무 까다로울 필요는 없습니다. 주관적인 견해가 많이 있을 수 있기 때문입니다 (그리고 저도 제 견해가 있을 거예요 🙈). 따라서 핵심적인 부분에 집중하는 것이 좋습니다. |
|||
|
|||
### 테스트 |
|||
|
|||
* PR에 **테스트**가 포함되어 있는지 확인하는 데 도움을 주세요. |
|||
|
|||
* PR을 적용하기 전에 테스트가 **실패**하는지 확인하세요. 🚨 |
|||
|
|||
* PR을 적용한 후 테스트가 **통과**하는지 확인하세요. ✅ |
|||
|
|||
* 많은 PR에는 테스트가 없습니다. 테스트를 추가하도록 **상기**시켜줄 수도 있고, 직접 테스트를 **제안**할 수도 있습니다. 이는 시간이 많이 소요되는 부분 중 하나이며, 그 부분을 많이 도와줄 수 있습니다. |
|||
|
|||
* 그리고 시도한 내용을 댓글로 남겨주세요. 그러면 제가 확인했다는 걸 알 수 있습니다. 🤓 |
|||
|
|||
## Pull Request를 만드십시오 |
|||
|
|||
Pull Requests를 이용하여 소스코드에 [컨트리뷰트](contributing.md){.internal-link target=\_blank} 할 수 있습니다. 예를 들면 다음과 같습니다: |
|||
|
|||
* 문서에서 발견한 오타를 수정할 때. |
|||
* FastAPI 관련 문서, 비디오 또는 팟캐스트를 작성했거나 발견하여 <a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">이 파일을 편집하여</a> 공유할 때. |
|||
* 해당 섹션의 시작 부분에 링크를 추가해야 합니다. |
|||
* 당신의 언어로 [문서 번역하는데](contributing.md#translations){.internal-link target=\_blank} 기여할 때. |
|||
* 다른 사람이 작성한 번역을 검토하는 것도 도울 수 있습니다. |
|||
* 새로운 문서의 섹션을 제안할 때. |
|||
* 기존 문제/버그를 수정할 때. |
|||
* 테스트를 반드시 추가해야 합니다. |
|||
* 새로운 feature를 추가할 때. |
|||
* 테스트를 반드시 추가해야 합니다. |
|||
* 관련 문서가 필요하다면 반드시 추가해야 합니다. |
|||
|
|||
## FastAPI 유지 관리에 도움 주기 |
|||
|
|||
**FastAPI**의 유지 관리를 도와주세요! 🤓 |
|||
|
|||
할 일이 많고, 그 중 대부분은 **여러분**이 할 수 있습니다. |
|||
|
|||
지금 할 수 있는 주요 작업은: |
|||
|
|||
* [GitHub에서 다른 사람들의 질문에 도움 주기](#github_1){.internal-link target=_blank} (위의 섹션을 참조하세요). |
|||
* [Pull Request 리뷰하기](#pull-requests){.internal-link target=_blank} (위의 섹션을 참조하세요). |
|||
|
|||
이 두 작업이 **가장 많은 시간을 소모**하는 일입니다. 그것이 FastAPI 유지 관리의 주요 작업입니다. |
|||
|
|||
이 작업을 도와주신다면, **FastAPI 유지 관리에 도움을 주는 것**이며 그것이 **더 빠르고 더 잘 발전하는 것**을 보장하는 것입니다. 🚀 |
|||
|
|||
## 채팅에 참여하십시오 |
|||
|
|||
👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">디스코드 채팅 서버</a> 👥 에 가입하고 FastAPI 커뮤니티에서 다른 사람들과 어울리세요. |
|||
|
|||
/// tip |
|||
|
|||
질문이 있는 경우, <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub 디스커션</a> 에서 질문하십시오, [FastAPI Experts](fastapi-people.md#fastapi-experts){.internal-link target=_blank} 의 도움을 받을 가능성이 높습니다. |
|||
|
|||
다른 일반적인 대화에서만 채팅을 사용하십시오. |
|||
|
|||
/// |
|||
|
|||
### 질문을 위해 채팅을 사용하지 마십시오 |
|||
|
|||
채팅은 더 많은 "자유로운 대화"를 허용하기 때문에, 너무 일반적인 질문이나 대답하기 어려운 질문을 쉽게 질문을 할 수 있으므로, 답변을 받지 못할 수 있습니다. |
|||
|
|||
GitHub 이슈에서의 템플릿은 올바른 질문을 작성하도록 안내하여 더 쉽게 좋은 답변을 얻거나 질문하기 전에 스스로 문제를 해결할 수도 있습니다. 그리고 GitHub에서는 시간이 조금 걸리더라도 항상 모든 것에 답할 수 있습니다. 채팅 시스템에서는 개인적으로 그렇게 할 수 없습니다. 😅 |
|||
|
|||
채팅 시스템에서의 대화 또한 GitHub에서 처럼 쉽게 검색할 수 없기 때문에 대화 중에 질문과 답변이 손실될 수 있습니다. 그리고 GitHub 이슈에 있는 것만 [FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}가 되는 것으로 간주되므로, GitHub 이슈에서 더 많은 관심을 받을 것입니다. |
|||
|
|||
반면, 채팅 시스템에는 수천 명의 사용자가 있기 때문에, 거의 항상 대화 상대를 찾을 가능성이 높습니다. 😄 |
|||
|
|||
## 개발자 스폰서가 되십시오 |
|||
|
|||
<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub 스폰서</a> 를 통해 개발자를 경제적으로 지원할 수 있습니다. |
|||
|
|||
감사하다는 말로 커피를 ☕️ 한잔 사줄 수 있습니다. 😄 |
|||
|
|||
또한 FastAPI의 실버 또는 골드 스폰서가 될 수 있습니다. 🏅🎉 |
|||
|
|||
## FastAPI를 강화하는 도구의 스폰서가 되십시오 |
|||
|
|||
문서에서 보았듯이, FastAPI는 Starlette과 Pydantic 라는 거인의 어깨에 타고 있습니다. |
|||
|
|||
다음의 스폰서가 될 수 있습니다 |
|||
|
|||
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a> |
|||
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a> |
|||
|
|||
--- |
|||
|
|||
감사합니다! 🚀 |
|||
|
@ -1,11 +0,0 @@ |
|||
from fastapi import FastAPI, Query |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/items/") |
|||
async def read_items(q: str = Query(default=..., min_length=3)): |
|||
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
if q: |
|||
results.update({"q": q}) |
|||
return results |
@ -1,12 +0,0 @@ |
|||
from fastapi import FastAPI, Query |
|||
from typing_extensions import Annotated |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/items/") |
|||
async def read_items(q: Annotated[str, Query(min_length=3)] = ...): |
|||
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
if q: |
|||
results.update({"q": q}) |
|||
return results |
@ -1,13 +0,0 @@ |
|||
from typing import Annotated |
|||
|
|||
from fastapi import FastAPI, Query |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/items/") |
|||
async def read_items(q: Annotated[str, Query(min_length=3)] = ...): |
|||
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
if q: |
|||
results.update({"q": q}) |
|||
return results |
@ -1,11 +0,0 @@ |
|||
from fastapi import FastAPI, Query |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/items/") |
|||
async def read_items(q: str = Query(default=..., min_length=3)): |
|||
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
if q: |
|||
results.update({"q": q}) |
|||
return results |
@ -1,12 +0,0 @@ |
|||
from fastapi import FastAPI, Query |
|||
from typing_extensions import Annotated |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/items/") |
|||
async def read_items(q: Annotated[str, Query(min_length=3)] = ...): |
|||
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
if q: |
|||
results.update({"q": q}) |
|||
return results |
@ -1,13 +0,0 @@ |
|||
from typing import Annotated |
|||
|
|||
from fastapi import FastAPI, Query |
|||
|
|||
app = FastAPI() |
|||
|
|||
|
|||
@app.get("/items/") |
|||
async def read_items(q: Annotated[str, Query(min_length=3)] = ...): |
|||
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
if q: |
|||
results.update({"q": q}) |
|||
return results |
@ -1,168 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE |
|||
from fastapi.testclient import TestClient |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial010_an import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
def test_query_params_str_validations_no_query(client: TestClient): |
|||
response = client.get("/items/") |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
def test_query_params_str_validations_item_query_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == { |
|||
"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], |
|||
"q": "fixedquery", |
|||
} |
|||
|
|||
|
|||
def test_query_params_str_validations_q_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"q": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
def test_query_params_str_validations_item_query_nonregexquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "nonregexquery"}) |
|||
assert response.status_code == 422 |
|||
assert response.json() == IsDict( |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"type": "string_pattern_mismatch", |
|||
"loc": ["query", "item-query"], |
|||
"msg": "String should match pattern '^fixedquery$'", |
|||
"input": "nonregexquery", |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
} |
|||
] |
|||
} |
|||
) | IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
"loc": ["query", "item-query"], |
|||
"msg": 'string does not match regex "^fixedquery$"', |
|||
"type": "value_error.str.regex", |
|||
} |
|||
] |
|||
} |
|||
) |
|||
|
|||
|
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
"required": False, |
|||
"deprecated": True, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{ |
|||
"type": "string", |
|||
"minLength": 3, |
|||
"maxLength": 50, |
|||
"pattern": "^fixedquery$", |
|||
}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Query string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34. |
|||
**( |
|||
{"deprecated": True} |
|||
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10) |
|||
else {} |
|||
), |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Query string", |
|||
"maxLength": 50, |
|||
"minLength": 3, |
|||
"pattern": "^fixedquery$", |
|||
"type": "string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
} |
|||
), |
|||
"name": "item-query", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,175 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial010_an_py310 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_no_query(client: TestClient): |
|||
response = client.get("/items/") |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_item_query_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == { |
|||
"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], |
|||
"q": "fixedquery", |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_q_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"q": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_item_query_nonregexquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "nonregexquery"}) |
|||
assert response.status_code == 422 |
|||
assert response.json() == IsDict( |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"type": "string_pattern_mismatch", |
|||
"loc": ["query", "item-query"], |
|||
"msg": "String should match pattern '^fixedquery$'", |
|||
"input": "nonregexquery", |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
} |
|||
] |
|||
} |
|||
) | IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
"loc": ["query", "item-query"], |
|||
"msg": 'string does not match regex "^fixedquery$"', |
|||
"type": "value_error.str.regex", |
|||
} |
|||
] |
|||
} |
|||
) |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
"required": False, |
|||
"deprecated": True, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{ |
|||
"type": "string", |
|||
"minLength": 3, |
|||
"maxLength": 50, |
|||
"pattern": "^fixedquery$", |
|||
}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Query string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34. |
|||
**( |
|||
{"deprecated": True} |
|||
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10) |
|||
else {} |
|||
), |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Query string", |
|||
"maxLength": 50, |
|||
"minLength": 3, |
|||
"pattern": "^fixedquery$", |
|||
"type": "string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
} |
|||
), |
|||
"name": "item-query", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,175 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial010_an_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_params_str_validations_no_query(client: TestClient): |
|||
response = client.get("/items/") |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_params_str_validations_item_query_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == { |
|||
"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], |
|||
"q": "fixedquery", |
|||
} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_params_str_validations_q_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"q": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_params_str_validations_item_query_nonregexquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "nonregexquery"}) |
|||
assert response.status_code == 422 |
|||
assert response.json() == IsDict( |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"type": "string_pattern_mismatch", |
|||
"loc": ["query", "item-query"], |
|||
"msg": "String should match pattern '^fixedquery$'", |
|||
"input": "nonregexquery", |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
} |
|||
] |
|||
} |
|||
) | IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
"loc": ["query", "item-query"], |
|||
"msg": 'string does not match regex "^fixedquery$"', |
|||
"type": "value_error.str.regex", |
|||
} |
|||
] |
|||
} |
|||
) |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
"required": False, |
|||
"deprecated": True, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{ |
|||
"type": "string", |
|||
"minLength": 3, |
|||
"maxLength": 50, |
|||
"pattern": "^fixedquery$", |
|||
}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Query string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34. |
|||
**( |
|||
{"deprecated": True} |
|||
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10) |
|||
else {} |
|||
), |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Query string", |
|||
"maxLength": 50, |
|||
"minLength": 3, |
|||
"pattern": "^fixedquery$", |
|||
"type": "string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
} |
|||
), |
|||
"name": "item-query", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,175 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial010_py310 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_no_query(client: TestClient): |
|||
response = client.get("/items/") |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_item_query_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == { |
|||
"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], |
|||
"q": "fixedquery", |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_q_fixedquery(client: TestClient): |
|||
response = client.get("/items/", params={"q": "fixedquery"}) |
|||
assert response.status_code == 200 |
|||
assert response.json() == {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_params_str_validations_item_query_nonregexquery(client: TestClient): |
|||
response = client.get("/items/", params={"item-query": "nonregexquery"}) |
|||
assert response.status_code == 422 |
|||
assert response.json() == IsDict( |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"type": "string_pattern_mismatch", |
|||
"loc": ["query", "item-query"], |
|||
"msg": "String should match pattern '^fixedquery$'", |
|||
"input": "nonregexquery", |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
} |
|||
] |
|||
} |
|||
) | IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"detail": [ |
|||
{ |
|||
"ctx": {"pattern": "^fixedquery$"}, |
|||
"loc": ["query", "item-query"], |
|||
"msg": 'string does not match regex "^fixedquery$"', |
|||
"type": "value_error.str.regex", |
|||
} |
|||
] |
|||
} |
|||
) |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
"required": False, |
|||
"deprecated": True, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{ |
|||
"type": "string", |
|||
"minLength": 3, |
|||
"maxLength": 50, |
|||
"pattern": "^fixedquery$", |
|||
}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Query string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34. |
|||
**( |
|||
{"deprecated": True} |
|||
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10) |
|||
else {} |
|||
), |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Query string", |
|||
"maxLength": 50, |
|||
"minLength": 3, |
|||
"pattern": "^fixedquery$", |
|||
"type": "string", |
|||
"description": "Query string for the items to search in the database that have a good match", |
|||
} |
|||
), |
|||
"name": "item-query", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,108 +0,0 @@ |
|||
from dirty_equals import IsDict |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from docs_src.query_params_str_validations.tutorial011_an import app |
|||
|
|||
client = TestClient(app) |
|||
|
|||
|
|||
def test_multi_query_values(): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
def test_query_no_values(): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": None} |
|||
|
|||
|
|||
def test_openapi_schema(): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{"type": "array", "items": {"type": "string"}}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Q", |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
} |
|||
), |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,118 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial011_an_py310 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_no_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": None} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{"type": "array", "items": {"type": "string"}}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Q", |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
} |
|||
), |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,118 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial011_an_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_no_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": None} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{"type": "array", "items": {"type": "string"}}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Q", |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
} |
|||
), |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,118 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial011_py310 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_query_no_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": None} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{"type": "array", "items": {"type": "string"}}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Q", |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
} |
|||
), |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,118 +0,0 @@ |
|||
import pytest |
|||
from dirty_equals import IsDict |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial011_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_no_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": None} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": IsDict( |
|||
{ |
|||
"anyOf": [ |
|||
{"type": "array", "items": {"type": "string"}}, |
|||
{"type": "null"}, |
|||
], |
|||
"title": "Q", |
|||
} |
|||
) |
|||
| IsDict( |
|||
# TODO: remove when deprecating Pydantic v1 |
|||
{ |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
} |
|||
), |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,96 +0,0 @@ |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from docs_src.query_params_str_validations.tutorial012_an import app |
|||
|
|||
client = TestClient(app) |
|||
|
|||
|
|||
def test_default_query_values(): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
def test_multi_query_values(): |
|||
url = "/items/?q=baz&q=foobar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["baz", "foobar"]} |
|||
|
|||
|
|||
def test_openapi_schema(): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": { |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
"default": ["foo", "bar"], |
|||
}, |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,106 +0,0 @@ |
|||
import pytest |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial012_an_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_default_query_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=baz&q=foobar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["baz", "foobar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": { |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
"default": ["foo", "bar"], |
|||
}, |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,106 +0,0 @@ |
|||
import pytest |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial012_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_default_query_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=baz&q=foobar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["baz", "foobar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": { |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {"type": "string"}, |
|||
"default": ["foo", "bar"], |
|||
}, |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,96 +0,0 @@ |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from docs_src.query_params_str_validations.tutorial013_an import app |
|||
|
|||
client = TestClient(app) |
|||
|
|||
|
|||
def test_multi_query_values(): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
def test_query_no_values(): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": []} |
|||
|
|||
|
|||
def test_openapi_schema(): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": { |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {}, |
|||
"default": [], |
|||
}, |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,106 +0,0 @@ |
|||
import pytest |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial013_an_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_multi_query_values(client: TestClient): |
|||
url = "/items/?q=foo&q=bar" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": ["foo", "bar"]} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_query_no_values(client: TestClient): |
|||
url = "/items/" |
|||
response = client.get(url) |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"q": []} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"parameters": [ |
|||
{ |
|||
"required": False, |
|||
"schema": { |
|||
"title": "Q", |
|||
"type": "array", |
|||
"items": {}, |
|||
"default": [], |
|||
}, |
|||
"name": "q", |
|||
"in": "query", |
|||
} |
|||
], |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,81 +0,0 @@ |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from docs_src.query_params_str_validations.tutorial014_an import app |
|||
|
|||
client = TestClient(app) |
|||
|
|||
|
|||
def test_hidden_query(): |
|||
response = client.get("/items?hidden_query=somevalue") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "somevalue"} |
|||
|
|||
|
|||
def test_no_hidden_query(): |
|||
response = client.get("/items") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "Not found"} |
|||
|
|||
|
|||
def test_openapi_schema(): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,91 +0,0 @@ |
|||
import pytest |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial014_an_py310 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_hidden_query(client: TestClient): |
|||
response = client.get("/items?hidden_query=somevalue") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "somevalue"} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_no_hidden_query(client: TestClient): |
|||
response = client.get("/items") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "Not found"} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,91 +0,0 @@ |
|||
import pytest |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial014_an_py39 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_hidden_query(client: TestClient): |
|||
response = client.get("/items?hidden_query=somevalue") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "somevalue"} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_no_hidden_query(client: TestClient): |
|||
response = client.get("/items") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "Not found"} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,91 +0,0 @@ |
|||
import pytest |
|||
from fastapi.testclient import TestClient |
|||
|
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@pytest.fixture(name="client") |
|||
def get_client(): |
|||
from docs_src.query_params_str_validations.tutorial014_py310 import app |
|||
|
|||
client = TestClient(app) |
|||
return client |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_hidden_query(client: TestClient): |
|||
response = client.get("/items?hidden_query=somevalue") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "somevalue"} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_no_hidden_query(client: TestClient): |
|||
response = client.get("/items") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == {"hidden_query": "Not found"} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_openapi_schema(client: TestClient): |
|||
response = client.get("/openapi.json") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"openapi": "3.1.0", |
|||
"info": {"title": "FastAPI", "version": "0.1.0"}, |
|||
"paths": { |
|||
"/items/": { |
|||
"get": { |
|||
"summary": "Read Items", |
|||
"operationId": "read_items_items__get", |
|||
"responses": { |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": {"application/json": {"schema": {}}}, |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
}, |
|||
}, |
|||
}, |
|||
} |
|||
} |
|||
}, |
|||
"components": { |
|||
"schemas": { |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": {"$ref": "#/components/schemas/ValidationError"}, |
|||
} |
|||
}, |
|||
}, |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": ["loc", "msg", "type"], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"anyOf": [{"type": "string"}, {"type": "integer"}] |
|||
}, |
|||
}, |
|||
"msg": {"title": "Message", "type": "string"}, |
|||
"type": {"title": "Error Type", "type": "string"}, |
|||
}, |
|||
}, |
|||
} |
|||
}, |
|||
} |
@ -1,10 +0,0 @@ |
|||
from docs_src.app_testing.app_b_an import test_main |
|||
|
|||
|
|||
def test_app(): |
|||
test_main.test_create_existing_item() |
|||
test_main.test_create_item() |
|||
test_main.test_create_item_bad_token() |
|||
test_main.test_read_nonexistent_item() |
|||
test_main.test_read_item() |
|||
test_main.test_read_item_bad_token() |
@ -1,13 +0,0 @@ |
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_app(): |
|||
from docs_src.app_testing.app_b_an_py310 import test_main |
|||
|
|||
test_main.test_create_existing_item() |
|||
test_main.test_create_item() |
|||
test_main.test_create_item_bad_token() |
|||
test_main.test_read_nonexistent_item() |
|||
test_main.test_read_item() |
|||
test_main.test_read_item_bad_token() |
@ -1,13 +0,0 @@ |
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_app(): |
|||
from docs_src.app_testing.app_b_an_py39 import test_main |
|||
|
|||
test_main.test_create_existing_item() |
|||
test_main.test_create_item() |
|||
test_main.test_create_item_bad_token() |
|||
test_main.test_read_nonexistent_item() |
|||
test_main.test_read_item() |
|||
test_main.test_read_item_bad_token() |
@ -1,13 +0,0 @@ |
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_app(): |
|||
from docs_src.app_testing.app_b_py310 import test_main |
|||
|
|||
test_main.test_create_existing_item() |
|||
test_main.test_create_item() |
|||
test_main.test_create_item_bad_token() |
|||
test_main.test_read_nonexistent_item() |
|||
test_main.test_read_item() |
|||
test_main.test_read_item_bad_token() |
@ -1,56 +0,0 @@ |
|||
from docs_src.dependency_testing.tutorial001_an import ( |
|||
app, |
|||
client, |
|||
test_override_in_items, |
|||
test_override_in_items_with_params, |
|||
test_override_in_items_with_q, |
|||
) |
|||
|
|||
|
|||
def test_override_in_items_run(): |
|||
test_override_in_items() |
|||
|
|||
|
|||
def test_override_in_items_with_q_run(): |
|||
test_override_in_items_with_q() |
|||
|
|||
|
|||
def test_override_in_items_with_params_run(): |
|||
test_override_in_items_with_params() |
|||
|
|||
|
|||
def test_override_in_users(): |
|||
response = client.get("/users/") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": None, "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
def test_override_in_users_with_q(): |
|||
response = client.get("/users/?q=foo") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
def test_override_in_users_with_params(): |
|||
response = client.get("/users/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
def test_normal_app(): |
|||
app.dependency_overrides = None |
|||
response = client.get("/items/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Items!", |
|||
"params": {"q": "foo", "skip": 100, "limit": 200}, |
|||
} |
@ -1,75 +0,0 @@ |
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_items_run(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import test_override_in_items |
|||
|
|||
test_override_in_items() |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_items_with_q_run(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import ( |
|||
test_override_in_items_with_q, |
|||
) |
|||
|
|||
test_override_in_items_with_q() |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_items_with_params_run(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import ( |
|||
test_override_in_items_with_params, |
|||
) |
|||
|
|||
test_override_in_items_with_params() |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_users(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import client |
|||
|
|||
response = client.get("/users/") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": None, "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_users_with_q(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import client |
|||
|
|||
response = client.get("/users/?q=foo") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_users_with_params(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import client |
|||
|
|||
response = client.get("/users/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_normal_app(): |
|||
from docs_src.dependency_testing.tutorial001_an_py310 import app, client |
|||
|
|||
app.dependency_overrides = None |
|||
response = client.get("/items/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Items!", |
|||
"params": {"q": "foo", "skip": 100, "limit": 200}, |
|||
} |
@ -1,75 +0,0 @@ |
|||
from ...utils import needs_py39 |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_override_in_items_run(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import test_override_in_items |
|||
|
|||
test_override_in_items() |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_override_in_items_with_q_run(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import ( |
|||
test_override_in_items_with_q, |
|||
) |
|||
|
|||
test_override_in_items_with_q() |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_override_in_items_with_params_run(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import ( |
|||
test_override_in_items_with_params, |
|||
) |
|||
|
|||
test_override_in_items_with_params() |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_override_in_users(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import client |
|||
|
|||
response = client.get("/users/") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": None, "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_override_in_users_with_q(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import client |
|||
|
|||
response = client.get("/users/?q=foo") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_override_in_users_with_params(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import client |
|||
|
|||
response = client.get("/users/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py39 |
|||
def test_normal_app(): |
|||
from docs_src.dependency_testing.tutorial001_an_py39 import app, client |
|||
|
|||
app.dependency_overrides = None |
|||
response = client.get("/items/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Items!", |
|||
"params": {"q": "foo", "skip": 100, "limit": 200}, |
|||
} |
@ -1,75 +0,0 @@ |
|||
from ...utils import needs_py310 |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_items_run(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import test_override_in_items |
|||
|
|||
test_override_in_items() |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_items_with_q_run(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import ( |
|||
test_override_in_items_with_q, |
|||
) |
|||
|
|||
test_override_in_items_with_q() |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_items_with_params_run(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import ( |
|||
test_override_in_items_with_params, |
|||
) |
|||
|
|||
test_override_in_items_with_params() |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_users(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import client |
|||
|
|||
response = client.get("/users/") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": None, "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_users_with_q(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import client |
|||
|
|||
response = client.get("/users/?q=foo") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_override_in_users_with_params(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import client |
|||
|
|||
response = client.get("/users/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Users!", |
|||
"params": {"q": "foo", "skip": 5, "limit": 10}, |
|||
} |
|||
|
|||
|
|||
@needs_py310 |
|||
def test_normal_app(): |
|||
from docs_src.dependency_testing.tutorial001_py310 import app, client |
|||
|
|||
app.dependency_overrides = None |
|||
response = client.get("/items/?q=foo&skip=100&limit=200") |
|||
assert response.status_code == 200, response.text |
|||
assert response.json() == { |
|||
"message": "Hello Items!", |
|||
"params": {"q": "foo", "skip": 100, "limit": 200}, |
|||
} |
Loading…
Reference in new issue