diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6a512a019..c9723b25b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ jobs: id: cache with: path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v04 + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v05 - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' run: pip install -r requirements-tests.txt @@ -62,7 +62,7 @@ jobs: id: cache with: path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v04 + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v05 - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' run: pip install -r requirements-tests.txt diff --git a/.gitignore b/.gitignore index d380d16b7..9be494cec 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ archive.zip *~ .*.sw? .cache + +# macOS +.DS_Store diff --git a/README.md b/README.md index 50f80ded6..266213426 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ The key features are: + @@ -56,6 +57,7 @@ The key features are: + diff --git a/docs/em/docs/advanced/extending-openapi.md b/docs/em/docs/advanced/extending-openapi.md deleted file mode 100644 index 496a8d9de..000000000 --- a/docs/em/docs/advanced/extending-openapi.md +++ /dev/null @@ -1,314 +0,0 @@ -# โ†” ๐Ÿ—„ - -!!! warning - ๐Ÿ‘‰ ๐Ÿ‘ ๐Ÿง โš’. ๐Ÿ‘† ๐ŸŽฒ ๐Ÿ’ช ๐Ÿšถ โšซ๏ธ. - - ๐Ÿšฅ ๐Ÿ‘† ๐Ÿ“„ ๐Ÿ”ฐ - ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿฆฎ, ๐Ÿ‘† ๐Ÿ’ช ๐ŸŽฒ ๐Ÿšถ ๐Ÿ‘‰ ๐Ÿ“„. - - ๐Ÿšฅ ๐Ÿ‘† โช ๐Ÿ’ญ ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ”€ ๐Ÿ— ๐Ÿ—„ ๐Ÿ”—, ๐Ÿ˜ฃ ๐Ÿ‘‚. - -๐Ÿ“ค ๐Ÿ’ผ ๐ŸŒโ” ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ’ช ๐Ÿ”€ ๐Ÿ— ๐Ÿ—„ ๐Ÿ”—. - -๐Ÿ‘‰ ๐Ÿ“„ ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ โ”. - -## ๐Ÿ˜ ๐Ÿ› ๏ธ - -๐Ÿ˜ (๐Ÿ”ข) ๐Ÿ› ๏ธ, โฉ. - -`FastAPI` ๐Ÿˆธ (๐Ÿ‘) โœ”๏ธ `.openapi()` ๐Ÿ‘ฉโ€๐Ÿ”ฌ ๐Ÿ‘ˆ ๐Ÿ“ˆ ๐Ÿ“จ ๐Ÿ—„ ๐Ÿ”—. - -๐Ÿ• ๐Ÿˆธ ๐ŸŽš ๐Ÿ—, *โžก ๐Ÿ› ๏ธ* `/openapi.json` (โš–๏ธ โšซ๏ธโ” ๐Ÿ‘† โš’ ๐Ÿ‘† `openapi_url`) ยฎ. - -โšซ๏ธ ๐Ÿ“จ ๐ŸŽป ๐Ÿ“จ โฎ๏ธ ๐Ÿ ๐Ÿˆธ `.openapi()` ๐Ÿ‘ฉโ€๐Ÿ”ฌ. - -๐Ÿ”ข, โšซ๏ธโ” ๐Ÿ‘ฉโ€๐Ÿ”ฌ `.openapi()` ๐Ÿ”จ โœ… ๐Ÿ  `.openapi_schema` ๐Ÿ‘€ ๐Ÿšฅ โšซ๏ธ โœ”๏ธ ๐ŸŽš & ๐Ÿ“จ ๐Ÿ‘ซ. - -๐Ÿšฅ โšซ๏ธ ๐Ÿšซ, โšซ๏ธ ๐Ÿ— ๐Ÿ‘ซ โš™๏ธ ๐Ÿš™ ๐Ÿ”ข `fastapi.openapi.utils.get_openapi`. - -& ๐Ÿ‘ˆ ๐Ÿ”ข `get_openapi()` ๐Ÿ“จ ๐Ÿ”ข: - -* `title`: ๐Ÿ—„ ๐Ÿ“›, ๐ŸŽฆ ๐Ÿฉบ. -* `version`: โฌ ๐Ÿ‘† ๐Ÿ› ๏ธ, โœ… `2.5.0`. -* `openapi_version`: โฌ ๐Ÿ—„ ๐Ÿ”ง โš™๏ธ. ๐Ÿ”ข, โช: `3.0.2`. -* `description`: ๐Ÿ“› ๐Ÿ‘† ๐Ÿ› ๏ธ. -* `routes`: ๐Ÿ“‡ ๐Ÿ›ฃ, ๐Ÿ‘ซ ๐Ÿ”  ยฎ *โžก ๐Ÿ› ๏ธ*. ๐Ÿ‘ซ โœŠ โšช๏ธโžก๏ธ `app.routes`. - -## ๐Ÿ”‘ ๐Ÿ”ข - -โš™๏ธ โ„น ๐Ÿ”›, ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐ŸŽ ๐Ÿš™ ๐Ÿ”ข ๐Ÿ— ๐Ÿ—„ ๐Ÿ”— & ๐Ÿ” ๐Ÿ”  ๐Ÿ• ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช. - -๐Ÿ–ผ, โžก๏ธ ๐Ÿšฎ ๐Ÿ“„ ๐Ÿ—„ โ†” ๐Ÿ”Œ ๐Ÿ›ƒ ๐Ÿ”ฑ. - -### ๐Ÿ˜ **FastAPI** - -๐Ÿฅ‡, โœ ๐ŸŒ ๐Ÿ‘† **FastAPI** ๐Ÿˆธ ๐Ÿ›Ž: - -```Python hl_lines="1 4 7-9" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### ๐Ÿ— ๐Ÿ—„ ๐Ÿ”— - -โคด๏ธ, โš™๏ธ ๐ŸŽ ๐Ÿš™ ๐Ÿ”ข ๐Ÿ— ๐Ÿ—„ ๐Ÿ”—, ๐Ÿ”˜ `custom_openapi()` ๐Ÿ”ข: - -```Python hl_lines="2 15-20" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### ๐Ÿ”€ ๐Ÿ—„ ๐Ÿ”— - -๐Ÿ”œ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšฎ ๐Ÿ“„ โ†”, โŽ ๐Ÿ›ƒ `x-logo` `info` "๐ŸŽš" ๐Ÿ—„ ๐Ÿ”—: - -```Python hl_lines="21-23" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### ๐Ÿ’พ ๐Ÿ—„ ๐Ÿ”— - -๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐Ÿ  `.openapi_schema` "๐Ÿ’พ", ๐Ÿช ๐Ÿ‘† ๐Ÿ— ๐Ÿ”—. - -๐Ÿ‘ˆ ๐ŸŒŒ, ๐Ÿ‘† ๐Ÿˆธ ๐Ÿ† ๐Ÿšซ โœ”๏ธ ๐Ÿ— ๐Ÿ”— ๐Ÿ”  ๐Ÿ•ฐ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ“‚ ๐Ÿ‘† ๐Ÿ› ๏ธ ๐Ÿฉบ. - -โšซ๏ธ ๐Ÿ”œ ๐Ÿ— ๐Ÿ•ด ๐Ÿ•, & โคด๏ธ ๐ŸŽ ๐Ÿ’พ ๐Ÿ”— ๐Ÿ”œ โš™๏ธ โญ ๐Ÿ“จ. - -```Python hl_lines="13-14 24-25" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### ๐Ÿ” ๐Ÿ‘ฉโ€๐Ÿ”ฌ - -๐Ÿ”œ ๐Ÿ‘† ๐Ÿ’ช โŽ `.openapi()` ๐Ÿ‘ฉโ€๐Ÿ”ฌ โฎ๏ธ ๐Ÿ‘† ๐Ÿ†• ๐Ÿ”ข. - -```Python hl_lines="28" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### โœ… โšซ๏ธ - -๐Ÿ• ๐Ÿ‘† ๐Ÿšถ http://127.0.0.1:8000/redoc ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐Ÿ‘ˆ ๐Ÿ‘† โš™๏ธ ๐Ÿ‘† ๐Ÿ›ƒ ๐Ÿ”ฑ (๐Ÿ‘‰ ๐Ÿ–ผ, **FastAPI**'โ“‚ ๐Ÿ”ฑ): - - - -## ๐Ÿ‘ค-๐Ÿ•ธ ๐Ÿ•ธ & ๐ŸŽš ๐Ÿฉบ - -๐Ÿ› ๏ธ ๐Ÿฉบ โš™๏ธ **๐Ÿฆ ๐ŸŽš** & **๐Ÿ“„**, & ๐Ÿ”  ๐Ÿ‘ˆ ๐Ÿ’ช ๐Ÿ•ธ & ๐ŸŽš ๐Ÿ“. - -๐Ÿ”ข, ๐Ÿ‘ˆ ๐Ÿ“ ๐Ÿฆ โšช๏ธโžก๏ธ ๐Ÿ’ฒ. - -โœ‹๏ธ โšซ๏ธ ๐Ÿ’ช ๐Ÿ›ƒ โšซ๏ธ, ๐Ÿ‘† ๐Ÿ’ช โš’ ๐ŸŽฏ ๐Ÿ’ฒ, โš–๏ธ ๐Ÿฆ ๐Ÿ“ ๐Ÿ‘†. - -๐Ÿ‘ˆ โš , ๐Ÿ–ผ, ๐Ÿšฅ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ‘† ๐Ÿ“ฑ ๐Ÿšง ๐Ÿ‘ท โช ๐Ÿ“ฑ, ๐Ÿต ๐Ÿ“‚ ๐Ÿ•ธ ๐Ÿ”, โš–๏ธ ๐Ÿ‡ง๐Ÿ‡ฟ ๐Ÿ•ธ. - -๐Ÿ“ฅ ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ โ” ๐Ÿฆ ๐Ÿ‘ˆ ๐Ÿ“ ๐Ÿ‘†, ๐ŸŽ FastAPI ๐Ÿ“ฑ, & ๐Ÿ”— ๐Ÿฉบ โš™๏ธ ๐Ÿ‘ซ. - -### ๐Ÿ— ๐Ÿ“ ๐Ÿ“Š - -โžก๏ธ ๐Ÿ’ฌ ๐Ÿ‘† ๐Ÿ— ๐Ÿ“ ๐Ÿ“Š ๐Ÿ‘€ ๐Ÿ’– ๐Ÿ‘‰: - -``` -. -โ”œโ”€โ”€ app -โ”‚ โ”œโ”€โ”€ __init__.py -โ”‚ โ”œโ”€โ”€ main.py -``` - -๐Ÿ”œ โœ ๐Ÿ“ ๐Ÿช ๐Ÿ“š ๐ŸŽป ๐Ÿ“. - -๐Ÿ‘† ๐Ÿ†• ๐Ÿ“ ๐Ÿ“Š ๐Ÿ’ช ๐Ÿ‘€ ๐Ÿ’– ๐Ÿ‘‰: - -``` -. -โ”œโ”€โ”€ app -โ”‚ย ย  โ”œโ”€โ”€ __init__.py -โ”‚ย ย  โ”œโ”€โ”€ main.py -โ””โ”€โ”€ static/ -``` - -### โฌ ๐Ÿ“ - -โฌ ๐ŸŽป ๐Ÿ“ ๐Ÿ’ช ๐Ÿฉบ & ๐Ÿšฎ ๐Ÿ‘ซ ๐Ÿ”› ๐Ÿ‘ˆ `static/` ๐Ÿ“. - -๐Ÿ‘† ๐Ÿ’ช ๐ŸŽฒ โ–ถ๏ธ๏ธ-๐Ÿ–Š ๐Ÿ”  ๐Ÿ”— & ๐Ÿ–Š ๐ŸŽ› ๐ŸŽ `Save link as...`. - -**๐Ÿฆ ๐ŸŽš** โš™๏ธ ๐Ÿ“: - -* `swagger-ui-bundle.js` -* `swagger-ui.css` - -& **๐Ÿ“„** โš™๏ธ ๐Ÿ“: - -* `redoc.standalone.js` - -โฎ๏ธ ๐Ÿ‘ˆ, ๐Ÿ‘† ๐Ÿ“ ๐Ÿ“Š ๐Ÿ’ช ๐Ÿ‘€ ๐Ÿ’–: - -``` -. -โ”œโ”€โ”€ app -โ”‚ย ย  โ”œโ”€โ”€ __init__.py -โ”‚ย ย  โ”œโ”€โ”€ main.py -โ””โ”€โ”€ static - โ”œโ”€โ”€ redoc.standalone.js - โ”œโ”€โ”€ swagger-ui-bundle.js - โ””โ”€โ”€ swagger-ui.css -``` - -### ๐Ÿฆ ๐ŸŽป ๐Ÿ“ - -* ๐Ÿ—„ `StaticFiles`. -* "๐Ÿ—ป" `StaticFiles()` ๐Ÿ‘ ๐ŸŽฏ โžก. - -```Python hl_lines="7 11" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -### ๐Ÿ’ฏ ๐ŸŽป ๐Ÿ“ - -โ–ถ๏ธ ๐Ÿ‘† ๐Ÿˆธ & ๐Ÿšถ http://127.0.0.1:8000/static/redoc.standalone.js. - -๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐Ÿ“ถ ๐Ÿ“ ๐Ÿ•ธ ๐Ÿ“ **๐Ÿ“„**. - -โšซ๏ธ ๐Ÿ’ช โ–ถ๏ธ โฎ๏ธ ๐Ÿ•ณ ๐Ÿ’–: - -```JavaScript -/*! - * ReDoc - OpenAPI/Swagger-generated API Reference Documentation - * ------------------------------------------------------------- - * Version: "2.0.0-rc.18" - * Repo: https://github.com/Redocly/redoc - */ -!function(e,t){"object"==typeof exports&&"object"==typeof m - -... -``` - -๐Ÿ‘ˆ โœ” ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’†โ€โ™‚ ๐Ÿ’ช ๐Ÿฆ ๐ŸŽป ๐Ÿ“ โšช๏ธโžก๏ธ ๐Ÿ‘† ๐Ÿ“ฑ, & ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿฅ‰ ๐ŸŽป ๐Ÿ“ ๐Ÿฉบ โ˜‘ ๐Ÿฅ‰. - -๐Ÿ”œ ๐Ÿ‘ฅ ๐Ÿ’ช ๐Ÿ”— ๐Ÿ“ฑ โš™๏ธ ๐Ÿ“š ๐ŸŽป ๐Ÿ“ ๐Ÿฉบ. - -### โŽ ๐Ÿง ๐Ÿฉบ - -๐Ÿฅ‡ ๐Ÿ” โŽ ๐Ÿง ๐Ÿฉบ, ๐Ÿ“š โš™๏ธ ๐Ÿ’ฒ ๐Ÿ”ข. - -โŽ ๐Ÿ‘ซ, โš’ ๐Ÿ‘ซ ๐Ÿ“› `None` ๐Ÿ•โ” ๐Ÿ— ๐Ÿ‘† `FastAPI` ๐Ÿ“ฑ: - -```Python hl_lines="9" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -### ๐Ÿ”Œ ๐Ÿ›ƒ ๐Ÿฉบ - -๐Ÿ”œ ๐Ÿ‘† ๐Ÿ’ช โœ *โžก ๐Ÿ› ๏ธ* ๐Ÿ›ƒ ๐Ÿฉบ. - -๐Ÿ‘† ๐Ÿ’ช ๐Ÿค-โš™๏ธ FastAPI ๐Ÿ”— ๐Ÿ”ข โœ ๐Ÿ•ธ ๐Ÿ“ƒ ๐Ÿฉบ, & ๐Ÿšถโ€โ™€๏ธ ๐Ÿ‘ซ ๐Ÿ’ช โŒ: - -* `openapi_url`: ๐Ÿ“› ๐ŸŒโ” ๐Ÿ•ธ ๐Ÿ“ƒ ๐Ÿฉบ ๐Ÿ’ช ๐Ÿคš ๐Ÿ—„ ๐Ÿ”— ๐Ÿ‘† ๐Ÿ› ๏ธ. ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐Ÿ“ฅ ๐Ÿ”ข `app.openapi_url`. -* `title`: ๐Ÿ“› ๐Ÿ‘† ๐Ÿ› ๏ธ. -* `oauth2_redirect_url`: ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ `app.swagger_ui_oauth2_redirect_url` ๐Ÿ“ฅ โš™๏ธ ๐Ÿ”ข. -* `swagger_js_url`: ๐Ÿ“› ๐ŸŒโ” ๐Ÿ•ธ ๐Ÿ‘† ๐Ÿฆ ๐ŸŽš ๐Ÿฉบ ๐Ÿ’ช ๐Ÿคš **๐Ÿ•ธ** ๐Ÿ“. ๐Ÿ‘‰ 1๏ธโƒฃ ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ‘ ๐Ÿ“ฑ ๐Ÿ”œ ๐Ÿฆ. -* `swagger_css_url`: ๐Ÿ“› ๐ŸŒโ” ๐Ÿ•ธ ๐Ÿ‘† ๐Ÿฆ ๐ŸŽš ๐Ÿฉบ ๐Ÿ’ช ๐Ÿคš **๐ŸŽš** ๐Ÿ“. ๐Ÿ‘‰ 1๏ธโƒฃ ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ‘ ๐Ÿ“ฑ ๐Ÿ”œ ๐Ÿฆ. - -& โžก ๐Ÿ“„... - -```Python hl_lines="2-6 14-22 25-27 30-36" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -!!! tip - *โžก ๐Ÿ› ๏ธ* `swagger_ui_redirect` ๐Ÿ‘ฉโ€๐ŸŽ“ ๐Ÿ•โ” ๐Ÿ‘† โš™๏ธ Oauth2๏ธโƒฃ. - - ๐Ÿšฅ ๐Ÿ‘† ๐Ÿ› ๏ธ ๐Ÿ‘† ๐Ÿ› ๏ธ โฎ๏ธ Oauth2๏ธโƒฃ ๐Ÿ•โ€๐Ÿฆบ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ’ช ๐Ÿ”“ & ๐Ÿ‘Ÿ ๐Ÿ”™ ๐Ÿ› ๏ธ ๐Ÿฉบ โฎ๏ธ ๐Ÿ“Ž ๐ŸŽ“. & ๐Ÿ”— โฎ๏ธ โšซ๏ธ โš™๏ธ ๐ŸŽฐ Oauth2๏ธโƒฃ ๐Ÿค. - - ๐Ÿฆ ๐ŸŽš ๐Ÿ”œ ๐Ÿต โšซ๏ธ โ›… ๐ŸŽ‘ ๐Ÿ‘†, โœ‹๏ธ โšซ๏ธ ๐Ÿ’ช ๐Ÿ‘‰ "โŽ" ๐Ÿ‘ฉโ€๐ŸŽ“. - -### โœ *โžก ๐Ÿ› ๏ธ* ๐Ÿ’ฏ โšซ๏ธ - -๐Ÿ”œ, ๐Ÿ’ช ๐Ÿ’ฏ ๐Ÿ‘ˆ ๐ŸŒ ๐Ÿ‘ท, โœ *โžก ๐Ÿ› ๏ธ*: - -```Python hl_lines="39-41" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -### ๐Ÿ’ฏ โšซ๏ธ - -๐Ÿ”œ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ’ช ๐Ÿ”Œ ๐Ÿ‘† ๐Ÿ“ป, ๐Ÿšถ ๐Ÿ‘† ๐Ÿฉบ http://127.0.0.1:8000/docs, & ๐Ÿ”ƒ ๐Ÿ“ƒ. - -& ๐Ÿต ๐Ÿ•ธ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ’ช ๐Ÿ‘€ ๐Ÿฉบ ๐Ÿ‘† ๐Ÿ› ๏ธ & ๐Ÿ”— โฎ๏ธ โšซ๏ธ. - -## ๐Ÿ› ๏ธ ๐Ÿฆ ๐ŸŽš - -๐Ÿ‘† ๐Ÿ’ช ๐Ÿ”— โž• ๐Ÿฆ ๐ŸŽš ๐Ÿ”ข. - -๐Ÿ”— ๐Ÿ‘ซ, ๐Ÿšถโ€โ™€๏ธ `swagger_ui_parameters` โŒ ๐Ÿ•โ” ๐Ÿ— `FastAPI()` ๐Ÿ“ฑ ๐ŸŽš โš–๏ธ `get_swagger_ui_html()` ๐Ÿ”ข. - -`swagger_ui_parameters` ๐Ÿ“จ ๐Ÿ“– โฎ๏ธ ๐Ÿ“ณ ๐Ÿšถโ€โ™€๏ธ ๐Ÿฆ ๐ŸŽš ๐Ÿ”—. - -FastAPI ๐Ÿ—œ ๐Ÿ“ณ **๐ŸŽป** โš’ ๐Ÿ‘ซ ๐Ÿ”— โฎ๏ธ ๐Ÿ•ธ, ๐Ÿ‘ˆ โšซ๏ธโ” ๐Ÿฆ ๐ŸŽš ๐Ÿ’ช. - -### โŽ โ• ๐ŸŽฆ - -๐Ÿ–ผ, ๐Ÿ‘† ๐Ÿ’ช โŽ โ• ๐ŸŽฆ ๐Ÿฆ ๐ŸŽš. - -๐Ÿต ๐Ÿ”€ โš’, โ• ๐ŸŽฆ ๐Ÿ› ๏ธ ๐Ÿ”ข: - - - -โœ‹๏ธ ๐Ÿ‘† ๐Ÿ’ช โŽ โšซ๏ธ โš’ `syntaxHighlight` `False`: - -```Python hl_lines="3" -{!../../../docs_src/extending_openapi/tutorial003.py!} -``` - -...& โคด๏ธ ๐Ÿฆ ๐ŸŽš ๐Ÿ† ๐Ÿšซ ๐ŸŽฆ โ• ๐ŸŽฆ ๐Ÿšซ๐Ÿ”œ: - - - -### ๐Ÿ”€ ๐ŸŽข - -๐ŸŽ ๐ŸŒŒ ๐Ÿ‘† ๐Ÿ’ช โš’ โ• ๐ŸŽฆ ๐ŸŽข โฎ๏ธ ๐Ÿ”‘ `"syntaxHighlight.theme"` (๐Ÿ‘€ ๐Ÿ‘ˆ โšซ๏ธ โœ”๏ธ โฃ ๐Ÿ–•): - -```Python hl_lines="3" -{!../../../docs_src/extending_openapi/tutorial004.py!} -``` - -๐Ÿ‘ˆ ๐Ÿ“ณ ๐Ÿ”œ ๐Ÿ”€ โ• ๐ŸŽฆ ๐ŸŽจ ๐ŸŽข: - - - -### ๐Ÿ”€ ๐Ÿ”ข ๐Ÿฆ ๐ŸŽš ๐Ÿ”ข - -FastAPI ๐Ÿ”Œ ๐Ÿ”ข ๐Ÿ“ณ ๐Ÿ”ข โ˜‘ ๐ŸŒ… โš™๏ธ ๐Ÿ’ผ. - -โšซ๏ธ ๐Ÿ”Œ ๐Ÿ‘ซ ๐Ÿ”ข ๐Ÿ“ณ: - -```Python -{!../../../fastapi/openapi/docs.py[ln:7-13]!} -``` - -๐Ÿ‘† ๐Ÿ’ช ๐Ÿ” ๐Ÿ™† ๐Ÿ‘ซ โš’ ๐ŸŽ ๐Ÿ’ฒ โŒ `swagger_ui_parameters`. - -๐Ÿ–ผ, โŽ `deepLinking` ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšถโ€โ™€๏ธ ๐Ÿ‘‰ โš’ `swagger_ui_parameters`: - -```Python hl_lines="3" -{!../../../docs_src/extending_openapi/tutorial005.py!} -``` - -### ๐ŸŽ ๐Ÿฆ ๐ŸŽš ๐Ÿ”ข - -๐Ÿ‘€ ๐ŸŒ ๐ŸŽ ๐Ÿ’ช ๐Ÿ“ณ ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ, โœ ๐Ÿ›‚ ๐Ÿฉบ ๐Ÿฆ ๐ŸŽš ๐Ÿ”ข. - -### ๐Ÿ•ธ-๐Ÿ•ด โš’ - -๐Ÿฆ ๐ŸŽš โœ” ๐ŸŽ ๐Ÿ“ณ **๐Ÿ•ธ-๐Ÿ•ด** ๐ŸŽš (๐Ÿ–ผ, ๐Ÿ•ธ ๐Ÿ”ข). - -FastAPI ๐Ÿ”Œ ๐Ÿ‘ซ ๐Ÿ•ธ-๐Ÿ•ด `presets` โš’: - -```JavaScript -presets: [ - SwaggerUIBundle.presets.apis, - SwaggerUIBundle.SwaggerUIStandalonePreset -] -``` - -๐Ÿ‘ซ **๐Ÿ•ธ** ๐ŸŽš, ๐Ÿšซ ๐ŸŽป, ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšซ ๐Ÿšถโ€โ™€๏ธ ๐Ÿ‘ซ โšช๏ธโžก๏ธ ๐Ÿ ๐Ÿ“Ÿ ๐Ÿ”—. - -๐Ÿšฅ ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐Ÿ•ธ-๐Ÿ•ด ๐Ÿ“ณ ๐Ÿ’– ๐Ÿ“š, ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ 1๏ธโƒฃ ๐Ÿ‘ฉโ€๐Ÿ”ฌ ๐Ÿ”›. ๐Ÿ” ๐ŸŒ ๐Ÿฆ ๐ŸŽš *โžก ๐Ÿ› ๏ธ* & โŽ โœ ๐Ÿ™† ๐Ÿ•ธ ๐Ÿ‘† ๐Ÿ’ช. diff --git a/docs/em/docs/deployment/deta.md b/docs/em/docs/deployment/deta.md deleted file mode 100644 index 89b6c4bdb..000000000 --- a/docs/em/docs/deployment/deta.md +++ /dev/null @@ -1,258 +0,0 @@ -# ๐Ÿ› ๏ธ FastAPI ๐Ÿ”› ๐Ÿช” - -๐Ÿ‘‰ ๐Ÿ“„ ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ’ก โ” ๐Ÿ’ช ๐Ÿ› ๏ธ **FastAPI** ๐Ÿˆธ ๐Ÿ”› ๐Ÿช” โš™๏ธ ๐Ÿ†“ ๐Ÿ“„. ๐Ÿ‘ถ - -โšซ๏ธ ๐Ÿ”œ โœŠ ๐Ÿ‘† ๐Ÿ”ƒ **1๏ธโƒฃ0๏ธโƒฃ โฒ**. - -!!! info - ๐Ÿช” **FastAPI** ๐Ÿ’ฐ. ๐Ÿ‘ถ - -## ๐Ÿ”ฐ **FastAPI** ๐Ÿ“ฑ - -* โœ ๐Ÿ“ ๐Ÿ‘† ๐Ÿ“ฑ, ๐Ÿ–ผ, `./fastapideta/` & โ›” ๐Ÿ”˜ โšซ๏ธ. - -### FastAPI ๐Ÿ“Ÿ - -* โœ `main.py` ๐Ÿ“ โฎ๏ธ: - -```Python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int): - return {"item_id": item_id} -``` - -### ๐Ÿ“„ - -๐Ÿ”œ, ๐ŸŽ ๐Ÿ“ โœ ๐Ÿ“ `requirements.txt` โฎ๏ธ: - -```text -fastapi -``` - -!!! tip - ๐Ÿ‘† ๐Ÿšซ ๐Ÿ’ช โŽ Uvicorn ๐Ÿ› ๏ธ ๐Ÿ”› ๐Ÿช”, ๐Ÿ‘ ๐Ÿ‘† ๐Ÿ”œ ๐ŸŽฒ ๐Ÿ’š โŽ โšซ๏ธ ๐ŸŒ ๐Ÿ’ฏ ๐Ÿ‘† ๐Ÿ“ฑ. - -### ๐Ÿ“ ๐Ÿ“Š - -๐Ÿ‘† ๐Ÿ”œ ๐Ÿ”œ โœ”๏ธ 1๏ธโƒฃ ๐Ÿ“ `./fastapideta/` โฎ๏ธ 2๏ธโƒฃ ๐Ÿ“: - -``` -. -โ””โ”€โ”€ main.py -โ””โ”€โ”€ requirements.txt -``` - -## โœ ๐Ÿ†“ ๐Ÿช” ๐Ÿง - -๐Ÿ”œ โœ ๐Ÿ†“ ๐Ÿง ๐Ÿ”› ๐Ÿช”, ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ“ง & ๐Ÿ”. - -๐Ÿ‘† ๐Ÿšซ ๐Ÿ’ช ๐Ÿ’ณ. - -## โŽ โœณ - -๐Ÿ• ๐Ÿ‘† โœ”๏ธ ๐Ÿ‘† ๐Ÿง, โŽ ๐Ÿช” โœณ: - -=== "๐Ÿ’พ, ๐Ÿ‡ธ๐Ÿ‡ป" - -
- - ```console - $ curl -fsSL https://get.deta.dev/cli.sh | sh - ``` - -
- -=== "๐Ÿšช ๐Ÿ“‹" - -
- - ```console - $ iwr https://get.deta.dev/cli.ps1 -useb | iex - ``` - -
- -โฎ๏ธ โŽ โšซ๏ธ, ๐Ÿ“‚ ๐Ÿ†• ๐Ÿ“ถ ๐Ÿ‘ˆ โŽ โœณ ๐Ÿ”. - -๐Ÿ†• ๐Ÿ“ถ, โœ” ๐Ÿ‘ˆ โšซ๏ธ โ˜‘ โŽ โฎ๏ธ: - -
- -```console -$ deta --help - -Deta command line interface for managing deta micros. -Complete documentation available at https://docs.deta.sh - -Usage: - deta [flags] - deta [command] - -Available Commands: - auth Change auth settings for a deta micro - -... -``` - -
- -!!! tip - ๐Ÿšฅ ๐Ÿ‘† โœ”๏ธ โš  โŽ โœณ, โœ… ๐Ÿ›‚ ๐Ÿช” ๐Ÿฉบ. - -## ๐Ÿ’ณ โฎ๏ธ โœณ - -๐Ÿ”œ ๐Ÿ’ณ ๐Ÿช” โšช๏ธโžก๏ธ โœณ โฎ๏ธ: - -
- -```console -$ deta login - -Please, log in from the web page. Waiting.. -Logged in successfully. -``` - -
- -๐Ÿ‘‰ ๐Ÿ”œ ๐Ÿ“‚ ๐Ÿ•ธ ๐Ÿ–ฅ & ๐Ÿ”“ ๐Ÿ”. - -## ๐Ÿ› ๏ธ โฎ๏ธ ๐Ÿช” - -โญ, ๐Ÿ› ๏ธ ๐Ÿ‘† ๐Ÿˆธ โฎ๏ธ ๐Ÿช” โœณ: - -
- -```console -$ deta new - -Successfully created a new micro - -// Notice the "endpoint" ๐Ÿ” - -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} - -Adding dependencies... - - ----> 100% - - -Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6 -``` - -
- -๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐ŸŽป ๐Ÿ“ง ๐ŸŽ: - -```JSON hl_lines="4" -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} -``` - -!!! tip - ๐Ÿ‘† ๐Ÿ› ๏ธ ๐Ÿ”œ โœ”๏ธ ๐ŸŽ `"endpoint"` ๐Ÿ“›. - -## โœ… โšซ๏ธ - -๐Ÿ”œ ๐Ÿ“‚ ๐Ÿ‘† ๐Ÿ–ฅ ๐Ÿ‘† `endpoint` ๐Ÿ“›. ๐Ÿ–ผ ๐Ÿ”› โšซ๏ธ `https://qltnci.deta.dev`, โœ‹๏ธ ๐Ÿ‘† ๐Ÿ”œ ๐ŸŽ. - -๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐ŸŽป ๐Ÿ“จ โšช๏ธโžก๏ธ ๐Ÿ‘† FastAPI ๐Ÿ“ฑ: - -```JSON -{ - "Hello": "World" -} -``` - -& ๐Ÿ”œ ๐Ÿšถ `/docs` ๐Ÿ‘† ๐Ÿ› ๏ธ, ๐Ÿ–ผ ๐Ÿ”› โšซ๏ธ ๐Ÿ”œ `https://qltnci.deta.dev/docs`. - -โšซ๏ธ ๐Ÿ”œ ๐ŸŽฆ ๐Ÿ‘† ๐Ÿฉบ ๐Ÿ’–: - - - -## ๐Ÿ› ๏ธ ๐Ÿ“ข ๐Ÿ” - -๐Ÿ”ข, ๐Ÿช” ๐Ÿ”œ ๐Ÿต ๐Ÿค โš™๏ธ ๐Ÿช ๐Ÿ‘† ๐Ÿง. - -โœ‹๏ธ ๐Ÿ• ๐Ÿ‘† ๐Ÿ”œ, ๐Ÿ‘† ๐Ÿ’ช โš’ โšซ๏ธ ๐Ÿ“ข โฎ๏ธ: - -
- -```console -$ deta auth disable - -Successfully disabled http auth -``` - -
- -๐Ÿ”œ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ’ฐ ๐Ÿ‘ˆ ๐Ÿ“› โฎ๏ธ ๐Ÿ™† & ๐Ÿ‘ซ ๐Ÿ”œ ๐Ÿ’ช ๐Ÿ” ๐Ÿ‘† ๐Ÿ› ๏ธ. ๐Ÿ‘ถ - -## ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” - -ใŠ— โ— ๐Ÿ‘† ๐Ÿ› ๏ธ ๐Ÿ‘† FastAPI ๐Ÿ“ฑ ๐Ÿช” โ— ๐Ÿ‘ถ ๐Ÿ‘ถ - -, ๐Ÿ‘€ ๐Ÿ‘ˆ ๐Ÿช” โ˜‘ ๐Ÿต ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” ๐Ÿ‘†, ๐Ÿ‘† ๐Ÿšซ โœ”๏ธ โœŠ ๐Ÿ’… ๐Ÿ‘ˆ & ๐Ÿ’ช ๐Ÿ’ญ ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ”œ โœ”๏ธ ๐Ÿ” ๐Ÿ—œ ๐Ÿ”—. ๐Ÿ‘ถ ๐Ÿ‘ถ - -## โœ… ๐Ÿ•ถ - -โšช๏ธโžก๏ธ ๐Ÿ‘† ๐Ÿฉบ ๐ŸŽš (๐Ÿ‘ซ ๐Ÿ”œ ๐Ÿ“› ๐Ÿ’– `https://qltnci.deta.dev/docs`) ๐Ÿ“จ ๐Ÿ“จ ๐Ÿ‘† *โžก ๐Ÿ› ๏ธ* `/items/{item_id}`. - -๐Ÿ–ผ โฎ๏ธ ๐Ÿ†” `5`. - -๐Ÿ”œ ๐Ÿšถ https://web.deta.sh. - -๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐Ÿ“ค ๐Ÿ“„ โ—€๏ธ ๐Ÿค™ "โ—พ" โฎ๏ธ ๐Ÿ”  ๐Ÿ‘† ๐Ÿ“ฑ. - -๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐Ÿ“‘ โฎ๏ธ "โ„น", & ๐Ÿ“‘ "๐Ÿ•ถ", ๐Ÿšถ ๐Ÿ“‘ "๐Ÿ•ถ". - -๐Ÿ“ค ๐Ÿ‘† ๐Ÿ’ช โœ” โฎ๏ธ ๐Ÿ“จ ๐Ÿ“จ ๐Ÿ‘† ๐Ÿ“ฑ. - -๐Ÿ‘† ๐Ÿ’ช โœ ๐Ÿ‘ซ & ๐Ÿค-๐Ÿคพ ๐Ÿ‘ซ. - - - -## ๐Ÿ’ก ๐ŸŒ… - -โ˜, ๐Ÿ‘† ๐Ÿ”œ ๐ŸŽฒ ๐Ÿ’š ๐Ÿช ๐Ÿ’ฝ ๐Ÿ‘† ๐Ÿ“ฑ ๐ŸŒŒ ๐Ÿ‘ˆ ๐Ÿ˜ฃ ๐Ÿ”˜ ๐Ÿ•ฐ. ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐Ÿช” ๐Ÿงข, โšซ๏ธ โœ”๏ธ ๐Ÿ‘ **๐Ÿ†“ ๐ŸŽš**. - -๐Ÿ‘† ๐Ÿ’ช โœ ๐ŸŒ… ๐Ÿช” ๐Ÿฉบ. - -## ๐Ÿ› ๏ธ ๐Ÿ”ง - -๐Ÿ‘Ÿ ๐Ÿ”™ ๐Ÿ”ง ๐Ÿ‘ฅ ๐Ÿ”ฌ [๐Ÿ› ๏ธ ๐Ÿ”ง](./concepts.md){.internal-link target=_blank}, ๐Ÿ“ฅ โ” ๐Ÿ”  ๐Ÿ‘ซ ๐Ÿ”œ ๐Ÿต โฎ๏ธ ๐Ÿช”: - -* **๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ”**: ๐Ÿต ๐Ÿช”, ๐Ÿ‘ซ ๐Ÿ”œ ๐Ÿค ๐Ÿ‘† ๐Ÿ“ & ๐Ÿต ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” ๐Ÿ”. -* **๐Ÿƒโ€โ™‚ ๐Ÿ”› ๐Ÿ•ด**: ๐Ÿต ๐Ÿช”, ๐Ÿ• ๐Ÿ‘ซ ๐Ÿ•โ€๐Ÿฆบ. -* **โ**: ๐Ÿต ๐Ÿช”, ๐Ÿ• ๐Ÿ‘ซ ๐Ÿ•โ€๐Ÿฆบ. -* **๐Ÿงฌ**: ๐Ÿต ๐Ÿช”, ๐Ÿ• ๐Ÿ‘ซ ๐Ÿ•โ€๐Ÿฆบ. -* **๐Ÿ’พ**: ๐Ÿ“‰ ๐Ÿ” ๐Ÿช”, ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ“ง ๐Ÿ‘ซ ๐Ÿ“ˆ โšซ๏ธ. -* **โฎ๏ธ ๐Ÿ” โญ โ–ถ๏ธ**: ๐Ÿšซ ๐Ÿ”— ๐Ÿ•โ€๐Ÿฆบ, ๐Ÿ‘† ๐Ÿ’ช โš’ โšซ๏ธ ๐Ÿ‘ท โฎ๏ธ ๐Ÿ‘ซ ๐Ÿ’พ โš™๏ธ โš–๏ธ ๐ŸŒ– โœ. - -!!! note - ๐Ÿช” ๐Ÿ”ง โš’ โšซ๏ธ โฉ (& ๐Ÿ†“) ๐Ÿ› ๏ธ ๐Ÿ™… ๐Ÿˆธ ๐Ÿ”œ. - - โšซ๏ธ ๐Ÿ’ช ๐Ÿ“‰ ๐Ÿ“š โš™๏ธ ๐Ÿ’ผ, โœ‹๏ธ ๐ŸŽ ๐Ÿ•ฐ, โšซ๏ธ ๐Ÿšซ ๐Ÿ•โ€๐Ÿฆบ ๐ŸŽ, ๐Ÿ’– โš™๏ธ ๐Ÿ”ข ๐Ÿ’ฝ (โ†–๏ธ โšช๏ธโžก๏ธ ๐Ÿช” ๐Ÿ‘ โ˜ ๐Ÿ’ฝ โš™๏ธ), ๐Ÿ›ƒ ๐Ÿ•น ๐ŸŽฐ, โ™’๏ธ. - - ๐Ÿ‘† ๐Ÿ’ช โœ ๐ŸŒ… โ„น ๐Ÿช” ๐Ÿฉบ ๐Ÿ‘€ ๐Ÿšฅ โšซ๏ธ โ–ถ๏ธ๏ธ โš’ ๐Ÿ‘†. diff --git a/docs/em/docs/advanced/conditional-openapi.md b/docs/em/docs/how-to/conditional-openapi.md similarity index 100% rename from docs/em/docs/advanced/conditional-openapi.md rename to docs/em/docs/how-to/conditional-openapi.md diff --git a/docs/em/docs/advanced/custom-request-and-route.md b/docs/em/docs/how-to/custom-request-and-route.md similarity index 100% rename from docs/em/docs/advanced/custom-request-and-route.md rename to docs/em/docs/how-to/custom-request-and-route.md diff --git a/docs/em/docs/how-to/extending-openapi.md b/docs/em/docs/how-to/extending-openapi.md new file mode 100644 index 000000000..6b3bc0075 --- /dev/null +++ b/docs/em/docs/how-to/extending-openapi.md @@ -0,0 +1,90 @@ +# โ†” ๐Ÿ—„ + +!!! warning + ๐Ÿ‘‰ ๐Ÿ‘ ๐Ÿง โš’. ๐Ÿ‘† ๐ŸŽฒ ๐Ÿ’ช ๐Ÿšถ โšซ๏ธ. + + ๐Ÿšฅ ๐Ÿ‘† ๐Ÿ“„ ๐Ÿ”ฐ - ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿฆฎ, ๐Ÿ‘† ๐Ÿ’ช ๐ŸŽฒ ๐Ÿšถ ๐Ÿ‘‰ ๐Ÿ“„. + + ๐Ÿšฅ ๐Ÿ‘† โช ๐Ÿ’ญ ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ”€ ๐Ÿ— ๐Ÿ—„ ๐Ÿ”—, ๐Ÿ˜ฃ ๐Ÿ‘‚. + +๐Ÿ“ค ๐Ÿ’ผ ๐ŸŒโ” ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ’ช ๐Ÿ”€ ๐Ÿ— ๐Ÿ—„ ๐Ÿ”—. + +๐Ÿ‘‰ ๐Ÿ“„ ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ โ”. + +## ๐Ÿ˜ ๐Ÿ› ๏ธ + +๐Ÿ˜ (๐Ÿ”ข) ๐Ÿ› ๏ธ, โฉ. + +`FastAPI` ๐Ÿˆธ (๐Ÿ‘) โœ”๏ธ `.openapi()` ๐Ÿ‘ฉโ€๐Ÿ”ฌ ๐Ÿ‘ˆ ๐Ÿ“ˆ ๐Ÿ“จ ๐Ÿ—„ ๐Ÿ”—. + +๐Ÿ• ๐Ÿˆธ ๐ŸŽš ๐Ÿ—, *โžก ๐Ÿ› ๏ธ* `/openapi.json` (โš–๏ธ โšซ๏ธโ” ๐Ÿ‘† โš’ ๐Ÿ‘† `openapi_url`) ยฎ. + +โšซ๏ธ ๐Ÿ“จ ๐ŸŽป ๐Ÿ“จ โฎ๏ธ ๐Ÿ ๐Ÿˆธ `.openapi()` ๐Ÿ‘ฉโ€๐Ÿ”ฌ. + +๐Ÿ”ข, โšซ๏ธโ” ๐Ÿ‘ฉโ€๐Ÿ”ฌ `.openapi()` ๐Ÿ”จ โœ… ๐Ÿ  `.openapi_schema` ๐Ÿ‘€ ๐Ÿšฅ โšซ๏ธ โœ”๏ธ ๐ŸŽš & ๐Ÿ“จ ๐Ÿ‘ซ. + +๐Ÿšฅ โšซ๏ธ ๐Ÿšซ, โšซ๏ธ ๐Ÿ— ๐Ÿ‘ซ โš™๏ธ ๐Ÿš™ ๐Ÿ”ข `fastapi.openapi.utils.get_openapi`. + +& ๐Ÿ‘ˆ ๐Ÿ”ข `get_openapi()` ๐Ÿ“จ ๐Ÿ”ข: + +* `title`: ๐Ÿ—„ ๐Ÿ“›, ๐ŸŽฆ ๐Ÿฉบ. +* `version`: โฌ ๐Ÿ‘† ๐Ÿ› ๏ธ, โœ… `2.5.0`. +* `openapi_version`: โฌ ๐Ÿ—„ ๐Ÿ”ง โš™๏ธ. ๐Ÿ”ข, โช: `3.0.2`. +* `description`: ๐Ÿ“› ๐Ÿ‘† ๐Ÿ› ๏ธ. +* `routes`: ๐Ÿ“‡ ๐Ÿ›ฃ, ๐Ÿ‘ซ ๐Ÿ”  ยฎ *โžก ๐Ÿ› ๏ธ*. ๐Ÿ‘ซ โœŠ โšช๏ธโžก๏ธ `app.routes`. + +## ๐Ÿ”‘ ๐Ÿ”ข + +โš™๏ธ โ„น ๐Ÿ”›, ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐ŸŽ ๐Ÿš™ ๐Ÿ”ข ๐Ÿ— ๐Ÿ—„ ๐Ÿ”— & ๐Ÿ” ๐Ÿ”  ๐Ÿ• ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช. + +๐Ÿ–ผ, โžก๏ธ ๐Ÿšฎ ๐Ÿ“„ ๐Ÿ—„ โ†” ๐Ÿ”Œ ๐Ÿ›ƒ ๐Ÿ”ฑ. + +### ๐Ÿ˜ **FastAPI** + +๐Ÿฅ‡, โœ ๐ŸŒ ๐Ÿ‘† **FastAPI** ๐Ÿˆธ ๐Ÿ›Ž: + +```Python hl_lines="1 4 7-9" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### ๐Ÿ— ๐Ÿ—„ ๐Ÿ”— + +โคด๏ธ, โš™๏ธ ๐ŸŽ ๐Ÿš™ ๐Ÿ”ข ๐Ÿ— ๐Ÿ—„ ๐Ÿ”—, ๐Ÿ”˜ `custom_openapi()` ๐Ÿ”ข: + +```Python hl_lines="2 15-20" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### ๐Ÿ”€ ๐Ÿ—„ ๐Ÿ”— + +๐Ÿ”œ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšฎ ๐Ÿ“„ โ†”, โŽ ๐Ÿ›ƒ `x-logo` `info` "๐ŸŽš" ๐Ÿ—„ ๐Ÿ”—: + +```Python hl_lines="21-23" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### ๐Ÿ’พ ๐Ÿ—„ ๐Ÿ”— + +๐Ÿ‘† ๐Ÿ’ช โš™๏ธ ๐Ÿ  `.openapi_schema` "๐Ÿ’พ", ๐Ÿช ๐Ÿ‘† ๐Ÿ— ๐Ÿ”—. + +๐Ÿ‘ˆ ๐ŸŒŒ, ๐Ÿ‘† ๐Ÿˆธ ๐Ÿ† ๐Ÿšซ โœ”๏ธ ๐Ÿ— ๐Ÿ”— ๐Ÿ”  ๐Ÿ•ฐ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ“‚ ๐Ÿ‘† ๐Ÿ› ๏ธ ๐Ÿฉบ. + +โšซ๏ธ ๐Ÿ”œ ๐Ÿ— ๐Ÿ•ด ๐Ÿ•, & โคด๏ธ ๐ŸŽ ๐Ÿ’พ ๐Ÿ”— ๐Ÿ”œ โš™๏ธ โญ ๐Ÿ“จ. + +```Python hl_lines="13-14 24-25" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### ๐Ÿ” ๐Ÿ‘ฉโ€๐Ÿ”ฌ + +๐Ÿ”œ ๐Ÿ‘† ๐Ÿ’ช โŽ `.openapi()` ๐Ÿ‘ฉโ€๐Ÿ”ฌ โฎ๏ธ ๐Ÿ‘† ๐Ÿ†• ๐Ÿ”ข. + +```Python hl_lines="28" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### โœ… โšซ๏ธ + +๐Ÿ• ๐Ÿ‘† ๐Ÿšถ http://127.0.0.1:8000/redoc ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐Ÿ‘ˆ ๐Ÿ‘† โš™๏ธ ๐Ÿ‘† ๐Ÿ›ƒ ๐Ÿ”ฑ (๐Ÿ‘‰ ๐Ÿ–ผ, **FastAPI**'โ“‚ ๐Ÿ”ฑ): + + diff --git a/docs/em/docs/advanced/graphql.md b/docs/em/docs/how-to/graphql.md similarity index 100% rename from docs/em/docs/advanced/graphql.md rename to docs/em/docs/how-to/graphql.md diff --git a/docs/em/docs/advanced/sql-databases-peewee.md b/docs/em/docs/how-to/sql-databases-peewee.md similarity index 100% rename from docs/em/docs/advanced/sql-databases-peewee.md rename to docs/em/docs/how-to/sql-databases-peewee.md diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml index 6d9119520..0d9597f07 100644 --- a/docs/en/data/sponsors.yml +++ b/docs/en/data/sponsors.yml @@ -33,6 +33,9 @@ silver: - url: https://databento.com/ title: Pay as you go for market data img: https://fastapi.tiangolo.com/img/sponsors/databento.svg + - url: https://speakeasyapi.dev?utm_source=fastapi+repo&utm_medium=github+sponsorship + title: SDKs for your API | Speakeasy + img: https://fastapi.tiangolo.com/img/sponsors/speakeasy.png bronze: - url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source title: Biosecurity risk assessments made easy. diff --git a/docs/en/data/sponsors_badge.yml b/docs/en/data/sponsors_badge.yml index 7c3bb2f47..7b605e0ff 100644 --- a/docs/en/data/sponsors_badge.yml +++ b/docs/en/data/sponsors_badge.yml @@ -19,3 +19,4 @@ logins: - Flint-company - porter-dev - fern-api + - ndimares diff --git a/docs/en/docs/advanced/extending-openapi.md b/docs/en/docs/advanced/extending-openapi.md deleted file mode 100644 index bec184dee..000000000 --- a/docs/en/docs/advanced/extending-openapi.md +++ /dev/null @@ -1,318 +0,0 @@ -# Extending OpenAPI - -!!! warning - This is a rather advanced feature. You probably can skip it. - - If you are just following the tutorial - user guide, you can probably skip this section. - - If you already know that you need to modify the generated OpenAPI schema, continue reading. - -There are some cases where you might need to modify the generated OpenAPI schema. - -In this section you will see how. - -## The normal process - -The normal (default) process, is as follows. - -A `FastAPI` application (instance) has an `.openapi()` method that is expected to return the OpenAPI schema. - -As part of the application object creation, a *path operation* for `/openapi.json` (or for whatever you set your `openapi_url`) is registered. - -It just returns a JSON response with the result of the application's `.openapi()` method. - -By default, what the method `.openapi()` does is check the property `.openapi_schema` to see if it has contents and return them. - -If it doesn't, it generates them using the utility function at `fastapi.openapi.utils.get_openapi`. - -And that function `get_openapi()` receives as parameters: - -* `title`: The OpenAPI title, shown in the docs. -* `version`: The version of your API, e.g. `2.5.0`. -* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.1.0`. -* `summary`: A short summary of the API. -* `description`: The description of your API, this can include markdown and will be shown in the docs. -* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`. - -!!! info - The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by FastAPI 0.99.0 and above. - -## Overriding the defaults - -Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need. - -For example, let's add ReDoc's OpenAPI extension to include a custom logo. - -### Normal **FastAPI** - -First, write all your **FastAPI** application as normally: - -```Python hl_lines="1 4 7-9" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### Generate the OpenAPI schema - -Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function: - -```Python hl_lines="2 15-21" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### Modify the OpenAPI schema - -Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema: - -```Python hl_lines="22-24" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### Cache the OpenAPI schema - -You can use the property `.openapi_schema` as a "cache", to store your generated schema. - -That way, your application won't have to generate the schema every time a user opens your API docs. - -It will be generated only once, and then the same cached schema will be used for the next requests. - -```Python hl_lines="13-14 25-26" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### Override the method - -Now you can replace the `.openapi()` method with your new function. - -```Python hl_lines="29" -{!../../../docs_src/extending_openapi/tutorial001.py!} -``` - -### Check it - -Once you go to http://127.0.0.1:8000/redoc you will see that you are using your custom logo (in this example, **FastAPI**'s logo): - - - -## Self-hosting JavaScript and CSS for docs - -The API docs use **Swagger UI** and **ReDoc**, and each of those need some JavaScript and CSS files. - -By default, those files are served from a CDN. - -But it's possible to customize it, you can set a specific CDN, or serve the files yourself. - -That's useful, for example, if you need your app to keep working even while offline, without open Internet access, or in a local network. - -Here you'll see how to serve those files yourself, in the same FastAPI app, and configure the docs to use them. - -### Project file structure - -Let's say your project file structure looks like this: - -``` -. -โ”œโ”€โ”€ app -โ”‚ โ”œโ”€โ”€ __init__.py -โ”‚ โ”œโ”€โ”€ main.py -``` - -Now create a directory to store those static files. - -Your new file structure could look like this: - -``` -. -โ”œโ”€โ”€ app -โ”‚ย ย  โ”œโ”€โ”€ __init__.py -โ”‚ย ย  โ”œโ”€โ”€ main.py -โ””โ”€โ”€ static/ -``` - -### Download the files - -Download the static files needed for the docs and put them on that `static/` directory. - -You can probably right-click each link and select an option similar to `Save link as...`. - -**Swagger UI** uses the files: - -* `swagger-ui-bundle.js` -* `swagger-ui.css` - -And **ReDoc** uses the file: - -* `redoc.standalone.js` - -After that, your file structure could look like: - -``` -. -โ”œโ”€โ”€ app -โ”‚ย ย  โ”œโ”€โ”€ __init__.py -โ”‚ย ย  โ”œโ”€โ”€ main.py -โ””โ”€โ”€ static - โ”œโ”€โ”€ redoc.standalone.js - โ”œโ”€โ”€ swagger-ui-bundle.js - โ””โ”€โ”€ swagger-ui.css -``` - -### Serve the static files - -* Import `StaticFiles`. -* "Mount" a `StaticFiles()` instance in a specific path. - -```Python hl_lines="7 11" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -### Test the static files - -Start your application and go to http://127.0.0.1:8000/static/redoc.standalone.js. - -You should see a very long JavaScript file for **ReDoc**. - -It could start with something like: - -```JavaScript -/*! - * ReDoc - OpenAPI/Swagger-generated API Reference Documentation - * ------------------------------------------------------------- - * Version: "2.0.0-rc.18" - * Repo: https://github.com/Redocly/redoc - */ -!function(e,t){"object"==typeof exports&&"object"==typeof m - -... -``` - -That confirms that you are being able to serve static files from your app, and that you placed the static files for the docs in the correct place. - -Now we can configure the app to use those static files for the docs. - -### Disable the automatic docs - -The first step is to disable the automatic docs, as those use the CDN by default. - -To disable them, set their URLs to `None` when creating your `FastAPI` app: - -```Python hl_lines="9" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -### Include the custom docs - -Now you can create the *path operations* for the custom docs. - -You can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments: - -* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`. -* `title`: the title of your API. -* `oauth2_redirect_url`: you can use `app.swagger_ui_oauth2_redirect_url` here to use the default. -* `swagger_js_url`: the URL where the HTML for your Swagger UI docs can get the **JavaScript** file. This is the one that your own app is now serving. -* `swagger_css_url`: the URL where the HTML for your Swagger UI docs can get the **CSS** file. This is the one that your own app is now serving. - -And similarly for ReDoc... - -```Python hl_lines="2-6 14-22 25-27 30-36" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -!!! tip - The *path operation* for `swagger_ui_redirect` is a helper for when you use OAuth2. - - If you integrate your API with an OAuth2 provider, you will be able to authenticate and come back to the API docs with the acquired credentials. And interact with it using the real OAuth2 authentication. - - Swagger UI will handle it behind the scenes for you, but it needs this "redirect" helper. - -### Create a *path operation* to test it - -Now, to be able to test that everything works, create a *path operation*: - -```Python hl_lines="39-41" -{!../../../docs_src/extending_openapi/tutorial002.py!} -``` - -### Test it - -Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page. - -And even without Internet, you would be able to see the docs for your API and interact with it. - -## Configuring Swagger UI - -You can configure some extra Swagger UI parameters. - -To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function. - -`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly. - -FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs. - -### Disable Syntax Highlighting - -For example, you could disable syntax highlighting in Swagger UI. - -Without changing the settings, syntax highlighting is enabled by default: - - - -But you can disable it by setting `syntaxHighlight` to `False`: - -```Python hl_lines="3" -{!../../../docs_src/extending_openapi/tutorial003.py!} -``` - -...and then Swagger UI won't show the syntax highlighting anymore: - - - -### Change the Theme - -The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle): - -```Python hl_lines="3" -{!../../../docs_src/extending_openapi/tutorial004.py!} -``` - -That configuration would change the syntax highlighting color theme: - - - -### Change Default Swagger UI Parameters - -FastAPI includes some default configuration parameters appropriate for most of the use cases. - -It includes these default configurations: - -```Python -{!../../../fastapi/openapi/docs.py[ln:7-13]!} -``` - -You can override any of them by setting a different value in the argument `swagger_ui_parameters`. - -For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`: - -```Python hl_lines="3" -{!../../../docs_src/extending_openapi/tutorial005.py!} -``` - -### Other Swagger UI Parameters - -To see all the other possible configurations you can use, read the official docs for Swagger UI parameters. - -### JavaScript-only settings - -Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions). - -FastAPI also includes these JavaScript-only `presets` settings: - -```JavaScript -presets: [ - SwaggerUIBundle.presets.apis, - SwaggerUIBundle.SwaggerUIStandalonePreset -] -``` - -These are **JavaScript** objects, not strings, so you can't pass them from Python code directly. - -If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need. diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md index 3fed48b0b..f439ed93a 100644 --- a/docs/en/docs/advanced/generate-clients.md +++ b/docs/en/docs/advanced/generate-clients.md @@ -12,10 +12,18 @@ A common tool is openapi-typescript-codegen. -Another option you could consider for several languages is Fern. +## Client and SDK Generators - Sponsor -!!! info - Fern is also a FastAPI sponsor. ๐Ÿ˜Ž๐ŸŽ‰ +There are also some **company-backed** Client and SDK generators based on OpenAPI (FastAPI), in some cases they can offer you **additional features** on top of high-quality generated SDKs/clients. + +Some of them also โœจ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} โœจ, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**. + +And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. ๐Ÿ™‡ + +You might want to try their services and follow their guides: + +* Fern +* Speakeasy ## Generate a TypeScript Frontend Client diff --git a/docs/en/docs/advanced/index.md b/docs/en/docs/advanced/index.md index 467f0833e..d8dcd4ca6 100644 --- a/docs/en/docs/advanced/index.md +++ b/docs/en/docs/advanced/index.md @@ -17,8 +17,17 @@ You could still use most of the features in **FastAPI** with the knowledge from And the next sections assume you already read it, and assume that you know those main ideas. -## TestDriven.io course +## External Courses -If you would like to take an advanced-beginner course to complement this section of the docs, you might want to check: Test-Driven Development with FastAPI and Docker by **TestDriven.io**. +Although the [Tutorial - User Guide](../tutorial/){.internal-link target=_blank} and this **Advanced User Guide** are written as a guided tutorial (like a book) and should be enough for you to **learn FastAPI**, you might want to complement it with additional courses. -They are currently donating 10% of all profits to the development of **FastAPI**. ๐ŸŽ‰ ๐Ÿ˜„ +Or it might be the case that you just prefer to take other courses because they adapt better to your learning style. + +Some course providers โœจ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} โœจ, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**. + +And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good learning experience** but also want to make sure you have a **good and healthy framework**, FastAPI. ๐Ÿ™‡ + +You might want to try their courses: + +* Talk Python Training +* Test-Driven Development diff --git a/docs/en/docs/deployment/cloud.md b/docs/en/docs/deployment/cloud.md new file mode 100644 index 000000000..b2836aeb4 --- /dev/null +++ b/docs/en/docs/deployment/cloud.md @@ -0,0 +1,17 @@ +# Deploy FastAPI on Cloud Providers + +You can use virtually **any cloud provider** to deploy your FastAPI application. + +In most of the cases, the main cloud providers have guides to deploy FastAPI with them. + +## Cloud Providers - Sponsors + +Some cloud providers โœจ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} โœจ, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**. + +And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. ๐Ÿ™‡ + +You might want to try their services and follow their guides: + +* Platform.sh +* Porter +* Deta diff --git a/docs/en/docs/deployment/deta.md b/docs/en/docs/deployment/deta.md deleted file mode 100644 index 229d7fd5d..000000000 --- a/docs/en/docs/deployment/deta.md +++ /dev/null @@ -1,391 +0,0 @@ -# Deploy FastAPI on Deta Space - -In this section you will learn how to easily deploy a **FastAPI** application on Deta Space, for free. ๐ŸŽ - -It will take you about **10 minutes** to deploy an API that you can use. After that, you can optionally release it to anyone. - -Let's dive in. - -!!! info - Deta is a **FastAPI** sponsor. ๐ŸŽ‰ - -## A simple **FastAPI** app - -* To start, create an empty directory with the name of your app, for example `./fastapi-deta/`, and then navigate into it. - -```console -$ mkdir fastapi-deta -$ cd fastapi-deta -``` - -### FastAPI code - -* Create a `main.py` file with: - -```Python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int): - return {"item_id": item_id} -``` - -### Requirements - -Now, in the same directory create a file `requirements.txt` with: - -```text -fastapi -uvicorn[standard] -``` - -### Directory structure - -You will now have a directory `./fastapi-deta/` with two files: - -``` -. -โ””โ”€โ”€ main.py -โ””โ”€โ”€ requirements.txt -``` - -## Create a free **Deta Space** account - -Next, create a free account on Deta Space, you just need an email and password. - -You don't even need a credit card, but make sure **Developer Mode** is enabled when you sign up. - - -## Install the CLI - -Once you have your account, install the Deta Space CLI: - -=== "Linux, macOS" - -
- - ```console - $ curl -fsSL https://get.deta.dev/space-cli.sh | sh - ``` - -
- -=== "Windows PowerShell" - -
- - ```console - $ iwr https://get.deta.dev/space-cli.ps1 -useb | iex - ``` - -
- -After installing it, open a new terminal so that the installed CLI is detected. - -In a new terminal, confirm that it was correctly installed with: - -
- -```console -$ space --help - -Deta command line interface for managing deta micros. -Complete documentation available at https://deta.space/docs - -Usage: - space [flags] - space [command] - -Available Commands: - help Help about any command - link link code to project - login login to space - new create new project - push push code for project - release create release for a project - validate validate spacefile in dir - version Space CLI version -... -``` - -
- -!!! tip - If you have problems installing the CLI, check the official Deta Space Documentation. - -## Login with the CLI - -In order to authenticate your CLI with Deta Space, you will need an access token. - -To obtain this token, open your Deta Space Canvas, open the **Teletype** (command bar at the bottom of the Canvas), and then click on **Settings**. From there, select **Generate Token** and copy the resulting token. - - - -Now run `space login` from the Space CLI. Upon pasting the token into the CLI prompt and pressing enter, you should see a confirmation message. - -
- -```console -$ space login - -To authenticate the Space CLI with your Space account, generate a new access token in your Space settings and paste it below: - -# Enter access token (41 chars) >$ ***************************************** - -๐Ÿ‘ Login Successful! -``` - -
- -## Create a new project in Space - -Now that you've authenticated with the Space CLI, use it to create a new Space Project: - -```console -$ space new - -# What is your project's name? >$ fastapi-deta -``` - -The Space CLI will ask you to name the project, we will call ours `fastapi-deta`. - -Then, it will try to automatically detect which framework or language you are using, showing you what it finds. In our case it will identify the Python app with the following message, prompting you to confirm: - -```console -โš™๏ธ No Spacefile found, trying to auto-detect configuration ... -๐Ÿ‘‡ Deta detected the following configuration: - -Micros: -name: fastapi-deta - L src: . - L engine: python3.9 - -# Do you want to bootstrap "fastapi-deta" with this configuration? (y/n)$ y -``` - -After you confirm, your project will be created in Deta Space inside a special app called Builder. Builder is a toolbox that helps you to create and manage your apps in Deta Space. - -The CLI will also create a `Spacefile` locally in the `fastapi-deta` directory. The Spacefile is a configuration file which tells Deta Space how to run your app. The `Spacefile` for your app will be as follows: - -```yaml -v: 0 -micros: - - name: fastapi-deta - src: . - engine: python3.9 -``` - -It is a `yaml` file, and you can use it to add features like scheduled tasks or modify how your app functions, which we'll do later. To learn more, read the `Spacefile` documentation. - -!!! tip - The Space CLI will also create a hidden `.space` folder in your local directory to link your local environment with Deta Space. This folder should not be included in your version control and will automatically be added to your `.gitignore` file, if you have initialized a Git repository. - -## Define the run command in the Spacefile - -The `run` command in the Spacefile tells Space what command should be executed to start your app. In this case it would be `uvicorn main:app`. - -```diff -v: 0 -micros: - - name: fastapi-deta - src: . - engine: python3.9 -+ run: uvicorn main:app -``` - -## Deploy to Deta Space - -To get your FastAPI live in the cloud, use one more CLI command: - -
- -```console -$ space push - ----> 100% - -build complete... created revision: satyr-jvjk - -โœ” Successfully pushed your code and created a new Revision! -โ„น Updating your development instance with the latest Revision, it will be available on your Canvas shortly. -``` -
- -This command will package your code, upload all the necessary files to Deta Space, and run a remote build of your app, resulting in a **revision**. Whenever you run `space push` successfully, a live instance of your API is automatically updated with the latest revision. - -!!! tip - You can manage your revisions by opening your project in the Builder app. The live copy of your API will be visible under the **Develop** tab in Builder. - -## Check it - -The live instance of your API will also be added automatically to your Canvas (the dashboard) on Deta Space. - - - -Click on the new app called `fastapi-deta`, and it will open your API in a new browser tab on a URL like `https://fastapi-deta-gj7ka8.deta.app/`. - -You will get a JSON response from your FastAPI app: - -```JSON -{ - "Hello": "World" -} -``` - -And now you can head over to the `/docs` of your API. For this example, it would be `https://fastapi-deta-gj7ka8.deta.app/docs`. - - - -## Enable public access - -Deta will handle authentication for your account using cookies. By default, every app or API that you `push` or install to your Space is personal - it's only accessible to you. - -But you can also make your API public using the `Spacefile` from earlier. - -With a `public_routes` parameter, you can specify which paths of your API should be available to the public. - -Set your `public_routes` to `"*"` to open every route of your API to the public: - -```yaml -v: 0 -micros: - - name: fastapi-deta - src: . - engine: python3.9 - public_routes: - - "/*" -``` - -Then run `space push` again to update your live API on Deta Space. - -Once it deploys, you can share your URL with anyone and they will be able to access your API. ๐Ÿš€ - -## HTTPS - -Congrats! You deployed your FastAPI app to Deta Space! ๐ŸŽ‰ ๐Ÿฐ - -Also, notice that Deta Space correctly handles HTTPS for you, so you don't have to take care of that and can be sure that your users will have a secure encrypted connection. โœ… ๐Ÿ”’ - -## Create a release - -Space also allows you to publish your API. When you publish it, anyone else can install their own copy of your API, in their own Deta Space cloud. - -To do so, run `space release` in the Space CLI to create an **unlisted release**: - -
- -```console -$ space release - -# Do you want to use the latest revision (buzzard-hczt)? (y/n)$ y - -~ Creating a Release with the latest Revision - ----> 100% - -creating release... -publishing release in edge locations.. -completed... -released: fastapi-deta-exp-msbu -https://deta.space/discovery/r/5kjhgyxewkdmtotx - - Lift off -- successfully created a new Release! - Your Release is available globally on 5 Deta Edges - Anyone can install their own copy of your app. -``` -
- -This command publishes your revision as a release and gives you a link. Anyone you give this link to can install your API. - - -You can also make your app publicly discoverable by creating a **listed release** with `space release --listed` in the Space CLI: - -
- -```console -$ space release --listed - -# Do you want to use the latest revision (buzzard-hczt)? (y/n)$ y - -~ Creating a listed Release with the latest Revision ... - -creating release... -publishing release in edge locations.. -completed... -released: fastapi-deta-exp-msbu -https://deta.space/discovery/@user/fastapi-deta - - Lift off -- successfully created a new Release! - Your Release is available globally on 5 Deta Edges - Anyone can install their own copy of your app. - Listed on Discovery for others to find! -``` -
- -This will allow anyone to find and install your app via Deta Discovery. Read more about releasing your app in the docs. - -## Check runtime logs - -Deta Space also lets you inspect the logs of every app you build or install. - -Add some logging functionality to your app by adding a `print` statement to your `main.py` file. - -```py -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int): - print(item_id) - return {"item_id": item_id} -``` - -The code within the `read_item` function includes a print statement that will output the `item_id` that is included in the URL. Send a request to your _path operation_ `/items/{item_id}` from the docs UI (which will have a URL like `https://fastapi-deta-gj7ka8.deta.app/docs`), using an ID like `5` as an example. - -Now go to your Space's Canvas. Click on the context menu (`...`) of your live app instance, and then click on **View Logs**. Here you can view your app's logs, sorted by time. - - - -## Learn more - -At some point, you will probably want to store some data for your app in a way that persists through time. For that you can use Deta Base and Deta Drive, both of which have a generous **free tier**. - -You can also read more in the Deta Space Documentation. - -!!! tip - If you have any Deta related questions, comments, or feedback, head to the Deta Discord server. - - -## Deployment Concepts - -Coming back to the concepts we discussed in [Deployments Concepts](./concepts.md){.internal-link target=_blank}, here's how each of them would be handled with Deta Space: - -- **HTTPS**: Handled by Deta Space, they will give you a subdomain and handle HTTPS automatically. -- **Running on startup**: Handled by Deta Space, as part of their service. -- **Restarts**: Handled by Deta Space, as part of their service. -- **Replication**: Handled by Deta Space, as part of their service. -- **Authentication**: Handled by Deta Space, as part of their service. -- **Memory**: Limit predefined by Deta Space, you could contact them to increase it. -- **Previous steps before starting**: Can be configured using the `Spacefile`. - -!!! note - Deta Space is designed to make it easy and free to build cloud applications for yourself. Then you can optionally share them with anyone. - - It can simplify several use cases, but at the same time, it doesn't support others, like using external databases (apart from Deta's own NoSQL database system), custom virtual machines, etc. - - You can read more details in the Deta Space Documentation to see if it's the right choice for you. diff --git a/docs/en/docs/advanced/async-sql-databases.md b/docs/en/docs/how-to/async-sql-encode-databases.md similarity index 98% rename from docs/en/docs/advanced/async-sql-databases.md rename to docs/en/docs/how-to/async-sql-encode-databases.md index 12549a190..697167f79 100644 --- a/docs/en/docs/advanced/async-sql-databases.md +++ b/docs/en/docs/how-to/async-sql-encode-databases.md @@ -1,4 +1,4 @@ -# Async SQL (Relational) Databases +# Async SQL (Relational) Databases with Encode/Databases !!! info These docs are about to be updated. ๐ŸŽ‰ diff --git a/docs/en/docs/advanced/conditional-openapi.md b/docs/en/docs/how-to/conditional-openapi.md similarity index 100% rename from docs/en/docs/advanced/conditional-openapi.md rename to docs/en/docs/how-to/conditional-openapi.md diff --git a/docs/en/docs/how-to/configure-swagger-ui.md b/docs/en/docs/how-to/configure-swagger-ui.md new file mode 100644 index 000000000..f36ba5ba8 --- /dev/null +++ b/docs/en/docs/how-to/configure-swagger-ui.md @@ -0,0 +1,78 @@ +# Configure Swagger UI + +You can configure some extra Swagger UI parameters. + +To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function. + +`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly. + +FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs. + +## Disable Syntax Highlighting + +For example, you could disable syntax highlighting in Swagger UI. + +Without changing the settings, syntax highlighting is enabled by default: + + + +But you can disable it by setting `syntaxHighlight` to `False`: + +```Python hl_lines="3" +{!../../../docs_src/configure_swagger_ui/tutorial001.py!} +``` + +...and then Swagger UI won't show the syntax highlighting anymore: + + + +## Change the Theme + +The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle): + +```Python hl_lines="3" +{!../../../docs_src/configure_swagger_ui/tutorial002.py!} +``` + +That configuration would change the syntax highlighting color theme: + + + +## Change Default Swagger UI Parameters + +FastAPI includes some default configuration parameters appropriate for most of the use cases. + +It includes these default configurations: + +```Python +{!../../../fastapi/openapi/docs.py[ln:7-13]!} +``` + +You can override any of them by setting a different value in the argument `swagger_ui_parameters`. + +For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`: + +```Python hl_lines="3" +{!../../../docs_src/configure_swagger_ui/tutorial003.py!} +``` + +## Other Swagger UI Parameters + +To see all the other possible configurations you can use, read the official docs for Swagger UI parameters. + +## JavaScript-only settings + +Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions). + +FastAPI also includes these JavaScript-only `presets` settings: + +```JavaScript +presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIBundle.SwaggerUIStandalonePreset +] +``` + +These are **JavaScript** objects, not strings, so you can't pass them from Python code directly. + +If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need. diff --git a/docs/en/docs/how-to/custom-docs-ui-assets.md b/docs/en/docs/how-to/custom-docs-ui-assets.md new file mode 100644 index 000000000..f26324869 --- /dev/null +++ b/docs/en/docs/how-to/custom-docs-ui-assets.md @@ -0,0 +1,199 @@ +# Custom Docs UI Static Assets (Self-Hosting) + +The API docs use **Swagger UI** and **ReDoc**, and each of those need some JavaScript and CSS files. + +By default, those files are served from a CDN. + +But it's possible to customize it, you can set a specific CDN, or serve the files yourself. + +## Custom CDN for JavaScript and CSS + +Let's say that you want to use a different CDN, for example you want to use `https://unpkg.com/`. + +This could be useful if for example you live in a country that restricts some URLs. + +### Disable the automatic docs + +The first step is to disable the automatic docs, as by default, those use the default CDN. + +To disable them, set their URLs to `None` when creating your `FastAPI` app: + +```Python hl_lines="8" +{!../../../docs_src/custom_docs_ui/tutorial001.py!} +``` + +### Include the custom docs + +Now you can create the *path operations* for the custom docs. + +You can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments: + +* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`. +* `title`: the title of your API. +* `oauth2_redirect_url`: you can use `app.swagger_ui_oauth2_redirect_url` here to use the default. +* `swagger_js_url`: the URL where the HTML for your Swagger UI docs can get the **JavaScript** file. This is the custom CDN URL. +* `swagger_css_url`: the URL where the HTML for your Swagger UI docs can get the **CSS** file. This is the custom CDN URL. + +And similarly for ReDoc... + +```Python hl_lines="2-6 11-19 22-24 27-33" +{!../../../docs_src/custom_docs_ui/tutorial001.py!} +``` + +!!! tip + The *path operation* for `swagger_ui_redirect` is a helper for when you use OAuth2. + + If you integrate your API with an OAuth2 provider, you will be able to authenticate and come back to the API docs with the acquired credentials. And interact with it using the real OAuth2 authentication. + + Swagger UI will handle it behind the scenes for you, but it needs this "redirect" helper. + +### Create a *path operation* to test it + +Now, to be able to test that everything works, create a *path operation*: + +```Python hl_lines="36-38" +{!../../../docs_src/custom_docs_ui/tutorial001.py!} +``` + +### Test it + +Now, you should be able to go to your docs at http://127.0.0.1:8000/docs, and reload the page, it will load those assets from the new CDN. + +## Self-hosting JavaScript and CSS for docs + +Self-hosting the JavaScript and CSS could be useful if, for example, you need your app to keep working even while offline, without open Internet access, or in a local network. + +Here you'll see how to serve those files yourself, in the same FastAPI app, and configure the docs to use them. + +### Project file structure + +Let's say your project file structure looks like this: + +``` +. +โ”œโ”€โ”€ app +โ”‚ โ”œโ”€โ”€ __init__.py +โ”‚ โ”œโ”€โ”€ main.py +``` + +Now create a directory to store those static files. + +Your new file structure could look like this: + +``` +. +โ”œโ”€โ”€ app +โ”‚ย ย  โ”œโ”€โ”€ __init__.py +โ”‚ย ย  โ”œโ”€โ”€ main.py +โ””โ”€โ”€ static/ +``` + +### Download the files + +Download the static files needed for the docs and put them on that `static/` directory. + +You can probably right-click each link and select an option similar to `Save link as...`. + +**Swagger UI** uses the files: + +* `swagger-ui-bundle.js` +* `swagger-ui.css` + +And **ReDoc** uses the file: + +* `redoc.standalone.js` + +After that, your file structure could look like: + +``` +. +โ”œโ”€โ”€ app +โ”‚ย ย  โ”œโ”€โ”€ __init__.py +โ”‚ย ย  โ”œโ”€โ”€ main.py +โ””โ”€โ”€ static + โ”œโ”€โ”€ redoc.standalone.js + โ”œโ”€โ”€ swagger-ui-bundle.js + โ””โ”€โ”€ swagger-ui.css +``` + +### Serve the static files + +* Import `StaticFiles`. +* "Mount" a `StaticFiles()` instance in a specific path. + +```Python hl_lines="7 11" +{!../../../docs_src/custom_docs_ui/tutorial002.py!} +``` + +### Test the static files + +Start your application and go to http://127.0.0.1:8000/static/redoc.standalone.js. + +You should see a very long JavaScript file for **ReDoc**. + +It could start with something like: + +```JavaScript +/*! + * ReDoc - OpenAPI/Swagger-generated API Reference Documentation + * ------------------------------------------------------------- + * Version: "2.0.0-rc.18" + * Repo: https://github.com/Redocly/redoc + */ +!function(e,t){"object"==typeof exports&&"object"==typeof m + +... +``` + +That confirms that you are being able to serve static files from your app, and that you placed the static files for the docs in the correct place. + +Now we can configure the app to use those static files for the docs. + +### Disable the automatic docs for static files + +The same as when using a custom CDN, the first step is to disable the automatic docs, as those use the CDN by default. + +To disable them, set their URLs to `None` when creating your `FastAPI` app: + +```Python hl_lines="9" +{!../../../docs_src/custom_docs_ui/tutorial002.py!} +``` + +### Include the custom docs for static files + +And the same way as with a custom CDN, now you can create the *path operations* for the custom docs. + +Again, you can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments: + +* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`. +* `title`: the title of your API. +* `oauth2_redirect_url`: you can use `app.swagger_ui_oauth2_redirect_url` here to use the default. +* `swagger_js_url`: the URL where the HTML for your Swagger UI docs can get the **JavaScript** file. **This is the one that your own app is now serving**. +* `swagger_css_url`: the URL where the HTML for your Swagger UI docs can get the **CSS** file. **This is the one that your own app is now serving**. + +And similarly for ReDoc... + +```Python hl_lines="2-6 14-22 25-27 30-36" +{!../../../docs_src/custom_docs_ui/tutorial002.py!} +``` + +!!! tip + The *path operation* for `swagger_ui_redirect` is a helper for when you use OAuth2. + + If you integrate your API with an OAuth2 provider, you will be able to authenticate and come back to the API docs with the acquired credentials. And interact with it using the real OAuth2 authentication. + + Swagger UI will handle it behind the scenes for you, but it needs this "redirect" helper. + +### Create a *path operation* to test static files + +Now, to be able to test that everything works, create a *path operation*: + +```Python hl_lines="39-41" +{!../../../docs_src/custom_docs_ui/tutorial002.py!} +``` + +### Test Static Files UI + +Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page. + +And even without Internet, you would be able to see the docs for your API and interact with it. diff --git a/docs/en/docs/advanced/custom-request-and-route.md b/docs/en/docs/how-to/custom-request-and-route.md similarity index 100% rename from docs/en/docs/advanced/custom-request-and-route.md rename to docs/en/docs/how-to/custom-request-and-route.md diff --git a/docs/en/docs/how-to/extending-openapi.md b/docs/en/docs/how-to/extending-openapi.md new file mode 100644 index 000000000..a18fd737e --- /dev/null +++ b/docs/en/docs/how-to/extending-openapi.md @@ -0,0 +1,87 @@ +# Extending OpenAPI + +There are some cases where you might need to modify the generated OpenAPI schema. + +In this section you will see how. + +## The normal process + +The normal (default) process, is as follows. + +A `FastAPI` application (instance) has an `.openapi()` method that is expected to return the OpenAPI schema. + +As part of the application object creation, a *path operation* for `/openapi.json` (or for whatever you set your `openapi_url`) is registered. + +It just returns a JSON response with the result of the application's `.openapi()` method. + +By default, what the method `.openapi()` does is check the property `.openapi_schema` to see if it has contents and return them. + +If it doesn't, it generates them using the utility function at `fastapi.openapi.utils.get_openapi`. + +And that function `get_openapi()` receives as parameters: + +* `title`: The OpenAPI title, shown in the docs. +* `version`: The version of your API, e.g. `2.5.0`. +* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.1.0`. +* `summary`: A short summary of the API. +* `description`: The description of your API, this can include markdown and will be shown in the docs. +* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`. + +!!! info + The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by FastAPI 0.99.0 and above. + +## Overriding the defaults + +Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need. + +For example, let's add ReDoc's OpenAPI extension to include a custom logo. + +### Normal **FastAPI** + +First, write all your **FastAPI** application as normally: + +```Python hl_lines="1 4 7-9" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### Generate the OpenAPI schema + +Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function: + +```Python hl_lines="2 15-21" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### Modify the OpenAPI schema + +Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema: + +```Python hl_lines="22-24" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### Cache the OpenAPI schema + +You can use the property `.openapi_schema` as a "cache", to store your generated schema. + +That way, your application won't have to generate the schema every time a user opens your API docs. + +It will be generated only once, and then the same cached schema will be used for the next requests. + +```Python hl_lines="13-14 25-26" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### Override the method + +Now you can replace the `.openapi()` method with your new function. + +```Python hl_lines="29" +{!../../../docs_src/extending_openapi/tutorial001.py!} +``` + +### Check it + +Once you go to http://127.0.0.1:8000/redoc you will see that you are using your custom logo (in this example, **FastAPI**'s logo): + + diff --git a/docs/en/docs/how-to/general.md b/docs/en/docs/how-to/general.md new file mode 100644 index 000000000..04367c6b7 --- /dev/null +++ b/docs/en/docs/how-to/general.md @@ -0,0 +1,39 @@ +# General - How To - Recipes + +Here are several pointers to other places in the docs, for general or frequent questions. + +## Filter Data - Security + +To ensure that you don't return more data than you should, read the docs for [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank}. + +## Documentation Tags - OpenAPI + +To add tags to your *path operations*, and group them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}. + +## Documentation Summary and Description - OpenAPI + +To add a summary and description to your *path operations*, and show them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}. + +## Documentation Response description - OpenAPI + +To define the description of the response, shown in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}. + +## Documentation Deprecate a *Path Operation* - OpenAPI + +To deprecate a *path operation*, and show it in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}. + +## Convert any Data to JSON-compatible + +To convert any data to JSON-compatible, read the docs for [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}. + +## OpenAPI Metadata - Docs + +To add metadata to your OpenAPI schema, including a license, version, contact, etc, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank}. + +## OpenAPI Custom URL + +To customize the OpenAPI URL (or remove it), read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}. + +## OpenAPI Docs URLs + +To update the URLs used for the automatically generated docs user interfaces, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}. diff --git a/docs/en/docs/advanced/graphql.md b/docs/en/docs/how-to/graphql.md similarity index 100% rename from docs/en/docs/advanced/graphql.md rename to docs/en/docs/how-to/graphql.md diff --git a/docs/en/docs/how-to/index.md b/docs/en/docs/how-to/index.md new file mode 100644 index 000000000..ec7fd38f8 --- /dev/null +++ b/docs/en/docs/how-to/index.md @@ -0,0 +1,11 @@ +# How To - Recipes + +Here you will see different recipes or "how to" guides for **several topics**. + +Most of these ideas would be more or less **independent**, and in most cases you should only need to study them if they apply directly to **your project**. + +If something seems interesting and useful to your project, go ahead and check it, but otherwise, you might probably just skip them. + +!!! tip + + If you want to **learn FastAPI** in a structured way (recommended), go and read the [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} chapter by chapter instead. diff --git a/docs/en/docs/advanced/nosql-databases.md b/docs/en/docs/how-to/nosql-databases-couchbase.md similarity index 99% rename from docs/en/docs/advanced/nosql-databases.md rename to docs/en/docs/how-to/nosql-databases-couchbase.md index 606db35c7..ae6ad604b 100644 --- a/docs/en/docs/advanced/nosql-databases.md +++ b/docs/en/docs/how-to/nosql-databases-couchbase.md @@ -1,4 +1,4 @@ -# NoSQL (Distributed / Big Data) Databases +# NoSQL (Distributed / Big Data) Databases with Couchbase !!! info These docs are about to be updated. ๐ŸŽ‰ diff --git a/docs/en/docs/advanced/sql-databases-peewee.md b/docs/en/docs/how-to/sql-databases-peewee.md similarity index 99% rename from docs/en/docs/advanced/sql-databases-peewee.md rename to docs/en/docs/how-to/sql-databases-peewee.md index 6a469634f..bf2f2e714 100644 --- a/docs/en/docs/advanced/sql-databases-peewee.md +++ b/docs/en/docs/how-to/sql-databases-peewee.md @@ -12,6 +12,8 @@ Because Pewee doesn't play well with anything async and there are better alternatives, I won't update these docs for Pydantic v2, they are kept for now only for historical purposes. + The examples here are no longer tested in CI (as they were before). + If you are starting a project from scratch, you are probably better off with SQLAlchemy ORM ([SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank}), or any other async ORM. If you already have a code base that uses Peewee ORM, you can check here how to use it with **FastAPI**. diff --git a/docs/en/docs/img/sponsors/speakeasy.png b/docs/en/docs/img/sponsors/speakeasy.png new file mode 100644 index 000000000..001b4b4ca Binary files /dev/null and b/docs/en/docs/img/sponsors/speakeasy.png differ diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 868628ae8..61ec91b4a 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -2,19 +2,47 @@ ## Latest Changes -* ๐ŸŒ Add Ukrainian translation for `docs/uk/docs/tutorial/cookie-params.md`. PR [#10032](https://github.com/tiangolo/fastapi/pull/10032) by [@rostik1410](https://github.com/rostik1410). -* ๐ŸŒ Add Russian translation for `docs/ru/docs/deployment/docker.md`. PR [#9971](https://github.com/tiangolo/fastapi/pull/9971) by [@Xewus](https://github.com/Xewus). -* ๐ŸŒ Add Vietnamese translation for `docs/vi/docs/python-types.md`. PR [#10047](https://github.com/tiangolo/fastapi/pull/10047) by [@magiskboy](https://github.com/magiskboy). -* ๐Ÿ”ง Add sponsor Porter. PR [#10051](https://github.com/tiangolo/fastapi/pull/10051) by [@tiangolo](https://github.com/tiangolo). -* ๐Ÿ”ง Update sponsors, add Jina back as bronze sponsor. PR [#10050](https://github.com/tiangolo/fastapi/pull/10050) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ“ Add new docs section, How To - Recipes, move docs that don't have to be read by everyone to How To. PR [#10114](https://github.com/tiangolo/fastapi/pull/10114) by [@tiangolo](https://github.com/tiangolo). +* โ™ป๏ธ Refactor tests for new Pydantic 2.2.1. PR [#10115](https://github.com/tiangolo/fastapi/pull/10115) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ“ Update Advanced docs, add links to sponsor courses. PR [#10113](https://github.com/tiangolo/fastapi/pull/10113) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ“ Update docs for generating clients. PR [#10112](https://github.com/tiangolo/fastapi/pull/10112) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ“ Tweak MkDocs and add redirects. PR [#10111](https://github.com/tiangolo/fastapi/pull/10111) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ“ Restructure docs for cloud providers, include links to sponsors. PR [#10110](https://github.com/tiangolo/fastapi/pull/10110) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ”ง Update sponsors, add Speakeasy. PR [#10098](https://github.com/tiangolo/fastapi/pull/10098) by [@tiangolo](https://github.com/tiangolo). +## 0.101.1 + +### Fixes + +* โœจ Add `ResponseValidationError` printable details, to show up in server error logs. PR [#10078](https://github.com/tiangolo/fastapi/pull/10078) by [@tiangolo](https://github.com/tiangolo). + +### Refactors + * โœ๏ธ Fix typo in deprecation warnings in `fastapi/params.py`. PR [#9854](https://github.com/tiangolo/fastapi/pull/9854) by [@russbiggs](https://github.com/russbiggs). -* โœ๏ธ Fix typo in release notes. PR [#9835](https://github.com/tiangolo/fastapi/pull/9835) by [@francisbergin](https://github.com/francisbergin). * โœ๏ธ Fix typos in comments on internal code in `fastapi/concurrency.py` and `fastapi/routing.py`. PR [#9590](https://github.com/tiangolo/fastapi/pull/9590) by [@ElliottLarsen](https://github.com/ElliottLarsen). + +### Docs + +* โœ๏ธ Fix typo in release notes. PR [#9835](https://github.com/tiangolo/fastapi/pull/9835) by [@francisbergin](https://github.com/francisbergin). * ๐Ÿ“ Add external article: Build an SMS Spam Classifier Serverless Database with FaunaDB and FastAPI. PR [#9847](https://github.com/tiangolo/fastapi/pull/9847) by [@adejumoridwan](https://github.com/adejumoridwan). * ๐Ÿ“ Fix typo in `docs/en/docs/contributing.md`. PR [#9878](https://github.com/tiangolo/fastapi/pull/9878) by [@VicenteMerino](https://github.com/VicenteMerino). * ๐Ÿ“ Fix code highlighting in `docs/en/docs/tutorial/bigger-applications.md`. PR [#9806](https://github.com/tiangolo/fastapi/pull/9806) by [@theonlykingpin](https://github.com/theonlykingpin). + +### Translations + +* ๐ŸŒ Add Japanese translation for `docs/ja/docs/deployment/concepts.md`. PR [#10062](https://github.com/tiangolo/fastapi/pull/10062) by [@tamtam-fitness](https://github.com/tamtam-fitness). +* ๐ŸŒ Add Japanese translation for `docs/ja/docs/deployment/server-workers.md`. PR [#10064](https://github.com/tiangolo/fastapi/pull/10064) by [@tamtam-fitness](https://github.com/tamtam-fitness). +* ๐ŸŒ Update Japanese translation for `docs/ja/docs/deployment/docker.md`. PR [#10073](https://github.com/tiangolo/fastapi/pull/10073) by [@tamtam-fitness](https://github.com/tamtam-fitness). +* ๐ŸŒ Add Ukrainian translation for `docs/uk/docs/fastapi-people.md`. PR [#10059](https://github.com/tiangolo/fastapi/pull/10059) by [@rostik1410](https://github.com/rostik1410). +* ๐ŸŒ Add Ukrainian translation for `docs/uk/docs/tutorial/cookie-params.md`. PR [#10032](https://github.com/tiangolo/fastapi/pull/10032) by [@rostik1410](https://github.com/rostik1410). +* ๐ŸŒ Add Russian translation for `docs/ru/docs/deployment/docker.md`. PR [#9971](https://github.com/tiangolo/fastapi/pull/9971) by [@Xewus](https://github.com/Xewus). +* ๐ŸŒ Add Vietnamese translation for `docs/vi/docs/python-types.md`. PR [#10047](https://github.com/tiangolo/fastapi/pull/10047) by [@magiskboy](https://github.com/magiskboy). * ๐ŸŒ Add Russian translation for `docs/ru/docs/tutorial/dependencies/global-dependencies.md`. PR [#9970](https://github.com/tiangolo/fastapi/pull/9970) by [@dudyaosuplayer](https://github.com/dudyaosuplayer). * ๐ŸŒ Add Urdu translation for `docs/ur/docs/benchmarks.md`. PR [#9974](https://github.com/tiangolo/fastapi/pull/9974) by [@AhsanSheraz](https://github.com/AhsanSheraz). + +### Internal + +* ๐Ÿ”ง Add sponsor Porter. PR [#10051](https://github.com/tiangolo/fastapi/pull/10051) by [@tiangolo](https://github.com/tiangolo). +* ๐Ÿ”ง Update sponsors, add Jina back as bronze sponsor. PR [#10050](https://github.com/tiangolo/fastapi/pull/10050) by [@tiangolo](https://github.com/tiangolo). * โฌ† Bump mypy from 1.4.0 to 1.4.1. PR [#9756](https://github.com/tiangolo/fastapi/pull/9756) by [@dependabot[bot]](https://github.com/apps/dependabot). * โฌ† Bump mkdocs-material from 9.1.17 to 9.1.21. PR [#9960](https://github.com/tiangolo/fastapi/pull/9960) by [@dependabot[bot]](https://github.com/apps/dependabot). diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml index a66b6c147..f75b84ff5 100644 --- a/docs/en/mkdocs.yml +++ b/docs/en/mkdocs.yml @@ -42,6 +42,16 @@ plugins: search: null markdownextradata: data: ../en/data + redirects: + redirect_maps: + deployment/deta.md: deployment/cloud.md + advanced/sql-databases-peewee.md: how-to/sql-databases-peewee.md + advanced/async-sql-databases.md: how-to/async-sql-encode-databases.md + advanced/nosql-databases.md: how-to/nosql-databases-couchbase.md + advanced/graphql.md: how-to/graphql.md + advanced/custom-request-and-route.md: how-to/custom-request-and-route.md + advanced/conditional-openapi.md: how-to/conditional-openapi.md + advanced/extending-openapi.md: how-to/extending-openapi.md nav: - FastAPI: index.md - Languages: @@ -60,6 +70,7 @@ nav: - ru: /ru/ - tr: /tr/ - uk: /uk/ + - ur: /ur/ - vi: /vi/ - zh: /zh/ - features.md @@ -130,24 +141,17 @@ nav: - advanced/using-request-directly.md - advanced/dataclasses.md - advanced/middleware.md - - advanced/sql-databases-peewee.md - - advanced/async-sql-databases.md - - advanced/nosql-databases.md - advanced/sub-applications.md - advanced/behind-a-proxy.md - advanced/templates.md - - advanced/graphql.md - advanced/websockets.md - advanced/events.md - - advanced/custom-request-and-route.md - advanced/testing-websockets.md - advanced/testing-events.md - advanced/testing-dependencies.md - advanced/testing-database.md - advanced/async-tests.md - advanced/settings.md - - advanced/conditional-openapi.md - - advanced/extending-openapi.md - advanced/openapi-callbacks.md - advanced/openapi-webhooks.md - advanced/wsgi.md @@ -159,9 +163,21 @@ nav: - deployment/https.md - deployment/manually.md - deployment/concepts.md - - deployment/deta.md + - deployment/cloud.md - deployment/server-workers.md - deployment/docker.md +- How To - Recipes: + - how-to/index.md + - how-to/general.md + - how-to/sql-databases-peewee.md + - how-to/async-sql-encode-databases.md + - how-to/nosql-databases-couchbase.md + - how-to/graphql.md + - how-to/custom-request-and-route.md + - how-to/conditional-openapi.md + - how-to/extending-openapi.md + - how-to/custom-docs-ui-assets.md + - how-to/configure-swagger-ui.md - project-generation.md - alternatives.md - history-design-future.md @@ -178,9 +194,9 @@ markdown_extensions: guess_lang: false mdx_include: base_path: docs - admonition: - codehilite: - extra: + admonition: null + codehilite: null + extra: null pymdownx.superfences: custom_fences: - name: mermaid @@ -188,8 +204,8 @@ markdown_extensions: format: !!python/name:pymdownx.superfences.fence_code_format '' pymdownx.tabbed: alternate_style: true - attr_list: - md_in_html: + attr_list: null + md_in_html: null extra: analytics: provider: google @@ -240,6 +256,8 @@ extra: name: tr - Tรผrkรงe - link: /uk/ name: uk + - link: /ur/ + name: ur - link: /vi/ name: vi - Tiแบฟng Viแป‡t - link: /zh/ diff --git a/docs/fr/docs/deployment/deta.md b/docs/fr/docs/deployment/deta.md deleted file mode 100644 index cceb7b058..000000000 --- a/docs/fr/docs/deployment/deta.md +++ /dev/null @@ -1,245 +0,0 @@ -# Dรฉployer FastAPI sur Deta - -Dans cette section, vous apprendrez ร  dรฉployer facilement une application **FastAPI** sur Deta en utilisant le plan tarifaire gratuit. ๐ŸŽ - -Cela vous prendra environ **10 minutes**. - -!!! info - Deta sponsorise **FastAPI**. ๐ŸŽ‰ - -## Une application **FastAPI** de base - -* Crรฉez un rรฉpertoire pour votre application, par exemple `./fastapideta/` et dรฉplacez-vous dedans. - -### Le code FastAPI - -* Crรฉer un fichier `main.py` avecย : - -```Python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int): - return {"item_id": item_id} -``` - -### Dรฉpendances - -Maintenant, dans le mรชme rรฉpertoire, crรฉez un fichier `requirements.txt` avecย : - -```text -fastapi -``` - -!!! tip "Astuce" - Il n'est pas nรฉcessaire d'installer Uvicorn pour dรฉployer sur Deta, bien qu'il soit probablement souhaitable de l'installer localement pour tester votre application. - -### Structure du rรฉpertoire - -Vous aurez maintenant un rรฉpertoire `./fastapideta/` avec deux fichiersย : - -``` -. -โ””โ”€โ”€ main.py -โ””โ”€โ”€ requirements.txt -``` - -## Crรฉer un compte gratuit sur Deta - -Crรฉez maintenant un compte gratuit -sur Deta, vous avez juste besoin d'une adresse email et d'un mot de passe. - -Vous n'avez mรชme pas besoin d'une carte de crรฉdit. - -## Installer le CLI (Interface en Ligne de Commande) - -Une fois que vous avez votre compte, installez le CLI de Deta : - -=== "Linux, macOS" - -
- - ```console - $ curl -fsSL https://get.deta.dev/cli.sh | sh - ``` - -
- -=== "Windows PowerShell" - -
- - ```console - $ iwr https://get.deta.dev/cli.ps1 -useb | iex - ``` - -
- -Aprรจs l'avoir installรฉ, ouvrez un nouveau terminal afin que la nouvelle installation soit dรฉtectรฉe. - -Dans un nouveau terminal, confirmez qu'il a รฉtรฉ correctement installรฉ avecย : - -
- -```console -$ deta --help - -Deta command line interface for managing deta micros. -Complete documentation available at https://docs.deta.sh - -Usage: - deta [flags] - deta [command] - -Available Commands: - auth Change auth settings for a deta micro - -... -``` - -
- -!!! tip "Astuce" - Si vous rencontrez des problรจmes pour installer le CLI, consultez la documentation officielle de Deta (en anglais). - -## Connexion avec le CLI - -Maintenant, connectez-vous ร  Deta depuis le CLI avecย : - -
- -```console -$ deta login - -Please, log in from the web page. Waiting.. -Logged in successfully. -``` - -
- -Cela ouvrira un navigateur web et permettra une authentification automatique. - -## Dรฉployer avec Deta - -Ensuite, dรฉployez votre application avec le CLI de Detaย : - -
- -```console -$ deta new - -Successfully created a new micro - -// Notice the "endpoint" ๐Ÿ” - -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} - -Adding dependencies... - - ----> 100% - - -Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6 -``` - -
- -Vous verrez un message JSON similaire ร ย : - -```JSON hl_lines="4" -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} -``` - -!!! tip "Astuce" - Votre dรฉploiement aura une URL `"endpoint"` diffรฉrente. - -## Vรฉrifiez - -Maintenant, dans votre navigateur ouvrez votre URL `endpoint`. Dans l'exemple ci-dessus, c'รฉtait -`https://qltnci.deta.dev`, mais la vรดtre sera diffรฉrente. - -Vous verrez la rรฉponse JSON de votre application FastAPIย : - -```JSON -{ - "Hello": "World" -} -``` - -Et maintenant naviguez vers `/docs` dans votre API, dans l'exemple ci-dessus ce serait `https://qltnci.deta.dev/docs`. - -Vous verrez votre documentation comme suitย : - - - -## Activer l'accรจs public - -Par dรฉfaut, Deta va gรฉrer l'authentification en utilisant des cookies pour votre compte. - -Mais une fois que vous รชtes prรชt, vous pouvez le rendre public avecย : - -
- -```console -$ deta auth disable - -Successfully disabled http auth -``` - -
- -Maintenant, vous pouvez partager cette URL avec n'importe qui et ils seront en mesure d'accรฉder ร  votre API. ๐Ÿš€ - -## HTTPS - -Fรฉlicitationsโ€ฏ! Vous avez dรฉployรฉ votre application FastAPI sur Detaโ€ฏ! ๐ŸŽ‰ ๐Ÿฐ - -Remarquez รฉgalement que Deta gรจre correctement HTTPS pour vous, vous n'avez donc pas ร  vous en occuper et pouvez รชtre sรปr que vos clients auront une connexion cryptรฉe sรฉcurisรฉe. โœ… ๐Ÿ”’ - -## Vรฉrifiez le Visor - -ร€ partir de l'interface graphique de votre documentation (dans une URL telle que `https://qltnci.deta.dev/docs`) -envoyez une requรชte ร  votre *opรฉration de chemin* `/items/{item_id}`. - -Par exemple avec l'ID `5`. - -Allez maintenant sur https://web.deta.sh. - -Vous verrez qu'il y a une section ร  gauche appelรฉe "Micros" avec chacune de vos applications. - -Vous verrez un onglet avec "Details", et aussi un onglet "Visor", allez ร  l'onglet "Visor". - -Vous pouvez y consulter les requรชtes rรฉcentes envoyรฉes ร  votre application. - -Vous pouvez รฉgalement les modifier et les relancer. - - - -## En savoir plus - -ร€ un moment donnรฉ, vous voudrez probablement stocker certaines donnรฉes pour votre application d'une maniรจre qui -persiste dans le temps. Pour cela, vous pouvez utiliser Deta Base, il dispose รฉgalement d'un gรฉnรฉreux **plan gratuit**. - -Vous pouvez รฉgalement en lire plus dans la documentation Deta. diff --git a/docs/ja/docs/deployment/concepts.md b/docs/ja/docs/deployment/concepts.md new file mode 100644 index 000000000..38cbca219 --- /dev/null +++ b/docs/ja/docs/deployment/concepts.md @@ -0,0 +1,323 @@ +# ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ + +**FastAPI**ใ‚’็”จใ„ใŸใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใจใใ€ใ‚‚ใ—ใใฏใฉใฎใ‚ˆใ†ใชใ‚ฟใ‚คใƒ—ใฎWeb APIใงใ‚ใฃใฆใ‚‚ใ€ใŠใใ‚‰ใๆฐ—ใซใชใ‚‹ใ‚ณใƒณใ‚ปใƒ—ใƒˆใŒใ„ใใคใ‹ใ‚ใ‚Šใพใ™ใ€‚ + +ใใ‚Œใ‚‰ใ‚’ๆดป็”จใ™ใ‚‹ใ“ใจใงใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’**ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใŸใ‚ใฎๆœ€้ฉใชๆ–นๆณ•**ใ‚’่ฆ‹ใคใ‘ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +้‡่ฆใชใ‚ณใƒณใ‚ปใƒ—ใƒˆใฎใ„ใใคใ‹ใ‚’็ดนไป‹ใ—ใพใ™: + +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰ +* ใƒกใƒขใƒชใƒผ +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ— + +ใ“ใ‚Œใ‚‰ใŒ**ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆ**ใซใฉใฎใ‚ˆใ†ใชๅฝฑ้Ÿฟใ‚’ไธŽใˆใ‚‹ใ‹ใ‚’่ฆ‹ใฆใ„ใใพใ—ใ‚‡ใ†ใ€‚ + +ๆœ€็ต‚็š„ใช็›ฎ็š„ใฏใ€**ๅฎ‰ๅ…จใชๆ–นๆณ•ใง**APIใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใซ**ใ‚ตใƒผใƒ“ใ‚นใ‚’ๆไพ›**ใ—ใ€**ไธญๆ–ญใ‚’ๅ›ž้ฟ**ใ™ใ‚‹ใ ใ‘ใงใชใใ€**่จˆ็ฎ—ใƒชใ‚ฝใƒผใ‚น**๏ผˆไพ‹ใˆใฐใƒชใƒขใƒผใƒˆใ‚ตใƒผใƒใƒผ/ไปฎๆƒณใƒžใ‚ทใƒณ๏ผ‰ใ‚’ๅฏ่ƒฝใช้™ใ‚ŠๅŠน็އ็š„ใซไฝฟ็”จใ™ใ‚‹ใ“ใจใงใ™ใ€‚๐Ÿš€ + +ใ“ใฎ็ซ ใงใฏๅ‰่ฟฐใ—ใŸ**ใ‚ณใƒณใ‚ปใƒ—ใƒˆ**ใซใคใ„ใฆใใ‚Œใžใ‚Œ่ชฌๆ˜Žใ—ใพใ™ใ€‚ + +ใ“ใฎ่ชฌๆ˜Žใ‚’้€šใ—ใฆใ€ๆ™ฎๆฎตใจใฏ้žๅธธใซ็•ฐใชใ‚‹็’ฐๅขƒใ‚„ๅญ˜ๅœจใ—ใชใ„ใงใ‚ใ‚ใ†**ๅฐ†ๆฅใฎ**็’ฐๅขƒใซๅฏพใ—ใ€ใƒ‡ใƒ—ใƒญใ‚คใฎๆ–นๆณ•ใ‚’ๆฑบใ‚ใ‚‹ไธŠใงๅฟ…่ฆใช**็›ดๆ„Ÿ**ใ‚’ไธŽใˆใฆใใ‚Œใ‚‹ใ“ใจใ‚’้ก˜ใฃใฆใ„ใพใ™ใ€‚ + +ใ“ใ‚Œใ‚‰ใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆใ‚’ๆ„่ญ˜ใ™ใ‚‹ใ“ใจใซใ‚ˆใ‚Šใ€**ใ‚ใชใŸ่‡ช่บซใฎAPI**ใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใŸใ‚ใฎๆœ€้ฉใชๆ–นๆณ•ใ‚’**่ฉ•ไพก**ใ—ใ€**่จญ่จˆ**ใ™ใ‚‹ใ“ใจใŒใงใใ‚‹ใ‚ˆใ†ใซใชใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ๆฌกใฎ็ซ ใงใฏใ€FastAPIใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใŸใ‚ใฎ**ๅ…ทไฝ“็š„ใชใƒฌใ‚ทใƒ”**ใ‚’็ดนไป‹ใ—ใพใ™ใ€‚ + +ใ—ใ‹ใ—ใ€ไปŠใฏใ“ใ‚Œใ‚‰ใฎ้‡่ฆใช**ใ‚ณใƒณใ‚ปใƒ—ใƒˆใซๅŸบใฅใใ‚ขใ‚คใƒ‡ใ‚ข**ใ‚’็ขบ่ชใ—ใพใ—ใ‚‡ใ†ใ€‚ใ“ใ‚Œใ‚‰ใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆใฏใ€ไป–ใฎใฉใฎใ‚ฟใ‚คใƒ—ใฎWeb APIใซใ‚‚ๅฝ“ใฆใฏใพใ‚Šใพใ™ใ€‚๐Ÿ’ก + +## ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS + + +[ๅ‰ใƒใƒฃใƒ—ใ‚ฟใƒผใฎHTTPSใซใคใ„ใฆ](./https.md){.internal-link target=_blank}ใงใฏใ€HTTPSใŒใฉใฎใ‚ˆใ†ใซAPIใ‚’ๆš—ๅทๅŒ–ใ™ใ‚‹ใฎใ‹ใซใคใ„ใฆๅญฆใณใพใ—ใŸใ€‚ + +้€šๅธธใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚ตใƒผใƒใซใจใฃใฆ**ๅค–้ƒจใฎ**ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใงใ‚ใ‚‹**TLS Termination Proxy**ใซใ‚ˆใฃใฆๆไพ›ใ•ใ‚Œใ‚‹ใ“ใจใŒไธ€่ˆฌ็š„ใงใ™ใ€‚ใ“ใฎใƒ—ใƒญใ‚ญใ‚ทใฏ้€šไฟกใฎๆš—ๅทๅŒ–ใ‚’ๆ‹…ๅฝ“ใ—ใพใ™ใ€‚ + +ใ•ใ‚‰ใซใ‚ปใ‚ญใƒฅใ‚ขใช้€šไฟกใซใŠใ„ใฆใ€HTTPS่จผๆ˜Žๆ›ธใฎๅฎšๆœŸ็š„ใชๆ›ดๆ–ฐใ‚’่กŒใ„ใพใ™ใŒใ€ใ“ใ‚ŒใฏTLS Termination ProxyใจๅŒใ˜ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๆ‹…ๅฝ“ใ™ใ‚‹ใ“ใจใ‚‚ใ‚ใ‚Œใฐใ€ๅˆฅใฎใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๆ‹…ๅฝ“ใ™ใ‚‹ใ“ใจใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ + +### HTTPS ็”จใƒ„ใƒผใƒซใฎไพ‹ +TLS Termination Proxyใจใ—ใฆไฝฟ็”จใงใใ‚‹ใƒ„ใƒผใƒซใซใฏไปฅไธ‹ใฎใ‚ˆใ†ใชใ‚‚ใฎใŒใ‚ใ‚Šใพใ™๏ผš + +* Traefik + * ่จผๆ˜Žๆ›ธใฎๆ›ดๆ–ฐใ‚’่‡ชๅ‹•็š„ใซๅ‡ฆ็† โœจ +* Caddy + * ่จผๆ˜Žๆ›ธใฎๆ›ดๆ–ฐใ‚’่‡ชๅ‹•็š„ใซๅ‡ฆ็† โœจ +* Nginx + * ่จผๆ˜Žๆ›ธๆ›ดๆ–ฐใฎใŸใ‚ใซCertbotใฎใ‚ˆใ†ใชๅค–้ƒจใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ไฝฟ็”จ +* HAProxy + * ่จผๆ˜Žๆ›ธๆ›ดๆ–ฐใฎใŸใ‚ใซCertbotใฎใ‚ˆใ†ใชๅค–้ƒจใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ไฝฟ็”จ +* Nginx ใฎใ‚ˆใ†ใช Ingress Controller ใ‚’ๆŒใค Kubernetes + * ่จผๆ˜Žๆ›ธใฎๆ›ดๆ–ฐใซ cert-manager ใฎใ‚ˆใ†ใชๅค–้ƒจใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ไฝฟ็”จ +* ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใƒ—ใƒญใƒใ‚คใƒ€ใƒผใŒใ‚ตใƒผใƒ“ใ‚นใฎไธ€้ƒจใจใ—ใฆๅ†…้ƒจ็š„ใซๅ‡ฆ็†๏ผˆไธ‹่จ˜ใ‚’ๅ‚็…ง๐Ÿ‘‡๏ผ‰ + +ใ‚‚ใ†1ใคใฎ้ธๆŠž่‚ขใฏใ€HTTPSใฎใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ‚’ๅซใ‚“ใ ใ‚ˆใ‚Šๅคšใใฎไฝœๆฅญใ‚’่กŒใ†**ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใ‚ตใƒผใƒ“ใ‚น**ใ‚’ๅˆฉ็”จใ™ใ‚‹ใ“ใจใงใ™ใ€‚ ใ“ใฎใ‚ตใƒผใƒ“ใ‚นใซใฏๅˆถ้™ใŒใ‚ใฃใŸใ‚Šใ€ๆ–™้‡‘ใŒ้ซ˜ใใชใฃใŸใ‚Šใ™ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ใ—ใ‹ใ—ใใฎๅ ดๅˆใ€TLS Termination Proxyใ‚’่‡ชๅˆ†ใงใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ™ใ‚‹ๅฟ…่ฆใฏใชใ„ใงใ™ใ€‚ + +ๆฌกใฎ็ซ ใงๅ…ทไฝ“ไพ‹ใ‚’ใ„ใใคใ‹็ดนไป‹ใ—ใพใ™ใ€‚ + +--- + +ๆฌกใซ่€ƒๆ…ฎใ™ในใใ‚ณใƒณใ‚ปใƒ—ใƒˆใฏใ€ๅฎŸ้š›ใฎAPIใ‚’ๅฎŸ่กŒใ™ใ‚‹ใƒ—ใƒญใ‚ฐใƒฉใƒ ๏ผˆไพ‹๏ผšUvicorn๏ผ‰ใซ้–ข้€ฃใ™ใ‚‹ใ‚‚ใฎใ™ในใฆใงใ™ใ€‚ + +## ใƒ—ใƒญใ‚ฐใƒฉใƒ  ใจ ใƒ—ใƒญใ‚ปใ‚น + +็งใŸใกใฏใ€Œ**ใƒ—ใƒญใ‚ปใ‚น**ใ€ใจใ„ใ†่จ€่‘‰ใซใคใ„ใฆใŸใใ•ใ‚“่ฉฑใ™ใฎใงใ€ใใฎๆ„ๅ‘ณใ‚„ใ€Œ**ใƒ—ใƒญใ‚ฐใƒฉใƒ **ใ€ใจใ„ใ†่จ€่‘‰ใจใฎ้•ใ„ใ‚’ๆ˜Ž็ขบใซใ—ใฆใŠใใจไพฟๅˆฉใงใ™ใ€‚ + +### ใƒ—ใƒญใ‚ฐใƒฉใƒ ใจใฏไฝ•ใ‹ + +**ใƒ—ใƒญใ‚ฐใƒฉใƒ **ใจใ„ใ†่จ€่‘‰ใฏใ€ไธ€่ˆฌ็š„ใซใ„ใ‚ใ„ใ‚ใชใ‚‚ใฎใ‚’่กจ็พใ™ใ‚‹ใฎใซไฝฟใ‚ใ‚Œใพใ™๏ผš + +* ใƒ—ใƒญใ‚ฐใƒฉใƒžใŒๆ›ธใ**ใ‚ณใƒผใƒ‰**ใ€**Pythonใƒ•ใ‚กใ‚คใƒซ** +* OSใซใ‚ˆใฃใฆๅฎŸ่กŒใ™ใ‚‹ใ“ใจใŒใงใใ‚‹ใƒ•ใ‚กใ‚คใƒซ๏ผˆไพ‹: `python`, `python.exe` or `uvicorn`๏ผ‰ +* OSไธŠใง**ๅฎŸ่กŒ**ใ—ใฆใ„ใ‚‹้–“ใ€CPUใ‚’ไฝฟ็”จใ—ใ€ใƒกใƒขใƒชไธŠใซไฝ•ใ‹ใ‚’ไฟๅญ˜ใ™ใ‚‹็‰นๅฎšใฎใƒ—ใƒญใ‚ฐใƒฉใƒ ๏ผˆ**ใƒ—ใƒญใ‚ปใ‚น**ใจใ‚‚ๅ‘ผใฐใ‚Œใ‚‹๏ผ‰ + +### ใƒ—ใƒญใ‚ปใ‚นใจใฏไฝ•ใ‹ + +**ใƒ—ใƒญใ‚ปใ‚น**ใจใ„ใ†่จ€่‘‰ใฏ้€šๅธธใ€ใ‚ˆใ‚Šๅ…ทไฝ“็š„ใชๆ„ๅ‘ณใงไฝฟใ‚ใ‚Œใ€OSใงๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใ‚‚ใฎใ ใ‘ใ‚’ๆŒ‡ใ—ใพใ™๏ผˆๅ…ˆใปใฉใฎๆœ€ๅพŒใฎ่ชฌๆ˜Žใฎใ‚ˆใ†ใซ๏ผ‰๏ผš + +* OSไธŠใง**ๅฎŸ่กŒ**ใ—ใฆใ„ใ‚‹็‰นๅฎšใฎใƒ—ใƒญใ‚ฐใƒฉใƒ  + * ใ“ใ‚Œใฏใƒ•ใ‚กใ‚คใƒซใ‚„ใ‚ณใƒผใƒ‰ใ‚’ๆŒ‡ใ™ใฎใงใฏใชใใ€OSใซใ‚ˆใฃใฆ**ๅฎŸ่กŒ**ใ•ใ‚Œใ€็ฎก็†ใ•ใ‚Œใฆใ„ใ‚‹ใ‚‚ใฎใ‚’ๆŒ‡ใ—ใพใ™ใ€‚ +* ใฉใ‚“ใชใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚„ใ‚ณใƒผใƒ‰ใ‚‚ใ€ใใ‚ŒใŒ**ๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใจใใซใ ใ‘ๆฉŸ่ƒฝ**ใ—ใพใ™ใ€‚ใคใพใ‚Šใ€**ใƒ—ใƒญใ‚ปใ‚นใจใ—ใฆๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใจใใ ใ‘**ใงใ™ใ€‚ +* ใƒ—ใƒญใ‚ปใ‚นใฏใ€ใƒฆใƒผใ‚ถใƒผใซใ‚ใ‚‹ใ„ใฏOSใซใ‚ˆใฃใฆใ€ **็ต‚ไบ†**๏ผˆใ‚ใ‚‹ใ„ใฏ "kill"๏ผ‰ใ•ใ›ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ใใฎๆ™‚็‚นใงใ€ใƒ—ใƒญใ‚ปใ‚นใฏๅฎŸ่กŒ/ๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ“ใจใ‚’ๅœๆญขใ—ใ€ใใ‚Œไปฅ้™ใฏ**ไฝ•ใ‚‚ใงใใชใใชใ‚Šใพใ™**ใ€‚ +* ใ‚ณใƒณใƒ”ใƒฅใƒผใ‚ฟใงๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ๅ„ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฏใ€ๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚„ๅ„ใ‚ฆใ‚ฃใƒณใƒ‰ใ‚ฆใชใฉใ€ใใฎ่ƒŒๅพŒใซใ„ใใคใ‹ใฎใƒ—ใƒญใ‚ปใ‚นใ‚’ๆŒใฃใฆใ„ใพใ™ใ€‚ใใ—ใฆ้€šๅธธใ€ใ‚ณใƒณใƒ”ใƒฅใƒผใ‚ฟใŒ่ตทๅ‹•ใ—ใฆใ„ใ‚‹้–“ใ€**ๅคšใใฎใƒ—ใƒญใ‚ปใ‚นใŒ**ๅŒๆ™‚ใซๅฎŸ่กŒใ•ใ‚Œใฆใ„ใพใ™ใ€‚ +* **ๅŒใ˜ใƒ—ใƒญใ‚ฐใƒฉใƒ **ใฎ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใŒๅŒๆ™‚ใซๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚ + +OSใฎใ€Œใ‚ฟใ‚นใ‚ฏใƒปใƒžใƒใƒผใ‚ธใƒฃใƒผใ€ใ‚„ใ€Œใ‚ทใ‚นใƒ†ใƒ ใƒปใƒขใƒ‹ใ‚ฟใƒผใ€๏ผˆใพใŸใฏๅŒๆง˜ใฎใƒ„ใƒผใƒซ๏ผ‰ใ‚’็ขบ่ชใ™ใ‚Œใฐใ€ใ“ใ‚Œใ‚‰ใฎใƒ—ใƒญใ‚ปใ‚นใฎๅคšใใŒๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใฎ่ฆ‹ใ‚‹ใ“ใจใŒใงใใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ไพ‹ใˆใฐใ€ๅŒใ˜ใƒ–ใƒฉใ‚ฆใ‚ถใƒ—ใƒญใ‚ฐใƒฉใƒ ๏ผˆFirefoxใ€Chromeใ€Edgeใชใฉ๏ผ‰ใ‚’ๅฎŸ่กŒใ—ใฆใ„ใ‚‹ใƒ—ใƒญใ‚ปใ‚นใŒ่ค‡ๆ•ฐใ‚ใ‚‹ใ“ใจใŒใ‚ใ‹ใ‚Šใพใ™ใ€‚้€šๅธธใ€1ใคใฎใ‚ฟใƒ–ใซใคใ1ใคใฎใƒ—ใƒญใ‚ปใ‚นใŒๅฎŸ่กŒใ•ใ‚Œใ€ใ•ใ‚‰ใซไป–ใฎใƒ—ใƒญใ‚ปใ‚นใ‚‚ๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚ + + + +--- + +ใ•ใฆใ€**ใƒ—ใƒญใ‚ปใ‚น**ใจ**ใƒ—ใƒญใ‚ฐใƒฉใƒ **ใจใ„ใ†็”จ่ชžใฎ้•ใ„ใ‚’็ขบ่ชใ—ใŸใจใ“ใ‚ใงใ€ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใซใคใ„ใฆ่ฉฑใ‚’็ถšใ‘ใพใ™ใ€‚ + +## ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ + +ใปใจใ‚“ใฉใฎๅ ดๅˆใ€Web APIใ‚’ไฝœๆˆใ™ใ‚‹ใจใใฏใ€ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใŒใ„ใคใงใ‚‚ใ‚ขใ‚ฏใ‚ปใ‚นใงใใ‚‹ใ‚ˆใ†ใซใ€**ๅธธใซ**ไธญๆ–ญใ•ใ‚Œใ‚‹ใ“ใจใชใ**ๅฎŸ่กŒใ•ใ‚Œใ‚‹**ใ“ใจใ‚’ๆœ›ใฟใพใ™ใ€‚ใ‚‚ใกใ‚ใ‚“ใ€็‰นๅฎšใฎ็ŠถๆณใงใฎใฟๅฎŸ่กŒใ•ใ›ใŸใ„็‰นๅˆฅใช็†็”ฑใŒใ‚ใ‚‹ๅ ดๅˆใฏๅˆฅใงใ™ใŒใ€ใใฎๆ™‚้–“ใฎใปใจใ‚“ใฉใฏใ€ๅธธใซๅฎŸ่กŒใ•ใ‚Œใ€**ๅˆฉ็”จๅฏ่ƒฝ**ใงใ‚ใ‚‹ใ“ใจใ‚’ๆœ›ใฟใพใ™ใ€‚ + +### ใƒชใƒขใƒผใƒˆใ‚ตใƒผใƒใƒผไธŠใงใฎๅฎŸ่กŒ + +ใƒชใƒขใƒผใƒˆใ‚ตใƒผใƒใƒผ๏ผˆใ‚ฏใƒฉใ‚ฆใƒ‰ใ‚ตใƒผใƒใƒผใ€ไปฎๆƒณใƒžใ‚ทใƒณใชใฉ๏ผ‰ใ‚’ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ™ใ‚‹ใจใใซใงใใ‚‹ๆœ€ใ‚‚็ฐกๅ˜ใชใ“ใจใฏใ€ใƒญใƒผใ‚ซใƒซใง้–‹็™บใ™ใ‚‹ใจใใจๅŒใ˜ใ‚ˆใ†ใซใ€Uvicorn๏ผˆใพใŸใฏๅŒๆง˜ใฎใ‚‚ใฎ๏ผ‰ใ‚’ๆ‰‹ๅ‹•ใงๅฎŸ่กŒใ™ใ‚‹ใ“ใจใงใ™ใ€‚ ใ“ใฎๆ–นๆณ•ใฏ**้–‹็™บไธญ**ใซใฏๅฝนใซ็ซ‹ใคใจๆ€ใ‚ใ‚Œใพใ™ใ€‚ + +ใ—ใ‹ใ—ใ€ใ‚ตใƒผใƒใƒผใธใฎๆŽฅ็ถšใŒๅˆ‡ใ‚ŒใŸๅ ดๅˆใ€**ๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚น**ใฏใŠใใ‚‰ใใƒ€ใ‚ฆใƒณใ—ใฆใ—ใพใ†ใงใ—ใ‚‡ใ†ใ€‚ + +ใใ—ใฆใ‚ตใƒผใƒใƒผใŒๅ†่ตทๅ‹•ใ•ใ‚ŒใŸๅ ดๅˆ๏ผˆใ‚ขใƒƒใƒ—ใƒ‡ใƒผใƒˆใ‚„ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒ—ใƒญใƒใ‚คใƒ€ใƒผใ‹ใ‚‰ใฎใƒžใ‚คใ‚ฐใƒฌใƒผใ‚ทใƒงใƒณใฎๅพŒใชใฉ๏ผ‰ใ€ใŠใใ‚‰ใใ‚ใชใŸใฏใใ‚Œใซ**ๆฐ—ใฅใ‹ใชใ„ใงใ—ใ‚‡ใ†**ใ€‚ใใฎใŸใ‚ใ€ใƒ—ใƒญใ‚ปใ‚นใ‚’ๆ‰‹ๅ‹•ใงๅ†่ตทๅ‹•ใ—ใชใ‘ใ‚Œใฐใชใ‚‰ใชใ„ใ“ใจใ™ใ‚‰ๆฐ—ใฅใ‹ใชใ„ใงใ—ใ‚‡ใ†ใ€‚ใคใพใ‚Šใ€APIใฏใƒ€ใ‚ฆใƒณใ—ใŸใพใพใชใฎใงใ™ใ€‚๐Ÿ˜ฑ + +### ่ตทๅ‹•ๆ™‚ใซ่‡ชๅ‹•็š„ใซๅฎŸ่กŒ + +ไธ€่ˆฌ็š„ใซใ€ใ‚ตใƒผใƒใƒผใƒ—ใƒญใ‚ฐใƒฉใƒ ๏ผˆUvicornใชใฉ๏ผ‰ใฏใ‚ตใƒผใƒใƒผ่ตทๅ‹•ๆ™‚ใซ่‡ชๅ‹•็š„ใซ้–‹ๅง‹ใ•ใ‚Œใ€**ไบบใฎไป‹ๅ…ฅ**ใ‚’ๅฟ…่ฆใจใ›ใšใซใ€APIใจไธ€็ท’ใซใƒ—ใƒญใ‚ปใ‚นใŒๅธธใซๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใ—ใŸใ„ใจๆ€ใ‚ใ‚Œใพใ™๏ผˆUvicornใŒFastAPIใ‚ขใƒ—ใƒชใ‚’ๅฎŸ่กŒใ™ใ‚‹ใชใฉ๏ผ‰ใ€‚ + +### ๅˆฅใฎใƒ—ใƒญใ‚ฐใƒฉใƒ ใฎ็”จๆ„ + +ใ“ใ‚Œใ‚’ๅฎŸ็พใ™ใ‚‹ใŸใ‚ใซใ€้€šๅธธใฏ**ๅˆฅใฎใƒ—ใƒญใ‚ฐใƒฉใƒ **ใ‚’็”จๆ„ใ—ใ€่ตทๅ‹•ๆ™‚ใซใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใŒๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใ—ใพใ™ใ€‚ใใ—ใฆๅคšใใฎๅ ดๅˆใ€ไป–ใฎใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚„ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ€ไพ‹ใˆใฐใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใ‚‚ๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใ—ใพใ™ใ€‚ + +### ่ตทๅ‹•ๆ™‚ใซๅฎŸ่กŒใ™ใ‚‹ใƒ„ใƒผใƒซใฎไพ‹ + +ๅฎŸ่กŒใ™ใ‚‹ใƒ„ใƒผใƒซใฎไพ‹ใ‚’ใ„ใใคใ‹ๆŒ™ใ’ใพใ™: + +* Docker +* Kubernetes +* Docker Compose +* Swarm ใƒขใƒผใƒ‰ใซใ‚ˆใ‚‹ Docker +* Systemd +* Supervisor +* ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒ—ใƒญใƒใ‚คใƒ€ใƒผใŒใ‚ตใƒผใƒ“ใ‚นใฎไธ€้ƒจใจใ—ใฆๅ†…้ƒจ็š„ใซๅ‡ฆ็† +* ใใฎใปใ‹... + +ๆฌกใฎ็ซ ใงใ€ใ‚ˆใ‚Šๅ…ทไฝ“็š„ใชไพ‹ใ‚’ๆŒ™ใ’ใฆใ„ใใพใ™ใ€‚ + +## ๅ†่ตทๅ‹• + +่ตทๅ‹•ๆ™‚ใซใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใŒๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ“ใจใ‚’็ขบ่ชใ™ใ‚‹ใฎใจๅŒๆง˜ใซใ€ๅคฑๆ•—ๅพŒใซใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใŒ**ๅ†่ตทๅ‹•**ใ•ใ‚Œใ‚‹ใ“ใจใ‚‚็ขบ่ชใ—ใŸใ„ใจๆ€ใ‚ใ‚Œใพใ™ใ€‚ + +### ๆˆ‘ใ€…ใฏ้–“้•ใ„ใ‚’็Šฏใ™ + +็งใŸใกไบบ้–“ใฏๅธธใซ**้–“้•ใ„**ใ‚’็Šฏใ—ใพใ™ใ€‚ใ‚ฝใƒ•ใƒˆใ‚ฆใ‚งใ‚ขใซใฏใ€ใปใจใ‚“ใฉๅธธใซ**ใƒใ‚ฐ**ใŒใ‚ใ‚‰ใ‚†ใ‚‹็ฎ‡ๆ‰€ใซ้š ใ•ใ‚Œใฆใ„ใพใ™ใ€‚๐Ÿ› + +### ๅฐใ•ใชใ‚จใƒฉใƒผใฏ่‡ชๅ‹•็š„ใซๅ‡ฆ็†ใ•ใ‚Œใ‚‹ + +FastAPIใงWeb APIใ‚’ๆง‹็ฏ‰ใ™ใ‚‹้š›ใซใ€ใ‚ณใƒผใƒ‰ใซใ‚จใƒฉใƒผใŒใ‚ใ‚‹ๅ ดๅˆใ€FastAPIใฏ้€šๅธธใ€ใ‚จใƒฉใƒผใ‚’ๅผ•ใ่ตทใ“ใ—ใŸๅ˜ไธ€ใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใซใ‚จใƒฉใƒผใ‚’ๅซใ‚ใพใ™ใ€‚๐Ÿ›ก + +ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใฏใใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใซๅฏพใ—ใฆ**500 Internal Server Error**ใ‚’ๅ—ใ‘ๅ–ใ‚Šใพใ™ใŒใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฏๅฎŒๅ…จใซใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ™ใ‚‹ใฎใงใฏใชใใ€ๆฌกใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใฎใŸใ‚ใซๅ‹•ไฝœใ‚’็ถšใ‘ใพใ™ใ€‚ + +### ้‡ๅคงใชใ‚จใƒฉใƒผ - ใ‚ฏใƒฉใƒƒใ‚ทใƒฅ + +ใ—ใ‹ใ—ใชใŒใ‚‰ใ€**ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณๅ…จไฝ“ใ‚’ใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ•ใ›ใ‚‹ใ‚ˆใ†ใชใ‚ณใƒผใƒ‰ใ‚’ๆ›ธใ„ใฆ**UvicornใจPythonใ‚’ใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ•ใ›ใ‚‹ใ‚ˆใ†ใชใ‚ฑใƒผใ‚นใ‚‚ใ‚ใ‚‹ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚๐Ÿ’ฅ + +ใใ‚Œใงใ‚‚ใ€ใ‚ใ‚‹็ฎ‡ๆ‰€ใงใ‚จใƒฉใƒผใŒ็™บ็”Ÿใ—ใŸใ‹ใ‚‰ใจใ„ใฃใฆใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅœๆญขใ•ใ›ใŸใพใพใซใ—ใŸใใชใ„ใงใ—ใ‚‡ใ†ใ€‚ ๅฐ‘ใชใใจใ‚‚ๅฃŠใ‚Œใฆใ„ใชใ„*ใƒ‘ใ‚นใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณ*ใซใคใ„ใฆใฏใ€**ๅฎŸ่กŒใ—็ถšใ‘ใŸใ„**ใฏใšใงใ™ใ€‚ + +### ใ‚ฏใƒฉใƒƒใ‚ทใƒฅๅพŒใฎๅ†่ตทๅ‹• + +ใ—ใ‹ใ—ใ€ๅฎŸ่กŒไธญใฎ**ใƒ—ใƒญใ‚ปใ‚น**ใ‚’ใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ•ใ›ใ‚‹ใ‚ˆใ†ใชๆœฌๅฝ“ใซใฒใฉใ„ใ‚จใƒฉใƒผใฎๅ ดๅˆใ€ๅฐ‘ใชใใจใ‚‚2ใ€œ3ๅ›žใปใฉใƒ—ใƒญใ‚ปใ‚นใ‚’**ๅ†่ตทๅ‹•**ใ•ใ›ใ‚‹ๅค–้ƒจใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๅฟ…่ฆใงใ—ใ‚‡ใ†ใ€‚ + +!!! tip + ...ใจใฏใ„ใˆใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณๅ…จไฝ“ใŒ**ใ™ใใซใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ™ใ‚‹**ใฎใงใ‚ใ‚Œใฐใ€ใ„ใคใพใงใ‚‚ๅ†่ตทๅ‹•ใ—็ถšใ‘ใ‚‹ใฎใฏๆ„ๅ‘ณใŒใชใ„ใงใ—ใ‚‡ใ†ใ€‚ใ—ใ‹ใ—ใ€ใใฎๅ ดๅˆใฏใŠใใ‚‰ใ้–‹็™บไธญใ‹ๅฐ‘ใชใใจใ‚‚ใƒ‡ใƒ—ใƒญใ‚ค็›ดๅพŒใซๆฐ—ใฅใใจๆ€ใ‚ใ‚Œใพใ™ใ€‚ + + ใใ“ใงใ€**ๅฐ†ๆฅ**ใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ™ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใ€ใใ‚Œใงใ‚‚ๅ†ใ‚นใ‚ฟใƒผใƒˆใ•ใ›ใ‚‹ใ“ใจใซๆ„ๅ‘ณใŒใ‚ใ‚‹ใ‚ˆใ†ใชใ€ไธปใชใ‚ฑใƒผใ‚นใซ็„ฆ็‚นใ‚’ๅฝ“ใฆใฆใฟใพใ™ใ€‚ + +ใ‚ใชใŸใฏใŠใใ‚‰ใ**ๅค–้ƒจใ‚ณใƒณใƒใƒผใƒใƒณใƒˆ**ใŒใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎๅ†่ตทๅ‹•ใ‚’ๆ‹…ๅฝ“ใ™ใ‚‹ใ“ใจใ‚’ๆœ›ใ‚€ใจ่€ƒใˆใพใ™ใ€‚ ใชใœใชใ‚‰ใ€ใใฎๆ™‚็‚นใงUvicornใจPythonใ‚’ไฝฟใฃใŸๅŒใ˜ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฏใ™ใงใซใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ—ใฆใŠใ‚Šใ€ๅŒใ˜ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎๅŒใ˜ใ‚ณใƒผใƒ‰ใซๅฏพใ—ใฆไฝ•ใ‚‚ใงใใชใ„ใŸใ‚ใงใ™ใ€‚ + +### ่‡ชๅ‹•็š„ใซๅ†่ตทๅ‹•ใ™ใ‚‹ใƒ„ใƒผใƒซใฎไพ‹ + +ใปใจใ‚“ใฉใฎๅ ดๅˆใ€ๅ‰่ฟฐใ—ใŸ**่ตทๅ‹•ๆ™‚ใซใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚’ๅฎŸ่กŒใ™ใ‚‹**ใŸใ‚ใซไฝฟ็”จใ•ใ‚Œใ‚‹ใƒ„ใƒผใƒซใฏใ€่‡ชๅ‹•ใง**ๅ†่ตทๅ‹•**ใ™ใ‚‹ใ“ใจใซใ‚‚ๅˆฉ็”จใ•ใ‚Œใพใ™ใ€‚ + +ไพ‹ใˆใฐใ€ๆฌกใฎใ‚ˆใ†ใชใ‚‚ใฎใŒใ‚ใ‚Šใพใ™๏ผš + +* Docker +* Kubernetes +* Docker Compose +* Swarm ใƒขใƒผใƒ‰ใซใ‚ˆใ‚‹ Docker +* Systemd +* Supervisor +* ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒ—ใƒญใƒใ‚คใƒ€ใƒผใŒใ‚ตใƒผใƒ“ใ‚นใฎไธ€้ƒจใจใ—ใฆๅ†…้ƒจ็š„ใซๅ‡ฆ็† +* ใใฎใปใ‹... + +## ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ - ใƒ—ใƒญใ‚ปใ‚นใจใƒกใƒขใƒชใƒผ + +FastAPI ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใงใฏใ€Uvicorn ใฎใ‚ˆใ†ใชใ‚ตใƒผใƒใƒผใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚’ไฝฟ็”จใ—ใ€**1ใคใฎใƒ—ใƒญใ‚ปใ‚น**ใง1ๅบฆใซ่ค‡ๆ•ฐใฎใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใซๅŒๆ™‚ใซๅฏพๅฟœใงใใพใ™ใ€‚ + +ใ—ใ‹ใ—ใ€ๅคšใใฎๅ ดๅˆใ€่ค‡ๆ•ฐใฎใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใ‚’ๅŒๆ™‚ใซๅฎŸ่กŒใ—ใŸใ„ใจ่€ƒใˆใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +### ่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น - Worker + +ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใฎๆ•ฐใŒๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚นใงๅ‡ฆ็†ใงใใ‚‹ๆ•ฐใ‚’่ถ…ใˆใฆใŠใ‚Š๏ผˆใŸใจใˆใฐไปฎๆƒณใƒžใ‚ทใƒณใŒใใ‚Œใปใฉๅคงใใใชใ„ๅ ดๅˆ๏ผ‰ใ€ใ‹ใคใ‚ตใƒผใƒใƒผใฎ CPU ใซ**่ค‡ๆ•ฐใฎใ‚ณใ‚ข**ใŒใ‚ใ‚‹ๅ ดๅˆใ€ๅŒใ˜ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใงๅŒๆ™‚ใซ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ•ใ›ใ€ใ™ในใฆใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅˆ†ๆ•ฃใ•ใ›ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +ๅŒใ˜APIใƒ—ใƒญใ‚ฐใƒฉใƒ ใฎ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ™ใ‚‹ๅ ดๅˆใ€ใใ‚Œใ‚‰ใฏไธ€่ˆฌ็š„ใซ**Worker๏ผใƒฏใƒผใ‚ซใƒผ**ใจๅ‘ผใฐใ‚Œใพใ™ใ€‚ + +### ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น ใจ ใƒใƒผใƒˆ + + +[HTTPSใซใคใ„ใฆ](./https.md){.internal-link target=_blank}ใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใงใ€1ใคใฎใ‚ตใƒผใƒใƒผใง1ใคใฎใƒใƒผใƒˆใจIPใ‚ขใƒ‰ใƒฌใ‚นใฎ็ต„ใฟๅˆใ‚ใ›ใงใƒชใƒƒใ‚นใƒณใงใใ‚‹ใฎใฏ1ใคใฎใƒ—ใƒญใ‚ปใ‚นใ ใ‘ใงใ‚ใ‚‹ใ“ใจใ‚’่ฆšใˆใฆใ„ใพใ™ใงใ—ใ‚‡ใ†ใ‹๏ผŸ + +ใ“ใ‚Œใฏใ„ใพใ ใซๅŒใ˜ใงใ™ใ€‚ + +ใใฎใŸใ‚ใ€**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅŒๆ™‚ใซๆŒใคใซใฏ**ใƒใƒผใƒˆใงใƒชใƒƒใ‚นใƒณใ—ใฆใ„ใ‚‹ๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚น**ใŒๅฟ…่ฆใงใ‚ใ‚Šใ€ใใ‚ŒใŒไฝ•ใ‚‰ใ‹ใฎๆ–นๆณ•ใงๅ„ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใซ้€šไฟกใ‚’้€ไฟกใ™ใ‚‹ใ“ใจใŒๆฑ‚ใ‚ใ‚‰ใ‚Œใพใ™ใ€‚ + +### ใƒ—ใƒญใ‚ปใ‚นใ‚ใŸใ‚Šใฎใƒกใƒขใƒชใƒผ + +ใ•ใฆใ€ใƒ—ใƒญใ‚ฐใƒฉใƒ ใŒใƒกใƒขใƒชใซใƒญใƒผใƒ‰ใ™ใ‚‹้š›ใซใฏใ€ไพ‹ใˆใฐๆฉŸๆขฐๅญฆ็ฟ’ใƒขใƒ‡ใƒซใ‚„ๅคงใใชใƒ•ใ‚กใ‚คใƒซใฎๅ†…ๅฎนใ‚’ๅค‰ๆ•ฐใซๅ…ฅใ‚ŒใŸใ‚Šใ™ใ‚‹ๅ ดๅˆใงใฏใ€**ใ‚ตใƒผใƒใƒผใฎใƒกใƒขใƒช๏ผˆRAM๏ผ‰**ใ‚’ๅฐ‘ใ—ๆถˆ่ฒปใ—ใพใ™ใ€‚ + +ใใ—ใฆ่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚นใฏ้€šๅธธใ€**ใƒกใƒขใƒชใ‚’ๅ…ฑๆœ‰ใ—ใพใ›ใ‚“**ใ€‚ใ“ใ‚Œใฏใ€ๅฎŸ่กŒไธญใฎๅ„ใƒ—ใƒญใ‚ปใ‚นใŒใใ‚Œใžใ‚Œ็‹ฌ่‡ชใฎๅค‰ๆ•ฐใ‚„ใƒกใƒขใƒช็ญ‰ใ‚’ๆŒใฃใฆใ„ใ‚‹ใ“ใจใ‚’ๆ„ๅ‘ณใ—ใพใ™ใ€‚ใคใพใ‚Šใ€ใ‚ณใƒผใƒ‰ๅ†…ใงๅคง้‡ใฎใƒกใƒขใƒชใ‚’ๆถˆ่ฒปใ—ใฆใ„ใ‚‹ๅ ดๅˆใ€**ๅ„ใƒ—ใƒญใ‚ปใ‚น**ใฏๅŒ็ญ‰ใฎ้‡ใฎใƒกใƒขใƒชใ‚’ๆถˆ่ฒปใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +### ใ‚ตใƒผใƒใƒผใƒกใƒขใƒชใƒผ + +ไพ‹ใˆใฐใ€ใ‚ใชใŸใฎใ‚ณใƒผใƒ‰ใŒ **1GBใฎใ‚ตใ‚คใ‚บใฎๆฉŸๆขฐๅญฆ็ฟ’ใƒขใƒ‡ใƒซ**ใ‚’ใƒญใƒผใƒ‰ใ™ใ‚‹ๅ ดๅˆใ€APIใง1ใคใฎใƒ—ใƒญใ‚ปใ‚นใ‚’ๅฎŸ่กŒใ™ใ‚‹ใจใ€ๅฐ‘ใชใใจใ‚‚1GBใฎRAMใ‚’ๆถˆ่ฒปใ—ใพใ™ใ€‚ + +ใพใŸใ€**4ใคใฎใƒ—ใƒญใ‚ปใ‚น**๏ผˆ4ใคใฎใƒฏใƒผใ‚ซใƒผ๏ผ‰ใ‚’่ตทๅ‹•ใ™ใ‚‹ใจใ€ใใ‚Œใžใ‚ŒใŒ1GBใฎRAMใ‚’ๆถˆ่ฒปใ—ใพใ™ใ€‚ใคใพใ‚Šใ€ๅˆ่จˆใงAPIใฏ**4GBใฎRAM**ใ‚’ๆถˆ่ฒปใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +ใƒชใƒขใƒผใƒˆใ‚ตใƒผใƒใƒผใ‚„ไปฎๆƒณใƒžใ‚ทใƒณใฎRAMใŒ3GBใ—ใ‹ใชใ„ๅ ดๅˆใ€4GBไปฅไธŠใฎRAMใ‚’ใƒญใƒผใƒ‰ใ—ใ‚ˆใ†ใจใ™ใ‚‹ใจๅ•้กŒใŒ็™บ็”Ÿใ—ใพใ™ใ€‚๐Ÿšจ + +### ่ค‡ๆ•ฐใƒ—ใƒญใ‚ปใ‚น - ไพ‹ + +ใ“ใฎไพ‹ใงใฏใ€2ใคใฎ**ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’่ตทๅ‹•ใ—ๅˆถๅพกใ™ใ‚‹**ใƒžใƒใƒผใ‚ธใƒฃใƒผใƒป ใƒ—ใƒญใ‚ปใ‚น**ใŒใ‚ใ‚Šใพใ™ใ€‚ + +ใ“ใฎใƒžใƒใƒผใ‚ธใƒฃใƒผใƒป ใƒ—ใƒญใ‚ปใ‚นใฏใ€ใŠใใ‚‰ใIPใฎ**ใƒใƒผใƒˆ**ใงใƒชใƒƒใ‚นใƒณใ—ใฆใ„ใ‚‹ใ‚‚ใฎใงใ™ใ€‚ใใ—ใฆใ€ใ™ในใฆใฎ้€šไฟกใ‚’ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใซ่ปข้€ใ—ใพใ™ใ€‚ + +ใ“ใ‚Œใ‚‰ใฎใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใฏใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅฎŸ่กŒใ™ใ‚‹ใ‚‚ใฎใงใ‚ใ‚Šใ€**ใƒชใ‚ฏใ‚จใ‚นใƒˆ**ใ‚’ๅ—ใ‘ใฆ**ใƒฌใ‚นใƒใƒณใ‚น**ใ‚’่ฟ”ใ™ใŸใ‚ใฎไธป่ฆใช่จˆ็ฎ—ใ‚’่กŒใ„ใ€ใ‚ใชใŸใŒๅค‰ๆ•ฐใซๅ…ฅใ‚ŒใŸใ‚‚ใฎใฏไฝ•ใงใ‚‚RAMใซใƒญใƒผใƒ‰ใ—ใพใ™ใ€‚ + + + +ใใ—ใฆใ‚‚ใกใ‚ใ‚“ใ€ๅŒใ˜ใƒžใ‚ทใƒณใงใฏใ€ใ‚ใชใŸใฎใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใจใฏๅˆฅใซใ€**ไป–ใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚‚ๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +่ˆˆๅ‘ณๆทฑใ„ใ“ใจใซใ€ๅ„ใƒ—ใƒญใ‚ปใ‚นใŒไฝฟ็”จใ™ใ‚‹**CPU**ใฎๅ‰ฒๅˆใฏๆ™‚้–“ใจใจใ‚‚ใซๅคงใใ**ๅค‰ๅ‹•**ใ™ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใŒใ€**ใƒกใƒขใƒช๏ผˆRAM๏ผ‰**ใฏ้€šๅธธใ€ๅคšใ‹ใ‚Œๅฐ‘ใชใ‹ใ‚Œ**ๅฎ‰ๅฎš**ใ—ใพใ™ใ€‚ + +ๆฏŽๅ›žๅŒ็จ‹ๅบฆใฎ่จˆ็ฎ—ใ‚’่กŒใ†APIใŒใ‚ใ‚Šใ€ๅคšใใฎใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใŒใ„ใ‚‹ใฎใงใ‚ใ‚Œใฐใ€**CPUไฝฟ็”จ็އ**ใ‚‚ใŠใใ‚‰ใ**ๅฎ‰ๅฎš**ใ™ใ‚‹ใงใ—ใ‚‡ใ†๏ผˆๅธธใซๆ€ฅๆฟ€ใซไธŠไธ‹ใ™ใ‚‹ใฎใงใฏใชใ๏ผ‰ใ€‚ + +### ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใƒปใƒ„ใƒผใƒซใจๆˆฆ็•ฅใฎไพ‹ + +ใ“ใ‚Œใ‚’ๅฎŸ็พใ™ใ‚‹ใซใฏใ„ใใคใ‹ใฎใ‚ขใƒ—ใƒญใƒผใƒใŒใ‚ใ‚Šใพใ™ใŒใ€ๅ…ทไฝ“็š„ใชๆˆฆ็•ฅใซใคใ„ใฆใฏๆฌกใฎ็ซ (Dockerใ‚„ใ‚ณใƒณใƒ†ใƒŠใฎ็ซ ใชใฉ)ใง่ฉณใ—ใ่ชฌๆ˜Žใ—ใพใ™ใ€‚ + +่€ƒๆ…ฎใ™ในใไธปใชๅˆถ็ด„ใฏใ€**ใƒ‘ใƒ–ใƒชใƒƒใ‚ฏIP**ใฎ**ใƒใƒผใƒˆ**ใ‚’ๅ‡ฆ็†ใ™ใ‚‹**ๅ˜ไธ€ใฎ**ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๅญ˜ๅœจใ—ใชใ‘ใ‚Œใฐใชใ‚‰ใชใ„ใจใ„ใ†ใ“ใจใงใ™ใ€‚ + +ใใ—ใฆใ€ใƒฌใƒ—ใƒชใ‚ฑใƒผใƒˆใ•ใ‚ŒใŸ**ใƒ—ใƒญใ‚ปใ‚น/ใƒฏใƒผใ‚ซใƒผ**ใซ้€šไฟกใ‚’**้€ไฟก**ใ™ใ‚‹ๆ–นๆณ•ใ‚’ๆŒใคๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚ + +่€ƒใˆใ‚‰ใ‚Œใ‚‹็ต„ใฟๅˆใ‚ใ›ใจๆˆฆ็•ฅใ‚’ใ„ใใคใ‹็ดนไป‹ใ—ใพใ™๏ผš + +* **Gunicorn**ใŒ**Uvicornใƒฏใƒผใ‚ซใƒผ**ใ‚’็ฎก็† + * Gunicornใฏ**IP**ใจ**ใƒใƒผใƒˆ**ใ‚’ใƒชใƒƒใ‚นใƒณใ™ใ‚‹**ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃ**ใงใ€ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฏ**่ค‡ๆ•ฐใฎUvicornใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใคใ“ใจใซใ‚ˆใฃใฆ่กŒใ‚ใ‚Œใ‚‹ใ€‚ +* **Uvicorn**ใŒ**Uvicornใƒฏใƒผใ‚ซใƒผ**ใ‚’็ฎก็† + * 1ใคใฎUvicornใฎ**ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผ**ใŒ**IP**ใจ**ใƒใƒผใƒˆ**ใ‚’ใƒชใƒƒใ‚นใƒณใ—ใ€**่ค‡ๆ•ฐใฎUvicornใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’่ตทๅ‹•ใ™ใ‚‹ใ€‚ +* **Kubernetes**ใ‚„ใใฎไป–ใฎๅˆ†ๆ•ฃ**ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚ทใ‚นใƒ†ใƒ ** + * **Kubernetes**ใƒฌใ‚คใƒคใƒผใฎไฝ•ใ‹ใŒ**IP**ใจ**ใƒใƒผใƒˆ**ใ‚’ใƒชใƒƒใ‚นใƒณใ™ใ‚‹ใ€‚ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฏใ€**่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠ**ใซใใ‚Œใžใ‚Œ**1ใคใฎUvicornใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ•ใ›ใ‚‹ใ“ใจใง่กŒใ‚ใ‚Œใ‚‹ใ€‚ +* **ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใ‚ตใƒผใƒ“ใ‚น**ใซใ‚ˆใ‚‹ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ + * ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใ‚ตใƒผใƒ“ใ‚นใฏใŠใใ‚‰ใ**ใ‚ใชใŸใฎใŸใ‚ใซใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅ‡ฆ็†**ใ—ใพใ™ใ€‚**ๅฎŸ่กŒใ™ใ‚‹ใƒ—ใƒญใ‚ปใ‚น**ใ‚„ไฝฟ็”จใ™ใ‚‹**ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธ**ใ‚’ๅฎš็พฉใงใใ‚‹ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใŒใ€ใ„ใšใ‚Œใซใ›ใ‚ˆใ€ใใ‚ŒใฏใŠใใ‚‰ใ**ๅ˜ไธ€ใฎUvicornใƒ—ใƒญใ‚ปใ‚น**ใงใ‚ใ‚Šใ€ใ‚ฏใƒฉใ‚ฆใƒ‰ใ‚ตใƒผใƒ“ใ‚นใฏใใฎใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๆ‹…ๅฝ“ใ™ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +!!! tip + ใ“ใ‚Œใ‚‰ใฎ**ใ‚ณใƒณใƒ†ใƒŠ**ใ‚„Dockerใใ—ใฆKubernetesใซ้–ขใ™ใ‚‹้ …็›ฎใŒใ€ใพใ ใ‚ใพใ‚Šๆ„ๅ‘ณใ‚’ใชใ—ใฆใ„ใชใใฆใ‚‚ๅฟƒ้…ใ—ใชใ„ใงใใ ใ•ใ„ใ€‚ + + + ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใ€Dockerใ€Kubernetesใชใฉใซใคใ„ใฆใฏใ€ๆฌกใฎ็ซ ใง่ฉณใ—ใ่ชฌๆ˜Žใ—ใพใ™: [ใ‚ณใƒณใƒ†ใƒŠๅ†…ใฎFastAPI - Docker](./docker.md){.internal-link target=_blank}. + +## ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ— + +ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’**้–‹ๅง‹ใ™ใ‚‹ๅ‰**ใซใ€ใ„ใใคใ‹ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’ๅฎŸ่กŒใ—ใŸใ„ๅ ดๅˆใŒๅคšใใ‚ใ‚Šใพใ™ใ€‚ + +ไพ‹ใˆใฐใ€**ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใƒปใƒžใ‚คใ‚ฐใƒฌใƒผใ‚ทใƒงใƒณ** ใ‚’ๅฎŸ่กŒใ—ใŸใ„ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ + +ใ—ใ‹ใ—ใปใจใ‚“ใฉใฎๅ ดๅˆใ€ใ“ใ‚Œใ‚‰ใฎๆ‰‹้ †ใ‚’**1ๅบฆ**ใซๅฎŸ่กŒใ—ใŸใ„ใจ่€ƒใˆใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ใใฎใŸใ‚ใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’้–‹ๅง‹ใ™ใ‚‹ๅ‰ใฎ**ไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—**ใ‚’ๅฎŸ่กŒใ™ใ‚‹**ๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’็”จๆ„ใ—ใŸใ„ใจๆ€ใ‚ใ‚Œใพใ™ใ€‚ + +ใใ—ใฆใ€ใใ‚Œใ‚‰ใฎไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’ๅฎŸ่กŒใ—ใฆใ„ใ‚‹ใฎใŒๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚นใงใ‚ใ‚‹ใ“ใจใ‚’็ขบ่ชใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚ใ“ใฎใ“ใจใฏใใฎๅพŒใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ่‡ชไฝ“ใฎใŸใ‚ใซ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**๏ผˆ่ค‡ๆ•ฐใฎใƒฏใƒผใ‚ซใƒผ๏ผ‰ใ‚’่ตทๅ‹•ใ—ใŸๅ ดๅˆใ‚‚ๅŒๆง˜ใงใ™ใ€‚ + +ใ“ใ‚Œใ‚‰ใฎใ‚นใƒ†ใƒƒใƒ—ใŒ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใซใ‚ˆใฃใฆๅฎŸ่กŒใ•ใ‚ŒใŸๅ ดๅˆใ€**ไธฆๅˆ—**ใซๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ“ใจใซใ‚ˆใฃใฆไฝœๆฅญใŒ**้‡่ค‡**ใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ใใ—ใฆใ€ใ‚‚ใ—ใใฎใ‚นใƒ†ใƒƒใƒ—ใŒใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใฎใƒžใ‚คใ‚ฐใƒฌใƒผใ‚ทใƒงใƒณใฎใ‚ˆใ†ใช็นŠ็ดฐใชใ‚‚ใฎใงใ‚ใฃใŸๅ ดๅˆใ€ไบ’ใ„ใซ็ซถๅˆใ‚’ๅผ•ใ่ตทใ“ใ™ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ + +ใ‚‚ใกใ‚ใ‚“ใ€ไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’ไฝ•ๅบฆใ‚‚ๅฎŸ่กŒใ—ใฆใ‚‚ๅ•้กŒใŒใชใ„ๅ ดๅˆใ‚‚ใ‚ใ‚Šใ€ใใฎ้š›ใฏๅฏพๅ‡ฆใŒใ‹ใชใ‚Šๆฅฝใซใชใ‚Šใพใ™ใ€‚ + +!!! tip + ใพใŸใ€ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใซใ‚ˆใฃใฆใฏใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’้–‹ๅง‹ใ™ใ‚‹ๅ‰ใฎ**ไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—**ใŒๅฟ…่ฆใชใ„ๅ ดๅˆใ‚‚ใ‚ใ‚‹ใ“ใจใ‚’่ฆšใˆใฆใŠใ„ใฆใใ ใ•ใ„ใ€‚ + + ใใฎๅ ดๅˆใฏใ€ใ“ใฎใ‚ˆใ†ใชใ“ใจใ‚’ๅฟƒ้…ใ™ใ‚‹ๅฟ…่ฆใฏใชใ„ใงใ™ใ€‚๐Ÿคท + +### ไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ—ใฎๆˆฆ็•ฅไพ‹ + +ใ“ใ‚Œใฏ**ใ‚ทใ‚นใƒ†ใƒ ใ‚’**ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ๆ–นๆณ•ใซ**ๅคงใใไพๅญ˜**ใ™ใ‚‹ใ ใ‚ใ†ใ—ใ€ใŠใใ‚‰ใใƒ—ใƒญใ‚ฐใƒฉใƒ ใฎ่ตทๅ‹•ๆ–นๆณ•ใ‚„ๅ†่ตทๅ‹•ใฎๅ‡ฆ็†ใชใฉใซใ‚‚้–ขไฟ‚ใ—ใฆใใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +่€ƒใˆใ‚‰ใ‚Œใ‚‹ใ‚ขใ‚คใƒ‡ใ‚ขใ‚’ใ„ใใคใ‹ๆŒ™ใ’ใฆใฟใพใ™๏ผš + +* ใ‚ขใƒ—ใƒชใ‚ณใƒณใƒ†ใƒŠใฎๅ‰ใซๅฎŸ่กŒใ•ใ‚Œใ‚‹KubernetesใฎInitใ‚ณใƒณใƒ†ใƒŠ +* ไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’ๅฎŸ่กŒใ—ใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’่ตทๅ‹•ใ™ใ‚‹bashใ‚นใ‚ฏใƒชใƒ—ใƒˆ + * ๅˆฉ็”จใ™ใ‚‹bashใ‚นใ‚ฏใƒชใƒ—ใƒˆใ‚’่ตทๅ‹•๏ผๅ†่ตทๅ‹•ใ—ใŸใ‚Šใ€ใ‚จใƒฉใƒผใ‚’ๆคœๅ‡บใ—ใŸใ‚Šใ™ใ‚‹ๆ–นๆณ•ใฏไปฅๅ‰ใจใ—ใฆๅฟ…่ฆใซใชใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +!!! tip + + ใ‚ณใƒณใƒ†ใƒŠใ‚’ไฝฟใฃใŸๅ…ทไฝ“็š„ใชไพ‹ใซใคใ„ใฆใฏใ€ๆฌกใฎ็ซ ใง็ดนไป‹ใ—ใพใ™: [ใ‚ณใƒณใƒ†ใƒŠๅ†…ใฎFastAPI - Docker](./docker.md){.internal-link target=_blank}. + +## ใƒชใ‚ฝใƒผใ‚นใฎๅˆฉ็”จ + +ใ‚ใชใŸใฎใ‚ตใƒผใƒใƒผใฏ**ใƒชใ‚ฝใƒผใ‚น**ใงใ‚ใ‚Šใ€ใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚’ๅฎŸ่กŒใ—CPUใฎ่จˆ็ฎ—ๆ™‚้–“ใ‚„ๅˆฉ็”จๅฏ่ƒฝใชRAMใƒกใƒขใƒชใ‚’ๆถˆ่ฒปใพใŸใฏ**ๅˆฉ็”จ**ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +ใ‚ทใ‚นใƒ†ใƒ ใƒชใ‚ฝใƒผใ‚นใ‚’ใฉใ‚Œใใ‚‰ใ„ๆถˆ่ฒป๏ผๅˆฉ็”จใ—ใŸใ„ใงใ™ใ‹๏ผŸ ใ€Œๅฐ‘ใชใ„ๆ–นใŒ่‰ฏใ„ใ€ใจ่€ƒใˆใ‚‹ใฎใฏ็ฐกๅ˜ใ‹ใ‚‚ใ—ใ‚Œใชใ„ใงใ™ใŒใ€ๅฎŸ้š›ใซใฏใ€**ใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ›ใšใซๅฏ่ƒฝใช้™ใ‚Š**ๆœ€ๅคง้™ใซๆดป็”จใ—ใŸใ„ใงใ—ใ‚‡ใ†ใ€‚ + +3ๅฐใฎใ‚ตใƒผใƒใƒผใซใŠ้‡‘ใ‚’ๆ‰•ใฃใฆใ„ใ‚‹ใซใ‚‚้–ขใ‚ใ‚‰ใšใ€ใใฎRAMใจCPUใ‚’ๅฐ‘ใ—ใ—ใ‹ไฝฟใฃใฆใ„ใชใ„ใจใ—ใŸใ‚‰ใ€ใŠใใ‚‰ใ**ใŠ้‡‘ใ‚’็„ก้ง„ใซใ—ใฆใ„ใ‚‹** ๐Ÿ’ธใ€ใŠใใ‚‰ใ**ใ‚ตใƒผใƒใƒผใฎ้›ปๅŠ›ใ‚’็„ก้ง„ใซใ—ใฆใ„ใ‚‹** ๐ŸŒŽใ“ใจใซใชใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ใใฎๅ ดๅˆใฏใ€ใ‚ตใƒผใƒใƒผใ‚’2ๅฐใ ใ‘ใซใ—ใฆใ€ใใฎใƒชใ‚ฝใƒผใ‚น๏ผˆCPUใ€ใƒกใƒขใƒชใ€ใƒ‡ใ‚ฃใ‚นใ‚ฏใ€ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏๅธฏๅŸŸๅน…ใชใฉ๏ผ‰ใ‚’ใ‚ˆใ‚Š้ซ˜ใ„ๅ‰ฒๅˆใงไฝฟ็”จใ™ใ‚‹ๆ–นใŒใ‚ˆใ„ใงใ—ใ‚‡ใ†ใ€‚ + +ไธ€ๆ–นใ€2ๅฐใฎใ‚ตใƒผใƒใƒผใŒใ‚ใ‚Šใ€ใใฎCPUใจRAMใฎ**100%ใ‚’ไฝฟ็”จใ—ใฆใ„ใ‚‹**ๅ ดๅˆใ€ใ‚ใ‚‹ๆ™‚็‚นใง1ใคใฎใƒ—ใƒญใ‚ปใ‚นใŒใ‚ˆใ‚Šๅคšใใฎใƒกใƒขใƒชใ‚’่ฆๆฑ‚ใ—ใ€ใ‚ตใƒผใƒใƒผใฏใƒ‡ใ‚ฃใ‚นใ‚ฏใ‚’ใ€Œใƒกใƒขใƒชใ€ใจใ—ใฆไฝฟ็”จใ—ใชใ„ใจใ„ใ‘ใพใ›ใ‚“ใ€‚๏ผˆไฝ•ๅƒๅ€ใ‚‚้…ใใชใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚๏ผ‰ +ใ‚‚ใ—ใใฏ**ใ‚ฏใƒฉใƒƒใ‚ทใƒฅ**ใ™ใ‚‹ใ“ใจใ‚‚ใ‚ใ‚Œใฐใ€ใ‚ใ‚‹ใ„ใฏใ‚ใ‚‹ใƒ—ใƒญใ‚ปใ‚นใŒไฝ•ใ‚‰ใ‹ใฎ่จˆ็ฎ—ใ‚’ใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใ€ใใ—ใฆCPUใŒๅ†ใณ็ฉบใใพใงๅพ…ใŸใชใ‘ใ‚Œใฐใชใ‚‰ใชใ„ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ + +ใ“ใฎๅ ดๅˆใ€**1ใคไฝ™ๅˆ†ใชใ‚ตใƒผใƒใƒผ**ใ‚’็”จๆ„ใ—ใ€ใใฎไธŠใงใ„ใใคใ‹ใฎใƒ—ใƒญใ‚ปใ‚นใ‚’ๅฎŸ่กŒใ—ใ€ใ™ในใฆใฎใ‚ตใƒผใƒใƒผใŒ**ๅๅˆ†ใชRAMใจCPUๆ™‚้–“ใ‚’ๆŒใคใ‚ˆใ†ใซใ™ใ‚‹**ใฎใŒใ‚ˆใ„ใงใ—ใ‚‡ใ†ใ€‚ + +ใพใŸใ€ไฝ•ใ‚‰ใ‹ใฎ็†็”ฑใงAPIใฎๅˆฉ็”จใŒๆ€ฅๅข—ใ™ใ‚‹ๅฏ่ƒฝๆ€งใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ใ‚‚ใ—ใ‹ใ—ใŸใ‚‰ใใ‚ŒใŒๆต่กŒใฃใŸใฎใ‹ใ‚‚ใ—ใ‚Œใชใ„ใ—ใ€ไป–ใฎใ‚ตใƒผใƒ“ใ‚นใ‚„ใƒœใƒƒใƒˆใŒไฝฟใ„ๅง‹ใ‚ใŸใฎใ‹ใ‚‚ใ—ใ‚Œใชใ„ใงใ™ใ€‚ใใฎใ‚ˆใ†ใชๅ ดๅˆใซๅ‚™ใˆใฆใ€ไฝ™ๅˆ†ใชใƒชใ‚ฝใƒผใ‚นใ‚’็”จๆ„ใ—ใฆใŠใใจๅฎ‰ๅฟƒใงใ—ใ‚‡ใ†ใ€‚ + +ไพ‹ใˆใฐใ€ใƒชใ‚ฝใƒผใ‚นไฝฟ็”จ็އใฎ**50%ใ‹ใ‚‰90%ใฎ็ฏ„ๅ›ฒ**ใง**ไปปๆ„ใฎๆ•ฐๅญ—**ใ‚’ใ‚ฟใƒผใ‚ฒใƒƒใƒˆใจใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +้‡่ฆใชใฎใฏใ€ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใ‚’ๅพฎ่ชฟๆ•ดใ™ใ‚‹ใŸใ‚ใซใ‚ฟใƒผใ‚ฒใƒƒใƒˆใ‚’่จญๅฎšใ—ๆธฌๅฎšใ™ใ‚‹ใ“ใจใŒใ€ใŠใใ‚‰ใไฝฟ็”จใ—ใŸใ„ไธป่ฆใช่ฆ็ด ใงใ‚ใ‚‹ใ“ใจใงใ™ใ€‚ + +`htop`ใฎใ‚ˆใ†ใชๅ˜็ด”ใชใƒ„ใƒผใƒซใ‚’ไฝฟใฃใฆใ€ใ‚ตใƒผใƒใƒผใงไฝฟ็”จใ•ใ‚Œใฆใ„ใ‚‹CPUใ‚„RAMใ€ใ‚ใ‚‹ใ„ใฏๅ„ใƒ—ใƒญใ‚ปใ‚นใงไฝฟ็”จใ•ใ‚Œใฆใ„ใ‚‹้‡ใ‚’่ฆ‹ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ใ‚ใ‚‹ใ„ใฏใ€ใ‚ˆใ‚Š่ค‡้›‘ใช็›ฃ่ฆ–ใƒ„ใƒผใƒซใ‚’ไฝฟใฃใฆใ€ใ‚ตใƒผใƒใซๅˆ†ๆ•ฃใ—ใฆไฝฟ็”จใ™ใ‚‹ใ“ใจใ‚‚ใงใใพใ™ใ€‚ + +## ใพใจใ‚ + +ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎใƒ‡ใƒ—ใƒญใ‚คๆ–นๆณ•ใ‚’ๆฑบๅฎšใ™ใ‚‹้š›ใซใ€่€ƒๆ…ฎใ™ในใใงใ‚ใ‚ใ†ไธป่ฆใชใ‚ณใƒณใ‚ปใƒ—ใƒˆใฎใ„ใใคใ‹ใ‚’็ดนไป‹ใ—ใฆใ„ใใพใ—ใŸ๏ผš + +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰ +* ใƒกใƒขใƒชใƒผ +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ— + +ใ“ใ‚Œใ‚‰ใฎ่€ƒใˆๆ–นใจใใฎ้ฉ็”จๆ–นๆณ•ใ‚’็†่งฃใ™ใ‚‹ใ“ใจใงใ€ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใ‚’่จญๅฎšใ—ใŸใ‚Š่ชฟๆ•ดใ—ใŸใ‚Šใ™ใ‚‹้š›ใซๅฟ…่ฆใช็›ดๆ„Ÿ็š„ใชๅˆคๆ–ญใŒใงใใ‚‹ใ‚ˆใ†ใซใชใ‚‹ใฏใšใงใ™ใ€‚๐Ÿค“ + +ๆฌกใฎใ‚ปใ‚ฏใ‚ทใƒงใƒณใงใฏใ€ใ‚ใชใŸใŒๅ–ใ‚Šๅพ—ใ‚‹ๆˆฆ็•ฅใซใคใ„ใฆใ€ใ‚ˆใ‚Šๅ…ทไฝ“็š„ใชไพ‹ใ‚’ๆŒ™ใ’ใพใ™ใ€‚๐Ÿš€ diff --git a/docs/ja/docs/deployment/deta.md b/docs/ja/docs/deployment/deta.md deleted file mode 100644 index 723f169a0..000000000 --- a/docs/ja/docs/deployment/deta.md +++ /dev/null @@ -1,240 +0,0 @@ -# Deta ใซใƒ‡ใƒ—ใƒญใ‚ค - -ใ“ใฎใ‚ปใ‚ฏใ‚ทใƒงใƒณใงใฏใ€**FastAPI** ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ Deta ใฎ็„กๆ–™ใƒ—ใƒฉใƒณใ‚’ๅˆฉ็”จใ—ใฆใ€็ฐกๅ˜ใซใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ๆ–นๆณ•ใ‚’ๅญฆ็ฟ’ใ—ใพใ™ใ€‚๐ŸŽ - -ๆ‰€่ฆๆ™‚้–“ใฏ็ด„**10ๅˆ†**ใงใ™ใ€‚ - -!!! info "ๅ‚™่€ƒ" - Deta ใฏ **FastAPI** ใฎใ‚นใƒใƒณใ‚ตใƒผใงใ™ใ€‚๐ŸŽ‰ - -## ใƒ™ใƒผใ‚ทใƒƒใ‚ฏใช **FastAPI** ใ‚ขใƒ—ใƒช - -* ใ‚ขใƒ—ใƒชใฎใŸใ‚ใฎใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช (ไพ‹ใˆใฐ `./fastapideta/`) ใ‚’ไฝœๆˆใ—ใ€ใใฎไธญใซๅ…ฅใฃใฆใใ ใ•ใ„ใ€‚ - -### FastAPI ใฎใ‚ณใƒผใƒ‰ - -* ไปฅไธ‹ใฎ `main.py` ใƒ•ใ‚กใ‚คใƒซใ‚’ไฝœๆˆใ—ใฆใใ ใ•ใ„: - -```Python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int): - return {"item_id": item_id} -``` - -### Requirements - -ใงใฏใ€ๅŒใ˜ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซไปฅไธ‹ใฎ `requirements.txt` ใƒ•ใ‚กใ‚คใƒซใ‚’ไฝœๆˆใ—ใฆใใ ใ•ใ„: - -```text -fastapi -``` - -!!! tip "่ฑ†็Ÿฅ่ญ˜" - ใ‚ขใƒ—ใƒชใฎใƒญใƒผใ‚ซใƒซใƒ†ใ‚นใƒˆใฎใŸใ‚ใซ Uvicorn ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใŸใใชใ‚‹ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใŒใ€Deta ใธใฎใƒ‡ใƒ—ใƒญใ‚คใซใฏไธ่ฆใงใ™ใ€‚ - -### ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชๆง‹้€  - -ไปฅไธ‹ใฎ2ใคใฎใƒ•ใ‚กใ‚คใƒซใจ1ใคใฎ `./fastapideta/` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใŒใ‚ใ‚‹ใฏใšใงใ™: - -``` -. -โ””โ”€โ”€ main.py -โ””โ”€โ”€ requirements.txt -``` - -## Detaใฎ็„กๆ–™ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฎไฝœๆˆ - -ใใ‚Œใงใฏใ€Detaใฎ็„กๆ–™ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‚’ไฝœๆˆใ—ใพใ—ใ‚‡ใ†ใ€‚ๅฟ…่ฆใชใ‚‚ใฎใฏใƒกใƒผใƒซใ‚ขใƒ‰ใƒฌใ‚นใจใƒ‘ใ‚นใƒฏใƒผใƒ‰ใ ใ‘ใงใ™ใ€‚ - -ใ‚ฏใƒฌใ‚ธใƒƒใƒˆใ‚ซใƒผใƒ‰ใ•ใˆๅฟ…่ฆใ‚ใ‚Šใพใ›ใ‚“ใ€‚ - -## CLIใฎใ‚คใƒณใ‚นใƒˆใƒผใƒซ - -ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‚’ๅ–ๅพ—ใ—ใŸใ‚‰ใ€Deta CLI ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใฆใใ ใ•ใ„: - -=== "Linux, macOS" - -
- - ```console - $ curl -fsSL https://get.deta.dev/cli.sh | sh - ``` - -
- -=== "Windows PowerShell" - -
- - ```console - $ iwr https://get.deta.dev/cli.ps1 -useb | iex - ``` - -
- -ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใŸใ‚‰ใ€ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใŸ CLI ใ‚’ๆœ‰ๅŠนใซใ™ใ‚‹ใŸใ‚ใซๆ–ฐใŸใชใ‚ฟใƒผใƒŸใƒŠใƒซใ‚’้–‹ใ„ใฆใใ ใ•ใ„ใ€‚ - -ๆ–ฐใŸใชใ‚ฟใƒผใƒŸใƒŠใƒซไธŠใงใ€ๆญฃใ—ใใ‚คใƒณใ‚นใƒˆใƒผใƒซใ•ใ‚ŒใŸใ‹็ขบ่ชใ—ใพใ™: - -
- -```console -$ deta --help - -Deta command line interface for managing deta micros. -Complete documentation available at https://docs.deta.sh - -Usage: - deta [flags] - deta [command] - -Available Commands: - auth Change auth settings for a deta micro - -... -``` - -
- -!!! tip "่ฑ†็Ÿฅ่ญ˜" - CLI ใฎใ‚คใƒณใ‚นใƒˆใƒผใƒซใซๅ•้กŒใŒ็™บ็”Ÿใ—ใŸๅ ดๅˆใฏใ€Deta ๅ…ฌๅผใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚ - -## CLIใงใƒญใ‚ฐใ‚คใƒณ - -CLI ใ‹ใ‚‰ Deta ใซใƒญใ‚ฐใ‚คใƒณใ—ใฆใฟใพใ—ใ‚‡ใ†: - -
- -```console -$ deta login - -Please, log in from the web page. Waiting.. -Logged in successfully. -``` - -
- -่‡ชๅ‹•็š„ใซใ‚ฆใ‚งใƒ–ใƒ–ใƒฉใ‚ฆใ‚ถใŒ้–‹ใ„ใฆใ€่ช่จผๅ‡ฆ็†ใŒ่กŒใ‚ใ‚Œใพใ™ใ€‚ - -## Deta ใงใƒ‡ใƒ—ใƒญใ‚ค - -ๆฌกใซใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ Deta CLIใงใƒ‡ใƒ—ใƒญใ‚คใ—ใพใ—ใ‚‡ใ†: - -
- -```console -$ deta new - -Successfully created a new micro - -// Notice the "endpoint" ๐Ÿ” - -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} - -Adding dependencies... - - ----> 100% - - -Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6 -``` - -
- -ๆฌกใฎใ‚ˆใ†ใชJSONใƒกใƒƒใ‚ปใƒผใ‚ธใŒ่กจ็คบใ•ใ‚Œใพใ™: - -```JSON hl_lines="4" -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} -``` - -!!! tip "่ฑ†็Ÿฅ่ญ˜" - ใ‚ใชใŸใฎใƒ‡ใƒ—ใƒญใ‚คใงใฏ็•ฐใชใ‚‹ `"endpoint"` URLใŒ่กจ็คบใ•ใ‚Œใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ - -## ็ขบ่ช - -ใใ‚Œใงใฏใ€`endpoint` URLใ‚’ใƒ–ใƒฉใ‚ฆใ‚ถใง้–‹ใ„ใฆใฟใพใ—ใ‚‡ใ†ใ€‚ไธŠ่จ˜ใฎไพ‹ใงใฏ `https://qltnci.deta.dev` ใงใ™ใŒใ€ใ‚ใชใŸใฎURLใฏ็•ฐใชใ‚‹ใฏใšใงใ™ใ€‚ - -FastAPIใ‚ขใƒ—ใƒชใ‹ใ‚‰่ฟ”ใฃใฆใใŸJSONใƒฌใ‚นใƒใƒณใ‚นใŒ่กจ็คบใ•ใ‚Œใพใ™: - -```JSON -{ - "Hello": "World" -} -``` - -ใใ—ใฆ `/docs` ใธ็งปๅ‹•ใ—ใฆใใ ใ•ใ„ใ€‚ไธŠ่จ˜ใฎไพ‹ใงใฏใ€`https://qltnci.deta.dev/docs` ใงใ™ใ€‚ - -ๆฌกใฎใ‚ˆใ†ใชใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใŒ่กจ็คบใ•ใ‚Œใพใ™: - - - -## ใƒ‘ใƒ–ใƒชใƒƒใ‚ฏใ‚ขใ‚ฏใ‚ปใ‚นใฎๆœ‰ๅŠนๅŒ– - -ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใงใฏใ€Deta ใฏใ‚ฏใƒƒใ‚ญใƒผใ‚’็”จใ„ใฆใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฎ่ช่จผใ‚’่กŒใ„ใพใ™ใ€‚ - -ใ—ใ‹ใ—ใ€ๆบ–ๅ‚™ใŒๆ•ดใˆใฐใ€ไปฅไธ‹ใฎๆง˜ใซๅ…ฌ้–‹ใงใใพใ™: - -
- -```console -$ deta auth disable - -Successfully disabled http auth -``` - -
- -ใ“ใ“ใงใ€URLใ‚’ๅ…ฑๆœ‰ใ™ใ‚‹ใจAPIใซใ‚ขใ‚ฏใ‚ปใ‚นใงใใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚๐Ÿš€ - -## HTTPS - -ใŠใ‚ใงใจใ†ใ”ใ–ใ„ใพใ™๏ผใ‚ใชใŸใฎ FastAPI ใ‚ขใƒ—ใƒชใŒ Deta ใธใƒ‡ใƒ—ใƒญใ‚คใ•ใ‚Œใพใ—ใŸ๏ผ๐ŸŽ‰ ๐Ÿฐ - -ใพใŸใ€DetaใŒHTTPSใ‚’ๆญฃใ—ใๅ‡ฆ็†ใ™ใ‚‹ใŸใ‚ใ€ใใฎๅ‡ฆ็†ใ‚’่กŒใ†ๅฟ…่ฆใŒใชใใ€ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใฏๆš—ๅทๅŒ–ใ•ใ‚ŒใŸๅฎ‰ๅ…จใช้€šไฟกใŒๅˆฉ็”จใงใใพใ™ใ€‚โœ… ๐Ÿ”’ - -## Visor ใ‚’็ขบ่ช - -ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆUI (`https://qltnci.deta.dev/docs` ใฎใ‚ˆใ†ใชURLใซใ‚ใ‚‹) ใฏ *path operation* `/items/{item_id}` ใธใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’้€ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ - -ID `5` ใฎไพ‹ใ‚’็คบใ—ใพใ™ใ€‚ - -ใพใšใ€https://web.deta.sh ใธใ‚ขใ‚ฏใ‚ปใ‚นใ—ใพใ™ใ€‚ - -ๅทฆๅดใซๅ„ใ‚ขใƒ—ใƒชใฎ ใ€ŒMicrosใ€ ใจใ„ใ†ใ‚ปใ‚ฏใ‚ทใƒงใƒณใŒ่กจ็คบใ•ใ‚Œใพใ™ใ€‚ - -ใพใŸใ€ใ€ŒDetailsใ€ใ‚„ใ€ŒVisorใ€ใ‚ฟใƒ–ใŒ่กจ็คบใ•ใ‚Œใฆใ„ใพใ™ใ€‚ใ€ŒVisorใ€ใ‚ฟใƒ–ใธ็งปๅ‹•ใ—ใฆใใ ใ•ใ„ใ€‚ - -ใใ“ใงใ‚ขใƒ—ใƒชใซ้€ใ‚‰ใ‚ŒใŸ็›ด่ฟ‘ใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใŒ่ชฟในใ‚‰ใ‚Œใพใ™ใ€‚ - -ใพใŸใ€ใใ‚Œใ‚‰ใ‚’็ทจ้›†ใ—ใฆใƒชใƒ—ใƒฌใ‚คใงใใพใ™ใ€‚ - - - -## ใ•ใ‚‰ใซ่ฉณใ—ใ็Ÿฅใ‚‹ - -ๆง˜ใ€…ใช็ฎ‡ๆ‰€ใงๆฐธ็ถš็š„ใซใƒ‡ใƒผใ‚ฟใ‚’ไฟๅญ˜ใ—ใŸใใชใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ใใฎใŸใ‚ใซใฏ Deta Base ใ‚’ไฝฟ็”จใงใใพใ™ใ€‚ๆƒœใ—ใฟใชใ„ **็„กๆ–™ๅˆฉ็”จๆž ** ใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ - -่ฉณใ—ใใฏ Deta ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚ diff --git a/docs/ja/docs/deployment/docker.md b/docs/ja/docs/deployment/docker.md index f10312b51..ca9dedc3c 100644 --- a/docs/ja/docs/deployment/docker.md +++ b/docs/ja/docs/deployment/docker.md @@ -1,71 +1,157 @@ -# Dockerใ‚’ไฝฟ็”จใ—ใŸใƒ‡ใƒ—ใƒญใ‚ค +# ใ‚ณใƒณใƒ†ใƒŠๅ†…ใฎFastAPI - Docker -ใ“ใฎใ‚ปใ‚ฏใ‚ทใƒงใƒณใงใฏไปฅไธ‹ใฎไฝฟใ„ๆ–นใฎ็ดนไป‹ใจใ‚ฌใ‚คใƒ‰ใธใฎใƒชใƒณใ‚ฏใŒ็ขบ่ชใงใใพใ™: +FastAPIใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ๅ ดๅˆใ€ไธ€่ˆฌ็š„ใชใ‚ขใƒ—ใƒญใƒผใƒใฏ**Linuxใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ**ใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹ใ“ใจใงใ™ใ€‚ -* **5ๅˆ†**็จ‹ๅบฆใงใ€**FastAPI** ใฎใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ใ€ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’ๆœ€ๅคง้™ใซ็™บๆฎใ™ใ‚‹Dockerใ‚คใƒกใƒผใ‚ธ (ใ‚ณใƒณใƒ†ใƒŠ)ใซใ™ใ‚‹ใ€‚ -* (ใ‚ชใƒ—ใ‚ทใƒงใƒณ) ้–‹็™บ่€…ใจใ—ใฆๅฟ…่ฆใช็ฏ„ๅ›ฒใงHTTPSใ‚’็†่งฃใ™ใ‚‹ใ€‚ -* **20ๅˆ†**็จ‹ๅบฆใงใ€่‡ชๅ‹•็š„ใชHTTPS็”Ÿๆˆใจใจใ‚‚ใซDockerใฎSwarmใƒขใƒผใƒ‰ ใ‚ฏใƒฉใ‚นใ‚ฟใ‚’ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ™ใ‚‹ (ๆœˆ5ใƒ‰ใƒซใฎใ‚ทใƒณใƒ—ใƒซใชใ‚ตใƒผใƒใƒผไธŠใง)ใ€‚ -* **10ๅˆ†**็จ‹ๅบฆใงใ€DockerใฎSwarmใƒขใƒผใƒ‰ ใ‚ฏใƒฉใ‚นใ‚ฟใ‚’ไฝฟใฃใฆใ€HTTPSใชใฉใ‚’ไฝฟ็”จใ—ใŸๅฎŒๅ…จใช**FastAPI** ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎไฝœๆˆใจใƒ‡ใƒ—ใƒญใ‚คใ€‚ +ๅŸบๆœฌ็š„ใซใฏ **Docker**ใ‚’็”จใ„ใฆ่กŒใ‚ใ‚Œใพใ™ใ€‚็”Ÿๆˆใ•ใ‚ŒใŸใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใฏใ€ใ„ใใคใ‹ใฎๆ–นๆณ•ใฎใ„ใšใ‚Œใ‹ใงใƒ‡ใƒ—ใƒญใ‚คใงใใพใ™ใ€‚ -ใƒ‡ใƒ—ใƒญใ‚คใฎใŸใ‚ใซใ€**Docker** ใ‚’ๅˆฉ็”จใงใใพใ™ใ€‚ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใ€ๅ†็พๆ€งใ€้–‹็™บใฎใ‚ทใƒณใƒ—ใƒซใ•ใชใฉใซๅˆฉ็‚นใŒใ‚ใ‚Šใพใ™ใ€‚ +Linuxใ‚ณใƒณใƒ†ใƒŠใฎไฝฟ็”จใซใฏใ€**ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ**ใ€**ๅๅพฉๅฏ่ƒฝๆ€ง๏ผˆใƒฌใƒ—ใƒชใ‚ซใƒ“ใƒชใƒ†ใ‚ฃ๏ผ‰**ใ€**ใ‚ทใƒณใƒ—ใƒชใ‚ทใƒ†ใ‚ฃ**ใชใฉใ€ใ„ใใคใ‹ใฎๅˆฉ็‚นใŒใ‚ใ‚Šใพใ™ใ€‚ -Dockerใ‚’ไฝฟใ†ๅ ดๅˆใ€ๅ…ฌๅผใฎDockerใ‚คใƒกใƒผใ‚ธใŒๅˆฉ็”จใงใใพใ™: +!!! tip + TODO: ใชใœใ‹้ท็งปใงใใชใ„ + ใŠๆ€ฅใŽใงใ€ใ™ใงใซใ“ใ‚Œใ‚‰ใฎๆƒ…ๅ ฑใ‚’ใ”ๅญ˜ใ˜ใงใ™ใ‹๏ผŸ [ไปฅไธ‹ใฎ`Dockerfile`ใฎ็ฎ‡ๆ‰€๐Ÿ‘‡](#build-a-docker-image-for-fastapi)ใธใ‚ธใƒฃใƒณใƒ—ใ—ใฆใใ ใ•ใ„ใ€‚ -## tiangolo/uvicorn-gunicorn-fastapi +
+Dockerfile ใƒ—ใƒฌใƒ“ใƒฅใƒผ ๐Ÿ‘€ -ใ“ใฎใ‚คใƒกใƒผใ‚ธใฏใ€Œ่‡ชๅ‹•ใƒใƒฅใƒผใƒ‹ใƒณใ‚ฐใ€ๆฉŸๆง‹ใ‚’ๅซใ‚“ใงใ„ใพใ™ใ€‚็Š ็‰ฒใ‚’ๆ‰•ใ†ใ“ใจใชใใ€ใŸใ ใ‚ณใƒผใƒ‰ใ‚’ๅŠ ใˆใ‚‹ใ ใ‘ใง่‡ชๅ‹•็š„ใซ้ซ˜ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’ๅฎŸ็พใงใใพใ™ใ€‚ +```Dockerfile +FROM python:3.9 -ใŸใ ใ—ใ€็’ฐๅขƒๅค‰ๆ•ฐใ‚„่จญๅฎšใƒ•ใ‚กใ‚คใƒซใ‚’ไฝฟใฃใฆๅ…จใฆใฎ่จญๅฎšใฎๅค‰ๆ›ดใ‚„ๆ›ดๆ–ฐใ‚’่กŒใˆใพใ™ใ€‚ +WORKDIR /code -!!! tip "่ฑ†็Ÿฅ่ญ˜" - ๅ…จใฆใฎ่จญๅฎšใจใ‚ชใƒ—ใ‚ทใƒงใƒณใ‚’็ขบ่ชใ™ใ‚‹ใซใฏใ€Dockerใ‚คใƒกใƒผใ‚ธใƒšใƒผใ‚ธใ‚’้–‹ใ„ใฆไธ‹ใ•ใ„: tiangolo/uvicorn-gunicorn-fastapi. +COPY ./requirements.txt /code/requirements.txt -## `Dockerfile` ใฎไฝœๆˆ +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt -* ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใธ็งปๅ‹•ใ€‚ -* ไปฅไธ‹ใฎ`Dockerfile` ใ‚’ไฝœๆˆ: +COPY ./app /code/app -```Dockerfile -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] -COPY ./app /app +# If running behind a proxy like Nginx or Traefik add --proxy-headers +# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"] ``` -### ใ‚ˆใ‚Šๅคงใใชใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ +
-[Bigger Applications with Multiple Files](tutorial/bigger-applications.md){.internal-link target=_blank} ใ‚ปใ‚ฏใ‚ทใƒงใƒณใซๅ€ฃใ†ๅ ดๅˆใฏใ€`Dockerfile` ใฏไธŠ่จ˜ใฎไปฃใ‚ใ‚Šใซใ€ไปฅไธ‹ใฎๆง˜ใซใชใ‚‹ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“: +## ใ‚ณใƒณใƒ†ใƒŠใจใฏไฝ•ใ‹ -```Dockerfile -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 +ใ‚ณใƒณใƒ†ใƒŠ๏ผˆไธปใซLinuxใ‚ณใƒณใƒ†ใƒŠ๏ผ‰ใฏใ€ๅŒใ˜ใ‚ทใ‚นใƒ†ใƒ ๅ†…ใฎไป–ใฎใ‚ณใƒณใƒ†ใƒŠ๏ผˆไป–ใฎใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚„ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆ๏ผ‰ใ‹ใ‚‰้š”้›ขใ•ใ‚ŒใŸ็Šถๆ…‹ใ‚’ไฟใกใชใŒใ‚‰ใ€ใ™ในใฆใฎไพๅญ˜้–ขไฟ‚ใ‚„ๅฟ…่ฆใชใƒ•ใ‚กใ‚คใƒซใ‚’ๅซใ‚€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธๅŒ–ใ™ใ‚‹้žๅธธใซ**่ปฝ้‡**ใชๆ–นๆณ•ใงใ™ใ€‚ -COPY ./app /app/app -``` +Linuxใ‚ณใƒณใƒ†ใƒŠใฏใ€ใƒ›ใ‚นใƒˆ๏ผˆใƒžใ‚ทใƒณใ€ไปฎๆƒณใƒžใ‚ทใƒณใ€ใ‚ฏใƒฉใ‚ฆใƒ‰ใ‚ตใƒผใƒใƒผใชใฉ๏ผ‰ใฎๅŒใ˜Linuxใ‚ซใƒผใƒใƒซใ‚’ไฝฟ็”จใ—ใฆๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚ใ“ใ‚Œใฏใ€๏ผˆOSๅ…จไฝ“ใ‚’ใ‚จใƒŸใƒฅใƒฌใƒผใƒˆใ™ใ‚‹ๅฎŒๅ…จใชไปฎๆƒณใƒžใ‚ทใƒณใจๆฏ”ในใฆ๏ผ‰้žๅธธใซ่ปฝ้‡ใงใ‚ใ‚‹ใ“ใจใ‚’ๆ„ๅ‘ณใ—ใพใ™ใ€‚ -### Raspberry Piใชใฉใฎใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒใƒฃ +ใ“ใฎใ‚ˆใ†ใซใ€ใ‚ณใƒณใƒ†ใƒŠใฏ**ใƒชใ‚ฝใƒผใ‚นใ‚’ใปใจใ‚“ใฉๆถˆ่ฒปใ—ใพใ›ใ‚“**ใŒใ€ใƒ—ใƒญใ‚ปใ‚นใ‚’็›ดๆŽฅๅฎŸ่กŒใ™ใ‚‹ใฎใซๅŒนๆ•ตใ™ใ‚‹้‡ใงใ™๏ผˆไปฎๆƒณใƒžใ‚ทใƒณใฏใ‚‚ใฃใจๆถˆ่ฒปใ—ใพใ™๏ผ‰ใ€‚ -Raspberry Pi (ARMใƒ—ใƒญใ‚ปใƒƒใ‚ตๆญ่ผ‰)ใ‚„ใใ‚Œไปฅๅค–ใฎใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒใƒฃใงDockerใŒไฝœๅ‹•ใ—ใฆใ„ใ‚‹ๅ ดๅˆใ€(ใƒžใƒซใƒใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒใƒฃใงใ‚ใ‚‹) Pythonใƒ™ใƒผใ‚นใ‚คใƒกใƒผใ‚ธใ‚’ไฝฟใฃใฆใ€ไธ€ใ‹ใ‚‰`Dockerfile`ใ‚’ไฝœๆˆใ—ใ€Uvicornใ‚’ๅ˜ไฝ“ใงไฝฟ็”จใงใใพใ™ใ€‚ +ใ‚ณใƒณใƒ†ใƒŠใฏใพใŸใ€็‹ฌ่‡ชใฎ**ๅˆ†้›ขใ•ใ‚ŒใŸ**ๅฎŸ่กŒใƒ—ใƒญใ‚ปใ‚น๏ผˆ้€šๅธธใฏ1ใคใฎใƒ—ใƒญใ‚ปใ‚นใฎใฟ๏ผ‰ใ‚„ใ€ใƒ•ใ‚กใ‚คใƒซใ‚ทใ‚นใƒ†ใƒ ใ€ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใ‚’ๆŒใกใพใ™ใ€‚ ใ“ใฎใ“ใจใฏใƒ‡ใƒ—ใƒญใ‚คใ€ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใ€้–‹็™บใชใฉใ‚’็ฐก็ด ๅŒ–ใ•ใ›ใพใ™ใ€‚ -ใ“ใฎๅ ดๅˆใ€`Dockerfile` ใฏไปฅไธ‹ใฎๆง˜ใซใชใ‚‹ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“: +## ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใจใฏไฝ•ใ‹ -```Dockerfile -FROM python:3.7 +**ใ‚ณใƒณใƒ†ใƒŠ**ใฏใ€**ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ**ใ‹ใ‚‰ๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚ -RUN pip install fastapi uvicorn +ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใฏใ€ใ‚ณใƒณใƒ†ใƒŠๅ†…ใซๅญ˜ๅœจใ™ในใใ™ในใฆใฎใƒ•ใ‚กใ‚คใƒซใ‚„็’ฐๅขƒๅค‰ๆ•ฐใ€ใใ—ใฆใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎใ‚ณใƒžใƒณใƒ‰/ใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚’**้™็š„ใซ**ใƒใƒผใ‚ธใƒงใƒณๅŒ–ใ—ใŸใ‚‚ใฎใงใ™ใ€‚ ใ“ใ“ใงใฎ**้™็š„**ใจใฏใ€ใ‚ณใƒณใƒ†ใƒŠ**ใ‚คใƒกใƒผใ‚ธ**ใฏๅฎŸ่กŒใ•ใ‚ŒใฆใŠใ‚‰ใšใ€ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธๅŒ–ใ•ใ‚ŒใŸใƒ•ใ‚กใ‚คใƒซใจใƒกใ‚ฟใƒ‡ใƒผใ‚ฟใฎใฟใงใ‚ใ‚‹ใ“ใจใ‚’ๆ„ๅ‘ณใ—ใพใ™ใ€‚ -EXPOSE 80 +ไฟๅญ˜ใ•ใ‚ŒใŸ้™็š„ใ‚ณใƒณใƒ†ใƒณใƒ„ใงใ‚ใ‚‹ใ€Œ**ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธ**ใ€ใจใฏๅฏพ็…ง็š„ใซใ€ใ€Œ**ใ‚ณใƒณใƒ†ใƒŠ**ใ€ใฏ้€šๅธธใ€ๅฎŸ่กŒไธญใฎใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใ€ใคใพใ‚Š**ๅฎŸ่กŒ**ใ•ใ‚Œใฆใ„ใ‚‹ใ‚‚ใฎใ‚’ๆŒ‡ใ—ใพใ™ใ€‚ -COPY ./app /app +**ใ‚ณใƒณใƒ†ใƒŠ**ใŒ่ตทๅ‹•ใ•ใ‚ŒๅฎŸ่กŒใ•ใ‚Œใ‚‹ใจใ๏ผˆ**ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธ**ใ‹ใ‚‰่ตทๅ‹•ใ•ใ‚Œใ‚‹ใจใ๏ผ‰ใ€ใƒ•ใ‚กใ‚คใƒซใ‚„็’ฐๅขƒๅค‰ๆ•ฐใชใฉใŒไฝœๆˆใ•ใ‚ŒใŸใ‚Šๅค‰ๆ›ดใ•ใ‚ŒใŸใ‚Šใ™ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +ใ“ใ‚Œใ‚‰ใฎๅค‰ๆ›ดใฏใใฎใ‚ณใƒณใƒ†ใƒŠๅ†…ใซใฎใฟๅญ˜ๅœจใ—ใพใ™ใŒใ€ๅŸบ็›คใจใชใ‚‹ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใซใฏๆฎ‹ใ‚Šใพใ›ใ‚“๏ผˆใƒ‡ใ‚ฃใ‚นใ‚ฏใซไฟๅญ˜ใ•ใ‚Œใพใ›ใ‚“๏ผ‰ใ€‚ + +ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใฏ **ใƒ—ใƒญใ‚ฐใƒฉใƒ ** ใƒ•ใ‚กใ‚คใƒซใ‚„ใใฎๅ†…ๅฎนใ€ไพ‹ใˆใฐ `python` ใจ `main.py` ใƒ•ใ‚กใ‚คใƒซใซๅŒนๆ•ตใ—ใพใ™ใ€‚ + +ใใ—ใฆใ€**ใ‚ณใƒณใƒ†ใƒŠ**่‡ชไฝ“ใฏ๏ผˆ**ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธ**ใจใฏๅฏพ็…ง็š„ใซ๏ผ‰ใ‚คใƒกใƒผใ‚ธใ‚’ใ‚‚ใจใซใ—ใŸๅฎŸ้š›ใฎๅฎŸ่กŒไธญใฎใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใงใ‚ใ‚Šใ€**ใƒ—ใƒญใ‚ปใ‚น**ใซๅŒนๆ•ตใ—ใพใ™ใ€‚ + +ๅฎŸ้š›ใ€ใ‚ณใƒณใƒ†ใƒŠใŒๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹ใฎใฏใ€**ใƒ—ใƒญใ‚ปใ‚นใŒๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹**ใจใใ ใ‘ใงใ™๏ผˆ้€šๅธธใฏๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚นใ ใ‘ใงใ™๏ผ‰ใ€‚ ใ‚ณใƒณใƒ†ใƒŠๅ†…ใงๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นใŒใชใ„ๅ ดๅˆใ€ใ‚ณใƒณใƒ†ใƒŠใฏๅœๆญขใ—ใพใ™ใ€‚ + +## ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ + +Dockerใฏใ€**ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ**ใจ**ใ‚ณใƒณใƒ†ใƒŠ**ใ‚’ไฝœๆˆใƒป็ฎก็†ใ™ใ‚‹ใŸใ‚ใฎไธป่ฆใชใƒ„ใƒผใƒซใฎ1ใคใงใ™ใ€‚ + +ใใ—ใฆใ€DockerใซใฏDockerใ‚คใƒกใƒผใ‚ธ๏ผˆใ‚ณใƒณใƒ†ใƒŠ๏ผ‰ใ‚’ๅ…ฑๆœ‰ใ™ใ‚‹Docker Hubใจใ„ใ†ใ‚‚ใฎใŒใ‚ใ‚Šใพใ™ใ€‚ + +Docker Hubใฏ ๅคšใใฎใƒ„ใƒผใƒซใ‚„็’ฐๅขƒใ€ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใซๅฏพๅฟœใ—ใฆใ„ใ‚‹ไบˆใ‚ไฝœๆˆใ•ใ‚ŒใŸ**ๅ…ฌๅผใฎใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ**ใ‚’ใƒ‘ใƒ–ใƒชใƒƒใ‚ฏใซๆไพ›ใ—ใฆใ„ใพใ™ใ€‚ + +ไพ‹ใˆใฐใ€ๅ…ฌๅผใ‚คใƒกใƒผใ‚ธใฎ1ใคใซPython ImageใŒใ‚ใ‚Šใพใ™ใ€‚ + +ใใฎไป–ใซใ‚‚ใ€ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใชใฉใ•ใพใ–ใพใชใ‚คใƒกใƒผใ‚ธใŒใ‚ใ‚Šใพใ™๏ผš + +* PostgreSQL +* MySQL +* MongoDB +* Redis, etc. + +ไบˆใ‚ไฝœๆˆใ•ใ‚ŒใŸใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใงใ€็•ฐใชใ‚‹ใƒ„ใƒผใƒซใ‚’**็ต„ใฟๅˆใ‚ใ›ใฆ**ไฝฟ็”จใ™ใ‚‹ใ“ใจใŒ้žๅธธใซ็ฐกๅ˜ใซใชใ‚Šใพใ™ใ€‚ไพ‹ใˆใฐใ€ๆ–ฐใ—ใ„ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใ‚’่ฉฆใ™ๅ ดๅˆใซ็‰นใซไพฟๅˆฉใงใ™ใ€‚ใปใจใ‚“ใฉใฎๅ ดๅˆใ€**ๅ…ฌๅผใ‚คใƒกใƒผใ‚ธ**ใ‚’ไฝฟใ„ใ€็’ฐๅขƒๅค‰ๆ•ฐใง่จญๅฎšใ™ใ‚‹ใ ใ‘ใง่‰ฏใ„ใงใ™ใ€‚ + +ใใ†ใ™ใ‚Œใฐๅคšใใฎๅ ดๅˆใ€ใ‚ณใƒณใƒ†ใƒŠใจDockerใซใคใ„ใฆๅญฆใณใ€ใใฎ็Ÿฅ่ญ˜ใ‚’ใ•ใพใ–ใพใชใƒ„ใƒผใƒซใ‚„ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซใ‚ˆใฃใฆๅ†ๅˆฉ็”จใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +ใคใพใ‚Šใ€ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใ€Pythonใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ€Reactใƒ•ใƒญใƒณใƒˆใ‚จใƒณใƒ‰ใƒปใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅ‚™ใˆใŸใ‚ฆใ‚งใƒ–ใƒปใ‚ตใƒผใƒใƒผใชใฉใ€ใ•ใพใ–ใพใชใ‚‚ใฎใ‚’**่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠ**ใงๅฎŸ่กŒใ—ใ€ใใ‚Œใ‚‰ใ‚’ๅ†…้ƒจใƒใƒƒใƒˆใƒฏใƒผใ‚ฏ็ตŒ็”ฑใงๆŽฅ็ถšใ—ใพใ™ใ€‚ + +ใ™ในใฆใฎใ‚ณใƒณใƒ†ใƒŠ็ฎก็†ใ‚ทใ‚นใƒ†ใƒ ๏ผˆDockerใ‚„Kubernetesใชใฉ๏ผ‰ใซใฏใ€ใ“ใ†ใ—ใŸใƒใƒƒใƒˆใƒฏใƒผใ‚ญใƒณใ‚ฐๆฉŸ่ƒฝใŒ็ตฑๅˆใ•ใ‚Œใฆใ„ใพใ™ใ€‚ + +## ใ‚ณใƒณใƒ†ใƒŠใจใƒ—ใƒญใ‚ปใ‚น + +้€šๅธธใ€**ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ**ใฏใใฎใƒกใ‚ฟใƒ‡ใƒผใ‚ฟใซ**ใ‚ณใƒณใƒ†ใƒŠ**ใฎ่ตทๅ‹•ๆ™‚ใซๅฎŸ่กŒใ•ใ‚Œใ‚‹ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎใƒ—ใƒญใ‚ฐใƒฉใƒ ใพใŸใฏใ‚ณใƒžใƒณใƒ‰ใจใ€ใใฎใƒ—ใƒญใ‚ฐใƒฉใƒ ใซๆธกใ•ใ‚Œใ‚‹ใƒ‘ใƒฉใƒกใƒผใ‚ฟใ‚’ๅซใฟใพใ™ใ€‚ใ‚ณใƒžใƒณใƒ‰ใƒฉใ‚คใƒณใงใฎๆ“ไฝœใจใ‚ˆใไผผใฆใ„ใพใ™ใ€‚ + +**ใ‚ณใƒณใƒ†ใƒŠ**ใŒ่ตทๅ‹•ใ•ใ‚Œใ‚‹ใจใ€ใใฎใ‚ณใƒžใƒณใƒ‰/ใƒ—ใƒญใ‚ฐใƒฉใƒ ใŒๅฎŸ่กŒใ•ใ‚Œใพใ™๏ผˆใŸใ ใ—ใ€ๅˆฅใฎใ‚ณใƒžใƒณใƒ‰/ใƒ—ใƒญใ‚ฐใƒฉใƒ ใ‚’ใ‚ชใƒผใƒใƒผใƒฉใ‚คใƒ‰ใ—ใฆๅฎŸ่กŒใ•ใ›ใ‚‹ใ“ใจใ‚‚ใงใใพใ™๏ผ‰ใ€‚ + +ใ‚ณใƒณใƒ†ใƒŠใฏใ€**ใƒกใ‚คใƒณใƒปใƒ—ใƒญใ‚ปใ‚น**๏ผˆใ‚ณใƒžใƒณใƒ‰ใพใŸใฏใƒ—ใƒญใ‚ฐใƒฉใƒ ๏ผ‰ใŒๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹้™ใ‚ŠๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚ + +ใ‚ณใƒณใƒ†ใƒŠใฏ้€šๅธธ**1ใคใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใกใพใ™ใŒใ€ใƒกใ‚คใƒณใƒปใƒ—ใƒญใ‚ปใ‚นใ‹ใ‚‰ใ‚ตใƒ–ใƒปใƒ—ใƒญใ‚ปใ‚นใ‚’่ตทๅ‹•ใ™ใ‚‹ใ“ใจใ‚‚ๅฏ่ƒฝใงใ€ใใ†ใ™ใ‚ŒใฐๅŒใ˜ใ‚ณใƒณใƒ†ใƒŠๅ†…ใซ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใคใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +ใ—ใ‹ใ—ใ€**ๅฐ‘ใชใใจใ‚‚1ใคใฎๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚น**ใŒใชใ‘ใ‚Œใฐใ€ๅฎŸ่กŒไธญใฎใ‚ณใƒณใƒ†ใƒŠใ‚’ๆŒใคใ“ใจใฏใงใใชใ„ใงใ™ใ€‚ใƒกใ‚คใƒณใƒปใƒ—ใƒญใ‚ปใ‚นใŒๅœๆญขใ™ใ‚Œใฐใ€ใ‚ณใƒณใƒ†ใƒŠใ‚‚ๅœๆญขใ—ใพใ™ใ€‚ + +## Build a Docker Image for FastAPI + +ใจใ„ใ†ใ“ใจใงใ€ไฝ•ใ‹ไฝœใ‚Šใพใ—ใ‚‡ใ†๏ผ๐Ÿš€ + +FastAPI็”จใฎ**Dockerใ‚คใƒกใƒผใ‚ธ**ใ‚’ใ€**ๅ…ฌๅผPython**ใ‚คใƒกใƒผใ‚ธใซๅŸบใฅใ„ใฆ**ใ‚ผใƒญใ‹ใ‚‰**ใƒ“ใƒซใƒ‰ใ™ใ‚‹ๆ–นๆณ•ใ‚’ใŠ่ฆ‹ใ›ใ—ใพใ™ใ€‚ + +ใ“ใ‚Œใฏ**ใปใจใ‚“ใฉใฎๅ ดๅˆ**ใซใ‚„ใ‚ŠใŸใ„ใ“ใจใงใ™ใ€‚ไพ‹ใˆใฐ๏ผš + +* **Kubernetes**ใพใŸใฏๅŒๆง˜ใฎใƒ„ใƒผใƒซใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆ +* **Raspberry Pi**ใงๅฎŸ่กŒใ™ใ‚‹ๅ ดๅˆ +* ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใ‚’ๅฎŸ่กŒใ—ใฆใใ‚Œใ‚‹ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใ‚ตใƒผใƒ“ใ‚นใชใฉใ‚’ๅˆฉ็”จใ™ใ‚‹ๅ ดๅˆ + +### ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธ่ฆไปถ๏ผˆpackage requirements๏ผ‰ + +ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎ**ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธ่ฆไปถ**ใฏ้€šๅธธใ€ไฝ•ใ‚‰ใ‹ใฎใƒ•ใ‚กใ‚คใƒซใซ่จ˜่ฟฐใ•ใ‚Œใฆใ„ใ‚‹ใฏใšใงใ™ใ€‚ + +ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธ่ฆไปถใฏไธปใซ**ใ‚คใƒณใ‚นใƒˆใƒผใƒซ**ใ™ใ‚‹ใŸใ‚ใซไฝฟ็”จใ™ใ‚‹ใƒ„ใƒผใƒซใซไพๅญ˜ใ™ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ๆœ€ใ‚‚ไธ€่ˆฌ็š„ใชๆ–นๆณ•ใฏใ€`requirements.txt` ใƒ•ใ‚กใ‚คใƒซใซใƒ‘ใƒƒใ‚ฑใƒผใ‚ธๅใจใใฎใƒใƒผใ‚ธใƒงใƒณใ‚’ 1 ่กŒใšใคๆ›ธใใ“ใจใงใ™ใ€‚ + +ใ‚‚ใกใ‚ใ‚“ใ€[FastAPI ใƒใƒผใ‚ธใƒงใƒณใซใคใ„ใฆ](./versions.md){.internal-link target=_blank}ใง่ชญใ‚“ใ ใฎใจๅŒใ˜ใ‚ขใ‚คใƒ‡ใ‚ขใ‚’ไฝฟ็”จใ—ใฆใ€ใƒใƒผใ‚ธใƒงใƒณใฎ็ฏ„ๅ›ฒใ‚’่จญๅฎšใ—ใพใ™ใ€‚ + +ไพ‹ใˆใฐใ€`requirements.txt` ใฏๆฌกใฎใ‚ˆใ†ใซใชใ‚Šใพใ™๏ผš + +``` +fastapi>=0.68.0,<0.69.0 +pydantic>=1.8.0,<2.0.0 +uvicorn>=0.15.0,<0.16.0 ``` -## **FastAPI** ใ‚ณใƒผใƒ‰ใฎไฝœๆˆ +ใใ—ใฆ้€šๅธธใ€ไพ‹ใˆใฐ `pip` ใ‚’ไฝฟใฃใฆใ“ใ‚Œใ‚‰ใฎใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใฎไพๅญ˜้–ขไฟ‚ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใพใ™๏ผš + +
-* `app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ไฝœๆˆใ—ใ€็งปๅ‹•ใ€‚ -* ไปฅไธ‹ใฎ`main.py` ใƒ•ใ‚กใ‚คใƒซใ‚’ไฝœๆˆ: +```console +$ pip install -r requirements.txt +---> 100% +Successfully installed fastapi pydantic uvicorn +``` + +
+ +!!! info + ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใฎไพๅญ˜้–ขไฟ‚ใ‚’ๅฎš็พฉใ—ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ใŸใ‚ใฎใƒ•ใ‚ฉใƒผใƒžใƒƒใƒˆใ‚„ใƒ„ใƒผใƒซใฏไป–ใซใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ + + Poetryใ‚’ไฝฟใฃใŸไพ‹ใฏใ€ๅพŒ่ฟฐใ™ใ‚‹ใ‚ปใ‚ฏใ‚ทใƒงใƒณใงใ”็ดนไป‹ใ—ใพใ™ใ€‚๐Ÿ‘‡ + +### **FastAPI**ใ‚ณใƒผใƒ‰ใ‚’ไฝœๆˆใ™ใ‚‹ + +* `app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ไฝœๆˆใ—ใ€ใใฎไธญใซๅ…ฅใ‚Šใพใ™ +* ็ฉบใฎใƒ•ใ‚กใ‚คใƒซ `__init__.py` ใ‚’ไฝœๆˆใ—ใพใ™ +* `main.py` ใƒ•ใ‚กใ‚คใƒซใ‚’ไฝœๆˆใ—ใพใ™๏ผš ```Python -from typing import Optional +from typing import Union from fastapi import FastAPI @@ -78,23 +164,136 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: Optional[str] = None): +def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` -* ใ“ใ“ใงใฏใ€ไปฅไธ‹ใฎๆง˜ใชใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชๆง‹้€ ใซใชใฃใฆใ„ใ‚‹ใฏใšใงใ™: +### Dockerfile + +ๅŒใ˜ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใƒปใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซ`Dockerfile`ใจใ„ใ†ใƒ•ใ‚กใ‚คใƒซใ‚’ไฝœๆˆใ—ใพใ™๏ผš + +```{ .dockerfile .annotate } +# (1) +FROM python:3.9 + +# (2) +WORKDIR /code + +# (3) +COPY ./requirements.txt /code/requirements.txt + +# (4) +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +# (5) +COPY ./app /code/app + +# (6) +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +``` + +1. ๅ…ฌๅผใฎPythonใƒ™ใƒผใ‚นใ‚คใƒกใƒผใ‚ธใ‹ใ‚‰ๅง‹ใ‚ใพใ™ + +2. ็พๅœจใฎไฝœๆฅญใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ `/code` ใซ่จญๅฎšใ—ใพใ™ + + ใ“ใ“ใซ `requirements.txt` ใƒ•ใ‚กใ‚คใƒซใจ `app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’็ฝฎใใพใ™ใ€‚ + +3. ่ฆไปถใŒๆ›ธใ‹ใ‚ŒใŸใƒ•ใ‚กใ‚คใƒซใ‚’ `/code` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซใ‚ณใƒ”ใƒผใ—ใพใ™ + + ๆฎ‹ใ‚Šใฎใ‚ณใƒผใƒ‰ใงใฏใชใใ€ๆœ€ๅˆใซๅฟ…่ฆใชใƒ•ใ‚กใ‚คใƒซใ ใ‘ใ‚’ใ‚ณใƒ”ใƒผใ—ใฆใใ ใ•ใ„ใ€‚ + + ใ“ใฎใƒ•ใ‚กใ‚คใƒซใฏ**้ ป็นใซใฏๅค‰ๆ›ดใ•ใ‚Œใชใ„**ใฎใงใ€Dockerใฏใ“ใฎใ‚นใƒ†ใƒƒใƒ—ใงใฏใใ‚Œใ‚’ๆคœ็Ÿฅใ—**ใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใ‚’ไฝฟ็”จใ—ใ€ๆฌกใฎใ‚นใƒ†ใƒƒใƒ—ใงใ‚‚ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’ๆœ‰ๅŠนใซใ—ใพใ™ใ€‚ + +4. ่ฆไปถใƒ•ใ‚กใ‚คใƒซใซใ‚ใ‚‹ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใฎไพๅญ˜้–ขไฟ‚ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใพใ™ + `--no-cache-dir` ใ‚ชใƒ—ใ‚ทใƒงใƒณใฏใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใŸใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใ‚’ใƒญใƒผใ‚ซใƒซใซไฟๅญ˜ใ—ใชใ„ใ‚ˆใ†ใซ `pip` ใซๆŒ‡็คบใ—ใพใ™ใ€‚ใ“ใ‚Œใฏใ€ๅŒใ˜ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ใŸใ‚ใซ `pip` ใ‚’ๅ†ๅบฆๅฎŸ่กŒใ™ใ‚‹ๅ ดๅˆใซใฎใฟๆœ‰ๅŠนใงใ™ใŒใ€ใ‚ณใƒณใƒ†ใƒŠใงไฝœๆฅญใ™ใ‚‹ๅ ดๅˆใฏใใ†ใงใฏใชใ„ใงใ™ใ€‚ + + !!! note + `--no-cache-dir`ใฏ`pip`ใซ้–ข้€ฃใ—ใฆใ„ใ‚‹ใ ใ‘ใงใ€Dockerใ‚„ใ‚ณใƒณใƒ†ใƒŠใจใฏไฝ•ใฎ้–ขไฟ‚ใ‚‚ใชใ„ใงใ™ใ€‚ + + `--upgrade` ใ‚ชใƒ—ใ‚ทใƒงใƒณใฏใ€ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใŒๆ—ขใซใ‚คใƒณใ‚นใƒˆใƒผใƒซใ•ใ‚Œใฆใ„ใ‚‹ๅ ดๅˆใ€`pip` ใซใ‚ขใƒƒใƒ—ใ‚ฐใƒฌใƒผใƒ‰ใ™ใ‚‹ใ‚ˆใ†ใซๆŒ‡็คบใ—ใพใ™ใ€‚ + + ไฝ•ๆ•…ใชใ‚‰ใƒ•ใ‚กใ‚คใƒซใ‚’ใ‚ณใƒ”ใƒผใ™ใ‚‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—ใฏ**Dockerใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใซใ‚ˆใฃใฆๆคœๅ‡บใ•ใ‚Œใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚‹ใŸใ‚ใงใ‚ใ‚Šใ€ใ“ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚‚ๅˆฉ็”จๅฏ่ƒฝใชๅ ดๅˆใฏ**Dockerใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚ + + ใ“ใฎใ‚นใƒ†ใƒƒใƒ—ใงใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’ไฝฟ็”จใ™ใ‚‹ใจใ€้–‹็™บไธญใซใ‚คใƒกใƒผใ‚ธใ‚’ไฝ•ๅบฆใ‚‚ใƒ“ใƒซใƒ‰ใ™ใ‚‹้š›ใซใ€**ๆฏŽๅ›ž**ใ™ในใฆใฎไพๅญ˜้–ขไฟ‚ใ‚’**ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใฆใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹**ไปฃใ‚ใ‚Šใซๅคšใใฎ**ๆ™‚้–“**ใ‚’**็ฏ€็ด„**ใงใใพใ™ใ€‚ + +5. ./app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ `/code` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใฎไธญใซใ‚ณใƒ”ใƒผใ™ใ‚‹ใ€‚ + + ใ“ใ‚Œใซใฏ**ๆœ€ใ‚‚้ ป็นใซๅค‰ๆ›ดใ•ใ‚Œใ‚‹**ใ™ในใฆใฎใ‚ณใƒผใƒ‰ใŒๅซใพใ‚Œใฆใ„ใ‚‹ใŸใ‚ใ€Dockerใฎ**ใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใฏ**ใ“ใ‚Œไปฅ้™ใฎใ‚นใƒ†ใƒƒใƒ—**ใซ็ฐกๅ˜ใซไฝฟ็”จใ•ใ‚Œใ‚‹ใ“ใจใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ + + ใใฎใŸใ‚ใ€ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใฎใƒ“ใƒซใƒ‰ๆ™‚้–“ใ‚’ๆœ€้ฉๅŒ–ใ™ใ‚‹ใŸใ‚ใซใ€`Dockerfile`ใฎ **ๆœ€ๅพŒ** ใซใ“ใ‚Œใ‚’็ฝฎใใ“ใจใŒ้‡่ฆใงใ™ใ€‚ + +6. `uvicorn`ใ‚ตใƒผใƒใƒผใ‚’ๅฎŸ่กŒใ™ใ‚‹ใŸใ‚ใฎ**ใ‚ณใƒžใƒณใƒ‰**ใ‚’่จญๅฎšใ—ใพใ™ + + `CMD` ใฏๆ–‡ๅญ—ๅˆ—ใฎใƒชใ‚นใƒˆใ‚’ๅ–ใ‚Šใ€ใใ‚Œใžใ‚Œใฎๆ–‡ๅญ—ๅˆ—ใฏใ‚นใƒšใƒผใ‚นใงๅŒบๅˆ‡ใ‚‰ใ‚ŒใŸใ‚ณใƒžใƒณใƒ‰ใƒฉใ‚คใƒณใซๅ…ฅๅŠ›ใ™ใ‚‹ใ‚‚ใฎใงใ™ใ€‚ + + ใ“ใฎใ‚ณใƒžใƒณใƒ‰ใฏ **็พๅœจใฎไฝœๆฅญใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช**ใ‹ใ‚‰ๅฎŸ่กŒใ•ใ‚Œใ€ไธŠ่จ˜ใฎ `WORKDIR /code` ใซใฆ่จญๅฎšใ—ใŸ `/code` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใจๅŒใ˜ใงใ™ใ€‚ + + ใใฎใŸใ‚ใƒ—ใƒญใ‚ฐใƒฉใƒ ใฏ `/code` ใง้–‹ๅง‹ใ—ใใฎไธญใซใ‚ใชใŸใฎใ‚ณใƒผใƒ‰ใŒใ‚ใ‚‹ `./app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใŒใ‚ใ‚‹ใฎใงใ€**Uvicorn** ใฏ `app.main` ใ‹ใ‚‰ `app` ใ‚’ๅ‚็…งใ—ใ€**ใ‚คใƒณใƒใƒผใƒˆ** ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +!!! tip + ใ‚ณใƒผใƒ‰ๅ†…ใฎ"+"ใฎๅนใๅ‡บใ—ใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆใ€ๅ„่กŒใŒไฝ•ใ‚’ใ™ใ‚‹ใฎใ‹ใ‚’ใƒฌใƒ“ใƒฅใƒผใ—ใฆใใ ใ•ใ„ใ€‚๐Ÿ‘† + +ใ“ใ‚Œใงใ€ๆฌกใฎใ‚ˆใ†ใชใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชๆง‹้€ ใซใชใ‚‹ใฏใšใงใ™๏ผš ``` . โ”œโ”€โ”€ app +โ”‚ย ย  โ”œโ”€โ”€ __init__.py โ”‚ โ””โ”€โ”€ main.py -โ””โ”€โ”€ Dockerfile +โ”œโ”€โ”€ Dockerfile +โ””โ”€โ”€ requirements.txt +``` + +#### TLS Termination Proxyใฎ่ฃๅด + +Nginx ใ‚„ Traefik ใฎใ‚ˆใ†ใช TLS Termination Proxy (ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ต) ใฎๅพŒใ‚ใงใ‚ณใƒณใƒ†ใƒŠใ‚’ๅ‹•ใ‹ใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€`--proxy-headers`ใ‚ชใƒ—ใ‚ทใƒงใƒณใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚ + +ใ“ใฎใ‚ชใƒ—ใ‚ทใƒงใƒณใฏใ€Uvicornใซใƒ—ใƒญใ‚ญใ‚ท็ตŒ็”ฑใงHTTPSใงๅ‹•ไฝœใ—ใฆใ„ใ‚‹ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใซๅฏพใ—ใฆใ€้€ไฟกใ•ใ‚Œใ‚‹ใƒ˜ใƒƒใƒ€ใ‚’ไฟก้ ผใ™ใ‚‹ใ‚ˆใ†ๆŒ‡็คบใ—ใพใ™ใ€‚ + +```Dockerfile +CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] +``` + +#### Dockerใ‚ญใƒฃใƒƒใ‚ทใƒฅ + +ใ“ใฎ`Dockerfile`ใซใฏ้‡่ฆใชใƒˆใƒชใƒƒใ‚ฏใŒใ‚ใ‚Šใ€ใพใš**ไพๅญ˜้–ขไฟ‚ใ ใ‘ใฎใƒ•ใ‚กใ‚คใƒซ**ใ‚’ใ‚ณใƒ”ใƒผใ—ใพใ™ใ€‚ใใฎ็†็”ฑใ‚’่ชฌๆ˜Žใ—ใพใ™ใ€‚ + +```Dockerfile +COPY ./requirements.txt /code/requirements.txt +``` + +Dockerใ‚„ไป–ใฎใƒ„ใƒผใƒซใฏใ€ใ“ใ‚Œใ‚‰ใฎใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใ‚’**ๆฎต้šŽ็š„ใซ**ใƒ“ใƒซใƒ‰ใ—ใ€**1ใคใฎใƒฌใ‚คใƒคใƒผใ‚’ไป–ใฎใƒฌใ‚คใƒคใƒผใฎไธŠใซ**่ฟฝๅŠ ใ—ใพใ™ใ€‚`Dockerfile`ใฎๅ…ˆ้ ญใ‹ใ‚‰้–‹ๅง‹ใ—ใ€`Dockerfile`ใฎๅ„ๅ‘ฝไปคใซใ‚ˆใฃใฆไฝœๆˆใ•ใ‚ŒใŸใƒ•ใ‚กใ‚คใƒซใ‚’่ฟฝๅŠ ใ—ใฆใ„ใใพใ™ใ€‚ + +Dockerใ‚„ๅŒๆง˜ใฎใƒ„ใƒผใƒซใฏใ€ใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹้š›ใซ**ๅ†…้ƒจใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใ‚‚ไฝฟ็”จใ—ใพใ™ใ€‚ๅ‰ๅ›žใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใ‚’ๆง‹็ฏ‰ใ—ใŸใจใใ‹ใ‚‰ใƒ•ใ‚กใ‚คใƒซใŒๅค‰ๆ›ดใ•ใ‚Œใฆใ„ใชใ„ๅ ดๅˆใ€ใƒ•ใ‚กใ‚คใƒซใ‚’ๅ†ๅบฆใ‚ณใƒ”ใƒผใ—ใฆใ‚ผใƒญใ‹ใ‚‰ๆ–ฐใ—ใ„ใƒฌใ‚คใƒคใƒผใ‚’ไฝœๆˆใ™ใ‚‹ไปฃใ‚ใ‚Šใซใ€**ๅ‰ๅ›žไฝœๆˆใ—ใŸๅŒใ˜ใƒฌใ‚คใƒคใƒผใ‚’ๅ†ๅˆฉ็”จ**ใ—ใพใ™ใ€‚ + +ใŸใ ใƒ•ใ‚กใ‚คใƒซใฎใ‚ณใƒ”ใƒผใ‚’้ฟใ‘ใ‚‹ใ ใ‘ใงใฏใ‚ใพใ‚Šๆ”นๅ–„ใ•ใ‚Œใพใ›ใ‚“ใŒใ€ใใฎใ‚นใƒ†ใƒƒใƒ—ใงใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’ๅˆฉ็”จใ—ใŸใŸใ‚ใ€**ๆฌกใฎใ‚นใƒ†ใƒƒใƒ—**ใงใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’ไฝฟใ†ใ“ใจใŒใงใใพใ™ใ€‚ + +ไพ‹ใˆใฐใ€ไพๅญ˜้–ขไฟ‚ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ๅ‘ฝไปคใฎใŸใ‚ใซใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’ไฝฟใ†ใ“ใจใŒใงใใพใ™๏ผš + +```Dockerfile +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt ``` -## Dockerใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ +ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธ่ฆไปถใฎใƒ•ใ‚กใ‚คใƒซใฏ**้ ป็นใซๅค‰ๆ›ดใ•ใ‚Œใ‚‹ใ“ใจใฏใ‚ใ‚Šใพใ›ใ‚“**ใ€‚ใใฎใŸใ‚ใ€ใใฎใƒ•ใ‚กใ‚คใƒซใ ใ‘ใ‚’ใ‚ณใƒ”ใƒผใ™ใ‚‹ใ“ใจใงใ€Dockerใฏใใฎใ‚นใƒ†ใƒƒใƒ—ใงใฏ**ใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +ใใ—ใฆใ€Dockerใฏ**ๆฌกใฎใ‚นใƒ†ใƒƒใƒ—ใฎใŸใ‚ใซใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใ‚’ไฝฟ็”จใ—ใ€ใใ‚Œใ‚‰ใฎไพๅญ˜้–ขไฟ‚ใ‚’ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใฆใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ใใ—ใฆใ€ใ“ใ“ใง**ๅคšใใฎๆ™‚้–“ใ‚’็ฏ€็ด„**ใ—ใพใ™ใ€‚โœจ ...ใใ—ใฆ้€€ๅฑˆใชๅพ…ใกๆ™‚้–“ใ‚’้ฟใ‘ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚๐Ÿ˜ช๐Ÿ˜† + +ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใฎไพๅญ˜้–ขไฟ‚ใ‚’ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใฆใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ใซใฏ**ๆ•ฐๅˆ†**ใ‹ใ‹ใ‚Šใพใ™ใŒใ€**ใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ใ‚’ไฝฟใˆใฐ**ใ›ใ„ใœใ„ๆ•ฐ็ง’**ใงใ™ใ€‚ -* ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช (`app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ๅซใ‚“ใ ใ€`Dockerfile` ใฎใ‚ใ‚‹ๅ ดๆ‰€) ใธ็งปๅ‹• -* FastAPIใ‚คใƒกใƒผใ‚ธใฎใƒ“ใƒซใƒ‰: +ๅŠ ใˆใฆใ€้–‹็™บไธญใซใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใ‚’ไฝ•ๅบฆใ‚‚ใƒ“ใƒซใƒ‰ใ—ใฆใ€ใ‚ณใƒผใƒ‰ใฎๅค‰ๆ›ดใŒๆฉŸ่ƒฝใ—ใฆใ„ใ‚‹ใ‹ใฉใ†ใ‹ใ‚’ใƒใ‚งใƒƒใ‚ฏใ™ใ‚‹ใ“ใจใซใชใ‚‹ใŸใ‚ใ€ๅคšใใฎๆ™‚้–“ใ‚’็ฏ€็ด„ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +ใใ—ใฆ`Dockerfile`ใฎๆœ€็ต‚่กŒใฎ่ฟ‘ใใงใ™ในใฆใฎใ‚ณใƒผใƒ‰ใ‚’ใ‚ณใƒ”ใƒผใ—ใพใ™ใ€‚ใ“ใฎ็†็”ฑใฏใ€**ๆœ€ใ‚‚้ ป็นใซ**ๅค‰ๆ›ดใ•ใ‚Œใ‚‹ใ‚‚ใฎใชใฎใงใ€ใ“ใฎใ‚นใƒ†ใƒƒใƒ—ใฎๅพŒใซใ‚ใ‚‹ใ‚‚ใฎใฏใปใจใ‚“ใฉใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใŒใงใใชใ„ใฎใŸใ‚ใงใ™ใ€‚ + +```Dockerfile +COPY ./app /code/app +``` + +### Dockerใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹ + +ใ™ในใฆใฎใƒ•ใ‚กใ‚คใƒซใŒๆƒใฃใŸใฎใงใ€ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ—ใพใ—ใ‚‡ใ†ใ€‚ + +* ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซ็งปๅ‹•ใ—ใพใ™๏ผˆ`Dockerfile`ใŒใ‚ใ‚‹ๅ ดๆ‰€ใงใ€`app`ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใŒใ‚ใ‚Šใพใ™๏ผ‰ +* FastAPI ใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ—ใพใ™๏ผš
@@ -106,9 +305,14 @@ $ docker build -t myimage .
-## Dockerใ‚ณใƒณใƒ†ใƒŠใ‚’่ตทๅ‹• +!!! tip + ๆœซๅฐพใฎ `.` ใซๆณจ็›ฎใ—ใฆใปใ—ใ„ใงใ™ใ€‚ใ“ใ‚Œใฏ `./` ใจๅŒใ˜ๆ„ๅ‘ณใงใ™ใ€‚ ใ“ใ‚ŒใฏDockerใซใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใฎใƒ“ใƒซใƒ‰ใซไฝฟ็”จใ™ใ‚‹ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ๆŒ‡็คบใ—ใพใ™ใ€‚ + + ใ“ใฎๅ ดๅˆใ€ๅŒใ˜ใ‚ซใƒฌใƒณใƒˆใƒปใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช(`.`)ใงใ™ใ€‚ -* ็”จๆ„ใ—ใŸใ‚คใƒกใƒผใ‚ธใ‚’ๅŸบใซใ—ใŸใ‚ณใƒณใƒ†ใƒŠใฎ่ตทๅ‹•: +### Dockerใ‚ณใƒณใƒ†ใƒŠใฎ่ตทๅ‹•ใ™ใ‚‹ + +* ใ‚คใƒกใƒผใ‚ธใซๅŸบใฅใ„ใฆใ‚ณใƒณใƒ†ใƒŠใ‚’ๅฎŸ่กŒใ—ใพใ™๏ผš
@@ -118,62 +322,394 @@ $ docker run -d --name mycontainer -p 80:80 myimage
-ใ“ใ‚Œใงใ€Dockerใ‚ณใƒณใƒ†ใƒŠๅ†…ใซๆœ€้ฉๅŒ–ใ•ใ‚ŒใŸFastAPIใ‚ตใƒผใƒใŒๅ‹•ไฝœใ—ใฆใ„ใพใ™ใ€‚ไฝฟ็”จใ—ใฆใ„ใ‚‹ใ‚ตใƒผใƒ (ใใ—ใฆCPUใ‚ณใ‚ขๆ•ฐ) ใซๆฒฟใฃใŸ่‡ชๅ‹•ใƒใƒฅใƒผใƒ‹ใƒณใ‚ฐใŒ่กŒใ‚ใ‚Œใฆใ„ใพใ™ใ€‚ - -## ็ขบ่ช +## ็ขบ่ชใ™ใ‚‹ -Dockerใ‚ณใƒณใƒ†ใƒŠใฎURLใง็ขบ่ชใงใใ‚‹ใฏใšใงใ™ใ€‚ไพ‹ใˆใฐ: http://192.168.99.100/items/5?q=somequery ใ‚„ http://127.0.0.1/items/5?q=somequery (ใ‚‚ใ—ใใฏDockerใƒ›ใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใŸใ“ใ‚Œใ‚‰ใจๅŒ็ญ‰ใฎใ‚‚ใฎ)ใ€‚ +Dockerใ‚ณใƒณใƒ†ใƒŠใฎhttp://192.168.99.100/items/5?q=somequery ใ‚„ http://127.0.0.1/items/5?q=somequery (ใพใŸใฏใใ‚Œใซ็›ธๅฝ“ใ™ใ‚‹Dockerใƒ›ใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใŸใ‚‚ใฎ๏ผ‰ใจใ„ใฃใŸURLใง็ขบ่ชใงใใ‚‹ใฏใšใงใ™ใ€‚ -ไปฅไธ‹ใฎๆง˜ใชใ‚‚ใฎใŒ่ฟ”ใ•ใ‚Œใพใ™: +ใ‚ขใ‚ฏใ‚ปใ‚นใ™ใ‚‹ใจไปฅไธ‹ใฎใ‚ˆใ†ใชใ‚‚ใฎใŒ่กจ็คบใ•ใ‚Œใพใ™๏ผš ```JSON {"item_id": 5, "q": "somequery"} ``` -## ๅฏพ่ฉฑ็š„APIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ +## ใ‚คใƒณใ‚ฟใƒฉใ‚ฏใƒ†ใ‚ฃใƒ–ใชAPIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ -ใ“ใ“ใงใ€http://192.168.99.100/docs ใ‚„ http://127.0.0.1/docs (ใ‚‚ใ—ใใฏDockerใƒ›ใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใŸใ“ใ‚Œใ‚‰ใจๅŒ็ญ‰ใฎใ‚‚ใฎ) ใ‚’้–‹ใ„ใฆไธ‹ใ•ใ„ใ€‚ +ใ“ใ‚Œใ‚‰ใฎURLใซใ‚‚ใ‚ขใ‚ฏใ‚ปใ‚นใงใใพใ™: http://192.168.99.100/docs ใ‚„ http://127.0.0.1/docs (ใพใŸใฏใใ‚Œใซ็›ธๅฝ“ใ™ใ‚‹Dockerใƒ›ใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใŸใ‚‚ใฎ๏ผ‰ -่‡ชๅ‹•็”Ÿๆˆใ•ใ‚ŒใŸๅฏพ่ฉฑ็š„APIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใŒ็ขบ่ชใงใใพใ™ (Swagger UIใซใ‚ˆใฃใฆๆไพ›ใ•ใ‚Œใพใ™): +ใ‚ขใ‚ฏใ‚ปใ‚นใ™ใ‚‹ใจใ€่‡ชๅ‹•ๅฏพ่ฉฑๅž‹APIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ๏ผˆSwagger UIใŒๆไพ›๏ผ‰ใŒ่กจ็คบใ•ใ‚Œใพใ™๏ผš ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) -## ใใฎไป–ใฎAPIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ +## ไปฃๆ›ฟใฎAPIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ -ใพใŸๅŒๆง˜ใซใ€http://192.168.99.100/redoc ใ‚„ http://127.0.0.1/redoc (ใ‚‚ใ—ใใฏDockerใƒ›ใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใŸใ“ใ‚Œใ‚‰ใจๅŒ็ญ‰ใฎใ‚‚ใฎ) ใ‚’้–‹ใ„ใฆไธ‹ใ•ใ„ใ€‚ +ใพใŸใ€http://192.168.99.100/redoc ใ‚„ http://127.0.0.1/redoc (ใพใŸใฏใใ‚Œใซ็›ธๅฝ“ใ™ใ‚‹Dockerใƒ›ใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใŸใ‚‚ใฎ๏ผ‰ใซใ‚‚ใ‚ขใ‚ฏใ‚ปใ‚นใงใใพใ™ใ€‚ -ไป–ใฎ่‡ชๅ‹•็”Ÿๆˆใ•ใ‚ŒใŸๅฏพ่ฉฑ็š„ใชAPIใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใŒ็ขบ่ชใงใใพใ™ (ReDocใซใ‚ˆใฃใฆๆไพ›ใ•ใ‚Œใพใ™): +ไปฃๆ›ฟใฎ่‡ชๅ‹•ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ๏ผˆReDocใซใ‚ˆใฃใฆๆไพ›ใ•ใ‚Œใ‚‹๏ผ‰ใŒ่กจ็คบใ•ใ‚Œใพใ™๏ผš ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) -## Traefik +## ๅ˜ไธ€ใƒ•ใ‚กใ‚คใƒซใฎFastAPIใงDockerใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹ + +FastAPI ใŒๅ˜ไธ€ใฎใƒ•ใ‚กใ‚คใƒซใ€ไพ‹ใˆใฐ `./app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใฎใชใ„ `main.py` ใฎๅ ดๅˆใ€ใƒ•ใ‚กใ‚คใƒซๆง‹้€ ใฏๆฌกใฎใ‚ˆใ†ใซใชใ‚Šใพใ™๏ผš +``` +. +โ”œโ”€โ”€ Dockerfile +โ”œโ”€โ”€ main.py +โ””โ”€โ”€ requirements.txt +``` + +ใใ†ใ™ใ‚Œใฐใ€`Dockerfile`ใฎไธญใซใƒ•ใ‚กใ‚คใƒซใ‚’ใ‚ณใƒ”ใƒผใ™ใ‚‹ใŸใ‚ใซใ€ๅฏพๅฟœใ™ใ‚‹ใƒ‘ใ‚นใ‚’ๅค‰ๆ›ดใ™ใ‚‹ใ ใ‘ใงใ‚ˆใ„ใงใ™๏ผš + +```{ .dockerfile .annotate hl_lines="10 13" } +FROM python:3.9 + +WORKDIR /code + +COPY ./requirements.txt /code/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +# (1) +COPY ./main.py /code/ + +# (2) +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] +``` + +1. main.py`ใƒ•ใ‚กใ‚คใƒซใ‚’ `/code` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซ็›ดๆŽฅใ‚ณใƒ”ใƒผใ—ใพใ™ใ€‚ + +2. Uvicornใ‚’ๅฎŸ่กŒใ—ใ€`main`ใ‹ใ‚‰`app`ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ใ‚คใƒณใƒใƒผใƒˆใ™ใ‚‹ใ‚ˆใ†ใซๆŒ‡็คบใ—ใพใ™๏ผˆ`app.main`ใ‹ใ‚‰ใ‚คใƒณใƒใƒผใƒˆใ™ใ‚‹ใฎใงใฏใชใ๏ผ‰ใ€‚ + +ๆฌกใซUvicornใ‚ณใƒžใƒณใƒ‰ใ‚’่ชฟๆ•ดใ—ใฆใ€`app.main` ใฎไปฃใ‚ใ‚Šใซๆ–ฐใ—ใ„ใƒขใ‚ธใƒฅใƒผใƒซ `main` ใ‚’ไฝฟ็”จใ—ใ€FastAPIใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใงใ‚ใ‚‹ `app` ใ‚’ใ‚คใƒณใƒใƒผใƒˆใ—ใพใ™ใ€‚ + +## ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ + +ใ‚ณใƒณใƒ†ใƒŠใจใ„ใ†่ฆณ็‚นใ‹ใ‚‰ใ€[ใƒ‡ใƒ—ใƒญใ‚คใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ](./concepts.md){.internal-link target=_blank}ใซๅ…ฑ้€šใ™ใ‚‹ใ„ใใคใ‹ใซใคใ„ใฆใ€ใ‚‚ใ†ไธ€ๅบฆ่ชฌๆ˜Žใ—ใพใ—ใ‚‡ใ†ใ€‚ + +ใ‚ณใƒณใƒ†ใƒŠใฏไธปใซใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎ**ใƒ“ใƒซใƒ‰ใจใƒ‡ใƒ—ใƒญใ‚ค**ใฎใƒ—ใƒญใ‚ปใ‚นใ‚’็ฐก็ด ๅŒ–ใ™ใ‚‹ใŸใ‚ใฎใƒ„ใƒผใƒซใงใ™ใŒใ€ใ“ใ‚Œใ‚‰ใฎ**ใƒ‡ใƒ—ใƒญใ‚คใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ**ใ‚’ๆ‰ฑใ†ใŸใ‚ใฎ็‰นๅฎšใฎใ‚ขใƒ—ใƒญใƒผใƒใ‚’ๅผทๅˆถใ™ใ‚‹ใ‚‚ใฎใงใฏใชใ„ใงใ™ใ€‚ -Traefikใฏใ€้ซ˜ๆ€ง่ƒฝใชใƒชใƒใƒผใ‚นใƒ—ใƒญใ‚ญใ‚ท/ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผใงใ™ใ€‚ใ€ŒTLSใ‚ฟใƒผใƒŸใƒใƒผใ‚ทใƒงใƒณใƒ—ใƒญใ‚ญใ‚ทใ€ใ‚ธใƒงใƒ–ใ‚’ๅฎŸ่กŒใงใใพใ™๏ผˆไป–ใฎๆฉŸ่ƒฝใจๅˆ‡ใ‚Š้›ขใ—ใฆ๏ผ‰ใ€‚ +**่‰ฏใ„ใƒ‹ใƒฅใƒผใ‚น**ใฏใ€ใใ‚Œใžใ‚Œใฎ็•ฐใชใ‚‹ๆˆฆ็•ฅใซใฏใ€ใ™ในใฆใฎใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆใ‚’ใ‚ซใƒใƒผใ™ใ‚‹ๆ–นๆณ•ใŒใ‚ใ‚‹ใจใ„ใ†ใ“ใจใงใ™ใ€‚๐ŸŽ‰ -Let's Encryptใจ็ตฑๅˆใ•ใ‚Œใฆใ„ใพใ™ใ€‚ใใฎใŸใ‚ใ€่จผๆ˜Žๆ›ธใฎๅ–ๅพ—ใจๆ›ดๆ–ฐใ‚’ๅซใ‚€HTTPSใซ้–ขใ™ใ‚‹ใ™ในใฆใฎๅ‡ฆ็†ใ‚’ๅฎŸ่กŒใงใใพใ™ใ€‚ +ใ“ใ‚Œใ‚‰ใฎ**ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ**ใ‚’ใ‚ณใƒณใƒ†ใƒŠใฎ่ฆณ็‚นใ‹ใ‚‰่ฆ‹็›ดใ—ใฆใฟใพใ—ใ‚‡ใ†๏ผš -ใพใŸใ€Dockerใจใ‚‚็ตฑๅˆใ•ใ‚Œใฆใ„ใพใ™ใ€‚ใ—ใŸใŒใฃใฆใ€ๅ„ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณๆง‹ๆˆใงใƒ‰ใƒกใ‚คใƒณใ‚’ๅฎฃ่จ€ใ—ใ€ใใ‚Œใ‚‰ใฎๆง‹ๆˆใ‚’่ชญใฟๅ–ใฃใฆใ€HTTPS่จผๆ˜Žๆ›ธใ‚’็”Ÿๆˆใ—ใ€ๆง‹ๆˆใซๅค‰ๆ›ดใ‚’ๅŠ ใˆใ‚‹ใ“ใจใชใใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใซHTTPSใ‚’่‡ชๅ‹•็š„ใซๆไพ›ใงใใพใ™ใ€‚ +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* **ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰** +* ใƒกใƒขใƒช +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ— + +## HTTPS + +FastAPI ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎ **ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธ**๏ผˆใŠใ‚ˆใณๅพŒใงๅฎŸ่กŒไธญใฎ **ใ‚ณใƒณใƒ†ใƒŠ**๏ผ‰ใ ใ‘ใซ็„ฆ็‚นใ‚’ๅฝ“ใฆใ‚‹ใจใ€้€šๅธธใ€HTTPSใฏๅˆฅใฎใƒ„ใƒผใƒซใ‚’็”จใ„ใฆ**ๅค–้ƒจใง**ๅ‡ฆ็†ใ•ใ‚Œใพใ™ใ€‚ + +ไพ‹ใˆใฐTraefikใฎใ‚ˆใ†ใซใ€**HTTPS**ใจ**่จผๆ˜Žๆ›ธ**ใฎ**่‡ชๅ‹•**ๅ–ๅพ—ใ‚’ๆ‰ฑใ†ๅˆฅใฎใ‚ณใƒณใƒ†ใƒŠใงใ‚ใ‚‹ๅฏ่ƒฝๆ€งใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ + +!!! tip + TraefikใฏDockerใ‚„Kubernetesใชใฉใจ็ตฑๅˆใ•ใ‚Œใฆใ„ใ‚‹ใฎใงใ€ใ‚ณใƒณใƒ†ใƒŠ็”จใฎHTTPSใฎ่จญๅฎšใ‚„ๆง‹ๆˆใฏใจใฆใ‚‚็ฐกๅ˜ใงใ™ใ€‚ + +ใ‚ใ‚‹ใ„ใฏใ€๏ผˆใ‚ณใƒณใƒ†ใƒŠๅ†…ใงใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅฎŸ่กŒใ—ใชใŒใ‚‰๏ผ‰ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใƒ—ใƒญใƒใ‚คใƒ€ใƒผใŒใ‚ตใƒผใƒ“ใ‚นใฎ1ใคใจใ—ใฆHTTPSใ‚’ๅ‡ฆ็†ใ™ใ‚‹ใ“ใจใ‚‚ใงใใพใ™ใ€‚ + +## ่ตทๅ‹•ๆ™‚ใŠใ‚ˆใณๅ†่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ + +้€šๅธธใ€ใ‚ณใƒณใƒ†ใƒŠใฎ**่ตทๅ‹•ใจๅฎŸ่กŒ**ใ‚’ๆ‹…ๅฝ“ใ™ใ‚‹ๅˆฅใฎใƒ„ใƒผใƒซใŒใ‚ใ‚Šใพใ™ใ€‚ + +ใใ‚Œใฏ็›ดๆŽฅ**Docker**ใงใ‚ใฃใŸใ‚Šใ€**Docker Compose**ใงใ‚ใฃใŸใ‚Šใ€**Kubernetes**ใงใ‚ใฃใŸใ‚Šใ€**ใ‚ฏใƒฉใ‚ฆใƒ‰ใ‚ตใƒผใƒ“ใ‚น**ใงใ‚ใฃใŸใ‚Šใ—ใพใ™ใ€‚ + +ใปใจใ‚“ใฉใฎๅ ดๅˆ๏ผˆใพใŸใฏใ™ในใฆใฎๅ ดๅˆ๏ผ‰ใ€่ตทๅ‹•ๆ™‚ใซใ‚ณใƒณใƒ†ใƒŠใ‚’ๅฎŸ่กŒใ—ใ€ๅคฑๆ•—ๆ™‚ใซๅ†่ตทๅ‹•ใ‚’ๆœ‰ๅŠนใซใ™ใ‚‹็ฐกๅ˜ใชใ‚ชใƒ—ใ‚ทใƒงใƒณใŒใ‚ใ‚Šใพใ™ใ€‚ไพ‹ใˆใฐDockerใงใฏใ€ใ‚ณใƒžใƒณใƒ‰ใƒฉใ‚คใƒณใ‚ชใƒ—ใ‚ทใƒงใƒณใฎ`--restart`ใŒ่ฉฒๅฝ“ใ—ใพใ™ใ€‚ + +ใ‚ณใƒณใƒ†ใƒŠใ‚’ไฝฟใ‚ใชใ‘ใ‚Œใฐใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’่ตทๅ‹•ๆ™‚ใ‚„ๅ†่ตทๅ‹•ๆ™‚ใซๅฎŸ่กŒใ•ใ›ใ‚‹ใฎใฏ้ขๅ€’ใง้›ฃใ—ใ„ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€**ใ‚ณใƒณใƒ†ใƒŠ**ใงไฝœๆฅญใ™ใ‚‹ๅ ดๅˆใ€ใปใจใ‚“ใฉใฎใ‚ฑใƒผใ‚นใงใใฎๆฉŸ่ƒฝใฏใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใงๅซใพใ‚Œใฆใ„ใพใ™ใ€‚โœจ + +## ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ - ใƒ—ใƒญใ‚ปใ‚นๆ•ฐ + +**Kubernetes** ใ‚„ Docker Swarm ใƒขใƒผใƒ‰ใ€Nomadใ€ใ‚ใ‚‹ใ„ใฏ่ค‡ๆ•ฐใฎใƒžใ‚ทใƒณไธŠใงๅˆ†ๆ•ฃใ‚ณใƒณใƒ†ใƒŠใ‚’็ฎก็†ใ™ใ‚‹ใŸใ‚ใฎๅŒๆง˜ใฎ่ค‡้›‘ใชใ‚ทใ‚นใƒ†ใƒ ใ‚’ไฝฟใฃใฆใƒžใ‚ทใƒณใฎใ‚ฏใƒฉใ‚นใ‚ฟใƒผใ‚’ๆง‹ๆˆใ—ใฆใ„ใ‚‹ๅ ดๅˆใ€ ๅ„ใ‚ณใƒณใƒ†ใƒŠใง๏ผˆWorkerใ‚’ๆŒใคGunicornใฎใ‚ˆใ†ใช๏ผ‰**ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃ**ใ‚’ไฝฟ็”จใ™ใ‚‹ไปฃใ‚ใ‚Šใซใ€**ใ‚ฏใƒฉใ‚นใ‚ฟใƒผใƒปใƒฌใƒ™ใƒซ**ใง**ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ**ใ‚’ๅ‡ฆ็†ใ—ใŸใ„ใจๆ€ใ†ใงใ—ใ‚‡ใ†ใ€‚ + +Kubernetesใฎใ‚ˆใ†ใชๅˆ†ๆ•ฃใ‚ณใƒณใƒ†ใƒŠ็ฎก็†ใ‚ทใ‚นใƒ†ใƒ ใฎ1ใคใฏ้€šๅธธใ€ๅ…ฅใฃใฆใใ‚‹ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎ**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ทใƒณใ‚ฐ**ใ‚’ใ‚ตใƒใƒผใƒˆใ—ใชใŒใ‚‰ใ€**ใ‚ณใƒณใƒ†ใƒŠใฎใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ**ใ‚’ๅ‡ฆ็†ใ™ใ‚‹็ตฑๅˆใ•ใ‚ŒใŸๆ–นๆณ•ใ‚’ๆŒใฃใฆใ„ใพใ™ใ€‚ใ“ใฎใ“ใจใฏใ™ในใฆ**ใ‚ฏใƒฉใ‚นใ‚ฟใƒฌใƒ™ใƒซ**ใซใฆใงใ™ใ€‚ + +ใใฎใ‚ˆใ†ใชๅ ดๅˆใ€Uvicornใƒฏใƒผใ‚ซใƒผใงGunicornใฎใ‚ˆใ†ใชใ‚‚ใฎใ‚’ๅฎŸ่กŒใ™ใ‚‹ใฎใงใฏใชใใ€[ไธŠ่จ˜ใฎ่ชฌๆ˜Ž](#dockerfile)ใฎใ‚ˆใ†ใซ**Dockerใ‚คใƒกใƒผใ‚ธใ‚’ใ‚ผใƒญใ‹ใ‚‰**ใƒ“ใƒซใƒ‰ใ—ใ€ไพๅญ˜้–ขไฟ‚ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใฆใ€**ๅ˜ไธ€ใฎUvicornใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ—ใŸใ„ใงใ—ใ‚‡ใ†ใ€‚ + +### ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ + +ใ‚ณใƒณใƒ†ใƒŠใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใ€้€šๅธธใฏใƒกใ‚คใƒณใƒปใƒใƒผใƒˆ**ใงใƒชใ‚นใƒ‹ใƒณใ‚ฐ**ใ—ใฆใ„ใ‚‹ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒใ‚ใ‚‹ใฏใšใงใ™ใ€‚ใใ‚ŒใฏใŠใใ‚‰ใใ€**HTTPS**ใ‚’ๅ‡ฆ็†ใ™ใ‚‹ใŸใ‚ใฎ**TLS Termination Proxy**ใงใ‚‚ใ‚ใ‚‹ๅˆฅใฎใ‚ณใƒณใƒ†ใƒŠใงใ‚ใฃใŸใ‚Šใ€ๅŒๆง˜ใฎใƒ„ใƒผใƒซใงใ‚ใฃใŸใ‚Šใ™ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ใ“ใฎใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฏใƒชใ‚ฏใ‚จใ‚นใƒˆใฎ **่ฒ ่ท** ใ‚’ๅ—ใ‘ใ€ (ใ†ใพใใ„ใ‘ใฐ) ใใฎ่ฒ ่ทใ‚’**ใƒใƒฉใƒณใ‚นใ‚ˆใ** ใƒฏใƒผใ‚ซใƒผใซๅˆ†้…ใ™ใ‚‹ใฎใงใ€ไธ€่ˆฌใซ **ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ต** ใจใ‚‚ๅ‘ผใฐใ‚Œใพใ™ใ€‚ + +!!! tip +ใ€€ใ€€HTTPSใซไฝฟใ‚ใ‚Œใ‚‹ใ‚‚ใฎใจๅŒใ˜**TLS Termination Proxy**ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฏใ€ใŠใใ‚‰ใ**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ**ใซใ‚‚ใชใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ใใ—ใฆใ‚ณใƒณใƒ†ใƒŠใงไฝœๆฅญใ™ใ‚‹ๅ ดๅˆใ€ใ‚ณใƒณใƒ†ใƒŠใฎ่ตทๅ‹•ใจ็ฎก็†ใซไฝฟ็”จใ™ใ‚‹ๅŒใ˜ใ‚ทใ‚นใƒ†ใƒ ใซใฏใ€**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ**๏ผˆ**TLS Termination Proxy**ใฎๅฏ่ƒฝๆ€งใ‚‚ใ‚ใ‚‹๏ผ‰ใ‹ใ‚‰**ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏ้€šไฟก**๏ผˆHTTPใƒชใ‚ฏใ‚จใ‚นใƒˆใชใฉ๏ผ‰ใ‚’ใ‚ขใƒ—ใƒชใฎใ‚ใ‚‹ใ‚ณใƒณใƒ†ใƒŠ๏ผˆ่ค‡ๆ•ฐๅฏ๏ผ‰ใซ้€ไฟกใ™ใ‚‹ใŸใ‚ใฎๅ†…้ƒจใƒ„ใƒผใƒซใŒๆ—ขใซใ‚ใ‚‹ใฏใšใงใ™ใ€‚ + +### 1ใคใฎใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ - ่ค‡ๆ•ฐใฎใƒฏใƒผใ‚ซใƒผใ‚ณใƒณใƒ†ใƒŠใƒผ + +**Kubernetes**ใ‚„ๅŒๆง˜ใฎๅˆ†ๆ•ฃใ‚ณใƒณใƒ†ใƒŠ็ฎก็†ใ‚ทใ‚นใƒ†ใƒ ใงไฝœๆฅญใ™ใ‚‹ๅ ดๅˆใ€ใใฎๅ†…้ƒจใฎใƒใƒƒใƒˆใƒฏใƒผใ‚ญใƒณใ‚ฐใฎใƒกใ‚ซใƒ‹ใ‚บใƒ ใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใงใ€ใƒกใ‚คใƒณใฎ**ใƒใƒผใƒˆ**ใงใƒชใƒƒใ‚นใƒณใ—ใฆใ„ใ‚‹ๅ˜ไธ€ใฎ**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ**ใŒใ€ใ‚ขใƒ—ใƒชใ‚’ๅฎŸ่กŒใ—ใฆใ„ใ‚‹ๅฏ่ƒฝๆ€งใฎใ‚ใ‚‹**่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠ**ใซ้€šไฟก๏ผˆใƒชใ‚ฏใ‚จใ‚นใƒˆ๏ผ‰ใ‚’้€ไฟกใงใใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚ + +ใ‚ขใƒ—ใƒชใ‚’ๅฎŸ่กŒใ™ใ‚‹ใ“ใ‚Œใ‚‰ใฎใ‚ณใƒณใƒ†ใƒŠใซใฏใ€้€šๅธธ**1ใคใฎใƒ—ใƒญใ‚ปใ‚น**๏ผˆใŸใจใˆใฐใ€FastAPIใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅฎŸ่กŒใ™ใ‚‹Uvicornใƒ—ใƒญใ‚ปใ‚น๏ผ‰ใŒใ‚ใ‚Šใพใ™ใ€‚ใ“ใ‚Œใ‚‰ใฏใ™ในใฆ**ๅŒไธ€ใฎใ‚ณใƒณใƒ†ใƒŠ**ใงใ‚ใ‚ŠๅŒใ˜ใ‚‚ใฎใ‚’ๅฎŸ่กŒใ—ใพใ™ใŒใ€ใใ‚Œใžใ‚ŒใŒ็‹ฌ่‡ชใฎใƒ—ใƒญใ‚ปใ‚นใ‚„ใƒกใƒขใƒชใชใฉใ‚’ๆŒใกใพใ™ใ€‚ใใ†ใ™ใ‚‹ใ“ใจใงใ€CPUใฎ**็•ฐใชใ‚‹ใ‚ณใ‚ข**ใ€ใ‚ใ‚‹ใ„ใฏ**็•ฐใชใ‚‹ใƒžใ‚ทใƒณ**ใงใฎ**ไธฆๅˆ—ๅŒ–**ใ‚’ๅˆฉ็”จใงใใพใ™ใ€‚ + +ใใ—ใฆใ€**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ**ใ‚’ๅ‚™ใˆใŸๅˆ†ๆ•ฃใ‚ณใƒณใƒ†ใƒŠใ‚ทใ‚นใƒ†ใƒ ใฏใ€**้ †็•ชใซ**ใ‚ใชใŸใฎใ‚ขใƒ—ใƒชใ‚’ๅซใ‚€ๅ„ใ‚ณใƒณใƒ†ใƒŠใซ**ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅˆ†้…**ใ—ใพใ™ใ€‚ใคใพใ‚Šใ€ๅ„ใƒชใ‚ฏใ‚จใ‚นใƒˆใฏใ€ใ‚ใชใŸใฎใ‚ขใƒ—ใƒชใ‚’ๅฎŸ่กŒใ—ใฆใ„ใ‚‹่ค‡ๆ•ฐใฎ**ใƒฌใƒ—ใƒชใ‚ฑใƒผใƒˆใ•ใ‚ŒใŸใ‚ณใƒณใƒ†ใƒŠ**ใฎ1ใคใซใ‚ˆใฃใฆๅ‡ฆ็†ใ•ใ‚Œใพใ™ใ€‚ + +ใใ—ใฆ้€šๅธธใ€ใ“ใฎ**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ**ใฏใ€ใ‚ฏใƒฉใ‚นใ‚ฟๅ†…ใฎ*ไป–ใฎ*ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆไพ‹ใˆใฐใ€็•ฐใชใ‚‹ใƒ‰ใƒกใ‚คใƒณใ‚„็•ฐใชใ‚‹URLใƒ‘ใ‚นใฎใƒ—ใƒฌใƒ•ใ‚ฃใƒƒใ‚ฏใ‚นใฎ้…ไธ‹๏ผ‰ใธใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅ‡ฆ็†ใ™ใ‚‹ใ“ใจใŒใงใใ€ใใฎ้€šไฟกใ‚’ใ‚ฏใƒฉใ‚นใ‚ฟๅ†…ใงๅฎŸ่กŒใ•ใ‚Œใฆใ„ใ‚‹*ไป–ใฎ*ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎใŸใ‚ใฎ้ฉๅˆ‡ใชใ‚ณใƒณใƒ†ใƒŠใซ้€ไฟกใ—ใพใ™ใ€‚ + +### 1ใ‚ณใƒณใƒ†ใƒŠใซใคใ1ใƒ—ใƒญใ‚ปใ‚น + +ใ“ใฎ็จฎใฎใ‚ทใƒŠใƒชใ‚ชใงใฏใ€ใ™ใงใซใ‚ฏใƒฉใ‚นใ‚ฟใƒปใƒฌใƒ™ใƒซใงใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๅ‡ฆ็†ใ—ใฆใ„ใ‚‹ใŸใ‚ใ€ใŠใใ‚‰ใใ‚ณใƒณใƒ†ใƒŠใ”ใจใซ**ๅ˜ไธ€ใฎ๏ผˆUvicorn๏ผ‰ใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใกใŸใ„ใงใ—ใ‚‡ใ†ใ€‚ + +ใ“ใฎๅ ดๅˆใ€Uvicornใƒฏใƒผใ‚ซใƒผใ‚’ๆŒใคGunicornใฎใ‚ˆใ†ใชใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผใ‚„ใ€Uvicornใƒฏใƒผใ‚ซใƒผใ‚’ไฝฟใ†Uvicornใฏ**้ฟใ‘ใŸใ„**ใงใ—ใ‚‡ใ†ใ€‚**ใ‚ณใƒณใƒ†ใƒŠใ”ใจใซUvicornใฎใƒ—ใƒญใ‚ปใ‚นใฏ1ใคใ ใ‘**ใซใ—ใŸใ„ใงใ—ใ‚‡ใ†๏ผˆใŠใใ‚‰ใ่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠใŒๅฟ…่ฆใงใ—ใ‚‡ใ†๏ผ‰ใ€‚ + +๏ผˆGunicornใ‚„UvicornใŒUvicornใƒฏใƒผใ‚ซใƒผใ‚’็ฎก็†ใ™ใ‚‹ใ‚ˆใ†ใซ๏ผ‰ใ‚ณใƒณใƒ†ใƒŠๅ†…ใซๅˆฅใฎใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผใ‚’ๆŒใคใ“ใจใฏใ€ใ‚ฏใƒฉใ‚นใ‚ฟใƒผใ‚ทใ‚นใƒ†ใƒ ใงใ™ใงใซๅฏพๅ‡ฆใ—ใฆใ„ใ‚‹ใงใ‚ใ‚ใ†**ไธ่ฆใช่ค‡้›‘ใ•**ใ‚’่ฟฝๅŠ ใ™ใ‚‹ใ ใ‘ใงใ™ใ€‚ + +### Containers with Multiple Processes and Special Cases + +ใ‚‚ใกใ‚ใ‚“ใ€**็‰นๆฎŠใชใ‚ฑใƒผใ‚น**ใจใ—ใฆใ€**Gunicornใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃ**ใ‚’ๆŒใค**ใ‚ณใƒณใƒ†ใƒŠ**ๅ†…ใง่ค‡ๆ•ฐใฎ**Uvicornใƒฏใƒผใ‚ซใƒผใƒ—ใƒญใ‚ปใ‚น**ใ‚’่ตทๅ‹•ใ•ใ›ใŸใ„ๅ ดๅˆใŒใ‚ใ‚Šใพใ™ใ€‚ + +ใ“ใฎใ‚ˆใ†ใชๅ ดๅˆใ€**ๅ…ฌๅผใฎDockerใ‚คใƒกใƒผใ‚ธ**ใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ใ“ใฎใ‚คใƒกใƒผใ‚ธใซใฏใ€่ค‡ๆ•ฐใฎ**Uvicornใƒฏใƒผใ‚ซใƒผใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ™ใ‚‹ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใจใ—ใฆ**Gunicorn**ใŒๅซใพใ‚ŒใฆใŠใ‚Šใ€็พๅœจใฎCPUใ‚ณใ‚ขใซๅŸบใฅใ„ใฆใƒฏใƒผใ‚ซใƒผใฎๆ•ฐใ‚’่‡ชๅ‹•็š„ใซ่ชฟๆ•ดใ™ใ‚‹ใŸใ‚ใฎใƒ‡ใƒ•ใ‚ฉใƒซใƒˆ่จญๅฎšใŒใ„ใใคใ‹ๅซใพใ‚Œใฆใ„ใพใ™ใ€‚่ฉณใ—ใใฏๅพŒ่ฟฐใฎ[Gunicornใซใ‚ˆใ‚‹ๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธ - Uvicorn](#gunicornใซใ‚ˆใ‚‹ๅ…ฌๅผdockerใ‚คใƒกใƒผใ‚ธ---Uvicorn)ใง่ชฌๆ˜Žใ—ใพใ™ใ€‚ + +ไปฅไธ‹ใฏใ€ใใ‚ŒใŒ็†ใซใ‹ใชใฃใฆใ„ใ‚‹ๅ ดๅˆใฎไพ‹ใงใ™๏ผš + +#### ใ‚ทใƒณใƒ—ใƒซใชใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ + +ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’**ใ‚ทใƒณใƒ—ใƒซ**ใชๅฝขใงๅฎŸ่กŒใ™ใ‚‹ๅ ดๅˆใ€ใƒ—ใƒญใ‚ปใ‚นๆ•ฐใฎ็ดฐใ‹ใ„่ชฟๆ•ดใŒๅฟ…่ฆใชใ„ๅ ดๅˆใ€่‡ชๅ‹•ๅŒ–ใ•ใ‚ŒใŸใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใ‚’ไฝฟ็”จใ™ใ‚‹ใ ใ‘ใงใ€ใ‚ณใƒณใƒ†ใƒŠๅ†…ใซใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใŒๅฟ…่ฆใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ไพ‹ใˆใฐใ€ๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธใงใ‚ทใƒณใƒ—ใƒซใช่จญๅฎšใŒๅฏ่ƒฝใงใ™ใ€‚ + +#### Docker Compose + +Docker Composeใง**ใ‚ทใƒณใ‚ฐใƒซใ‚ตใƒผใƒ**๏ผˆใ‚ฏใƒฉใ‚นใ‚ฟใงใฏใชใ„๏ผ‰ใซใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใ“ใจใ‚‚ใงใใพใ™ใฎใงใ€ๅ…ฑๆœ‰ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใจ**ใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ทใƒณใ‚ฐ**ใ‚’็ถญๆŒใ—ใชใŒใ‚‰๏ผˆDocker Composeใง๏ผ‰ใ‚ณใƒณใƒ†ใƒŠใฎใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’็ฎก็†ใ™ใ‚‹็ฐกๅ˜ใชๆ–นๆณ•ใฏใชใ„ใงใ—ใ‚‡ใ†ใ€‚ + +ใใฎๅ ดๅˆใ€**ๅ˜ไธ€ใฎใ‚ณใƒณใƒ†ใƒŠ**ใงใ€**ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃ**ใŒๅ†…้ƒจใง**่ค‡ๆ•ฐใฎใƒฏใƒผใ‚ซใƒผใƒ—ใƒญใ‚ปใ‚น**ใ‚’่ตทๅ‹•ใ™ใ‚‹ใ‚ˆใ†ใซใ—ใพใ™ใ€‚ + +#### Prometheusใจใใฎไป–ใฎ็†็”ฑ + +ใพใŸใ€**1ใคใฎใ‚ณใƒณใƒ†ใƒŠ**ใซ**1ใคใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใŸใ›ใ‚‹ใฎใงใฏใชใใ€**1ใคใฎใ‚ณใƒณใƒ†ใƒŠ**ใซ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใŸใ›ใ‚‹ๆ–นใŒ็ฐกๅ˜ใ ใจใ„ใ†**ไป–ใฎ็†็”ฑ**ใ‚‚ใ‚ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ + +ไพ‹ใˆใฐใ€(ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใซใ‚‚ใ‚ˆใ‚Šใพใ™ใŒ)Prometheusใ‚จใ‚ฏใ‚นใƒใƒผใ‚ฟใƒผใฎใ‚ˆใ†ใชใƒ„ใƒผใƒซใ‚’ๅŒใ˜ใ‚ณใƒณใƒ†ใƒŠๅ†…ใซๆŒใคใ“ใจใŒใงใใพใ™ใ€‚ + +ใ“ใฎๅ ดๅˆใ€**่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠ**ใŒใ‚ใ‚‹ใจใ€ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใงใฏใ€PrometheusใŒ**ใƒกใƒˆใƒชใ‚ฏใ‚นใ‚’**่ชญใฟใซๆฅใŸใจใใ€ใ™ในใฆใฎใƒฌใƒ—ใƒชใ‚ฑใƒผใƒˆใ•ใ‚ŒใŸใ‚ณใƒณใƒ†ใƒŠใฎ**่“„็ฉใ•ใ‚ŒใŸใƒกใƒˆใƒชใ‚ฏใ‚น**ใ‚’ๅ–ๅพ—ใ™ใ‚‹ใฎใงใฏใชใใ€ๆฏŽๅ›ž**ๅ˜ไธ€ใฎใ‚ณใƒณใƒ†ใƒŠ**๏ผˆใใฎ็‰นๅฎšใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅ‡ฆ็†ใ—ใŸใ‚ณใƒณใƒ†ใƒŠ๏ผ‰ใฎใ‚‚ใฎใ‚’ๅ–ๅพ—ใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +ใใฎๅ ดๅˆใ€**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๆŒใค**1ใคใฎใ‚ณใƒณใƒ†ใƒŠ**ใ‚’็”จๆ„ใ—ใ€ๅŒใ˜ใ‚ณใƒณใƒ†ใƒŠไธŠใฎใƒญใƒผใ‚ซใƒซใƒ„ใƒผใƒซ๏ผˆไพ‹ใˆใฐPrometheusใ‚จใ‚ฏใ‚นใƒใƒผใ‚ฟใƒผ๏ผ‰ใŒใ™ในใฆใฎๅ†…้ƒจใƒ—ใƒญใ‚ปใ‚นใฎPrometheusใƒกใƒˆใƒชใ‚ฏใ‚นใ‚’ๅŽ้›†ใ—ใ€ใใฎ1ใคใฎใ‚ณใƒณใƒ†ใƒŠไธŠใงใใ‚Œใ‚‰ใฎใƒกใƒˆใƒชใ‚ฏใ‚นใ‚’ๅ…ฌ้–‹ใ™ใ‚‹ๆ–นใŒใ‚ทใƒณใƒ—ใƒซใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ --- -ๆฌกใฎใ‚ปใ‚ฏใ‚ทใƒงใƒณใซ้€ฒใฟใ€ใ“ใฎๆƒ…ๅ ฑใจใƒ„ใƒผใƒซใ‚’ไฝฟ็”จใ—ใฆใ€ใ™ในใฆใ‚’็ต„ใฟๅˆใ‚ใ›ใพใ™ใ€‚ +้‡่ฆใชใฎใฏใ€็›ฒ็›ฎ็š„ใซๅพ“ใ‚ใชใ‘ใ‚Œใฐใชใ‚‰ใชใ„ๆ™ฎ้ใฎใƒซใƒผใƒซใฏใชใ„ใจใ„ใ†ใ“ใจใงใ™ใ€‚ + +ใ“ใ‚Œใ‚‰ใฎใ‚ขใ‚คใƒ‡ใ‚ขใฏใ€**ใ‚ใชใŸ่‡ช่บซใฎใƒฆใƒผใ‚นใ‚ฑใƒผใ‚น**ใ‚’่ฉ•ไพกใ—ใ€ใ‚ใชใŸใฎใ‚ทใ‚นใƒ†ใƒ ใซๆœ€้ฉใชใ‚ขใƒ—ใƒญใƒผใƒใ‚’ๆฑบๅฎšใ™ใ‚‹ใŸใ‚ใซไฝฟ็”จใ™ใ‚‹ใ“ใจใŒใงใใพใ™๏ผš + +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* **ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰** +* ใƒกใƒขใƒช +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ— + +## ใƒกใƒขใƒชใƒผ + +ใ‚ณใƒณใƒ†ใƒŠใ”ใจใซ**ๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚นใ‚’ๅฎŸ่กŒใ™ใ‚‹**ใจใ€ใใ‚Œใ‚‰ใฎใ‚ณใƒณใƒ†ใƒŠ๏ผˆใƒฌใƒ—ใƒชใ‚ฑใƒผใƒˆใ•ใ‚Œใฆใ„ใ‚‹ๅ ดๅˆใฏ1ใคไปฅไธŠ๏ผ‰ใซใ‚ˆใฃใฆๆถˆ่ฒปใ•ใ‚Œใ‚‹ๅคšใ‹ใ‚Œๅฐ‘ใชใ‹ใ‚Œๆ˜Ž็ขบใซๅฎš็พฉใ•ใ‚ŒใŸใ€ๅฎ‰ๅฎšใ—ๅˆถ้™ใ•ใ‚ŒใŸ้‡ใฎใƒกใƒขใƒชใ‚’ๆŒใคใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +ใใ—ใฆใ€ใ‚ณใƒณใƒ†ใƒŠ็ฎก็†ใ‚ทใ‚นใƒ†ใƒ ๏ผˆ**Kubernetes**ใชใฉ๏ผ‰ใฎ่จญๅฎšใงใ€ๅŒใ˜ใƒกใƒขใƒชๅˆถ้™ใจ่ฆไปถใ‚’่จญๅฎšใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ + +ใใ†ใ™ใ‚Œใฐใ€ใ‚ณใƒณใƒ†ใƒŠใŒๅฟ…่ฆใจใ™ใ‚‹ใƒกใƒขใƒช้‡ใจใ‚ฏใƒฉใ‚นใ‚ฟๅ†…ใฎใƒžใ‚ทใƒณใงๅˆฉ็”จๅฏ่ƒฝใชใƒกใƒขใƒช้‡ใ‚’่€ƒๆ…ฎใ—ใฆใ€**ๅˆฉ็”จๅฏ่ƒฝใชใƒžใ‚ทใƒณ**ใซ**ใ‚ณใƒณใƒ†ใƒŠ**ใ‚’ใƒฌใƒ—ใƒชใ‚ฑใƒผใƒˆใงใใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚ + +ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใŒ**ใ‚ทใƒณใƒ—ใƒซ**ใชใ‚‚ใฎใงใ‚ใ‚Œใฐใ€ใ“ใ‚ŒใฏใŠใใ‚‰ใ**ๅ•้กŒใซใฏใชใ‚‰ใชใ„**ใงใ—ใ‚‡ใ†ใ—ใ€ใƒใƒผใƒ‰ใชใƒกใƒขใƒชๅˆถ้™ใ‚’ๆŒ‡ๅฎšใ™ใ‚‹ๅฟ…่ฆใฏใชใ„ใ‹ใ‚‚ใ—ใ‚Œใชใ„ใงใ™ใ€‚ + +ใ—ใ‹ใ—ใ€**ๅคšใใฎใƒกใƒขใƒชใ‚’ไฝฟ็”จ**ใ—ใฆใ„ใ‚‹ๅ ดๅˆ๏ผˆใŸใจใˆใฐ**ๆฉŸๆขฐๅญฆ็ฟ’**ใƒขใƒ‡ใƒซใชใฉ๏ผ‰ใ€ใฉใ‚Œใ ใ‘ใฎใƒกใƒขใƒชใ‚’ๆถˆ่ฒปใ—ใฆใ„ใ‚‹ใ‹ใ‚’็ขบ่ชใ—ใ€**ๅ„ใƒžใ‚ทใƒณใงๅฎŸ่กŒใ™ใ‚‹ใ‚ณใƒณใƒ†ใƒŠใฎๆ•ฐ**ใ‚’่ชฟๆ•ดใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™๏ผˆใใ—ใฆใŠใใ‚‰ใใ‚ฏใƒฉใ‚นใ‚ฟใซใƒžใ‚ทใƒณใ‚’่ฟฝๅŠ ใ—ใพใ™๏ผ‰ใ€‚ + +**ใ‚ณใƒณใƒ†ใƒŠใ”ใจใซ่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ™ใ‚‹ๅ ดๅˆ๏ผˆใŸใจใˆใฐๅ…ฌๅผใฎDockerใ‚คใƒกใƒผใ‚ธใง๏ผ‰ใ€่ตทๅ‹•ใ™ใ‚‹ใƒ—ใƒญใ‚ปใ‚นใฎๆ•ฐใŒ**ๅˆฉ็”จๅฏ่ƒฝใชใƒกใƒขใƒชไปฅไธŠใซๆถˆ่ฒปใ—ใชใ„**ใ‚ˆใ†ใซใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚ + +## ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ—ใจใ‚ณใƒณใƒ†ใƒŠ + +ใ‚ณใƒณใƒ†ใƒŠ๏ผˆDockerใ‚„Kubernetesใชใฉ๏ผ‰ใ‚’ไฝฟใฃใฆใ„ใ‚‹ๅ ดๅˆใ€ไธปใซ2ใคใฎใ‚ขใƒ—ใƒญใƒผใƒใŒใ‚ใ‚Šใพใ™ใ€‚ + +### ่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠ + +่ค‡ๆ•ฐใฎ**ใ‚ณใƒณใƒ†ใƒŠ**ใŒใ‚ใ‚Šใ€ใŠใใ‚‰ใใใ‚Œใžใ‚ŒใŒ**ๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ—ใฆใ„ใ‚‹ๅ ดๅˆ๏ผˆ**Kubernetes**ใ‚ฏใƒฉใ‚นใ‚ฟใชใฉ๏ผ‰ใ€ใƒฌใƒ—ใƒชใ‚ฑใƒผใƒˆใ•ใ‚ŒใŸใƒฏใƒผใ‚ซใƒผใ‚ณใƒณใƒ†ใƒŠใ‚’ๅฎŸ่กŒใ™ใ‚‹**ๅ‰ใซ**ใ€ๅ˜ไธ€ใฎใ‚ณใƒณใƒ†ใƒŠใง**ไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—**ใฎไฝœๆฅญใ‚’่กŒใ†**ๅˆฅใฎใ‚ณใƒณใƒ†ใƒŠ**ใ‚’ๆŒใกใŸใ„ใจๆ€ใ†ใงใ—ใ‚‡ใ†ใ€‚ + +!!! info + ใ‚‚ใ—Kubernetesใ‚’ไฝฟ็”จใ—ใฆใ„ใ‚‹ๅ ดๅˆ, ใ“ใ‚ŒใฏใŠใใ‚‰ใInit ใ‚ณใƒณใƒ†ใƒŠใงใ—ใ‚‡ใ†ใ€‚ + +ใƒฆใƒผใ‚นใ‚ฑใƒผใ‚นใŒไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’**ไธฆๅˆ—ใง่ค‡ๆ•ฐๅ›ž**ๅฎŸ่กŒใ™ใ‚‹ใฎใซๅ•้กŒใŒใชใ„ๅ ดๅˆ๏ผˆไพ‹๏ผšใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใฎๆบ–ๅ‚™ใƒใ‚งใƒƒใ‚ฏ๏ผ‰ใ€ใƒกใ‚คใƒณใƒ—ใƒญใ‚ปใ‚นใ‚’้–‹ๅง‹ใ™ใ‚‹ๅ‰ใซใ€ใใ‚Œใ‚‰ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’ๅ„ใ‚ณใƒณใƒ†ใƒŠใซๅ…ฅใ‚Œใ‚‹ใ“ใจใŒๅฏ่ƒฝใงใ™ใ€‚ + +### ๅ˜ไธ€ใ‚ณใƒณใƒ†ใƒŠ + +ๅ˜็ด”ใชใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใงใ€**ๅ˜ไธ€ใฎใ‚ณใƒณใƒ†ใƒŠ**ใง่ค‡ๆ•ฐใฎ**ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**๏ผˆใพใŸใฏ1ใคใฎใƒ—ใƒญใ‚ปใ‚นใฎใฟ๏ผ‰ใ‚’่ตทๅ‹•ใ™ใ‚‹ๅ ดๅˆใ€ใ‚ขใƒ—ใƒชใงใƒ—ใƒญใ‚ปใ‚นใ‚’้–‹ๅง‹ใ™ใ‚‹็›ดๅ‰ใซใ€ๅŒใ˜ใ‚ณใƒณใƒ†ใƒŠใงไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ—ใ‚’ๅฎŸ่กŒใงใใพใ™ใ€‚ๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธใฏใ€ๅ†…้ƒจ็š„ใซใ“ใ‚Œใ‚’ใ‚ตใƒใƒผใƒˆใ—ใฆใ„ใพใ™ใ€‚ + +## Gunicornใซใ‚ˆใ‚‹ๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธ - Uvicorn + +ๅ‰ใฎ็ซ ใง่ฉณใ—ใ่ชฌๆ˜Žใ—ใŸใ‚ˆใ†ใซใ€Uvicornใƒฏใƒผใ‚ซใƒผใงๅ‹•ไฝœใ™ใ‚‹Gunicornใ‚’ๅซใ‚€ๅ…ฌๅผใฎDockerใ‚คใƒกใƒผใ‚ธใŒใ‚ใ‚Šใพใ™๏ผš [Server Workers - Gunicorn ใจ Uvicorn](./server-workers.md){.internal-link target=_blank}ใง่ฉณใ—ใ่ชฌๆ˜Žใ—ใฆใ„ใพใ™ใ€‚ + +ใ“ใฎใ‚คใƒกใƒผใ‚ธใฏใ€ไธปใซไธŠ่จ˜ใง่ชฌๆ˜Žใ—ใŸ็Šถๆณใงๅฝนใซ็ซ‹ใคใงใ—ใ‚‡ใ†๏ผš [่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚นใจ็‰นๆฎŠใชใ‚ฑใƒผใ‚นใ‚’ๆŒใคใ‚ณใƒณใƒ†ใƒŠ๏ผˆContainers with Multiple Processes and Special Cases๏ผ‰](#containers-with-multiple-processes-and-special-cases) + +* tiangolo/uvicorn-gunicorn-fastapi. + +!!! warning + ใ“ใฎใƒ™ใƒผใ‚นใ‚คใƒกใƒผใ‚ธใ‚„้กžไผผใฎใ‚คใƒกใƒผใ‚ธใฏ**ๅฟ…่ฆใชใ„**ๅฏ่ƒฝๆ€งใŒ้ซ˜ใ„ใฎใงใ€[ไธŠ่จ˜ใฎ: FastAPI็”จใฎDockerใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹๏ผˆBuild a Docker Image for FastAPI๏ผ‰](#build-a-docker-image-for-fastapi)ใฎใ‚ˆใ†ใซใ‚ผใƒญใ‹ใ‚‰ใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹ๆ–นใŒ่‰ฏใ„ใงใ—ใ‚‡ใ†ใ€‚ + +ใ“ใฎใ‚คใƒกใƒผใ‚ธใซใฏใ€ๅˆฉ็”จๅฏ่ƒฝใชCPUใ‚ณใ‚ขใซๅŸบใฅใ„ใฆ**ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใฎๆ•ฐ**ใ‚’่จญๅฎšใ™ใ‚‹**ใ‚ชใƒผใƒˆใƒใƒฅใƒผใƒ‹ใƒณใ‚ฐ**ใƒกใ‚ซใƒ‹ใ‚บใƒ ใŒๅซใพใ‚Œใฆใ„ใพใ™ใ€‚ + +ใ“ใ‚Œใฏ**่ณขๆ˜Žใชใƒ‡ใƒ•ใ‚ฉใƒซใƒˆ**ใ‚’ๅ‚™ใˆใฆใ„ใพใ™ใŒใ€**็’ฐๅขƒๅค‰ๆ•ฐ**ใ‚„่จญๅฎšใƒ•ใ‚กใ‚คใƒซใ‚’ไฝฟใฃใฆใ™ในใฆใฎ่จญๅฎšใ‚’ๅค‰ๆ›ดใ—ใŸใ‚Šๆ›ดๆ–ฐใ—ใŸใ‚Šใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ -## TraefikใจHTTPSใ‚’ไฝฟ็”จใ—ใŸDocker Swarmใƒขใƒผใƒ‰ใฎใ‚ฏใƒฉใ‚นใ‚ฟ +ใพใŸใ€ใ‚นใ‚ฏใƒชใƒ—ใƒˆใง**้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ—**ใ‚’ๅฎŸ่กŒใ™ใ‚‹ใ“ใจใ‚‚ใ‚ตใƒใƒผใƒˆใ—ใฆใ„ใ‚‹ใ€‚ -HTTPSใ‚’ๅ‡ฆ็†ใ™ใ‚‹๏ผˆ่จผๆ˜Žๆ›ธใฎๅ–ๅพ—ใจๆ›ดๆ–ฐใ‚’ๅซใ‚€๏ผ‰Traefikใ‚’ไฝฟ็”จใ—ใฆใ€Docker Swarmใƒขใƒผใƒ‰ใฎใ‚ฏใƒฉใ‚นใ‚ฟใ‚’ๆ•ฐๅˆ†๏ผˆ20ๅˆ†็จ‹ๅบฆ๏ผ‰ใงใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใงใใพใ™ใ€‚ +!!! tip + ใ™ในใฆใฎ่จญๅฎšใจใ‚ชใƒ—ใ‚ทใƒงใƒณใ‚’่ฆ‹ใ‚‹ใซใฏใ€Dockerใ‚คใƒกใƒผใ‚ธใฎใƒšใƒผใ‚ธใ‚’ใ”่ฆงใใ ใ•ใ„: tiangolo/uvicorn-gunicorn-fastapi -Docker Swarmใƒขใƒผใƒ‰ใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใงใ€1ๅฐใฎใƒžใ‚ทใƒณใฎใ€Œใ‚ฏใƒฉใ‚นใ‚ฟใ€ใ‹ใ‚‰้–‹ๅง‹ใงใ๏ผˆ1ใ‹ๆœˆใ‚ใŸใ‚Š5ใƒ‰ใƒซใฎใ‚ตใƒผใƒใƒผใงใ‚‚ใงใใพใ™๏ผ‰ใ€ๅพŒใ‹ใ‚‰ๅฟ…่ฆใชใ ใ‘ใ‚ตใƒผใƒใƒผใ‚’ๆ‹กๅผตใงใใพใ™ใ€‚ +### ๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ -TraefikใŠใ‚ˆใณHTTPSๅ‡ฆ็†ใ‚’ๅ‚™ใˆใŸDocker Swarm Modeใ‚ฏใƒฉใ‚นใ‚ฟใƒผใ‚’ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ™ใ‚‹ใซใฏใ€ๆฌกใฎใ‚ฌใ‚คใƒ‰ใซๅพ“ใ„ใพใ™: +ใ“ใฎใ‚คใƒกใƒผใ‚ธใฎ**ใƒ—ใƒญใ‚ปใ‚นๆ•ฐ**ใฏใ€ๅˆฉ็”จๅฏ่ƒฝใชCPU**ใ‚ณใ‚ข**ใ‹ใ‚‰**่‡ชๅ‹•็š„ใซ่จˆ็ฎ—**ใ•ใ‚Œใพใ™ใ€‚ + +ใคใพใ‚Šใ€CPUใ‹ใ‚‰ๅฏ่ƒฝใช้™ใ‚Š**ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚น**ใ‚’**ๅผ•ใๅ‡บใใ†**ใจใ—ใพใ™ใ€‚ + +ใพใŸใ€**็’ฐๅขƒๅค‰ๆ•ฐ**ใชใฉใ‚’ไฝฟใฃใŸ่จญๅฎšใง่ชฟๆ•ดใ™ใ‚‹ใ“ใจใ‚‚ใงใใพใ™ใ€‚ + +ใ—ใ‹ใ—ใ€ใƒ—ใƒญใ‚ปใ‚นใฎๆ•ฐใฏใ‚ณใƒณใƒ†ใƒŠใŒๅฎŸ่กŒใ—ใฆใ„ใ‚‹CPUใซไพๅญ˜ใ™ใ‚‹ใŸใ‚ใ€**ๆถˆ่ฒปใ•ใ‚Œใ‚‹ใƒกใƒขใƒชใฎ้‡**ใ‚‚ใใ‚Œใซไพๅญ˜ใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +ใใฎใŸใ‚ใ€๏ผˆๆฉŸๆขฐๅญฆ็ฟ’ใƒขใƒ‡ใƒซใชใฉใง๏ผ‰ๅคง้‡ใฎใƒกใƒขใƒชใ‚’ๆถˆ่ฒปใ™ใ‚‹ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใงใ€ใ‚ตใƒผใƒใƒผใฎCPUใ‚ณใ‚ขใŒๅคšใ„ใŒ**ใƒกใƒขใƒชใŒๅฐ‘ใชใ„**ๅ ดๅˆใ€ใ‚ณใƒณใƒ†ใƒŠใฏๅˆฉ็”จๅฏ่ƒฝใชใƒกใƒขใƒชใ‚ˆใ‚Šใ‚‚ๅคšใใฎใƒกใƒขใƒชใ‚’ไฝฟใŠใ†ใจใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ + +ใใฎ็ตๆžœใ€ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใŒๅคงๅน…ใซไฝŽไธ‹ใ™ใ‚‹๏ผˆใ‚ใ‚‹ใ„ใฏใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ™ใ‚‹๏ผ‰ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚๐Ÿšจ + +### Dockerfileใ‚’ไฝœๆˆใ™ใ‚‹ + +ใ“ใฎ็”ปๅƒใซๅŸบใฅใ„ใฆ`Dockerfile`ใ‚’ไฝœๆˆใ™ใ‚‹ๆ–นๆณ•ใ‚’ไปฅไธ‹ใซ็คบใ—ใพใ™๏ผš + +```Dockerfile +FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 + +COPY ./requirements.txt /app/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt + +COPY ./app /app +``` + +### ใ‚ˆใ‚Šๅคงใใชใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ + +[่ค‡ๆ•ฐใฎใƒ•ใ‚กใ‚คใƒซใ‚’ๆŒใคๅคงใใชใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ](../tutorial/bigger-applications.md){.internal-link target=_blank}ใ‚’ไฝœๆˆใ™ใ‚‹ใ‚ปใ‚ฏใ‚ทใƒงใƒณใซๅพ“ใฃใŸๅ ดๅˆใ€`Dockerfile`ใฏๆฌกใฎใ‚ˆใ†ใซใชใ‚Šใพใ™๏ผš + +```Dockerfile hl_lines="7" +FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 + +COPY ./requirements.txt /app/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt + +COPY ./app /app/app +``` + +### ใ„ใคไฝฟใ†ใฎใ‹ + +ใŠใใ‚‰ใใ€**Kubernetes**๏ผˆใพใŸใฏไป–ใฎใ‚‚ใฎ๏ผ‰ใ‚’ไฝฟ็”จใ—ใฆใ„ใฆใ€ใ™ใงใซใ‚ฏใƒฉใ‚นใ‚ฟใƒฌใƒ™ใƒซใง่ค‡ๆ•ฐใฎ**ใ‚ณใƒณใƒ†ใƒŠ**ใง**ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ**ใ‚’่จญๅฎšใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€ใ“ใฎๅ…ฌๅผใƒ™ใƒผใ‚นใ‚คใƒกใƒผใ‚ธ๏ผˆใพใŸใฏไป–ใฎ้กžไผผใฎใ‚‚ใฎ๏ผ‰ใฏ**ไฝฟ็”จใ™ในใใงใฏใ‚ใ‚Šใพใ›ใ‚“**ใ€‚ + +ใใฎใ‚ˆใ†ใชๅ ดๅˆใฏใ€ไธŠ่จ˜ใฎใ‚ˆใ†ใซ**ใ‚ผใƒญใ‹ใ‚‰**ใ‚คใƒกใƒผใ‚ธใ‚’ๆง‹็ฏ‰ใ™ใ‚‹ๆ–นใŒใ‚ˆใ„ใงใ—ใ‚‡ใ†๏ผš [FastAPI็”จใฎDockerใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ™ใ‚‹๏ผˆBuild a Docker Image for FastAPI๏ผ‰](#build-a-docker-image-for-fastapi) ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚ + +ใ“ใฎใ‚คใƒกใƒผใ‚ธใฏใ€ไธปใซไธŠ่จ˜ใฎ[่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚นใจ็‰นๆฎŠใชใ‚ฑใƒผใ‚นใ‚’ๆŒใคใ‚ณใƒณใƒ†ใƒŠ๏ผˆContainers with Multiple Processes and Special Cases๏ผ‰](#containers-with-multiple-processes-and-special-cases)ใง่ชฌๆ˜Žใ—ใŸใ‚ˆใ†ใช็‰นๆฎŠใชใ‚ฑใƒผใ‚นใงๅฝนใซ็ซ‹ใกใพใ™ใ€‚ + +ไพ‹ใˆใฐใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใŒ**ใ‚ทใƒณใƒ—ใƒซ**ใงใ€CPUใซๅฟœใ˜ใŸใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐใ‚’่จญๅฎšใ™ใ‚Œใฐใ†ใพใใ„ใๅ ดๅˆใ‚„ใ€ใ‚ฏใƒฉใ‚นใ‚ฟใƒฌใƒ™ใƒซใงใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ๆ‰‹ๅ‹•ใง่จญๅฎšใ™ใ‚‹ๆ‰‹้–“ใ‚’็œใใŸใ„ๅ ดๅˆใ€ใ‚ขใƒ—ใƒชใง่ค‡ๆ•ฐใฎใ‚ณใƒณใƒ†ใƒŠใ‚’ๅฎŸ่กŒใ—ใชใ„ๅ ดๅˆใชใฉใงใ™ใ€‚ + +ใพใŸใฏใ€**Docker Compose**ใงใƒ‡ใƒ—ใƒญใ‚คใ—ใ€ๅ˜ไธ€ใฎใ‚ตใƒผใƒใงๅฎŸ่กŒใ—ใฆใ„ใ‚‹ๅ ดๅˆใชใฉใงใ™ใ€‚ + +## ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใฎใƒ‡ใƒ—ใƒญใ‚ค + +ใ‚ณใƒณใƒ†ใƒŠ๏ผˆDocker๏ผ‰ใ‚คใƒกใƒผใ‚ธใ‚’ๆ‰‹ใซๅ…ฅใ‚ŒใŸๅพŒใ€ใใ‚Œใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใซใฏใ„ใใคใ‹ใฎๆ–นๆณ•ใŒใ‚ใ‚Šใพใ™ใ€‚ + +ไพ‹ใˆใฐไปฅไธ‹ใฎใƒชใ‚นใƒˆใฎๆ–นๆณ•ใงใ™: + +* ๅ˜ไธ€ใ‚ตใƒผใƒใƒผใฎ**Docker Compose** +* **Kubernetes**ใ‚ฏใƒฉใ‚นใ‚ฟ +* Docker Swarmใƒขใƒผใƒ‰ใฎใ‚ฏใƒฉใ‚นใ‚ฟใƒผ +* Nomadใฎใ‚ˆใ†ใชๅˆฅใฎใƒ„ใƒผใƒซ +* ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹ใ‚ฏใƒฉใ‚ฆใƒ‰ใƒปใ‚ตใƒผใƒ“ใ‚น + +## Poetryใ‚’ๅˆฉ็”จใ—ใŸDockerใ‚คใƒกใƒผใ‚ธ + +ใ‚‚ใ—ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฎไพๅญ˜้–ขไฟ‚ใ‚’็ฎก็†ใ™ใ‚‹ใŸใ‚ใซPoetryใ‚’ๅˆฉ็”จใ™ใ‚‹ๅ ดๅˆใ€ใƒžใƒซใƒใ‚นใƒ†ใƒผใ‚ธใƒ“ใƒซใƒ‰ใ‚’ไฝฟใ†ใจ่‰ฏใ„ใงใ—ใ‚‡ใ†ใ€‚ + +```{ .dockerfile .annotate } +# (1) +FROM python:3.9 as requirements-stage + +# (2) +WORKDIR /tmp + +# (3) +RUN pip install poetry + +# (4) +COPY ./pyproject.toml ./poetry.lock* /tmp/ + +# (5) +RUN poetry export -f requirements.txt --output requirements.txt --without-hashes + +# (6) +FROM python:3.9 + +# (7) +WORKDIR /code + +# (8) +COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt + +# (9) +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +# (10) +COPY ./app /code/app + +# (11) +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +``` + +1. ใ“ใ‚Œใฏๆœ€ๅˆใฎใ‚นใƒ†ใƒผใ‚ธใงใ€`requirements-stage`ใจๅไป˜ใ‘ใ‚‰ใ‚Œใพใ™ +2. `/tmp` ใ‚’็พๅœจใฎไฝœๆฅญใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซ่จญๅฎšใ—ใพใ™ + ใ“ใ“ใง `requirements.txt` ใจใ„ใ†ใƒ•ใ‚กใ‚คใƒซใ‚’็”Ÿๆˆใ—ใพใ™ใ€‚ + +3. ใ“ใฎDockerใ‚นใƒ†ใƒผใ‚ธใซPoetryใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใพใ™ + +4. pyproject.toml`ใจ`poetry.lock`ใƒ•ใ‚กใ‚คใƒซใ‚’`/tmp` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซใ‚ณใƒ”ใƒผใ—ใพใ™ + + `./poetry.lock*`๏ผˆๆœซๅฐพใซ`*`๏ผ‰ใ‚’ไฝฟ็”จใ™ใ‚‹ใŸใ‚ใ€ใใฎใƒ•ใ‚กใ‚คใƒซใŒใพใ ๅˆฉ็”จใงใใชใ„ๅ ดๅˆใงใ‚‚ใ‚ฏใƒฉใƒƒใ‚ทใƒฅใ™ใ‚‹ใ“ใจใฏใชใ„ใงใ™ใ€‚ +5. requirements.txt`ใƒ•ใ‚กใ‚คใƒซใ‚’็”Ÿๆˆใ—ใพใ™ + +6. ใ“ใ‚Œใฏๆœ€ๅพŒใฎใ‚นใƒ†ใƒผใ‚ธใงใ‚ใ‚Šใ€ใ“ใ“ใซใ‚ใ‚‹ใ‚‚ใฎใฏใ™ในใฆๆœ€็ต‚็š„ใชใ‚ณใƒณใƒ†ใƒŠใƒปใ‚คใƒกใƒผใ‚ธใซไฟๅญ˜ใ•ใ‚Œใพใ™ +7. ็พๅœจใฎไฝœๆฅญใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ `/code` ใซ่จญๅฎšใ—ใพใ™ +8. `requirements.txt`ใƒ•ใ‚กใ‚คใƒซใ‚’ `/code` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซใ‚ณใƒ”ใƒผใ—ใพใ™ + ใ“ใฎใƒ•ใ‚กใ‚คใƒซใฏๅ‰ใฎDockerใ‚นใƒ†ใƒผใ‚ธใซใ—ใ‹ๅญ˜ๅœจใ—ใชใ„ใŸใ‚ใ€`--from-requirements-stage`ใ‚’ไฝฟใฃใฆใ‚ณใƒ”ใƒผใ—ใพใ™ใ€‚ +9. ็”Ÿๆˆใ•ใ‚ŒใŸ `requirements.txt` ใƒ•ใ‚กใ‚คใƒซใซใ‚ใ‚‹ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใฎไพๅญ˜้–ขไฟ‚ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใพใ™ +10. app` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ `/code` ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซใ‚ณใƒ”ใƒผใ—ใพใ™ +11. uvicorn` ใ‚ณใƒžใƒณใƒ‰ใ‚’ๅฎŸ่กŒใ—ใฆใ€`app.main` ใ‹ใ‚‰ใ‚คใƒณใƒใƒผใƒˆใ—ใŸ `app` ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ไฝฟ็”จใ™ใ‚‹ใ‚ˆใ†ใซๆŒ‡็คบใ—ใพใ™ +!!! tip + "+"ใฎๅนใๅ‡บใ—ใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ™ใ‚‹ใจใ€ใใ‚Œใžใ‚Œใฎ่กŒใŒไฝ•ใ‚’ใ™ใ‚‹ใฎใ‹ใ‚’่ฆ‹ใ‚‹ใ“ใจใŒใงใใพใ™ + +**Dockerใ‚นใƒ†ใƒผใ‚ธ**ใฏ`Dockerfile`ใฎไธ€้ƒจใงใ€**ไธ€ๆ™‚็š„ใชใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธ**ใจใ—ใฆๅ‹•ไฝœใ—ใพใ™ใ€‚ + +ๆœ€ๅˆใฎใ‚นใƒ†ใƒผใ‚ธใฏ **Poetryใฎใ‚คใƒณใ‚นใƒˆใƒผใƒซ**ใจ Poetry ใฎ `pyproject.toml` ใƒ•ใ‚กใ‚คใƒซใ‹ใ‚‰ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฎไพๅญ˜้–ขไฟ‚ใ‚’ๅซใ‚€**`requirements.txt`ใ‚’็”Ÿๆˆ**ใ™ใ‚‹ใŸใ‚ใ ใ‘ใซไฝฟ็”จใ•ใ‚Œใพใ™ใ€‚ + +ใ“ใฎ `requirements.txt` ใƒ•ใ‚กใ‚คใƒซใฏๅพŒๅŠใฎ **ๆฌกใฎใ‚นใƒ†ใƒผใ‚ธ**ใง `pip` ใจๅ…ฑใซไฝฟ็”จใ•ใ‚Œใพใ™ใ€‚ + +ๆœ€็ต‚็š„ใชใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใงใฏใ€**ๆœ€็ต‚ใ‚นใƒ†ใƒผใ‚ธ**ใฎใฟใŒไฟๅญ˜ใ•ใ‚Œใพใ™ใ€‚ๅ‰ใฎใ‚นใƒ†ใƒผใ‚ธใฏ็ ดๆฃ„ใ•ใ‚Œใพใ™ใ€‚ + +Poetryใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใ€**Dockerใƒžใƒซใƒใ‚นใƒ†ใƒผใ‚ธใƒ“ใƒซใƒ‰**ใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใฏ็†ใซใ‹ใชใฃใฆใ„ใพใ™ใ€‚ + +ใชใœใชใ‚‰ใ€ๆœ€็ต‚็š„ใชใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใซPoetryใจใใฎไพๅญ˜้–ขไฟ‚ใŒใ‚คใƒณใ‚นใƒˆใƒผใƒซใ•ใ‚Œใฆใ„ใ‚‹ๅฟ…่ฆใฏใชใใ€**ๅฟ…่ฆใชใฎใฏ**ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฎไพๅญ˜้–ขไฟ‚ใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ใŸใ‚ใซ็”Ÿๆˆใ•ใ‚ŒใŸ `requirements.txt` ใƒ•ใ‚กใ‚คใƒซใ ใ‘ใ ใ‹ใ‚‰ใงใ™ใ€‚ + +ใใ—ใฆๆฌกใฎ๏ผˆใใ—ใฆๆœ€็ต‚็š„ใช๏ผ‰ใ‚นใƒ†ใƒผใ‚ธใงใฏใ€ๅ‰่ฟฐใจใปใผๅŒใ˜ๆ–นๆณ•ใงใ‚คใƒกใƒผใ‚ธใ‚’ใƒ“ใƒซใƒ‰ใ—ใพใ™ใ€‚ + +### TLS Termination Proxyใฎ่ฃๅด - Poetry + +็นฐใ‚Š่ฟ”ใ—ใซใชใ‚Šใพใ™ใŒใ€Nginxใ‚„Traefikใฎใ‚ˆใ†ใชTLS Termination Proxy๏ผˆใƒญใƒผใƒ‰ใƒใƒฉใƒณใ‚ตใƒผ๏ผ‰ใฎๅพŒใ‚ใงใ‚ณใƒณใƒ†ใƒŠใ‚’ๅ‹•ใ‹ใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€`--proxy-headers`ใ‚ชใƒ—ใ‚ทใƒงใƒณใ‚’ใ‚ณใƒžใƒณใƒ‰ใซ่ฟฝๅŠ ใ—ใพใ™๏ผš + +```Dockerfile +CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] +``` -### Docker Swarm Mode and Traefik for an HTTPS cluster +## ใพใจใ‚ -### FastAPIใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎใƒ‡ใƒ—ใƒญใ‚ค +ใ‚ณใƒณใƒ†ใƒŠใƒปใ‚ทใ‚นใƒ†ใƒ ๏ผˆไพ‹ใˆใฐ**Docker**ใ‚„**Kubernetes**ใชใฉ๏ผ‰ใ‚’ไฝฟใˆใฐใ€ใ™ในใฆใฎ**ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ**ใ‚’ๆ‰ฑใ†ใฎใŒใ‹ใชใ‚Š็ฐกๅ˜ใซใชใ‚Šใพใ™๏ผš -ใ™ในใฆใ‚’่จญๅฎšใ™ใ‚‹ใŸใ‚ใฎๆœ€ใ‚‚็ฐกๅ˜ใชๆ–นๆณ•ใฏใ€[**FastAPI** Project Generators](../project-generation.md){.internal-link target=_blank}ใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใงใ—ใ‚‡ใ†ใ€‚ +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* **ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰** +* ใƒกใƒขใƒช +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ— -ไธŠ่ฟฐใ—ใŸTraefikใจHTTPSใ‚’ๅ‚™ใˆใŸDocker Swarm ใ‚ฏใƒฉใ‚นใ‚ฟใŒ็ตฑๅˆใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซ่จญ่จˆใ•ใ‚Œใฆใ„ใพใ™ใ€‚ +ใปใจใ‚“ใฉใฎๅ ดๅˆใ€ใƒ™ใƒผใ‚นใจใชใ‚‹ใ‚คใƒกใƒผใ‚ธใฏไฝฟ็”จใ›ใšใ€ๅ…ฌๅผใฎPython Dockerใ‚คใƒกใƒผใ‚ธใ‚’ใƒ™ใƒผใ‚นใซใ—ใŸ**ใ‚ณใƒณใƒ†ใƒŠใ‚คใƒกใƒผใ‚ธใ‚’ใ‚ผใƒญใ‹ใ‚‰ใƒ“ใƒซใƒ‰**ใ—ใพใ™ใ€‚ -2ๅˆ†็จ‹ๅบฆใงใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใŒ็”Ÿๆˆใ•ใ‚Œใพใ™ใ€‚ +`Dockerfile`ใจ**Dockerใ‚ญใƒฃใƒƒใ‚ทใƒฅ**ๅ†…ใฎๅ‘ฝไปคใฎ**้ †็•ช**ใซๆณจๆ„ใ™ใ‚‹ใ“ใจใงใ€**ใƒ“ใƒซใƒ‰ๆ™‚้–“ใ‚’ๆœ€ๅฐๅŒ–**ใ™ใ‚‹ใ“ใจใŒใงใใ€็”Ÿ็”ฃๆ€งใ‚’ๆœ€ๅคงๅŒ–ใ™ใ‚‹ใ“ใจใŒใงใใพใ™๏ผˆใใ—ใฆ้€€ๅฑˆใ‚’้ฟใ‘ใ‚‹ใ“ใจใŒใงใใพใ™๏ผ‰ใ€‚๐Ÿ˜Ž -็”Ÿๆˆใ•ใ‚ŒใŸใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฏใƒ‡ใƒ—ใƒญใ‚คใฎๆŒ‡็คบใŒใ‚ใ‚Šใพใ™ใŒใ€ใใ‚Œใ‚’ๅฎŸ่กŒใ™ใ‚‹ใจใ•ใ‚‰ใซ2ๅˆ†ใ‹ใ‹ใ‚Šใพใ™ใ€‚ +็‰นๅˆฅใชใ‚ฑใƒผใ‚นใงใฏใ€FastAPI็”จใฎๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธใ‚’ไฝฟใ„ใŸใ„ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚๐Ÿค“ diff --git a/docs/ja/docs/deployment/server-workers.md b/docs/ja/docs/deployment/server-workers.md new file mode 100644 index 000000000..e1ea165a2 --- /dev/null +++ b/docs/ja/docs/deployment/server-workers.md @@ -0,0 +1,182 @@ +# Server Workers - Gunicorn ใจ Uvicorn + +ๅ‰ๅ›žใฎใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆใ‚’ๆŒฏใ‚Š่ฟ”ใฃใฆใฟใพใ—ใ‚‡ใ†๏ผš + +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* **ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰** +* ใƒกใƒขใƒช +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใ‚นใƒ†ใƒƒใƒ— + +ใ“ใ“ใพใงใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใฎใƒใƒฅใƒผใƒˆใƒชใ‚ขใƒซใงใฏใ€ใŠใใ‚‰ใUvicornใฎใ‚ˆใ†ใช**ใ‚ตใƒผใƒใƒผใƒ—ใƒญใ‚ฐใƒฉใƒ **ใ‚’**ๅ˜ไธ€ใฎใƒ—ใƒญใ‚ปใ‚น**ใงๅฎŸ่กŒใ—ใฆใ„ใพใ™ใ€‚ + +ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ใƒ‡ใƒ—ใƒญใ‚คใ™ใ‚‹้š›ใซใฏใ€**่ค‡ๆ•ฐใฎใ‚ณใ‚ข**ใ‚’ๅˆฉ็”จใ—ใ€ใใ—ใฆใ‚ˆใ‚Šๅคšใใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅ‡ฆ็†ใงใใ‚‹ใ‚ˆใ†ใซใ™ใ‚‹ใŸใ‚ใซใ€ใƒ—ใƒญใ‚ปใ‚นใฎ**ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ**ใ‚’ๆŒใคใ“ใจใ‚’ๆœ›ใ‚€ใงใ—ใ‚‡ใ†ใ€‚ + +ๅ‰ใฎใƒใƒฃใƒ—ใ‚ฟใƒผใงใ‚ใ‚‹[ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ](./concepts.md){.internal-link target=_blank}ใซใฆ่ฆ‹ใฆใใŸใ‚ˆใ†ใซใ€ๆœ‰ๅŠนใชๆˆฆ็•ฅใŒใ„ใใคใ‹ใ‚ใ‚Šใพใ™ใ€‚ + +ใ“ใ“ใงใฏ**Gunicorn**ใŒ**Uvicornใฎใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’็ฎก็†ใ™ใ‚‹ๅ ดๅˆใฎไฝฟใ„ๆ–นใซใคใ„ใฆ็ดนไป‹ใ—ใฆใ„ใใพใ™ใ€‚ + +!!! info + + Dockerใ‚„Kubernetesใชใฉใฎใ‚ณใƒณใƒ†ใƒŠใ‚’ไฝฟ็”จใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€ๆฌกใฎ็ซ ใง่ฉณใ—ใ่ชฌๆ˜Žใ—ใพใ™๏ผš [ใ‚ณใƒณใƒ†ใƒŠๅ†…ใฎFastAPI - Docker](./docker.md){.internal-link target=_blank} + + ็‰นใซ**Kubernetes**ไธŠใงๅฎŸ่กŒใ™ใ‚‹ๅ ดๅˆใฏใ€ใŠใใ‚‰ใ**Gunicornใ‚’ไฝฟ็”จใ›ใš**ใ€**ใ‚ณใƒณใƒ†ใƒŠใ”ใจใซๅ˜ไธ€ใฎUvicornใƒ—ใƒญใ‚ปใ‚น**ใ‚’ๅฎŸ่กŒใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใŒใ€ใใ‚Œใซใคใ„ใฆใฏใ“ใฎ็ซ ใฎๅพŒๅŠใง่ชฌๆ˜Žใ—ใพใ™ใ€‚ + +## Gunicornใซใ‚ˆใ‚‹Uvicornใฎใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใฎ็ฎก็† + +**Gunicorn**ใฏ**WSGIๆจ™ๆบ–**ใฎใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚ตใƒผใƒใƒผใงใ™ใ€‚ใ“ใฎใ“ใจใฏใ€GunicornใฏFlaskใ‚„Djangoใฎใ‚ˆใ†ใชใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใซใ‚ตใƒผใƒ“ใ‚นใ‚’ๆไพ›ใงใใ‚‹ใ“ใจใ‚’ๆ„ๅ‘ณใ—ใพใ™ใ€‚Gunicornใใ‚Œ่‡ชไฝ“ใฏ**FastAPI**ใจไบ’ๆ›ๆ€งใŒใชใ„ใงใ™ใŒใ€ใจใ„ใ†ใฎใ‚‚FastAPIใฏๆœ€ๆ–ฐใฎ**ASGI ๆจ™ๆบ–**ใ‚’ไฝฟ็”จใ—ใฆใ„ใ‚‹ใŸใ‚ใงใ™ใ€‚ + +ใ—ใ‹ใ—ใ€Gunicornใฏ**ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผ**ใจใ—ใฆๅ‹•ไฝœใ—ใ€ใƒฆใƒผใ‚ถใƒผใŒ็‰นๅฎšใฎ**ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใ‚ฏใƒฉใ‚น**ใ‚’ไฝฟ็”จใ™ใ‚‹ใ‚ˆใ†ใซๆŒ‡็คบใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚ใ™ใ‚‹ใจGunicornใฏใใฎใ‚ฏใƒฉใ‚นใ‚’ไฝฟใ„1ใคไปฅไธŠใฎ**ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’้–‹ๅง‹ใ—ใพใ™ใ€‚ + +ใใ—ใฆ**Uvicorn**ใซใฏ**Gunicornไบ’ๆ›ใฎใƒฏใƒผใ‚ซใƒผใ‚ฏใƒฉใ‚น**ใŒใ‚ใ‚Šใพใ™ใ€‚ + +ใ“ใฎ็ต„ใฟๅˆใ‚ใ›ใงใ€Gunicornใฏ**ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผ**ใจใ—ใฆๅ‹•ไฝœใ—ใ€**ใƒใƒผใƒˆ**ใจ**IP**ใ‚’ใƒชใƒƒใ‚นใƒณใ—ใพใ™ใ€‚ใใ—ใฆใ€**Uvicornใ‚ฏใƒฉใ‚น**ใ‚’ๅฎŸ่กŒใ—ใฆใ„ใ‚‹ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใซ้€šไฟกใ‚’**่ปข้€**ใ—ใพใ™ใ€‚ + +ใใ—ใฆใ€Gunicornไบ’ๆ›ใฎ**Uvicornใƒฏใƒผใ‚ซใƒผ**ใ‚ฏใƒฉใ‚นใŒใ€FastAPIใŒไฝฟใˆใ‚‹ใ‚ˆใ†ใซใ€Gunicornใ‹ใ‚‰้€ใ‚‰ใ‚ŒใฆใใŸใƒ‡ใƒผใ‚ฟใ‚’ASGIๆจ™ๆบ–ใซๅค‰ๆ›ใ™ใ‚‹ๅฝนๅ‰ฒใ‚’ๆ‹…ใ„ใพใ™ใ€‚ + +## GunicornใจUvicornใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ + +
+ +```console +$ pip install "uvicorn[standard]" gunicorn + +---> 100% +``` + +
+ +ใ“ใ‚Œใซใ‚ˆใ‚ŠUvicornใจ๏ผˆ้ซ˜ๆ€ง่ƒฝใ‚’ๅพ—ใ‚‹ใŸใ‚ใฎ๏ผ‰ๆจ™ๆบ–๏ผˆ`standard`๏ผ‰ใฎ่ฟฝๅŠ ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใจGunicornใฎไธกๆ–นใŒใ‚คใƒณใ‚นใƒˆใƒผใƒซใ•ใ‚Œใพใ™ใ€‚ + +## Uvicornใฎใƒฏใƒผใ‚ซใƒผใจใจใ‚‚ใซGunicornใ‚’ๅฎŸ่กŒใ™ใ‚‹ + +Gunicornใ‚’ไปฅไธ‹ใฎใ‚ˆใ†ใซ่ตทๅ‹•ใ•ใ›ใ‚‹ใ“ใจใŒใงใใพใ™: + +
+ +```console +$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80 + +[19499] [INFO] Starting gunicorn 20.1.0 +[19499] [INFO] Listening at: http://0.0.0.0:80 (19499) +[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker +[19511] [INFO] Booting worker with pid: 19511 +[19513] [INFO] Booting worker with pid: 19513 +[19514] [INFO] Booting worker with pid: 19514 +[19515] [INFO] Booting worker with pid: 19515 +[19511] [INFO] Started server process [19511] +[19511] [INFO] Waiting for application startup. +[19511] [INFO] Application startup complete. +[19513] [INFO] Started server process [19513] +[19513] [INFO] Waiting for application startup. +[19513] [INFO] Application startup complete. +[19514] [INFO] Started server process [19514] +[19514] [INFO] Waiting for application startup. +[19514] [INFO] Application startup complete. +[19515] [INFO] Started server process [19515] +[19515] [INFO] Waiting for application startup. +[19515] [INFO] Application startup complete. +``` + +
+ +ใใ‚Œใžใ‚Œใฎใ‚ชใƒ—ใ‚ทใƒงใƒณใฎๆ„ๅ‘ณใ‚’่ฆ‹ใฆใฟใพใ—ใ‚‡ใ†๏ผš + +* `main:app`๏ผš `main`ใฏ"`main`"ใจใ„ใ†ๅๅ‰ใฎPythonใƒขใ‚ธใƒฅใƒผใƒซใ€ใคใพใ‚Šใƒ•ใ‚กใ‚คใƒซ`main.py`ใ‚’ๆ„ๅ‘ณใ—ใพใ™ใ€‚ใใ—ใฆ `app` ใฏ **FastAPI** ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎๅค‰ๆ•ฐๅใงใ™ใ€‚ + * main:app`ใฏPythonใฎ`import`ๆ–‡ใจๅŒใ˜ใ‚ˆใ†ใชใ‚‚ใฎใ ใจๆƒณๅƒใงใใพใ™๏ผš + + ```Python + from main import app + ``` + + * ใคใพใ‚Šใ€`main:app`ใฎใ‚ณใƒญใƒณใฏใ€`from main import app`ใฎPythonใฎ`import`ใฎ้ƒจๅˆ†ใจๅŒใ˜ใซใชใ‚Šใพใ™ใ€‚ + +* `--workers`๏ผš ไฝฟ็”จใ™ใ‚‹ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใฎๆ•ฐใงใ€ใใ‚Œใžใ‚ŒใŒUvicornใฎใƒฏใƒผใ‚ซใƒผใ‚’ๅฎŸ่กŒใ—ใพใ™ใ€‚ + +* `--worker-class`๏ผš ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใงไฝฟ็”จใ™ใ‚‹Gunicornไบ’ๆ›ใฎใƒฏใƒผใ‚ซใƒผใ‚ฏใƒฉใ‚นใงใ™ใ€‚ + * ใ“ใ“ใงใฏGunicornใŒใ‚คใƒณใƒใƒผใƒˆใ—ใฆไฝฟ็”จใงใใ‚‹ใ‚ฏใƒฉใ‚นใ‚’ๆธกใ—ใพใ™๏ผš + + ```Python + import uvicorn.workers.UvicornWorker + ``` + +* `--bind`๏ผš Gunicornใซใƒชใƒƒใ‚นใƒณใ™ใ‚‹IPใจใƒใƒผใƒˆใ‚’ไผใˆใพใ™ใ€‚ใ‚ณใƒญใƒณ(`:`)ใงIPใจใƒใƒผใƒˆใ‚’ๅŒบๅˆ‡ใ‚Šใพใ™ใ€‚ + * Uvicornใ‚’็›ดๆŽฅๅฎŸ่กŒใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€`--bind 0.0.0.0:80` ๏ผˆGunicornใฎใ‚ชใƒ—ใ‚ทใƒงใƒณ๏ผ‰ใฎไปฃใ‚ใ‚Šใซใ€`--host 0.0.0.0`ใจ `--port 80`ใ‚’ไฝฟใ„ใพใ™ใ€‚ + +ๅ‡บๅŠ›ใงใฏใ€ๅ„ใƒ—ใƒญใ‚ปใ‚นใฎ**PID**๏ผˆใƒ—ใƒญใ‚ปใ‚นID๏ผ‰ใŒ่กจ็คบใ•ใ‚Œใฆใ„ใ‚‹ใฎใŒใ‚ใ‹ใ‚Šใพใ™๏ผˆๅ˜ใชใ‚‹ๆ•ฐๅญ—ใงใ™๏ผ‰ใ€‚ + +ไปฅไธ‹ใฎ้€šใ‚Šใงใ™๏ผš + +* Gunicornใฎ**ใƒ—ใƒญใ‚ปใ‚นใƒปใƒžใƒใƒผใ‚ธใƒฃใƒผ**ใฏPID `19499`๏ผˆใ‚ใชใŸใฎๅ ดๅˆใฏ้•ใ†็•ชๅทใงใ—ใ‚‡ใ†๏ผ‰ใงๅง‹ใพใ‚Šใพใ™ใ€‚ +* ๆฌกใซใ€`Listening at: http://0.0.0.0:80`ใ‚’้–‹ๅง‹ใ—ใพใ™ใ€‚ +* ใใ‚Œใ‹ใ‚‰ `uvicorn.workers.UvicornWorker` ใงใƒฏใƒผใ‚ซใƒผใ‚ฏใƒฉใ‚นใ‚’ไฝฟ็”จใ™ใ‚‹ใ“ใจใ‚’ๆคœๅ‡บใ—ใพใ™ใ€‚ +* ใใ—ใฆใ€**4ใคใฎใƒฏใƒผใ‚ซใƒผ**ใ‚’่ตทๅ‹•ใ—ใพใ™ใ€‚ใใ‚Œใžใ‚Œใฎใƒฏใƒผใ‚ซใƒผใฎPIDใฏใ€`19511`ใ€`19513`ใ€`19514`ใ€`19515`ใงใ™ใ€‚ + +GunicornใฏใพใŸใ€ใƒฏใƒผใ‚ซใƒผใฎๆ•ฐใ‚’็ถญๆŒใ™ใ‚‹ใŸใ‚ใซๅฟ…่ฆใงใ‚ใ‚Œใฐใ€**ใƒ€ใ‚ฆใƒณใ—ใŸใƒ—ใƒญใ‚ปใ‚น**ใ‚’็ฎก็†ใ—ใ€**ๆ–ฐใ—ใ„ใƒ—ใƒญใ‚ปใ‚นใ‚’**ๅ†่ตทๅ‹•**ใ•ใ›ใพใ™ใ€‚ใใฎใŸใ‚ใ€ไธŠ่จ˜ใฎใƒชใ‚นใƒˆใซใ‚ใ‚‹**ๅ†่ตทๅ‹•**ใฎๆฆ‚ๅฟตใซไธ€้ƒจๅฝน็ซ‹ใกใพใ™ใ€‚ + +ใ—ใ‹ใ—ใชใŒใ‚‰ใ€ๅฟ…่ฆใงใ‚ใ‚ŒใฐGunicornใ‚’**ๅ†่ตทๅ‹•**ใ•ใ›ใ€**่ตทๅ‹•ๆ™‚ใซๅฎŸ่กŒ**ใ•ใ›ใ‚‹ใชใฉใ€ๅค–้ƒจใฎใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ๆŒใŸใ›ใ‚‹ใ“ใจใ‚‚ๅฟ…่ฆใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ + +## Uvicornใจใƒฏใƒผใ‚ซใƒผ + +Uvicornใซใฏ่ค‡ๆ•ฐใฎ**ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’่ตทๅ‹•ใ—ๅฎŸ่กŒใ™ใ‚‹ใ‚ชใƒ—ใ‚ทใƒงใƒณใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ + +ใจใฏใ„ใ†ใ‚‚ใฎใฎใ€ไปŠใฎใจใ“ใ‚Uvicornใฎใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใ‚’ๆ‰ฑใ†ๆฉŸ่ƒฝใฏGunicornใ‚ˆใ‚Šใ‚‚ๅˆถ้™ใ•ใ‚Œใฆใ„ใพใ™ใ€‚ใใฎใŸใ‚ใ€ใ“ใฎใƒฌใƒ™ใƒซ๏ผˆPythonใƒฌใƒ™ใƒซ๏ผ‰ใงใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผใ‚’ๆŒใกใŸใ„ใฎใงใ‚ใ‚Œใฐใ€Gunicornใ‚’ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใƒผใจใ—ใฆไฝฟใฃใฆใฟใŸๆ–นใŒ่ณขๆ˜Žใ‹ใ‚‚ใ—ใ‚Œใชใ„ใงใ™ใ€‚ + +ใฉใ‚“ใชๅ ดๅˆใงใ‚ใ‚Œใ€ไปฅไธ‹ใฎใ‚ˆใ†ใซๅฎŸ่กŒใ—ใพใ™๏ผš + +
+ +```console +$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4 +INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit) +INFO: Started parent process [27365] +INFO: Started server process [27368] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Started server process [27369] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Started server process [27370] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Started server process [27367] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +
+ +ใ“ใ“ใงๅ”ฏไธ€ใฎๆ–ฐใ—ใ„ใ‚ชใƒ—ใ‚ทใƒงใƒณใฏ `--workers` ใงใ€Uvicornใซ4ใคใฎใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใ‚’่ตทๅ‹•ใ™ใ‚‹ใ‚ˆใ†ใซๆŒ‡็คบใ—ใฆใ„ใพใ™ใ€‚ + +ๅ„ใƒ—ใƒญใ‚ปใ‚นใฎ **PID** ใŒ่กจ็คบใ•ใ‚Œใ€่ฆชใƒ—ใƒญใ‚ปใ‚นใฎ `27365` (ใ“ใ‚Œใฏ **ใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃ**) ใจใ€ๅ„ใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚นใฎ **PID** ใŒ่กจ็คบใ•ใ‚Œใพใ™๏ผš `27368`ใ€`27369`ใ€`27370`ใ€`27367`ใซใชใ‚Šใพใ™ใ€‚ + +## ใƒ‡ใƒ—ใƒญใ‚คใƒกใƒณใƒˆใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ + +ใ“ใ“ใงใฏใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎๅฎŸ่กŒใ‚’**ไธฆๅˆ—ๅŒ–**ใ—ใ€CPUใฎ**ใƒžใƒซใƒใ‚ณใ‚ข**ใ‚’ๆดป็”จใ—ใ€**ใ‚ˆใ‚Šๅคšใใฎใƒชใ‚ฏใ‚จใ‚นใƒˆ**ใซๅฏพๅฟœใงใใ‚‹ใ‚ˆใ†ใซใ™ใ‚‹ใŸใ‚ใซใ€**Gunicorn**๏ผˆใพใŸใฏUvicorn๏ผ‰ใ‚’ไฝฟ็”จใ—ใฆ**Uvicornใƒฏใƒผใ‚ซใƒผใƒปใƒ—ใƒญใ‚ปใ‚น**ใ‚’็ฎก็†ใ™ใ‚‹ๆ–นๆณ•ใ‚’่ฆ‹ใฆใ„ใใพใ—ใŸใ€‚ + +ไธŠ่จ˜ใฎใƒ‡ใƒ—ใƒญใ‚คใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆใฎใƒชใ‚นใƒˆใ‹ใ‚‰ใ€ใƒฏใƒผใ‚ซใƒผใ‚’ไฝฟใ†ใ“ใจใฏไธปใซ**ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ**ใฎ้ƒจๅˆ†ใจใ€**ๅ†่ตทๅ‹•**ใ‚’ๅฐ‘ใ—ๅŠฉใ‘ใฆใใ‚Œใพใ™๏ผš + +* ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ - HTTPS +* ่ตทๅ‹•ๆ™‚ใฎๅฎŸ่กŒ +* ๅ†่ตทๅ‹• +* ใƒฌใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ๏ผˆๅฎŸ่กŒไธญใฎใƒ—ใƒญใ‚ปใ‚นๆ•ฐ๏ผ‰ +* ใƒกใƒขใƒชใƒผ +* ้–‹ๅง‹ๅ‰ใฎไบ‹ๅ‰ใฎใ‚นใƒ†ใƒƒใƒ— + + +## ใ‚ณใƒณใƒ†ใƒŠใจDocker + +ๆฌก็ซ ใฎ[ใ‚ณใƒณใƒ†ใƒŠๅ†…ใฎFastAPI - Docker](./docker.md){.internal-link target=_blank}ใงใฏใ€ใใฎไป–ใฎ**ใƒ‡ใƒ—ใƒญใ‚คใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ**ใ‚’ๆ‰ฑใ†ใŸใ‚ใซๅฎŸๆ–ฝใ™ใ‚‹ใงใ‚ใ‚ใ†ๆˆฆ็•ฅใ‚’ใ„ใใคใ‹็ดนไป‹ใ—ใพใ™ใ€‚ + +ใพใŸใ€**GunicornใจUvicornใƒฏใƒผใ‚ซใƒผ**ใ‚’ๅซใ‚€**ๅ…ฌๅผDockerใ‚คใƒกใƒผใ‚ธ**ใจใ€็ฐกๅ˜ใชใ‚ฑใƒผใ‚นใซๅฝน็ซ‹ใคใ„ใใคใ‹ใฎใƒ‡ใƒ•ใ‚ฉใƒซใƒˆ่จญๅฎšใ‚‚็ดนไป‹ใ—ใพใ™ใ€‚ + +ใพใŸใ€(Gunicornใ‚’ไฝฟใ‚ใšใซ)Uvicornใƒ—ใƒญใ‚ปใ‚นใ‚’1ใคใ ใ‘ๅฎŸ่กŒใ™ใ‚‹ใŸใ‚ใซใ€**ใ‚ผใƒญใ‹ใ‚‰็‹ฌ่‡ชใฎใ‚คใƒกใƒผใ‚ธใ‚’**ๆง‹็ฏ‰ใ™ใ‚‹ๆ–นๆณ•ใ‚‚็ดนไป‹ใ—ใพใ™ใ€‚ใ“ใ‚Œใฏ็ฐกๅ˜ใชใƒ—ใƒญใ‚ปใ‚นใงใ€ใŠใใ‚‰ใ**Kubernetes**ใฎใ‚ˆใ†ใชๅˆ†ๆ•ฃใ‚ณใƒณใƒ†ใƒŠ็ฎก็†ใ‚ทใ‚นใƒ†ใƒ ใ‚’ไฝฟใ†ใจใใซใ‚„ใ‚ŠใŸใ„ใ“ใจใงใ—ใ‚‡ใ†ใ€‚ + +## ใพใจใ‚ + +Uvicornใƒฏใƒผใ‚ซใƒผใ‚’ไฝฟใฃใŸใƒ—ใƒญใ‚ปใ‚นใƒžใƒใƒผใ‚ธใƒฃใจใ—ใฆ**Gunicorn**๏ผˆใพใŸใฏUvicorn๏ผ‰ใ‚’ไฝฟใˆใฐใ€**ใƒžใƒซใƒใ‚ณใ‚ขCPU**ใ‚’ๆดป็”จใ—ใฆ**่ค‡ๆ•ฐใฎใƒ—ใƒญใ‚ปใ‚นใ‚’ไธฆๅˆ—ๅฎŸ่กŒ**ใงใใพใ™ใ€‚ + +ใ“ใ‚Œใ‚‰ใฎใƒ„ใƒผใƒซใ‚„ใ‚ขใ‚คใƒ‡ใ‚ขใฏใ€**ใ‚ใชใŸ่‡ช่บซใฎใƒ‡ใƒ—ใƒญใ‚คใ‚ทใ‚นใƒ†ใƒ **ใ‚’ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ—ใชใŒใ‚‰ใ€ไป–ใฎใƒ‡ใƒ—ใƒญใ‚คใ‚ณใƒณใ‚ปใƒ—ใƒˆใ‚’่‡ชๅˆ†ใง่กŒใ†ๅ ดๅˆใซใ‚‚ไฝฟใˆใพใ™ใ€‚ + +ๆฌกใฎ็ซ ใงใฏใ€ใ‚ณใƒณใƒ†ใƒŠ๏ผˆDockerใ‚„Kubernetesใชใฉ๏ผ‰ใ‚’ไฝฟใฃใŸ**FastAPI**ใซใคใ„ใฆๅญฆใ‚“ใงใ„ใใพใ—ใ‚‡ใ†ใ€‚ใ“ใ‚Œใ‚‰ใฎใƒ„ใƒผใƒซใซใฏใ€ไป–ใฎ**ใƒ‡ใƒ—ใƒญใ‚คใฎใ‚ณใƒณใ‚ปใƒ—ใƒˆ**ใ‚‚่งฃๆฑบใ™ใ‚‹็ฐกๅ˜ใชๆ–นๆณ•ใŒใ‚ใ‚‹ใ“ใจใŒใ‚ใ‹ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚โœจ diff --git a/docs/ja/docs/advanced/conditional-openapi.md b/docs/ja/docs/how-to/conditional-openapi.md similarity index 100% rename from docs/ja/docs/advanced/conditional-openapi.md rename to docs/ja/docs/how-to/conditional-openapi.md diff --git a/docs/pt/docs/deployment/deta.md b/docs/pt/docs/deployment/deta.md deleted file mode 100644 index 9271bba42..000000000 --- a/docs/pt/docs/deployment/deta.md +++ /dev/null @@ -1,258 +0,0 @@ -# Implantaรงรฃo FastAPI na Deta - -Nessa seรงรฃo vocรช aprenderรก sobre como realizar a implantaรงรฃo de uma aplicaรงรฃo **FastAPI** na Deta utilizando o plano gratuito. ๐ŸŽ - -Isso tudo levarรก aproximadamente **10 minutos**. - -!!! info "Informaรงรฃo" - Deta รฉ uma patrocinadora do **FastAPI**. ๐ŸŽ‰ - -## Uma aplicaรงรฃo **FastAPI** simples - -* Crie e entre em um diretรณrio para a sua aplicaรงรฃo, por exemplo, `./fastapideta/`. - -### Cรณdigo FastAPI - -* Crie o arquivo `main.py` com: - -```Python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int): - return {"item_id": item_id} -``` - -### Requisitos - -Agora, no mesmo diretรณrio crie o arquivo `requirements.txt` com: - -```text -fastapi -``` - -!!! tip "Dica" - Vocรช nรฃo precisa instalar Uvicorn para realizar a implantaรงรฃo na Deta, embora provavelmente queira instalรก-lo para testar seu aplicativo localmente. - -### Estrutura de diretรณrio - -Agora vocรช terรก o diretรณrio `./fastapideta/` com dois arquivos: - -``` -. -โ””โ”€โ”€ main.py -โ””โ”€โ”€ requirements.txt -``` - -## Crie uma conta gratuita na Deta - -Agora crie uma conta gratuita na Deta, vocรช precisarรก apenas de um email e senha. - -Vocรช nem precisa de um cartรฃo de crรฉdito. - -## Instale a CLI - -Depois de ter sua conta criada, instale Deta CLI: - -=== "Linux, macOS" - -
- - ```console - $ curl -fsSL https://get.deta.dev/cli.sh | sh - ``` - -
- -=== "Windows PowerShell" - -
- - ```console - $ iwr https://get.deta.dev/cli.ps1 -useb | iex - ``` - -
- -Apรณs a instalaรงรฃo, abra um novo terminal para que a CLI seja detectada. - -Em um novo terminal, confirme se foi instalado corretamente com: - -
- -```console -$ deta --help - -Deta command line interface for managing deta micros. -Complete documentation available at https://docs.deta.sh - -Usage: - deta [flags] - deta [command] - -Available Commands: - auth Change auth settings for a deta micro - -... -``` - -
- -!!! tip "Dica" - Se vocรช tiver problemas ao instalar a CLI, verifique a documentaรงรฃo oficial da Deta. - -## Login pela CLI - -Agora faรงa login na Deta pela CLI com: - -
- -```console -$ deta login - -Please, log in from the web page. Waiting.. -Logged in successfully. -``` - -
- -Isso abrirรก um navegador da Web e autenticarรก automaticamente. - -## Implantaรงรฃo com Deta - -Em seguida, implante seu aplicativo com a Deta CLI: - -
- -```console -$ deta new - -Successfully created a new micro - -// Notice the "endpoint" ๐Ÿ” - -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} - -Adding dependencies... - - ----> 100% - - -Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6 -``` - -
- -Vocรช verรก uma mensagem JSON semelhante a: - -```JSON hl_lines="4" -{ - "name": "fastapideta", - "runtime": "python3.7", - "endpoint": "https://qltnci.deta.dev", - "visor": "enabled", - "http_auth": "enabled" -} -``` - -!!! tip "Dica" - Sua implantaรงรฃo terรก um URL `"endpoint"` diferente. - -## Confira - -Agora, abra seu navegador na URL do `endpoint`. No exemplo acima foi `https://qltnci.deta.dev`, mas o seu serรก diferente. - -Vocรช verรก a resposta JSON do seu aplicativo FastAPI: - -```JSON -{ - "Hello": "World" -} -``` - -Agora vรก para o `/docs` da sua API, no exemplo acima seria `https://qltnci.deta.dev/docs`. - -Ele mostrarรก sua documentaรงรฃo como: - - - -## Permitir acesso pรบblico - -Por padrรฃo, a Deta lidarรก com a autenticaรงรฃo usando cookies para sua conta. - -Mas quando estiver pronto, vocรช pode tornรก-lo pรบblico com: - -
- -```console -$ deta auth disable - -Successfully disabled http auth -``` - -
- -Agora vocรช pode compartilhar essa URL com qualquer pessoa e elas conseguirรฃo acessar sua API. ๐Ÿš€ - -## HTTPS - -Parabรฉns! Vocรช realizou a implantaรงรฃo do seu app FastAPI na Deta! ๐ŸŽ‰ ๐Ÿฐ - -Alรฉm disso, observe que a Deta lida corretamente com HTTPS para vocรช, para que vocรช nรฃo precise cuidar disso e tenha a certeza de que seus clientes terรฃo uma conexรฃo criptografada segura. โœ… ๐Ÿ”’ - -## Verifique o Visor - -Na UI da sua documentaรงรฃo (vocรช estarรก em um URL como `https://qltnci.deta.dev/docs`) envie um request para *operaรงรฃo de rota* `/items/{item_id}`. - -Por exemplo com ID `5`. - -Agora vรก para https://web.deta.sh. - -Vocรช verรก que hรก uma seรงรฃo ร  esquerda chamada "Micros" com cada um dos seus apps. - -Vocรช verรก uma aba com "Detalhes", e tambรฉm a aba "Visor", vรก para "Visor". - -Lรก vocรช pode inspecionar as solicitaรงรตes recentes enviadas ao seu aplicativo. - -Vocรช tambรฉm pode editรก-los e reproduzi-los novamente. - - - -## Saiba mais - -Em algum momento, vocรช provavelmente desejarรก armazenar alguns dados para seu aplicativo de uma forma que persista ao longo do tempo. Para isso vocรช pode usar Deta Base, que tambรฉm tem um generoso **nรญvel gratuito**. - -Vocรช tambรฉm pode ler mais na documentaรงรฃo da Deta. - -## Conceitos de implantaรงรฃo - -Voltando aos conceitos que discutimos em [Deployments Concepts](./concepts.md){.internal-link target=_blank}, veja como cada um deles seria tratado com a Deta: - -* **HTTPS**: Realizado pela Deta, eles fornecerรฃo um subdomรญnio e lidarรฃo com HTTPS automaticamente. -* **Executando na inicializaรงรฃo**: Realizado pela Deta, como parte de seu serviรงo. -* **Reinicializaรงรฃo**: Realizado pela Deta, como parte de seu serviรงo. -* **Replicaรงรฃo**: Realizado pela Deta, como parte de seu serviรงo. -* **Memรณria**: Limite predefinido pela Deta, vocรช pode contatรก-los para aumentรก-lo. -* **Etapas anteriores a inicializaรงรฃo**: Nรฃo suportado diretamente, vocรช pode fazรช-lo funcionar com o sistema Cron ou scripts adicionais. - -!!! note "Nota" - O Deta foi projetado para facilitar (e gratuitamente) a implantaรงรฃo rรกpida de aplicativos simples. - - Ele pode simplificar vรกrios casos de uso, mas, ao mesmo tempo, nรฃo suporta outros, como o uso de bancos de dados externos (alรฉm do prรณprio sistema de banco de dados NoSQL da Deta), mรกquinas virtuais personalizadas, etc. - - Vocรช pode ler mais detalhes na documentaรงรฃo da Deta para ver se รฉ a escolha certa para vocรช. diff --git a/docs/uk/docs/fastapi-people.md b/docs/uk/docs/fastapi-people.md new file mode 100644 index 000000000..b32f0e5ce --- /dev/null +++ b/docs/uk/docs/fastapi-people.md @@ -0,0 +1,178 @@ +# ะ›ัŽะดะธ FastAPI + +FastAPI ะผะฐั” ะดะธะฒะพะฒะธะถะฝัƒ ัะฟั–ะปัŒะฝะพั‚ัƒ, ัะบะฐ ะฒั–ั‚ะฐั” ะปัŽะดะตะน ั€ั–ะทะฝะพะณะพ ะฟะพั…ะพะดะถะตะฝะฝั. + +## ะขะฒะพั€ะตั†ัŒ โ€“ ะกัƒะฟั€ะพะฒะพะดะถัƒะฒะฐั‡ + +ะŸั€ะธะฒั–ั‚! ๐Ÿ‘‹ + +ะฆะต ั: + +{% if people %} +
+{% for user in people.maintainers %} + +
@{{ user.login }}
Answers: {{ user.answers }}
Pull Requests: {{ user.prs }}
+{% endfor %} + +
+{% endif %} + +ะฏ - ั‚ะฒะพั€ะตั†ัŒ ั– ััƒะฟั€ะพะฒะพะดะถัƒะฒะฐั‡ **FastAPI**. ะ”ะตั‚ะฐะปัŒะฝั–ัˆะต ะฟั€ะพ ั†ะต ะผะพะถะฝะฐ ะฟั€ะพั‡ะธั‚ะฐั‚ะธ ะฒ [ะ”ะพะฒั–ะดะบะฐ FastAPI - ะžั‚ั€ะธะผะฐั‚ะธ ะดะพะฒั–ะดะบัƒ - ะ—ะฒ'ัะทะฐั‚ะธัั ะท ะฐะฒั‚ะพั€ะพะผ](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}. + +...ะะปะต ั‚ัƒั‚ ั ั…ะพั‡ัƒ ะฟะพะบะฐะทะฐั‚ะธ ะฒะฐะผ ัะฟั–ะปัŒะฝะพั‚ัƒ. + +--- + +**FastAPI** ะพั‚ั€ะธะผัƒั” ะฒะตะปะธะบัƒ ะฟั–ะดั‚ั€ะธะผะบัƒ ะฒั–ะด ัะฟั–ะปัŒะฝะพั‚ะธ. ะ† ั ั…ะพั‡ัƒ ะฒั–ะดะทะฝะฐั‡ะธั‚ะธ ั—ั…ะฝั–ะน ะฒะฝะตัะพะบ. + +ะฆะต ะปัŽะดะธ, ัะบั–: + +* [ะ”ะพะฟะพะผะฐะณะฐัŽั‚ัŒ ั–ะฝัˆะธะผ ั–ะท ะฟั€ะพะฑะปะตะผะฐะผะธ (ะทะฐะฟะธั‚ะฐะฝะฝัะผะธ) ัƒ GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}. +* [ะกั‚ะฒะพั€ัŽัŽั‚ัŒ ะฟัƒะป ั€ะตะบะฒะตัั‚ะธ](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}. +* ะŸะตั€ะตะณะปัะดะฐัŽั‚ัŒ ะฟัƒะป ั€ะตะบะฒะตัั‚ะธ, [ะพัะพะฑะปะธะฒะพ ะฒะฐะถะปะธะฒะพ ะดะปั ะฟะตั€ะตะบะปะฐะดั–ะฒ](contributing.md#translations){.internal-link target=_blank}. + +ะžะฟะปะตัะบะธ ั—ะผ. ๐Ÿ‘ ๐Ÿ™‡ + +## ะะฐะนะฑั–ะปัŒัˆ ะฐะบั‚ะธะฒะฝั– ะบะพั€ะธัั‚ัƒะฒะฐั‡ั– ะผะธะฝัƒะปะพะณะพ ะผั–ััั†ั + +ะฆะต ะบะพั€ะธัั‚ัƒะฒะฐั‡ั–, ัะบั– [ะฝะฐะนะฑั–ะปัŒัˆะต ะดะพะฟะพะผะฐะณะฐะปะธ ั–ะฝัˆะธะผ ั–ะท ะฟั€ะพะฑะปะตะผะฐะผะธ (ะทะฐะฟะธั‚ะฐะฝะฝัะผะธ) ัƒ GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} ะฟั€ะพั‚ัะณะพะผ ะผะธะฝัƒะปะพะณะพ ะผั–ััั†ั. โ˜• + +{% if people %} +
+{% for user in people.last_month_active %} + +
@{{ user.login }}
Issues replied: {{ user.count }}
+{% endfor %} + +
+{% endif %} + +## ะ•ะบัะฟะตั€ั‚ะธ + +ะžััŒ **ะตะบัะฟะตั€ั‚ะธ FastAPI**. ๐Ÿค“ + +ะฆะต ะบะพั€ะธัั‚ัƒะฒะฐั‡ั–, ัะบั– [ะฝะฐะนะฑั–ะปัŒัˆะต ะดะพะฟะพะผะฐะณะฐะปะธ ั–ะฝัˆะธะผ ั–ะท ะฟั€ะพะฑะปะตะผะฐะผะธ (ะทะฐะฟะธั‚ะฐะฝะฝัะผะธ) ัƒ GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} ะฟั€ะพั‚ัะณะพะผ *ะฒััŒะพะณะพ ั‡ะฐััƒ*. + +ะ’ะพะฝะธ ะทะฐั€ะตะบะพะผะตะฝะดัƒะฒะฐะปะธ ัะตะฑะต ัะบ ะตะบัะฟะตั€ั‚ะธ, ะดะพะฟะพะผะฐะณะฐัŽั‡ะธ ะฑะฐะณะฐั‚ัŒะพะผ ั–ะฝัˆะธะผ. โœจ + +{% if people %} +
+{% for user in people.experts %} + +
@{{ user.login }}
Issues replied: {{ user.count }}
+{% endfor %} + +
+{% endif %} + +## ะะฐะนะบั€ะฐั‰ั– ะบะพะฝั‚ั€ะธะฑัŽั‚ะพั€ะธ + +ะžััŒ **ะะฐะนะบั€ะฐั‰ั– ะบะพะฝั‚ั€ะธะฑัŽั‚ะพั€ะธ**. ๐Ÿ‘ท + +ะฆั– ะบะพั€ะธัั‚ัƒะฒะฐั‡ั– [ัั‚ะฒะพั€ะธะปะธ ะฝะฐะนะฑั–ะปัŒัˆัƒ ะบั–ะปัŒะบั–ัั‚ัŒ ะฟัƒะป ั€ะตะบะฒะตัั‚ั–ะฒ](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} ัะบั– ะฑัƒะปะธ *ะทะผะตั€ะถะตะฝั–*. + +ะ’ะพะฝะธ ะฝะฐะดะฐะปะธ ะฟั€ะพะณั€ะฐะผะฝะธะน ะบะพะด, ะดะพะบัƒะผะตะฝั‚ะฐั†ั–ัŽ, ะฟะตั€ะตะบะปะฐะดะธ ั‚ะพั‰ะพ. ๐Ÿ“ฆ + +{% if people %} +
+{% for user in people.top_contributors %} + +
@{{ user.login }}
Pull Requests: {{ user.count }}
+{% endfor %} + +
+{% endif %} + +ะ„ ะฑะฐะณะฐั‚ะพ ั–ะฝัˆะธั… ะบะพะฝั‚ั€ะธะฑัŽั‚ะพั€ั–ะฒ (ะฑั–ะปัŒัˆะต ัะพั‚ะฝั–), ั—ั… ัƒัั–ั… ะผะพะถะฝะฐ ะฟะพะฑะฐั‡ะธั‚ะธ ะฝะฐ ัั‚ะพั€ั–ะฝั†ั– FastAPI GitHub Contributors. ๐Ÿ‘ท + +## ะะฐะนะบั€ะฐั‰ั– ั€ะตั†ะตะฝะทะตะฝั‚ะธ + +ะฆั– ะบะพั€ะธัั‚ัƒะฒะฐั‡ั– ั” **ะะฐะนะบั€ะฐั‰ะธะผะธ ั€ะตั†ะตะฝะทะตะฝั‚ะฐะผะธ**. ๐Ÿ•ต๏ธ + +### ะ ะตั†ะตะฝะทะตะฝั‚ะธ ะฝะฐ ะฟะตั€ะตะบะปะฐะดะธ + +ะฏ ั€ะพะทะผะพะฒะปััŽ ะปะธัˆะต ะบั–ะปัŒะบะพะผะฐ ะผะพะฒะฐะผะธ (ั– ะฝะต ะดัƒะถะต ะดะพะฑั€ะต ๐Ÿ˜…). ะžั‚ะถะต, ั€ะตั†ะตะฝะทะตะฝั‚ะธ โ€“ ั†ะต ั‚ั–, ั…ั‚ะพ ะผะฐั” [**ะฟะพะฒะฝะพะฒะฐะถะตะฝะฝั ัั…ะฒะฐะปัŽะฒะฐั‚ะธ ะฟะตั€ะตะบะปะฐะดะธ**](contributing.md#translations){.internal-link target=_blank} ะดะพะบัƒะผะตะฝั‚ะฐั†ั–ั—. ะ‘ะตะท ะฝะธั… ะฝะต ะฑัƒะปะพ ะฑ ะดะพะบัƒะผะตะฝั‚ะฐั†ั–ั— ะบั–ะปัŒะบะพะผะฐ ั–ะฝัˆะธะผะธ ะผะพะฒะฐะผะธ. + +--- + +**ะะฐะนะบั€ะฐั‰ั– ั€ะตั†ะตะฝะทะตะฝั‚ะธ** ๐Ÿ•ต๏ธ ะฟะตั€ะตะณะปัะฝัƒะปะธ ะฑั–ะปัŒัˆั–ัั‚ัŒ ะฟัƒะป ั€ะตะบะฒะตัั‚ั–ะฒ ะฒั–ะด ั–ะฝัˆะธั…, ะทะฐะฑะตะทะฟะตั‡ัƒัŽั‡ะธ ัะบั–ัั‚ัŒ ะบะพะดัƒ, ะดะพะบัƒะผะตะฝั‚ะฐั†ั–ั— ั– ะพัะพะฑะปะธะฒะพ **ะฟะตั€ะตะบะปะฐะดั–ะฒ**. + +{% if people %} +
+{% for user in people.top_reviewers %} + +
@{{ user.login }}
Reviews: {{ user.count }}
+{% endfor %} + +
+{% endif %} + +## ะกะฟะพะฝัะพั€ะธ + +ะฆะต **ะกะฟะพะฝัะพั€ะธ**. ๐Ÿ˜Ž + +ะ’ะพะฝะธ ะฟั–ะดั‚ั€ะธะผัƒัŽั‚ัŒ ะผะพัŽ ั€ะพะฑะพั‚ัƒ ะท **FastAPI** (ั‚ะฐ ั–ะฝัˆะธะผะธ), ะฟะตั€ะตะฒะฐะถะฝะพ ั‡ะตั€ะตะท GitHub Sponsors. + +{% if sponsors %} + +{% if sponsors.gold %} + +### ะ—ะพะปะพั‚ั– ัะฟะพะฝัะพั€ะธ + +{% for sponsor in sponsors.gold -%} + +{% endfor %} +{% endif %} + +{% if sponsors.silver %} + +### ะกั€ั–ะฑะฝั– ัะฟะพะฝัะพั€ะธ + +{% for sponsor in sponsors.silver -%} + +{% endfor %} +{% endif %} + +{% if sponsors.bronze %} + +### ะ‘ั€ะพะฝะทะพะฒั– ัะฟะพะฝัะพั€ะธ + +{% for sponsor in sponsors.bronze -%} + +{% endfor %} +{% endif %} + +{% endif %} + +### ะ†ะฝะดะธะฒั–ะดัƒะฐะปัŒะฝั– ัะฟะพะฝัะพั€ะธ + +{% if github_sponsors %} +{% for group in github_sponsors.sponsors %} + +
+ +{% for user in group %} +{% if user.login not in sponsors_badge.logins %} + +
@{{ user.login }}
+ +{% endif %} +{% endfor %} + +
+ +{% endfor %} +{% endif %} + +## ะŸั€ะพ ะดะฐะฝั– - ั‚ะตั…ะฝั–ั‡ะฝั– ะดะตั‚ะฐะปั– + +ะžัะฝะพะฒะฝะฐ ะผะตั‚ะฐ ั†ั–ั”ั— ัั‚ะพั€ั–ะฝะบะธ โ€“ ะฒะธัะฒั–ั‚ะปะธั‚ะธ ะทัƒัะธะปะปั ัะฟั–ะปัŒะฝะพั‚ะธ, ั‰ะพะฑ ะดะพะฟะพะผะพะณั‚ะธ ั–ะฝัˆะธะผ. + +ะžัะพะฑะปะธะฒะพ ะฒั€ะฐั…ะพะฒัƒัŽั‡ะธ ะทัƒัะธะปะปั, ัะบั– ะทะฐะทะฒะธั‡ะฐะน ะผะตะฝัˆ ะฟะพะผั–ั‚ะฝั–, ะฐ ะฒ ะฑะฐะณะฐั‚ัŒะพั… ะฒะธะฟะฐะดะบะฐั… ะฑั–ะปัŒัˆ ะฒะฐะถะบั–, ัะบ-ะพั‚ ะดะพะฟะพะผะพะณะฐ ั–ะฝัˆะธะผ ั–ะท ะฟั€ะพะฑะปะตะผะฐะผะธ ั‚ะฐ ะฟะตั€ะตะณะปัะด ะฟัƒะป ั€ะตะบะฒะตัั‚ั–ะฒ ะฟะตั€ะตะบะปะฐะดั–ะฒ. + +ะ”ะฐะฝั– ั€ะพะทั€ะฐั…ะพะฒัƒัŽั‚ัŒัั ั‰ะพะผั–ััั†ั, ะฒะธ ะผะพะถะตั‚ะต ะพะทะฝะฐะนะพะผะธั‚ะธัั ะท ะฒะธั…ั–ะดะฝะธะผ ะบะพะดะพะผ ั‚ัƒั‚. + +ะขัƒั‚ ั ั‚ะฐะบะพะถ ะฟั–ะดะบั€ะตัะปัŽัŽ ะฒะฝะตัะบะธ ัะฟะพะฝัะพั€ั–ะฒ. + +ะฏ ั‚ะฐะบะพะถ ะทะฐะปะธัˆะฐัŽ ะทะฐ ัะพะฑะพัŽ ะฟั€ะฐะฒะพ ะพะฝะพะฒะปัŽะฒะฐั‚ะธ ะฐะปะณะพั€ะธั‚ะผะธ ะฟั–ะดั€ะฐั…ัƒะฝะบัƒ, ะฒะธะดะธ ั€ะตะนั‚ะธะฝะณั–ะฒ, ะฟะพั€ะพะณะพะฒั– ะทะฝะฐั‡ะตะฝะฝั ั‚ะพั‰ะพ (ะฟั€ะพ ะฒััะบ ะฒะธะฟะฐะดะพะบ ๐Ÿคท). diff --git a/docs_src/extending_openapi/tutorial003.py b/docs_src/configure_swagger_ui/tutorial001.py similarity index 100% rename from docs_src/extending_openapi/tutorial003.py rename to docs_src/configure_swagger_ui/tutorial001.py diff --git a/docs_src/extending_openapi/tutorial004.py b/docs_src/configure_swagger_ui/tutorial002.py similarity index 100% rename from docs_src/extending_openapi/tutorial004.py rename to docs_src/configure_swagger_ui/tutorial002.py diff --git a/docs_src/extending_openapi/tutorial005.py b/docs_src/configure_swagger_ui/tutorial003.py similarity index 100% rename from docs_src/extending_openapi/tutorial005.py rename to docs_src/configure_swagger_ui/tutorial003.py diff --git a/docs_src/custom_docs_ui/tutorial001.py b/docs_src/custom_docs_ui/tutorial001.py new file mode 100644 index 000000000..f7ceb0c2f --- /dev/null +++ b/docs_src/custom_docs_ui/tutorial001.py @@ -0,0 +1,38 @@ +from fastapi import FastAPI +from fastapi.openapi.docs import ( + get_redoc_html, + get_swagger_ui_html, + get_swagger_ui_oauth2_redirect_html, +) + +app = FastAPI(docs_url=None, redoc_url=None) + + +@app.get("/docs", include_in_schema=False) +async def custom_swagger_ui_html(): + return get_swagger_ui_html( + openapi_url=app.openapi_url, + title=app.title + " - Swagger UI", + oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url, + swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js", + swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css", + ) + + +@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False) +async def swagger_ui_redirect(): + return get_swagger_ui_oauth2_redirect_html() + + +@app.get("/redoc", include_in_schema=False) +async def redoc_html(): + return get_redoc_html( + openapi_url=app.openapi_url, + title=app.title + " - ReDoc", + redoc_js_url="https://unpkg.com/redoc@next/bundles/redoc.standalone.js", + ) + + +@app.get("/users/{username}") +async def read_user(username: str): + return {"message": f"Hello {username}"} diff --git a/docs_src/extending_openapi/tutorial002.py b/docs_src/custom_docs_ui/tutorial002.py similarity index 100% rename from docs_src/extending_openapi/tutorial002.py rename to docs_src/custom_docs_ui/tutorial002.py diff --git a/fastapi/__init__.py b/fastapi/__init__.py index c113ac1fd..d8abf2103 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.101.0" +__version__ = "0.101.1" from starlette import status as status diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py index 21b47b9cb..808c86b39 100644 --- a/fastapi/exceptions.py +++ b/fastapi/exceptions.py @@ -48,6 +48,12 @@ class ResponseValidationError(ValidationException): super().__init__(errors) self.body = body + def __str__(self) -> str: + message = f"{len(self._errors)} validation errors:\n" + for err in self._errors: + message += f" {err}\n" + return message + class RouteAlreadyExistsError(FastAPIError): def __init__(self, f_name: str): diff --git a/requirements-docs.txt b/requirements-docs.txt index 220d1ec3a..2e667720e 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -2,6 +2,7 @@ mkdocs-material==9.1.21 mdx-include >=1.4.1,<2.0.0 mkdocs-markdownextradata-plugin >=0.1.7,<0.3.0 +mkdocs-redirects>=1.2.1,<1.3.0 typer-cli >=0.0.13,<0.0.14 typer[all] >=0.6.1,<0.8.0 pyyaml >=5.3.1,<7.0.0 diff --git a/requirements-tests.txt b/requirements-tests.txt index 0113b6f7a..6f7f4ac23 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -11,7 +11,6 @@ dirty-equals ==0.6.0 # TODO: once removing databases from tutorial, upgrade SQLAlchemy # probably when including SQLModel sqlalchemy >=1.3.18,<1.4.43 -peewee >=3.13.3,<4.0.0 databases[sqlite] >=0.3.2,<0.7.0 orjson >=3.2.1,<4.0.0 ujson >=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0 diff --git a/tests/test_multi_body_errors.py b/tests/test_multi_body_errors.py index 931f08fc1..a51ca7253 100644 --- a/tests/test_multi_body_errors.py +++ b/tests/test_multi_body_errors.py @@ -51,7 +51,7 @@ def test_jsonable_encoder_requiring_error(): "loc": ["body", 0, "age"], "msg": "Input should be greater than 0", "input": -1.0, - "ctx": {"gt": "0"}, + "ctx": {"gt": 0}, "url": match_pydantic_error_url("greater_than"), } ] @@ -84,25 +84,12 @@ def test_put_incorrect_body_multiple(): "input": {"age": "five"}, "url": match_pydantic_error_url("missing"), }, - { - "ctx": {"class": "Decimal"}, - "input": "five", - "loc": ["body", 0, "age", "is-instance[Decimal]"], - "msg": "Input should be an instance of Decimal", - "type": "is_instance_of", - "url": match_pydantic_error_url("is_instance_of"), - }, { "type": "decimal_parsing", - "loc": [ - "body", - 0, - "age", - "function-after[to_decimal(), " - "union[int,constrained-str,function-plain[str()]]]", - ], + "loc": ["body", 0, "age"], "msg": "Input should be a valid decimal", "input": "five", + "url": match_pydantic_error_url("decimal_parsing"), }, { "type": "missing", @@ -111,25 +98,12 @@ def test_put_incorrect_body_multiple(): "input": {"age": "six"}, "url": match_pydantic_error_url("missing"), }, - { - "ctx": {"class": "Decimal"}, - "input": "six", - "loc": ["body", 1, "age", "is-instance[Decimal]"], - "msg": "Input should be an instance of Decimal", - "type": "is_instance_of", - "url": match_pydantic_error_url("is_instance_of"), - }, { "type": "decimal_parsing", - "loc": [ - "body", - 1, - "age", - "function-after[to_decimal(), " - "union[int,constrained-str,function-plain[str()]]]", - ], + "loc": ["body", 1, "age"], "msg": "Input should be a valid decimal", "input": "six", + "url": match_pydantic_error_url("decimal_parsing"), }, ] } diff --git a/tests/test_response_model_as_return_annotation.py b/tests/test_response_model_as_return_annotation.py index 85dd450eb..6948430a1 100644 --- a/tests/test_response_model_as_return_annotation.py +++ b/tests/test_response_model_as_return_annotation.py @@ -277,13 +277,15 @@ def test_response_model_no_annotation_return_exact_dict(): def test_response_model_no_annotation_return_invalid_dict(): - with pytest.raises(ResponseValidationError): + with pytest.raises(ResponseValidationError) as excinfo: client.get("/response_model-no_annotation-return_invalid_dict") + assert "missing" in str(excinfo.value) def test_response_model_no_annotation_return_invalid_model(): - with pytest.raises(ResponseValidationError): + with pytest.raises(ResponseValidationError) as excinfo: client.get("/response_model-no_annotation-return_invalid_model") + assert "missing" in str(excinfo.value) def test_response_model_no_annotation_return_dict_with_extra_data(): @@ -313,13 +315,15 @@ def test_no_response_model_annotation_return_exact_dict(): def test_no_response_model_annotation_return_invalid_dict(): - with pytest.raises(ResponseValidationError): + with pytest.raises(ResponseValidationError) as excinfo: client.get("/no_response_model-annotation-return_invalid_dict") + assert "missing" in str(excinfo.value) def test_no_response_model_annotation_return_invalid_model(): - with pytest.raises(ResponseValidationError): + with pytest.raises(ResponseValidationError) as excinfo: client.get("/no_response_model-annotation-return_invalid_model") + assert "missing" in str(excinfo.value) def test_no_response_model_annotation_return_dict_with_extra_data(): @@ -395,13 +399,15 @@ def test_response_model_model1_annotation_model2_return_exact_dict(): def test_response_model_model1_annotation_model2_return_invalid_dict(): - with pytest.raises(ResponseValidationError): + with pytest.raises(ResponseValidationError) as excinfo: client.get("/response_model_model1-annotation_model2-return_invalid_dict") + assert "missing" in str(excinfo.value) def test_response_model_model1_annotation_model2_return_invalid_model(): - with pytest.raises(ResponseValidationError): + with pytest.raises(ResponseValidationError) as excinfo: client.get("/response_model_model1-annotation_model2-return_invalid_model") + assert "missing" in str(excinfo.value) def test_response_model_model1_annotation_model2_return_dict_with_extra_data(): diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001.py b/tests/test_tutorial/test_body_updates/test_tutorial001.py index f1a46210a..58587885e 100644 --- a/tests/test_tutorial/test_body_updates/test_tutorial001.py +++ b/tests/test_tutorial/test_body_updates/test_tutorial001.py @@ -53,7 +53,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -87,7 +87,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -116,7 +116,7 @@ def test_openapi_schema(client: TestClient): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -126,7 +126,7 @@ def test_openapi_schema(client: TestClient): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "type": "object", "properties": { @@ -151,7 +151,7 @@ def test_openapi_schema(client: TestClient): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "type": "object", "required": ["name", "description", "price", "tax", "tags"], diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py b/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py index ab696e4c8..d8a62502f 100644 --- a/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py +++ b/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py @@ -56,7 +56,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -90,7 +90,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -119,7 +119,7 @@ def test_openapi_schema(client: TestClient): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -129,7 +129,7 @@ def test_openapi_schema(client: TestClient): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "type": "object", "properties": { @@ -154,7 +154,7 @@ def test_openapi_schema(client: TestClient): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "type": "object", "required": ["name", "description", "price", "tax", "tags"], diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py b/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py index 2ee6a5cb4..c604df6ec 100644 --- a/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py +++ b/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py @@ -56,7 +56,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -90,7 +90,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -119,7 +119,7 @@ def test_openapi_schema(client: TestClient): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -129,7 +129,7 @@ def test_openapi_schema(client: TestClient): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "type": "object", "properties": { @@ -154,7 +154,7 @@ def test_openapi_schema(client: TestClient): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "type": "object", "required": ["name", "description", "price", "tax", "tags"], diff --git a/docs_src/sql_databases_peewee/__init__.py b/tests/test_tutorial/test_configure_swagger_ui/__init__.py similarity index 100% rename from docs_src/sql_databases_peewee/__init__.py rename to tests/test_tutorial/test_configure_swagger_ui/__init__.py diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial003.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py similarity index 95% rename from tests/test_tutorial/test_extending_openapi/test_tutorial003.py rename to tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py index 0184dd9f8..72db54bd2 100644 --- a/tests/test_tutorial/test_extending_openapi/test_tutorial003.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.extending_openapi.tutorial003 import app +from docs_src.configure_swagger_ui.tutorial001 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial004.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py similarity index 96% rename from tests/test_tutorial/test_extending_openapi/test_tutorial004.py rename to tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py index 4f7615126..166901188 100644 --- a/tests/test_tutorial/test_extending_openapi/test_tutorial004.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.extending_openapi.tutorial004 import app +from docs_src.configure_swagger_ui.tutorial002 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial005.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py similarity index 96% rename from tests/test_tutorial/test_extending_openapi/test_tutorial005.py rename to tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py index 24aeb93db..187e89ace 100644 --- a/tests/test_tutorial/test_extending_openapi/test_tutorial005.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.extending_openapi.tutorial005 import app +from docs_src.configure_swagger_ui.tutorial003 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_sql_databases_peewee/__init__.py b/tests/test_tutorial/test_custom_docs_ui/__init__.py similarity index 100% rename from tests/test_tutorial/test_sql_databases_peewee/__init__.py rename to tests/test_tutorial/test_custom_docs_ui/__init__.py diff --git a/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py b/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py new file mode 100644 index 000000000..aff070d74 --- /dev/null +++ b/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py @@ -0,0 +1,42 @@ +import os +from pathlib import Path + +import pytest +from fastapi.testclient import TestClient + + +@pytest.fixture(scope="module") +def client(): + static_dir: Path = Path(os.getcwd()) / "static" + print(static_dir) + static_dir.mkdir(exist_ok=True) + from docs_src.custom_docs_ui.tutorial001 import app + + with TestClient(app) as client: + yield client + static_dir.rmdir() + + +def test_swagger_ui_html(client: TestClient): + response = client.get("/docs") + assert response.status_code == 200, response.text + assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js" in response.text + assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" in response.text + + +def test_swagger_ui_oauth2_redirect_html(client: TestClient): + response = client.get("/docs/oauth2-redirect") + assert response.status_code == 200, response.text + assert "window.opener.swaggerUIRedirectOauth2" in response.text + + +def test_redoc_html(client: TestClient): + response = client.get("/redoc") + assert response.status_code == 200, response.text + assert "https://unpkg.com/redoc@next/bundles/redoc.standalone.js" in response.text + + +def test_api(client: TestClient): + response = client.get("/users/john") + assert response.status_code == 200, response.text + assert response.json()["message"] == "Hello john" diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial002.py b/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py similarity index 95% rename from tests/test_tutorial/test_extending_openapi/test_tutorial002.py rename to tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py index 654db2e4c..712618807 100644 --- a/tests/test_tutorial/test_extending_openapi/test_tutorial002.py +++ b/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py @@ -10,7 +10,7 @@ def client(): static_dir: Path = Path(os.getcwd()) / "static" print(static_dir) static_dir.mkdir(exist_ok=True) - from docs_src.extending_openapi.tutorial002 import app + from docs_src.custom_docs_ui.tutorial002 import app with TestClient(app) as client: yield client diff --git a/tests/test_tutorial/test_dataclasses/test_tutorial003.py b/tests/test_tutorial/test_dataclasses/test_tutorial003.py index 2e5809914..f2ca85823 100644 --- a/tests/test_tutorial/test_dataclasses/test_tutorial003.py +++ b/tests/test_tutorial/test_dataclasses/test_tutorial003.py @@ -79,7 +79,9 @@ def test_openapi_schema(): "schema": { "title": "Items", "type": "array", - "items": {"$ref": "#/components/schemas/ItemInput"}, + "items": { + "$ref": "#/components/schemas/Item-Input" + }, } } }, @@ -141,7 +143,7 @@ def test_openapi_schema(): "items": { "title": "Items", "type": "array", - "items": {"$ref": "#/components/schemas/ItemOutput"}, + "items": {"$ref": "#/components/schemas/Item-Output"}, }, }, }, @@ -156,7 +158,7 @@ def test_openapi_schema(): } }, }, - "ItemInput": { + "Item-Input": { "title": "Item", "required": ["name"], "type": "object", @@ -168,7 +170,7 @@ def test_openapi_schema(): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "required": ["name", "description"], "type": "object", diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py index 3ffc0bca7..c5b2fb670 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py @@ -35,7 +35,7 @@ def test_openapi_schema(): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -57,7 +57,7 @@ def test_openapi_schema(): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -67,7 +67,7 @@ def test_openapi_schema(): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "required": ["name", "price"], "type": "object", @@ -91,7 +91,7 @@ def test_openapi_schema(): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "required": ["name", "description", "price", "tax", "tags"], "type": "object", diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py index ff98295a6..458923b5a 100644 --- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py +++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py @@ -35,7 +35,7 @@ def test_openapi_schema(): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -57,7 +57,7 @@ def test_openapi_schema(): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -67,7 +67,7 @@ def test_openapi_schema(): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "required": ["name", "price"], "type": "object", @@ -91,7 +91,7 @@ def test_openapi_schema(): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "required": ["name", "description", "price", "tax", "tags"], "type": "object", diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py index ad1c09eae..1fcc5c4e0 100644 --- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py +++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py @@ -42,7 +42,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -64,7 +64,7 @@ def test_openapi_schema(client: TestClient): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -74,7 +74,7 @@ def test_openapi_schema(client: TestClient): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "required": ["name", "price"], "type": "object", @@ -98,7 +98,7 @@ def test_openapi_schema(client: TestClient): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "required": ["name", "description", "price", "tax", "tags"], "type": "object", diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py index 045d1d402..470fe032b 100644 --- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py +++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py @@ -42,7 +42,7 @@ def test_openapi_schema(client: TestClient): "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ItemOutput" + "$ref": "#/components/schemas/Item-Output" } } }, @@ -64,7 +64,7 @@ def test_openapi_schema(client: TestClient): "requestBody": { "content": { "application/json": { - "schema": {"$ref": "#/components/schemas/ItemInput"} + "schema": {"$ref": "#/components/schemas/Item-Input"} } }, "required": True, @@ -74,7 +74,7 @@ def test_openapi_schema(client: TestClient): }, "components": { "schemas": { - "ItemInput": { + "Item-Input": { "title": "Item", "required": ["name", "price"], "type": "object", @@ -98,7 +98,7 @@ def test_openapi_schema(client: TestClient): }, }, }, - "ItemOutput": { + "Item-Output": { "title": "Item", "required": ["name", "description", "price", "tax", "tags"], "type": "object", diff --git a/tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py b/tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py deleted file mode 100644 index 4350567d1..000000000 --- a/tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py +++ /dev/null @@ -1,454 +0,0 @@ -import time -from pathlib import Path -from unittest.mock import MagicMock - -import pytest -from fastapi.testclient import TestClient - -from ...utils import needs_pydanticv1 - - -@pytest.fixture(scope="module") -def client(): - # Import while creating the client to create the DB after starting the test session - from docs_src.sql_databases_peewee.sql_app.main import app - - test_db = Path("./test.db") - with TestClient(app) as c: - yield c - test_db.unlink() - - -@needs_pydanticv1 -def test_create_user(client): - test_user = {"email": "johndoe@example.com", "password": "secret"} - response = client.post("/users/", json=test_user) - assert response.status_code == 200, response.text - data = response.json() - assert test_user["email"] == data["email"] - assert "id" in data - response = client.post("/users/", json=test_user) - assert response.status_code == 400, response.text - - -@needs_pydanticv1 -def test_get_user(client): - response = client.get("/users/1") - assert response.status_code == 200, response.text - data = response.json() - assert "email" in data - assert "id" in data - - -@needs_pydanticv1 -def test_inexistent_user(client): - response = client.get("/users/999") - assert response.status_code == 404, response.text - - -@needs_pydanticv1 -def test_get_users(client): - response = client.get("/users/") - assert response.status_code == 200, response.text - data = response.json() - assert "email" in data[0] - assert "id" in data[0] - - -time.sleep = MagicMock() - - -@needs_pydanticv1 -def test_get_slowusers(client): - response = client.get("/slowusers/") - assert response.status_code == 200, response.text - data = response.json() - assert "email" in data[0] - assert "id" in data[0] - - -@needs_pydanticv1 -def test_create_item(client): - item = {"title": "Foo", "description": "Something that fights"} - response = client.post("/users/1/items/", json=item) - assert response.status_code == 200, response.text - item_data = response.json() - assert item["title"] == item_data["title"] - assert item["description"] == item_data["description"] - assert "id" in item_data - assert "owner_id" in item_data - response = client.get("/users/1") - assert response.status_code == 200, response.text - user_data = response.json() - item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0] - assert item_to_check["title"] == item["title"] - assert item_to_check["description"] == item["description"] - response = client.get("/users/1") - assert response.status_code == 200, response.text - user_data = response.json() - item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0] - assert item_to_check["title"] == item["title"] - assert item_to_check["description"] == item["description"] - - -@needs_pydanticv1 -def test_read_items(client): - response = client.get("/items/") - assert response.status_code == 200, response.text - data = response.json() - assert data - first_item = data[0] - assert "title" in first_item - assert "description" in first_item - - -@needs_pydanticv1 -def test_openapi_schema(client): - 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": { - "/users/": { - "get": { - "summary": "Read Users", - "operationId": "read_users_users__get", - "parameters": [ - { - "required": False, - "schema": { - "title": "Skip", - "type": "integer", - "default": 0, - }, - "name": "skip", - "in": "query", - }, - { - "required": False, - "schema": { - "title": "Limit", - "type": "integer", - "default": 100, - }, - "name": "limit", - "in": "query", - }, - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "title": "Response Read Users Users Get", - "type": "array", - "items": {"$ref": "#/components/schemas/User"}, - } - } - }, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - }, - "post": { - "summary": "Create User", - "operationId": "create_user_users__post", - "requestBody": { - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/UserCreate"} - } - }, - "required": True, - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/User"} - } - }, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - }, - }, - "/users/{user_id}": { - "get": { - "summary": "Read User", - "operationId": "read_user_users__user_id__get", - "parameters": [ - { - "required": True, - "schema": {"title": "User Id", "type": "integer"}, - "name": "user_id", - "in": "path", - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/User"} - } - }, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - } - }, - "/users/{user_id}/items/": { - "post": { - "summary": "Create Item For User", - "operationId": "create_item_for_user_users__user_id__items__post", - "parameters": [ - { - "required": True, - "schema": {"title": "User Id", "type": "integer"}, - "name": "user_id", - "in": "path", - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/ItemCreate"} - } - }, - "required": True, - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/Item"} - } - }, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - } - }, - "/items/": { - "get": { - "summary": "Read Items", - "operationId": "read_items_items__get", - "parameters": [ - { - "required": False, - "schema": { - "title": "Skip", - "type": "integer", - "default": 0, - }, - "name": "skip", - "in": "query", - }, - { - "required": False, - "schema": { - "title": "Limit", - "type": "integer", - "default": 100, - }, - "name": "limit", - "in": "query", - }, - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "title": "Response Read Items Items Get", - "type": "array", - "items": {"$ref": "#/components/schemas/Item"}, - } - } - }, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - } - }, - "/slowusers/": { - "get": { - "summary": "Read Slow Users", - "operationId": "read_slow_users_slowusers__get", - "parameters": [ - { - "required": False, - "schema": { - "title": "Skip", - "type": "integer", - "default": 0, - }, - "name": "skip", - "in": "query", - }, - { - "required": False, - "schema": { - "title": "Limit", - "type": "integer", - "default": 100, - }, - "name": "limit", - "in": "query", - }, - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "title": "Response Read Slow Users Slowusers Get", - "type": "array", - "items": {"$ref": "#/components/schemas/User"}, - } - } - }, - }, - "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"}, - } - }, - }, - "Item": { - "title": "Item", - "required": ["title", "id", "owner_id"], - "type": "object", - "properties": { - "title": {"title": "Title", "type": "string"}, - "description": {"title": "Description", "type": "string"}, - "id": {"title": "Id", "type": "integer"}, - "owner_id": {"title": "Owner Id", "type": "integer"}, - }, - }, - "ItemCreate": { - "title": "ItemCreate", - "required": ["title"], - "type": "object", - "properties": { - "title": {"title": "Title", "type": "string"}, - "description": {"title": "Description", "type": "string"}, - }, - }, - "User": { - "title": "User", - "required": ["email", "id", "is_active"], - "type": "object", - "properties": { - "email": {"title": "Email", "type": "string"}, - "id": {"title": "Id", "type": "integer"}, - "is_active": {"title": "Is Active", "type": "boolean"}, - "items": { - "title": "Items", - "type": "array", - "items": {"$ref": "#/components/schemas/Item"}, - "default": [], - }, - }, - }, - "UserCreate": { - "title": "UserCreate", - "required": ["email", "password"], - "type": "object", - "properties": { - "email": {"title": "Email", "type": "string"}, - "password": {"title": "Password", "type": "string"}, - }, - }, - "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"}, - }, - }, - } - }, - }