Browse Source

๐ŸŒ Update translations for ko (update-all and add-missing) (#14923)

* Update all and add missing

* ๐ŸŽจ Auto format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
pull/14925/head
Motov Yurii 4 months ago
committed by GitHub
parent
commit
01e2e1088c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      docs/ko/docs/_llm-test.md
  2. 4
      docs/ko/docs/advanced/additional-responses.md
  3. 8
      docs/ko/docs/advanced/additional-status-codes.md
  4. 8
      docs/ko/docs/advanced/advanced-dependencies.md
  5. 61
      docs/ko/docs/advanced/advanced-python-types.md
  6. 8
      docs/ko/docs/advanced/async-tests.md
  7. 12
      docs/ko/docs/advanced/behind-a-proxy.md
  8. 32
      docs/ko/docs/advanced/custom-response.md
  9. 2
      docs/ko/docs/advanced/dataclasses.md
  10. 12
      docs/ko/docs/advanced/events.md
  11. 8
      docs/ko/docs/advanced/generate-clients.md
  12. 2
      docs/ko/docs/advanced/index.md
  13. 8
      docs/ko/docs/advanced/middleware.md
  14. 34
      docs/ko/docs/advanced/openapi-callbacks.md
  15. 2
      docs/ko/docs/advanced/openapi-webhooks.md
  16. 16
      docs/ko/docs/advanced/path-operation-advanced-configuration.md
  17. 2
      docs/ko/docs/advanced/response-change-status-code.md
  18. 4
      docs/ko/docs/advanced/response-cookies.md
  19. 2
      docs/ko/docs/advanced/response-directly.md
  20. 8
      docs/ko/docs/advanced/response-headers.md
  21. 8
      docs/ko/docs/advanced/security/http-basic-auth.md
  22. 24
      docs/ko/docs/advanced/settings.md
  23. 6
      docs/ko/docs/advanced/sub-applications.md
  24. 2
      docs/ko/docs/advanced/templates.md
  25. 4
      docs/ko/docs/advanced/testing-events.md
  26. 4
      docs/ko/docs/advanced/testing-websockets.md
  27. 2
      docs/ko/docs/advanced/using-request-directly.md
  28. 18
      docs/ko/docs/advanced/websockets.md
  29. 2
      docs/ko/docs/advanced/wsgi.md
  30. 8
      docs/ko/docs/alternatives.md
  31. 10
      docs/ko/docs/deployment/docker.md
  32. 4
      docs/ko/docs/deployment/https.md
  33. 2
      docs/ko/docs/deployment/manually.md
  34. 12
      docs/ko/docs/deployment/server-workers.md
  35. 4
      docs/ko/docs/deployment/versions.md
  36. 34
      docs/ko/docs/environment-variables.md
  37. 10
      docs/ko/docs/features.md
  38. 4
      docs/ko/docs/how-to/authentication-error-status-code.md
  39. 4
      docs/ko/docs/how-to/conditional-openapi.md
  40. 8
      docs/ko/docs/how-to/configure-swagger-ui.md
  41. 16
      docs/ko/docs/how-to/custom-docs-ui-assets.md
  42. 10
      docs/ko/docs/how-to/extending-openapi.md
  43. 2
      docs/ko/docs/how-to/graphql.md
  44. 4
      docs/ko/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
  45. 2
      docs/ko/docs/how-to/separate-openapi-schemas.md
  46. 10
      docs/ko/docs/index.md
  47. 2
      docs/ko/docs/project-generation.md
  48. 186
      docs/ko/docs/python-types.md
  49. 2
      docs/ko/docs/resources/index.md
  50. 11
      docs/ko/docs/translation-banner.md
  51. 6
      docs/ko/docs/tutorial/background-tasks.md
  52. 52
      docs/ko/docs/tutorial/bigger-applications.md
  53. 4
      docs/ko/docs/tutorial/body-fields.md
  54. 7
      docs/ko/docs/tutorial/body-multiple-params.md
  55. 4
      docs/ko/docs/tutorial/body-nested-models.md
  56. 8
      docs/ko/docs/tutorial/body.md
  57. 8
      docs/ko/docs/tutorial/cookie-param-models.md
  58. 4
      docs/ko/docs/tutorial/cookie-params.md
  59. 4
      docs/ko/docs/tutorial/cors.md
  60. 2
      docs/ko/docs/tutorial/debugging.md
  61. 24
      docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md
  62. 30
      docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
  63. 24
      docs/ko/docs/tutorial/dependencies/dependencies-with-yield.md
  64. 5
      docs/ko/docs/tutorial/dependencies/global-dependencies.md
  65. 6
      docs/ko/docs/tutorial/dependencies/index.md
  66. 6
      docs/ko/docs/tutorial/dependencies/sub-dependencies.md
  67. 2
      docs/ko/docs/tutorial/encoder.md
  68. 16
      docs/ko/docs/tutorial/extra-models.md
  69. 22
      docs/ko/docs/tutorial/first-steps.md
  70. 16
      docs/ko/docs/tutorial/handling-errors.md
  71. 4
      docs/ko/docs/tutorial/header-param-models.md
  72. 12
      docs/ko/docs/tutorial/metadata.md
  73. 8
      docs/ko/docs/tutorial/middleware.md
  74. 8
      docs/ko/docs/tutorial/path-operation-configuration.md
  75. 14
      docs/ko/docs/tutorial/path-params-numeric-validations.md
  76. 32
      docs/ko/docs/tutorial/path-params.md
  77. 48
      docs/ko/docs/tutorial/query-params-str-validations.md
  78. 6
      docs/ko/docs/tutorial/query-params.md
  79. 14
      docs/ko/docs/tutorial/request-files.md
  80. 4
      docs/ko/docs/tutorial/request-form-models.md
  81. 4
      docs/ko/docs/tutorial/request-forms-and-files.md
  82. 8
      docs/ko/docs/tutorial/request-forms.md
  83. 6
      docs/ko/docs/tutorial/response-model.md
  84. 10
      docs/ko/docs/tutorial/response-status-code.md
  85. 2
      docs/ko/docs/tutorial/schema-extra-example.md
  86. 6
      docs/ko/docs/tutorial/security/first-steps.md
  87. 2
      docs/ko/docs/tutorial/security/get-current-user.md
  88. 26
      docs/ko/docs/tutorial/security/oauth2-jwt.md
  89. 4
      docs/ko/docs/tutorial/security/simple-oauth2.md
  90. 2
      docs/ko/docs/tutorial/sql-databases.md
  91. 2
      docs/ko/docs/tutorial/static-files.md
  92. 12
      docs/ko/docs/tutorial/testing.md
  93. 24
      docs/ko/docs/virtual-environments.md

12
docs/ko/docs/_llm-test.md

@ -35,7 +35,7 @@
//// tab | ํ…Œ์ŠคํŠธ
์–ด์ œ ์ œ ์นœ๊ตฌ๊ฐ€ ์ด๋ ‡๊ฒŒ ์ผ์Šต๋‹ˆ๋‹ค: "If you spell incorrectly correctly, you have spelled it incorrectly". ์ด์— ์ €๋Š” ์ด๋ ‡๊ฒŒ ๋‹ตํ–ˆ์Šต๋‹ˆ๋‹ค: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"".
์–ด์ œ ์ œ ์นœ๊ตฌ๊ฐ€ ์ด๋ ‡๊ฒŒ ์ผ์Šต๋‹ˆ๋‹ค: "If you spell incorrectly correctly, you have spelled it incorrectly". ์ด์— ์ €๋Š” ์ด๋ ‡๊ฒŒ ๋‹ตํ–ˆ์Šต๋‹ˆ๋‹ค: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'".
/// note | ์ฐธ๊ณ 
@ -256,15 +256,15 @@ works(foo="bar") # ์ด๊ฑด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค ๐ŸŽ‰
//// tab | ํ…Œ์ŠคํŠธ
* ๋‹น์‹ 
* ๋‹น์‹ ์˜
* ์—ฌ๋Ÿฌ๋ถ„
* ์—ฌ๋Ÿฌ๋ถ„์˜
* ์˜ˆ: (e.g.)
* ๋“ฑ (etc.)
* `int`๋กœ์„œ์˜ `foo`
* `str`๋กœ์„œ์˜ `bar`
* `list`๋กœ์„œ์˜ `baz`
* `foo`๋กœ์„œ์˜ `int`
* `bar`๋กœ์„œ์˜ `str`
* `baz`๋กœ์„œ์˜ `list`
* ํŠœํ† ๋ฆฌ์–ผ - ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ
* ๊ณ ๊ธ‰ ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ

4
docs/ko/docs/advanced/additional-responses.md

@ -26,7 +26,7 @@
์˜ˆ๋ฅผ ๋“ค์–ด, ์ƒํƒœ ์ฝ”๋“œ `404`์™€ Pydantic ๋ชจ๋ธ `Message`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ์‘๋‹ต์„ ์„ ์–ธํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
/// note | ์ฐธ๊ณ 
@ -203,7 +203,7 @@
๋˜ํ•œ `response_model`์„ ์‚ฌ์šฉํ•˜๋Š” ์ƒํƒœ ์ฝ”๋“œ `200` ์‘๋‹ต์„ ์„ ์–ธํ•˜๋˜, ์ปค์Šคํ…€ `example`์„ ํฌํ•จํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
์ด ๋ชจ๋“  ๋‚ด์šฉ์€ OpenAPI์— ๊ฒฐํ•ฉ๋˜์–ด ํฌํ•จ๋˜๊ณ , API ๋ฌธ์„œ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค:

8
docs/ko/docs/advanced/additional-status-codes.md

@ -1,14 +1,14 @@
# ์ถ”๊ฐ€ ์ƒํƒœ ์ฝ”๋“œ { #additional-status-codes }
๊ธฐ๋ณธ์ ์œผ๋กœ **FastAPI**๋Š” ์‘๋‹ต์„ `JSONResponse`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, *๊ฒฝ๋กœ ์ž‘์—…(path operation)*์—์„œ ๋ฐ˜ํ™˜ํ•œ ๋‚ด์šฉ์„ ํ•ด๋‹น `JSONResponse` ์•ˆ์— ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ **FastAPI**๋Š” ์‘๋‹ต์„ `JSONResponse`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ๋ฐ˜ํ™˜ํ•œ ๋‚ด์šฉ์„ ํ•ด๋‹น `JSONResponse` ์•ˆ์— ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ณธ ์ƒํƒœ ์ฝ”๋“œ ๋˜๋Š” *๊ฒฝ๋กœ ์ž‘์—…*์—์„œ ์„ค์ •ํ•œ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ณธ ์ƒํƒœ ์ฝ”๋“œ ๋˜๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ์„ค์ •ํ•œ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
## ์ถ”๊ฐ€ ์ƒํƒœ ์ฝ”๋“œ { #additional-status-codes_1 }
๊ธฐ๋ณธ ์ƒํƒœ ์ฝ”๋“œ์™€ ๋ณ„๋„๋กœ ์ถ”๊ฐ€ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด `JSONResponse`์™€ ๊ฐ™์ด `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ถ”๊ฐ€ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ํ•ญ๋ชฉ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋Š” *๊ฒฝ๋กœ ์ž‘์—…*์ด ์žˆ๊ณ  ์„ฑ๊ณต ์‹œ 200 โ€œOKโ€์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ํ•ญ๋ชฉ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ์žˆ๊ณ  ์„ฑ๊ณต ์‹œ 200 โ€œOKโ€์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ƒˆ๋กœ์šด ํ•ญ๋ชฉ์„ ํ—ˆ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ญ๋ชฉ์ด ์ด์ „์— ์กด์žฌํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  HTTP ์ƒํƒœ ์ฝ”๋“œ 201 "Created"๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
@ -16,7 +16,7 @@
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
/// warning | ๊ฒฝ๊ณ 
/// warning
์œ„์˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฐ”๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

8
docs/ko/docs/advanced/advanced-dependencies.md

@ -18,7 +18,7 @@ Python์—๋Š” ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ "ํ˜ธ์ถœ ๊ฐ€๋Šฅ"ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•
์ด๋ฅผ ์œ„ํ•ด `__call__` ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
์ด ๊ฒฝ์šฐ, **FastAPI**๋Š” ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•˜์œ„ ์˜์กด์„ฑ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด `__call__`์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉฐ,
๋‚˜์ค‘์— *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ์ „๋‹ฌํ•  ๋•Œ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
@ -27,7 +27,7 @@ Python์—๋Š” ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ "ํ˜ธ์ถœ ๊ฐ€๋Šฅ"ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•
์ด์ œ `__init__`์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜์กด์„ฑ์„ "๋งค๊ฐœ๋ณ€์ˆ˜ํ™”"ํ•  ์ˆ˜ ์žˆ๋Š” ์ธ์Šคํ„ด์Šค์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
์ด ๊ฒฝ์šฐ, **FastAPI**๋Š” `__init__`์— ์ „ํ˜€ ๊ด€์—ฌํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์šฐ๋ฆฌ๋Š” ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์ฝ”๋“œ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
@ -35,7 +35,7 @@ Python์—๋Š” ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ "ํ˜ธ์ถœ ๊ฐ€๋Šฅ"ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•
๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `checker.fixed_content` ์†์„ฑ์— `"bar"`๋ผ๋Š” ๊ฐ’์„ ๋‹ด์•„ ์˜์กด์„ฑ์„ "๋งค๊ฐœ๋ณ€์ˆ˜ํ™”"ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -51,7 +51,7 @@ checker(q="somequery")
...๊ทธ๋ฆฌ๊ณ  ์ด๋•Œ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์„ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์˜ ์˜์กด์„ฑ ๊ฐ’์œผ๋กœ, `fixed_content_included` ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
/// tip | ํŒ

61
docs/ko/docs/advanced/advanced-python-types.md

@ -0,0 +1,61 @@
# ๊ณ ๊ธ‰ Python ํƒ€์ž… { #advanced-python-types }
Python ํƒ€์ž…์„ ๋‹ค๋ฃฐ ๋•Œ ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์•„์ด๋””์–ด๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
## `Union` ๋˜๋Š” `Optional` ์‚ฌ์šฉ { #using-union-or-optional }
์–ด๋–ค ์ด์œ ๋กœ ์ฝ”๋“œ์—์„œ `|`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋ฉด, ์˜ˆ๋ฅผ ๋“ค์–ด ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ์•„๋‹ˆ๋ผ `response_model=` ๊ฐ™์€ ๊ณณ์ด๋ผ๋ฉด, ํŒŒ์ดํ”„ ๋ฌธ์ž(`|`) ๋Œ€์‹  `typing`์˜ `Union`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ์–ด๋–ค ๊ฐ’์ด `str` ๋˜๋Š” `None`์ด ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing`์—๋Š” `None`์ด ๋  ์ˆ˜ ์žˆ์Œ์„ ์„ ์–ธํ•˜๋Š” ์ถ•์•ฝํ˜•์œผ๋กœ `Optional`๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„์ฃผ ๊ฐœ์ธ์ ์ธ ๊ด€์ ์—์„œ์˜ ํŒ์ž…๋‹ˆ๋‹ค:
- ๐Ÿšจ `Optional[SomeType]` ์‚ฌ์šฉ์€ ํ”ผํ•˜์„ธ์š”
- ๋Œ€์‹  โœจ **`Union[SomeType, None]`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”** โœจ.
๋‘˜์€ ๋™๋“ฑํ•˜๋ฉฐ ๋‚ด๋ถ€์ ์œผ๋กœ๋„ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹จ์–ด "optional"์€ ๊ฐ’์ด ์„ ํƒ ์‚ฌํ•ญ์ด๋ผ๋Š” ์ธ์ƒ์„ ์ฃผ๋Š” ๋ฐ˜๋ฉด, ์‹ค์ œ ์˜๋ฏธ๋Š” "๊ฐ’์ด `None`์ด ๋  ์ˆ˜ ์žˆ๋‹ค"๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๊ฐ’์ด ์„ ํƒ ์‚ฌํ•ญ์ด ์•„๋‹ˆ๋ผ ์—ฌ์ „ํžˆ ํ•„์ˆ˜์ธ ๊ฒฝ์šฐ์—๋„ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.
`Union[SomeType, None]`๊ฐ€ ์˜๋ฏธ๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋“œ๋Ÿฌ๋‚ธ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์ด๋Š” ๋‹จ์ง€ ๋‹จ์–ด์™€ ๋ช…์นญ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋‹จ์–ด๊ฐ€ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ํŒ€์›์ด ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋Š”์ง€์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ํ•จ์ˆ˜๋ฅผ ๋ณด์„ธ์š”:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
๋งค๊ฐœ๋ณ€์ˆ˜ `name`์€ `Optional[str]`๋กœ ์ •์˜๋˜์–ด ์žˆ์ง€๋งŒ, ์‚ฌ์‹ค ์„ ํƒ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค:
```Python
say_hi() # ์ด๋Ÿฐ, ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ˜ฑ
```
`name` ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค(์„ ํƒ์ ์ด ์•„๋‹˜). ๋Œ€์‹ , `name`์—๋Š” `None`์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```Python
say_hi(name=None) # ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. None์€ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค ๐ŸŽ‰
```
์ข‹์€ ์†Œ์‹์€, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํƒ€์ž…์˜ ํ•ฉ์ง‘ํ•ฉ์„ ์ •์˜ํ•  ๋•Œ ๊ทธ๋ƒฅ `|`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
๊ทธ๋ž˜์„œ ๋ณดํ†ต์€ `Optional`๊ณผ `Union` ๊ฐ™์€ ์ด๋ฆ„์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜์ง€ ์•Š์œผ์…”๋„ ๋ฉ๋‹ˆ๋‹ค. ๐Ÿ˜Ž

8
docs/ko/docs/advanced/async-tests.md

@ -32,11 +32,11 @@
`main.py` ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/async_tests/app_a_py39/main.py *}
{* ../../docs_src/async_tests/app_a_py310/main.py *}
`test_main.py` ํŒŒ์ผ์—๋Š” `main.py`์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์œผ๋ฉฐ, ์ด์ œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
## ์‹คํ–‰ํ•˜๊ธฐ { #run-it }
@ -56,7 +56,7 @@ $ pytest
`@pytest.mark.anyio` ๋งˆ์ปค๋Š” pytest์—๊ฒŒ ์ด ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ค๋‹ˆ๋‹ค:
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
/// tip | ํŒ
@ -66,7 +66,7 @@ $ pytest
๊ทธ ๋‹ค์Œ ์•ฑ์œผ๋กœ `AsyncClient`๋ฅผ ๋งŒ๋“ค๊ณ , `await`๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋™๊ธฐ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
์ด๋Š” ๋‹ค์Œ๊ณผ ๋™๋“ฑํ•ฉ๋‹ˆ๋‹ค:

12
docs/ko/docs/advanced/behind-a-proxy.md

@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
์˜ˆ๋ฅผ ๋“ค์–ด, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* `/items/`๋ฅผ ์ •์˜ํ–ˆ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค:
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
ํด๋ผ์ด์–ธํŠธ๊ฐ€ `/items`๋กœ ์ ‘๊ทผํ•˜๋ฉด, ๊ธฐ๋ณธ์ ์œผ๋กœ `/items/`๋กœ ๋ฆฌ๋””๋ ‰์…˜๋ฉ๋‹ˆ๋‹ค.
@ -115,7 +115,7 @@ sequenceDiagram
์ฝ”๋“œ๋Š” ๋ชจ๋‘ `/app`๋งŒ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š”๋ฐ๋„ ๋ง์ž…๋‹ˆ๋‹ค.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
๊ทธ๋ฆฌ๊ณ  ํ”„๋ก์‹œ๋Š” ์š”์ฒญ์„ ์•ฑ ์„œ๋ฒ„(์•„๋งˆ FastAPI CLI๋ฅผ ํ†ตํ•ด ์‹คํ–‰๋˜๋Š” Uvicorn)๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์ „์—, ๋™์ ์œผ๋กœ **๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ**๋ฅผ **"์ œ๊ฑฐ"**ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์—ฌ์ „ํžˆ `/app`์—์„œ ์„œ๋น„์Šค๋œ๋‹ค๊ณ  ๋ฏฟ๊ฒŒ ๋˜๊ณ , ์ฝ”๋“œ ์ „์ฒด๋ฅผ `/api/v1` ์ ‘๋‘์‚ฌ๋ฅผ ํฌํ•จํ•˜๋„๋ก ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง‘๋‹ˆ๋‹ค.
@ -193,7 +193,7 @@ ASGI ์‚ฌ์–‘์€ ์ด ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์œ„ํ•ด `root_path`๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” ๋ฐ๋ชจ ๋ชฉ์ ์„ ์œ„ํ•ด ๋ฉ”์‹œ์ง€์— ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
๊ทธ ๋‹ค์Œ Uvicorn์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹œ์ž‘ํ•˜๋ฉด:
@ -220,7 +220,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
๋˜๋Š” `--root-path` ๊ฐ™์€ ์ปค๋งจ๋“œ ๋ผ์ธ ์˜ต์…˜(๋˜๋Š” ๋™๋“ฑํ•œ ๋ฐฉ๋ฒ•)์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, FastAPI ์•ฑ์„ ์ƒ์„ฑํ•  ๋•Œ `root_path` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
`FastAPI`์— `root_path`๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ Uvicorn์ด๋‚˜ Hypercorn์— ์ปค๋งจ๋“œ ๋ผ์ธ ์˜ต์…˜ `--root-path`๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
@ -400,7 +400,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
์˜ˆ:
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
๋‹ค์Œ๊ณผ ๊ฐ™์€ OpenAPI ์Šคํ‚ค๋งˆ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
@ -455,7 +455,7 @@ OpenAPI ์‚ฌ์–‘์—์„œ `servers` ์†์„ฑ์€ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.
**FastAPI**๊ฐ€ `root_path`๋ฅผ ์‚ฌ์šฉํ•œ ์ž๋™ server๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด, `root_path_in_servers=False` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
๊ทธ๋Ÿฌ๋ฉด OpenAPI ์Šคํ‚ค๋งˆ์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

32
docs/ko/docs/advanced/custom-response.md

@ -30,7 +30,7 @@
ํ•˜์ง€๋งŒ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‚ด์šฉ์ด **JSON์œผ๋กœ ์ง๋ ฌํ™” ๊ฐ€๋Šฅ**ํ•˜๋‹ค๊ณ  ํ™•์‹ ํ•˜๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๋‚ด์šฉ์„ ์‘๋‹ต ํด๋ž˜์Šค์— ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, FastAPI๊ฐ€ ๋ฐ˜ํ™˜ ๋‚ด์šฉ์„ `jsonable_encoder`๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•œ ๋’ค ์‘๋‹ต ํด๋ž˜์Šค์— ์ „๋‹ฌํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
/// info | ์ •๋ณด
@ -55,7 +55,7 @@
* `HTMLResponse`๋ฅผ ์ž„ํฌํŠธ ํ•ฉ๋‹ˆ๋‹ค.
* *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์˜ `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ `HTMLResponse`๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info | ์ •๋ณด
@ -73,7 +73,7 @@
์œ„์˜ ์˜ˆ์ œ์™€ ๋™์ผํ•˜๊ฒŒ `HTMLResponse`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning | ๊ฒฝ๊ณ 
@ -97,7 +97,7 @@
์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
์ด ์˜ˆ์ œ์—์„œ, `generate_html_response()` ํ•จ์ˆ˜๋Š” HTML์„ `str`๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹  ์ด๋ฏธ `Response`๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
@ -136,7 +136,7 @@
FastAPI (์‹ค์ œ๋กœ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. ๋˜ํ•œ `media_type`์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ Content-Type ํ—ค๋”๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ํ…์ŠคํŠธ ํƒ€์ž…์˜ ๊ฒฝ์šฐ ๋ฌธ์ž ์ง‘ํ•ฉ์„ ์ถ”๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@ -146,7 +146,7 @@ FastAPI (์‹ค์ œ๋กœ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ
ํ…์ŠคํŠธ ๋˜๋Š” ๋ฐ”์ดํŠธ๋ฅผ ๋ฐ›์•„ ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@ -180,7 +180,7 @@ FastAPI (์‹ค์ œ๋กœ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ
///
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// tip | ํŒ
@ -194,14 +194,14 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
`RedirectResponse`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
๋˜๋Š” `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
์ด ๊ฒฝ์šฐ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ํ•จ์ˆ˜์—์„œ URL์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -211,13 +211,13 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
`status_code` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
๋น„๋™๊ธฐ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๋˜๋Š” ์ผ๋ฐ˜ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ/์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ŠคํŠธ๋ฆฌ๋ฐ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ `StreamingResponse` { #using-streamingresponse-with-file-like-objects }
@ -227,7 +227,7 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
์ด ๋ฐฉ์‹์€ ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€, ๋น„๋””์˜ค ์ฒ˜๋ฆฌ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
1. ์ด๊ฒƒ์ด ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. `yield` ๋ฌธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ "์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜"์ž…๋‹ˆ๋‹ค.
2. `with` ๋ธ”๋ก์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ, ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ๋‹ซํžˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์‘๋‹ต ์ „์†ก์ด ๋๋‚œ ํ›„ ๋‹ซํž™๋‹ˆ๋‹ค.
@ -256,11 +256,11 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
ํŒŒ์ผ ์‘๋‹ต์—๋Š” ์ ์ ˆํ•œ `Content-Length`, `Last-Modified`, ๋ฐ `ETag` ํ—ค๋”๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
๋˜ํ•œ `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
์ด ๊ฒฝ์šฐ, ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜์—์„œ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -274,7 +274,7 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
`CustomORJSONResponse`๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ `Response.render(content)` ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋‚ด์šฉ์„ `bytes`๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
์ด์ œ ๋‹ค์Œ ๋Œ€์‹ :
@ -300,7 +300,7 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
์•„๋ž˜ ์˜ˆ์ œ์—์„œ **FastAPI**๋Š” ๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ `JSONResponse` ๋Œ€์‹  `ORJSONResponse`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip | ํŒ

2
docs/ko/docs/advanced/dataclasses.md

@ -64,7 +64,7 @@ dataclass๋Š” ์ž๋™์œผ๋กœ Pydantic dataclass๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
6. ์—ฌ๊ธฐ์„œ๋Š” dataclasses ๋ฆฌ์ŠคํŠธ์ธ `items`๋ฅผ ํฌํ•จํ•˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
FastAPI๋Š” ์—ฌ์ „ํžˆ ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ <abbr title="converting the data to a format that can be transmitted - ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก ๊ฐ€๋Šฅํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ">serializing</abbr>ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
FastAPI๋Š” ์—ฌ์ „ํžˆ ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ <dfn title="๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก ๊ฐ€๋Šฅํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ">์ง๋ ฌํ™”</dfn>ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
7. ์—ฌ๊ธฐ์„œ `response_model`์€ `Author` dataclasses ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ํƒ€์ž… ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

12
docs/ko/docs/advanced/events.md

@ -30,7 +30,7 @@
`yield`๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋™๊ธฐ ํ•จ์ˆ˜ `lifespan()`์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
์—ฌ๊ธฐ์„œ๋Š” `yield` ์ด์ „์— (๊ฐ€์งœ) ๋ชจ๋ธ ํ•จ์ˆ˜๋ฅผ ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์ด ๋“ค์–ด ์žˆ๋Š” ๋”•์…”๋„ˆ๋ฆฌ์— ๋„ฃ์–ด ๋ชจ๋ธ์„ ๋กœ๋“œํ•˜๋Š” ๋น„์šฉ์ด ํฐ *์‹œ์ž‘* ์ž‘์—…์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด **์š”์ฒญ์„ ๋ฐ›๊ธฐ ์‹œ์ž‘ํ•˜๊ธฐ ์ „**, *์‹œ์ž‘* ๋™์•ˆ์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
@ -48,7 +48,7 @@
๋จผ์ € ์ฃผ๋ชฉํ•  ์ ์€ `yield`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” `yield`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜์กด์„ฑ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„, ์ฆ‰ `yield` ์ด์ „์˜ ์ฝ”๋“œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋˜๊ธฐ **์ „์—** ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
@ -60,7 +60,7 @@
์ด๋Š” ํ•จ์ˆ˜๋ฅผ "**๋น„๋™๊ธฐ ์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €**"๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
ํŒŒ์ด์ฌ์—์„œ **์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €**๋Š” `with` ๋ฌธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `open()`์€ ์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -82,7 +82,7 @@ async with lifespan(app):
`FastAPI` ์•ฑ์˜ `lifespan` ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” **๋น„๋™๊ธฐ ์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €**๋ฅผ ๋ฐ›์œผ๋ฏ€๋กœ, ์ƒˆ `lifespan` ๋น„๋™๊ธฐ ์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
## ๋Œ€์ฒด ์ด๋ฒคํŠธ(์‚ฌ์šฉ ์ค‘๋‹จ) { #alternative-events-deprecated }
@ -104,7 +104,7 @@ async with lifespan(app):
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด, `"startup"` ์ด๋ฒคํŠธ๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
์ด ๊ฒฝ์šฐ, `startup` ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋Š” "database"(๊ทธ๋ƒฅ `dict`) ํ•ญ๋ชฉ์„ ์ผ๋ถ€ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
@ -116,7 +116,7 @@ async with lifespan(app):
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด, `"shutdown"` ์ด๋ฒคํŠธ๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
์—ฌ๊ธฐ์„œ `shutdown` ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋Š” ํ…์ŠคํŠธ ํ•œ ์ค„ `"Application shutdown"`์„ `log.txt` ํŒŒ์ผ์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

8
docs/ko/docs/advanced/generate-clients.md

@ -40,7 +40,7 @@ FastAPI๋Š” **OpenAPI 3.1** ์‚ฌ์–‘์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋ฏ€๋กœ, ์‚ฌ์šฉํ•˜๋Š”
๊ฐ„๋‹จํ•œ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
*path operation*์—์„œ ์š”์ฒญ ํŽ˜์ด๋กœ๋“œ์™€ ์‘๋‹ต ํŽ˜์ด๋กœ๋“œ์— ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ธ์„ `Item`, `ResponseMessage` ๋ชจ๋ธ๋กœ ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜์„ธ์š”.
@ -98,7 +98,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
์˜ˆ๋ฅผ ๋“ค์–ด **items** ์„น์…˜๊ณผ **users** ์„น์…˜์ด ์žˆ๊ณ , ์ด๋ฅผ ํƒœ๊ทธ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
### ํƒœ๊ทธ๋กœ TypeScript ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑํ•˜๊ธฐ { #generate-a-typescript-client-with-tags }
@ -145,7 +145,7 @@ FastAPI๋Š” ๊ฐ *path operation*์— ๋Œ€ํ•ด **์œ ์ผ ID**๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์ด๋Š”
๊ทธ ๋‹ค์Œ ์ด ์ปค์Šคํ…€ ํ•จ์ˆ˜๋ฅผ `generate_unique_id_function` ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ **FastAPI**์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
### ์ปค์Šคํ…€ Operation ID๋กœ TypeScript ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑํ•˜๊ธฐ { #generate-a-typescript-client-with-custom-operation-ids }
@ -167,7 +167,7 @@ OpenAPI ์ „๋ฐ˜์—์„œ๋Š” operation ID๊ฐ€ **์œ ์ผ**ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ
OpenAPI JSON์„ `openapi.json` ํŒŒ์ผ๋กœ ๋‹ค์šด๋กœ๋“œํ•œ ๋’ค, ์•„๋ž˜์™€ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŠธ๋กœ **์ ‘๋‘์‚ฌ ํƒœ๊ทธ๋ฅผ ์ œ๊ฑฐ**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
//// tab | Node.js

2
docs/ko/docs/advanced/index.md

@ -1,4 +1,4 @@
# ์‹ฌํ™” ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ - ๋„์ž…๋ถ€ { #advanced-user-guide }
# ์‹ฌํ™” ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ { #advanced-user-guide }
## ์ถ”๊ฐ€ ๊ธฐ๋Šฅ { #additional-features }

8
docs/ko/docs/advanced/middleware.md

@ -8,7 +8,7 @@
## ASGI middleware ์ถ”๊ฐ€ํ•˜๊ธฐ { #adding-asgi-middlewares }
**FastAPI**๋Š” Starlette๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> ์‚ฌ์–‘์„ ๊ตฌํ˜„ํ•˜๋ฏ€๋กœ, ์–ด๋–ค ASGI middleware๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” Starlette๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  <abbr title="Asynchronous Server Gateway Interface - ๋น„๋™๊ธฐ ์„œ๋ฒ„ ๊ฒŒ์ดํŠธ์›จ์ด ์ธํ„ฐํŽ˜์ด์Šค">ASGI</abbr> ์‚ฌ์–‘์„ ๊ตฌํ˜„ํ•˜๋ฏ€๋กœ, ์–ด๋–ค ASGI middleware๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ASGI ์‚ฌ์–‘์„ ๋”ฐ๋ฅด๊ธฐ๋งŒ ํ•˜๋ฉด, FastAPI๋‚˜ Starlette๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ middleware๊ฐ€ ์•„๋‹ˆ์–ด๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
@ -57,13 +57,13 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
`http` ๋˜๋Š” `ws`๋กœ ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์€ ๋Œ€์‹  ๋ณด์•ˆ ์Šคํ‚ด์œผ๋กœ ๋ฆฌ๋””๋ ‰์…˜๋ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
HTTP Host Header ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด, ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋œ `Host` ํ—ค๋”๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
๋‹ค์Œ ์ธ์ž๋“ค์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:
@ -78,7 +78,7 @@ HTTP Host Header ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด, ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์—
์ด middleware๋Š” ์ผ๋ฐ˜ ์‘๋‹ต๊ณผ ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์„ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
๋‹ค์Œ ์ธ์ž๋“ค์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

34
docs/ko/docs/advanced/openapi-callbacks.md

@ -1,8 +1,8 @@
# OpenAPI ์ฝœ๋ฐฑ { #openapi-callbacks }
๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋งŒ๋“  *external API*(์•„๋งˆ๋„ ๋‹น์‹ ์˜ API๋ฅผ *์‚ฌ์šฉ*ํ•  ๋™์ผํ•œ ๊ฐœ๋ฐœ์ž)๊ฐ€ ์š”์ฒญ์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋„๋ก ๋งŒ๋“œ๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ๊ฐ€์ง„ API๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋งŒ๋“  *external API*(์•„๋งˆ๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ API๋ฅผ *์‚ฌ์šฉ*ํ•  ๋™์ผํ•œ ๊ฐœ๋ฐœ์ž)๊ฐ€ ์š”์ฒญ์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋„๋ก ๋งŒ๋“œ๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ๊ฐ€์ง„ API๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹น์‹ ์˜ API ์•ฑ์ด *external API*๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ผ์–ด๋‚˜๋Š” ๊ณผ์ •์„ "callback"์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ๋‹น์‹ ์˜ API๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ ๋‹ค์Œ, ๋‹น์‹ ์˜ API๊ฐ€ ๋‹ค์‹œ *external API*๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด *๋˜๋Œ๋ ค ํ˜ธ์ถœ*ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(์•„๋งˆ๋„ ๊ฐ™์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŒ๋“  API์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค).
์—ฌ๋Ÿฌ๋ถ„์˜ API ์•ฑ์ด *external API*๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ผ์–ด๋‚˜๋Š” ๊ณผ์ •์„ "callback"์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์—ฌ๋Ÿฌ๋ถ„์˜ API๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ ๋‹ค์Œ, ์—ฌ๋Ÿฌ๋ถ„์˜ API๊ฐ€ ๋‹ค์‹œ *external API*๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด *๋˜๋Œ๋ ค ํ˜ธ์ถœ*ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(์•„๋งˆ๋„ ๊ฐ™์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŒ๋“  API์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค).
์ด ๊ฒฝ์šฐ, ๊ทธ *external API*๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ์—ฌ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ๊ฐ€์ ธ์•ผ ํ•˜๋Š”์ง€, ์–ด๋–ค body๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š”์ง€, ์–ด๋–ค ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋“ฑ์ž…๋‹ˆ๋‹ค.
@ -14,14 +14,14 @@
์ด ์ฒญ๊ตฌ์„œ๋Š” `id`, `title`(์„ ํƒ ์‚ฌํ•ญ), `customer`, `total`์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.
๋‹น์‹ ์˜ API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)๋Š” POST ์š”์ฒญ์œผ๋กœ ๋‹น์‹ ์˜ API์—์„œ ์ฒญ๊ตฌ์„œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ๋ถ„์˜ API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)๋Š” POST ์š”์ฒญ์œผ๋กœ ์—ฌ๋Ÿฌ๋ถ„์˜ API์—์„œ ์ฒญ๊ตฌ์„œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
๊ทธ ๋‹ค์Œ ๋‹น์‹ ์˜ API๋Š”(๊ฐ€์ •ํ•ด ๋ณด๋ฉด):
๊ทธ ๋‹ค์Œ ์—ฌ๋Ÿฌ๋ถ„์˜ API๋Š”(๊ฐ€์ •ํ•ด ๋ณด๋ฉด):
* ์ฒญ๊ตฌ์„œ๋ฅผ ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž์˜ ๊ณ ๊ฐ์—๊ฒŒ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
* ๋ˆ์„ ์ˆ˜๊ธˆํ•ฉ๋‹ˆ๋‹ค.
* API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)์˜ API๋กœ ๋‹ค์‹œ ์•Œ๋ฆผ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
* ์ด๋Š” (๋‹น์‹ ์˜ API์—์„œ) ๊ทธ ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์–ด๋–ค *external API*๋กœ POST ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค(์ด๊ฒƒ์ด "callback"์ž…๋‹ˆ๋‹ค).
* ์ด๋Š” (์—ฌ๋Ÿฌ๋ถ„์˜ API์—์„œ) ๊ทธ ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์–ด๋–ค *external API*๋กœ POST ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค(์ด๊ฒƒ์ด "callback"์ž…๋‹ˆ๋‹ค).
## ์ผ๋ฐ˜์ ์ธ **FastAPI** ์•ฑ { #the-normal-fastapi-app }
@ -43,7 +43,7 @@
## ์ฝœ๋ฐฑ ๋ฌธ์„œํ™”ํ•˜๊ธฐ { #documenting-the-callback }
์‹ค์ œ ์ฝœ๋ฐฑ ์ฝ”๋“œ๋Š” ๋‹น์‹ ์˜ API ์•ฑ์— ํฌ๊ฒŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค.
์‹ค์ œ ์ฝœ๋ฐฑ ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ API ์•ฑ์— ํฌ๊ฒŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์•ฑ๋งˆ๋‹ค ๋งŽ์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -54,11 +54,11 @@ callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
```
ํ•˜์ง€๋งŒ ์ฝœ๋ฐฑ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€, ๋‹น์‹ ์˜ API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)๊ฐ€ ์ฝœ๋ฐฑ ์š”์ฒญ body๋กœ *๋‹น์‹ ์˜ API*๊ฐ€ ๋ณด๋‚ผ ๋ฐ์ดํ„ฐ ๋“ฑ์— ๋งž์ถฐ *external API*๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•˜๋„๋ก ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ฝœ๋ฐฑ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€, ์—ฌ๋Ÿฌ๋ถ„์˜ API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)๊ฐ€ ์ฝœ๋ฐฑ ์š”์ฒญ body๋กœ *์—ฌ๋Ÿฌ๋ถ„์˜ API*๊ฐ€ ๋ณด๋‚ผ ๋ฐ์ดํ„ฐ ๋“ฑ์— ๋งž์ถฐ *external API*๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•˜๋„๋ก ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋‹ค์Œ์œผ๋กœ ํ•  ์ผ์€, *๋‹น์‹ ์˜ API*์—์„œ ๋ณด๋‚ด๋Š” ์ฝœ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๊ทธ *external API*๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ์—ฌ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์„œํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋‹ค์Œ์œผ๋กœ ํ•  ์ผ์€, *์—ฌ๋Ÿฌ๋ถ„์˜ API*์—์„œ ๋ณด๋‚ด๋Š” ์ฝœ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๊ทธ *external API*๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ์—ฌ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์„œํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ ๋ฌธ์„œ๋Š” ๋‹น์‹ ์˜ API์—์„œ `/docs`์˜ Swagger UI์— ํ‘œ์‹œ๋˜๋ฉฐ, ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๋“ค์ด *external API*๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
๊ทธ ๋ฌธ์„œ๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ API์—์„œ `/docs`์˜ Swagger UI์— ํ‘œ์‹œ๋˜๋ฉฐ, ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๋“ค์ด *external API*๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
์ด ์˜ˆ์‹œ๋Š” ์ฝœ๋ฐฑ ์ž์ฒด(ํ•œ ์ค„ ์ฝ”๋“œ๋กœ๋„ ๋  ์ˆ˜ ์žˆ์Œ)๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ , ๋ฌธ์„œํ™” ๋ถ€๋ถ„๋งŒ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
@ -76,11 +76,11 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
ํ•˜์ง€๋งŒ **FastAPI**๋กœ API์˜ ์ž๋™ ๋ฌธ์„œ๋ฅผ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ๊ทธ์™€ ๊ฐ™์€ ์ง€์‹์„ ์‚ฌ์šฉํ•ด *external API*๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์„œํ™”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค... ์ฆ‰ ์™ธ๋ถ€ API๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ(๋“ค)*(๋‹น์‹ ์˜ API๊ฐ€ ํ˜ธ์ถœํ•  ๊ฒƒ๋“ค)์„ ๋งŒ๋“ค์–ด์„œ ๋ง์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ๊ทธ์™€ ๊ฐ™์€ ์ง€์‹์„ ์‚ฌ์šฉํ•ด *external API*๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์„œํ™”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค... ์ฆ‰ ์™ธ๋ถ€ API๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ(๋“ค)*(์—ฌ๋Ÿฌ๋ถ„์˜ API๊ฐ€ ํ˜ธ์ถœํ•  ๊ฒƒ๋“ค)์„ ๋งŒ๋“ค์–ด์„œ ๋ง์ž…๋‹ˆ๋‹ค.
/// tip | ํŒ
์ฝœ๋ฐฑ์„ ๋ฌธ์„œํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋Š”, ์ž์‹ ์ด ๊ทธ *์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž*๋ผ๊ณ  ์ƒ์ƒํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€๊ธˆ์€ *๋‹น์‹ ์˜ API*๊ฐ€ ์•„๋‹ˆ๋ผ *external API*๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์„ธ์š”.
์ฝœ๋ฐฑ์„ ๋ฌธ์„œํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋Š”, ์ž์‹ ์ด ๊ทธ *์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž*๋ผ๊ณ  ์ƒ์ƒํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€๊ธˆ์€ *์—ฌ๋Ÿฌ๋ถ„์˜ API*๊ฐ€ ์•„๋‹ˆ๋ผ *external API*๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์„ธ์š”.
์ด ๊ด€์ (์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž์˜ ๊ด€์ )์„ ์ž ์‹œ ์ฑ„ํƒํ•˜๋ฉด, ๊ทธ *external API*๋ฅผ ์œ„ํ•ด ํŒŒ๋ผ๋ฏธํ„ฐ, body์šฉ Pydantic ๋ชจ๋ธ, ์‘๋‹ต ๋“ฑ์„ ์–ด๋””์— ๋‘์–ด์•ผ ํ•˜๋Š”์ง€๊ฐ€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -105,12 +105,12 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
์ผ๋ฐ˜์ ์ธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์™€์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ 2๊ฐ€์ง€์ž…๋‹ˆ๋‹ค:
* ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์งˆ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ์•ฑ์€ ์ด ์ฝ”๋“œ๋ฅผ ์ ˆ๋Œ€ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” *external API*๋ฅผ ๋ฌธ์„œํ™”ํ•˜๋Š” ๋ฐ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋Š” ๊ทธ๋ƒฅ `pass`๋งŒ ์žˆ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค.
* *path*์—๋Š” <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฐธ๊ณ )์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด *๋‹น์‹ ์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ผ๋ถ€ ๊ฐ’์„ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์งˆ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์˜ ์•ฑ์€ ์ด ์ฝ”๋“œ๋ฅผ ์ ˆ๋Œ€ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” *external API*๋ฅผ ๋ฌธ์„œํ™”ํ•˜๋Š” ๋ฐ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋Š” ๊ทธ๋ƒฅ `pass`๋งŒ ์žˆ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค.
* *path*์—๋Š” <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฐธ๊ณ )์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ผ๋ถ€ ๊ฐ’์„ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### ์ฝœ๋ฐฑ ๊ฒฝ๋กœ ํ‘œํ˜„์‹ { #the-callback-path-expression }
์ฝœ๋ฐฑ *path*๋Š” *๋‹น์‹ ์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ์ผ๋ถ€๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฝœ๋ฐฑ *path*๋Š” *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ์ผ๋ถ€๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ, ๋‹ค์Œ `str`์ž…๋‹ˆ๋‹ค:
@ -118,7 +118,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
"{$callback_url}/invoices/{$request.body.id}"
```
๋”ฐ๋ผ์„œ ๋‹น์‹ ์˜ API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)๊ฐ€ *๋‹น์‹ ์˜ API*๋กœ ๋‹ค์Œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ :
๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ API ์‚ฌ์šฉ์ž(์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž)๊ฐ€ *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋‹ค์Œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ :
```
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
@ -134,7 +134,7 @@ JSON body๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๋ฉด:
}
```
๊ทธ๋Ÿฌ๋ฉด *๋‹น์‹ ์˜ API*๋Š” ์ฒญ๊ตฌ์„œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋‚˜์ค‘์— ์–ด๋А ์‹œ์ ์—์„œ `callback_url`(์ฆ‰ *external API*)๋กœ ์ฝœ๋ฐฑ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค:
๊ทธ๋Ÿฌ๋ฉด *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋Š” ์ฒญ๊ตฌ์„œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋‚˜์ค‘์— ์–ด๋А ์‹œ์ ์—์„œ `callback_url`(์ฆ‰ *external API*)๋กœ ์ฝœ๋ฐฑ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค:
```
https://www.external.org/events/invoices/2expen51ve
@ -167,7 +167,7 @@ https://www.external.org/events/invoices/2expen51ve
์ด ์‹œ์ ์—์„œ, ์œ„์—์„œ ๋งŒ๋“  ์ฝœ๋ฐฑ ๋ผ์šฐํ„ฐ ์•ˆ์— *์ฝœ๋ฐฑ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ(๋“ค)*(์ฆ‰ *external developer*๊ฐ€ *external API*์— ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๋“ค)์„ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ *๋‹น์‹ ์˜ API ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ `callbacks` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด, ๊ทธ ์ฝœ๋ฐฑ ๋ผ์šฐํ„ฐ์˜ `.routes` ์†์„ฑ(์‹ค์ œ๋กœ๋Š” routes/*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์˜ `list`)์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค:
์ด์ œ *์—ฌ๋Ÿฌ๋ถ„์˜ API ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ `callbacks` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด, ๊ทธ ์ฝœ๋ฐฑ ๋ผ์šฐํ„ฐ์˜ `.routes` ์†์„ฑ(์‹ค์ œ๋กœ๋Š” routes/*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์˜ `list`)์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}

2
docs/ko/docs/advanced/openapi-webhooks.md

@ -32,7 +32,7 @@ Webhooks๋Š” OpenAPI 3.1.0 ์ด์ƒ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, FastAPI `0.99.0`
**FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๋ฉด, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ(์˜ˆ: `@app.webhooks.post()`), *webhooks*๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” `webhooks` ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
์—ฌ๋Ÿฌ๋ถ„์ด ์ •์˜ํ•œ webhook์€ **OpenAPI** ์Šคํ‚ค๋งˆ์™€ ์ž๋™ **docs UI**์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

16
docs/ko/docs/advanced/path-operation-advanced-configuration.md

@ -12,7 +12,7 @@ OpenAPI โ€œ์ „๋ฌธ๊ฐ€โ€๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ์•„๋งˆ ์ด ๋‚ด์šฉ์€ ํ•„์š”ํ•˜์ง€ ์•Š
๊ฐ ์ž‘์—…๋งˆ๋‹ค ๊ณ ์œ ํ•˜๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜* ์ด๋ฆ„์„ operationId๋กœ ์‚ฌ์šฉํ•˜๊ธฐ { #using-the-path-operation-function-name-as-the-operationid }
@ -20,7 +20,7 @@ API์˜ ํ•จ์ˆ˜ ์ด๋ฆ„์„ `operationId`๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๋ชจ๋“  API๋ฅผ
๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ถ”๊ฐ€ํ•œ ๋’ค์— ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip | ํŒ
@ -40,7 +40,7 @@ API์˜ ํ•จ์ˆ˜ ์ด๋ฆ„์„ `operationId`๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๋ชจ๋“  API๋ฅผ
์ƒ์„ฑ๋œ OpenAPI ์Šคํ‚ค๋งˆ(๋”ฐ๋ผ์„œ ์ž๋™ ๋ฌธ์„œํ™” ์‹œ์Šคํ…œ)์—์„œ ํŠน์ • *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ œ์™ธํ•˜๋ ค๋ฉด, `include_in_schema` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `False`๋กœ ์„ค์ •ํ•˜์„ธ์š”:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## docstring์—์„œ ๊ณ ๊ธ‰ ์„ค๋ช… ๊ฐ€์ ธ์˜ค๊ธฐ { #advanced-description-from-docstring }
@ -92,7 +92,7 @@ OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ <a href="https://github.com/OAI/OpenAPI-Specifica
์˜ˆ๋ฅผ ๋“ค์–ด `openapi_extra`๋Š” [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions)๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
์ž๋™ API ๋ฌธ์„œ๋ฅผ ์—ด๋ฉด, ํ•ด๋‹น ํŠน์ • *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์˜ ํ•˜๋‹จ์— ํ™•์žฅ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
@ -139,9 +139,9 @@ OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ <a href="https://github.com/OAI/OpenAPI-Specifica
๊ทธ๋Ÿด ๋•Œ `openapi_extra`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
์ด ์˜ˆ์‹œ์—์„œ๋Š” ์–ด๋–ค Pydantic ๋ชจ๋ธ๋„ ์„ ์–ธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์š”์ฒญ ๋ฐ”๋””๋Š” JSON์œผ๋กœ <abbr title="converted from some plain format, like bytes, into Python objects - bytes ๊ฐ™์€ ์ผ๋ฐ˜ ํ˜•์‹์—์„œ Python ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜">parsed</abbr>๋˜์ง€๋„ ์•Š๊ณ , `bytes`๋กœ ์ง์ ‘ ์ฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜ `magic_data_reader()`๊ฐ€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ์ด๋ฅผ ํŒŒ์‹ฑํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
์ด ์˜ˆ์‹œ์—์„œ๋Š” ์–ด๋–ค Pydantic ๋ชจ๋ธ๋„ ์„ ์–ธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์š”์ฒญ ๋ฐ”๋””๋Š” JSON์œผ๋กœ <dfn title="bytes ๊ฐ™์€ ์ผ๋ฐ˜ ํ˜•์‹์—์„œ Python ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜">ํŒŒ์‹ฑ</dfn>๋˜์ง€๋„ ์•Š๊ณ , `bytes`๋กœ ์ง์ ‘ ์ฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜ `magic_data_reader()`๊ฐ€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ์ด๋ฅผ ํŒŒ์‹ฑํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์š”์ฒญ ๋ฐ”๋””์— ๋Œ€ํ•ด ๊ธฐ๋Œ€ํ•˜๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -153,7 +153,7 @@ OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ <a href="https://github.com/OAI/OpenAPI-Specifica
์˜ˆ๋ฅผ ๋“ค์–ด ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” Pydantic ๋ชจ๋ธ์—์„œ JSON Schema๋ฅผ ์ถ”์ถœํ•˜๋Š” FastAPI์˜ ํ†ตํ•ฉ ๊ธฐ๋Šฅ๋„, JSON์— ๋Œ€ํ•œ ์ž๋™ ๊ฒ€์ฆ๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์š”์ฒญ ์ฝ˜ํ…์ธ  ํƒ€์ž…์„ JSON์ด ์•„๋‹ˆ๋ผ YAML๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
๊ทธ๋Ÿผ์—๋„ ๊ธฐ๋ณธ ํ†ตํ•ฉ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„, YAML๋กœ ๋ฐ›๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ JSON Schema๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด Pydantic ๋ชจ๋ธ์„ ์—ฌ์ „ํžˆ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
@ -161,7 +161,7 @@ OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ <a href="https://github.com/OAI/OpenAPI-Specifica
๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ์—์„œ YAML ์ฝ˜ํ…์ธ ๋ฅผ ์ง์ ‘ ํŒŒ์‹ฑํ•œ ๋’ค, ๋‹ค์‹œ ๊ฐ™์€ Pydantic ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด YAML ์ฝ˜ํ…์ธ ๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip | ํŒ

2
docs/ko/docs/advanced/response-change-status-code.md

@ -20,7 +20,7 @@
๊ทธ๋ฆฌ๊ณ  ์ด *์ž„์‹œ* ์‘๋‹ต ๊ฐ์ฒด์—์„œ `status_code`๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
๊ทธ๋ฆฌ๊ณ  ํ‰์†Œ์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ์–ด๋–ค ๊ฐ์ฒด๋“  ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(`dict`, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋“ฑ).

4
docs/ko/docs/advanced/response-cookies.md

@ -6,7 +6,7 @@
๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•ด๋‹น *์ž„์‹œ* ์‘๋‹ต ๊ฐ์ฒด์—์„œ ์ฟ ํ‚ค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
๊ทธ๋Ÿฐ ๋‹ค์Œ ์ผ๋ฐ˜์ ์œผ๋กœ ํ•˜๋“ฏ์ด ํ•„์š”ํ•œ ์–ด๋–ค ๊ฐ์ฒด๋“  ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(`dict`, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋“ฑ).
@ -24,7 +24,7 @@
๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฟ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip | ํŒ

2
docs/ko/docs/advanced/response-directly.md

@ -54,7 +54,7 @@ Pydantic ๋ชจ๋ธ๋กœ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋‚ด์šฉ์„ ๋‹ค๋ฅธ
XML ๋‚ด์šฉ์„ ๋ฌธ์ž์—ด์— ๋„ฃ๊ณ , ์ด๋ฅผ `Response`์— ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## ์ฐธ๊ณ  ์‚ฌํ•ญ { #notes }

8
docs/ko/docs/advanced/response-headers.md

@ -6,7 +6,7 @@
๊ทธ๋Ÿฐ ๋‹ค์Œ, ์—ฌ๋Ÿฌ๋ถ„์€ ํ•ด๋‹น *์ž„์‹œ* ์‘๋‹ต ๊ฐ์ฒด์—์„œ ํ—ค๋”๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
๊ทธ ํ›„, ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋“ฏ์ด ํ•„์š”ํ•œ ๊ฐ์ฒด(`dict`, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋“ฑ)๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -20,15 +20,15 @@
`Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ๋•Œ์—๋„ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๊ณ , ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์„ธ์š”.
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๊ณ , ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์„ธ์š”:
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
`from starlette.responses import Response`๋‚˜ `from starlette.responses import JSONResponse`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ํ•ด๋‹น *์ž„์‹œ* ์‘๋‹ต์—์„œ ํ—ค๋”(์ฟ ํ‚ค์™€ ์ƒํƒœ ์ฝ”๋“œ๋„ ํฌํ•จ)๋ฅผ ์ถ”์ถœํ•˜์—ฌ, ์—ฌ๋Ÿฌ๋ถ„์ด ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ์ตœ์ข… ์‘๋‹ต์— `response_model`๋กœ ํ•„ํ„ฐ๋ง๋œ ๊ฐ’์„ ๋„ฃ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ๊ฐœ๋ฐœ์ž์ธ ์—ฌ๋Ÿฌ๋ถ„์˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด `starlette.responses`์™€ ๋™์ผํ•œ ๊ฒƒ์„ `fastapi.responses`๋กœ๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์‘๋‹ต์€ Starlette์—์„œ ์ง์ ‘ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  `Response`๋Š” ํ—ค๋”์™€ ์ฟ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐ ์ž์ฃผ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, **FastAPI**๋Š” `fastapi.Response`๋กœ๋„ ์ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

8
docs/ko/docs/advanced/security/http-basic-auth.md

@ -20,7 +20,7 @@ HTTP Basic Auth์—์„œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€
* `HTTPBasicCredentials` ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:
* ์ „์†ก๋œ `username`๊ณผ `password`๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
์ฒ˜์Œ์œผ๋กœ URL์„ ์—ด์–ด๋ณด๋ฉด(๋˜๋Š” ๋ฌธ์„œ์—์„œ "Execute" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด) ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ฌผ์–ด๋ด…๋‹ˆ๋‹ค:
@ -40,13 +40,13 @@ dependency๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜
๊ทธ๋Ÿฐ ๋‹ค์Œ `secrets.compare_digest()`๋ฅผ ์‚ฌ์šฉํ•ด `credentials.username`์ด `"stanleyjobson"`์ด๊ณ  `credentials.password`๊ฐ€ `"swordfish"`์ธ์ง€ ํ™•์‹คํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
์ด๋Š” ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค:
```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# Return some error
# ์–ด๋–ค ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜
...
```
@ -104,4 +104,4 @@ Python์€ ๋‘ ๋ฌธ์ž์—ด์ด ๊ฐ™์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„์ฐจ๋ฆฌ๊ธฐ ์ „๊นŒ์ง€ `st
์ž๊ฒฉ ์ฆ๋ช…์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด, ์ƒํƒœ ์ฝ”๋“œ 401(์ž๊ฒฉ ์ฆ๋ช…์ด ์ œ๊ณต๋˜์ง€ ์•Š์•˜์„ ๋•Œ์™€ ๋™์ผ)์„ ์‚ฌ์šฉํ•˜๋Š” `HTTPException`์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋กœ๊ทธ์ธ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋‹ค์‹œ ํ‘œ์‹œํ•˜๋„๋ก `WWW-Authenticate` ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}

24
docs/ko/docs/advanced/settings.md

@ -54,7 +54,7 @@ Pydantic ๋ชจ๋ธ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ, ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜(๊ทธ๋ฆฌ๊ณ  ํ•„์š”
๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…, `Field()`๋กœ ์ถ”๊ฐ€ ๊ฒ€์ฆ ๋“ฑ Pydantic ๋ชจ๋ธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋™์ผํ•œ ๊ฒ€์ฆ ๊ธฐ๋Šฅ๊ณผ ๋„๊ตฌ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
/// tip | ํŒ
@ -70,7 +70,7 @@ Pydantic ๋ชจ๋ธ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ, ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜(๊ทธ๋ฆฌ๊ณ  ํ•„์š”
์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ƒˆ `settings` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
### ์„œ๋ฒ„ ์‹คํ–‰ํ•˜๊ธฐ { #run-the-server }
@ -104,11 +104,11 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
์˜ˆ๋ฅผ ๋“ค์–ด `config.py` ํŒŒ์ผ์„ ๋‹ค์Œ์ฒ˜๋Ÿผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/settings/app01_py39/config.py *}
{* ../../docs_src/settings/app01_py310/config.py *}
๊ทธ๋ฆฌ๊ณ  `main.py` ํŒŒ์ผ์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
/// tip | ํŒ
@ -126,7 +126,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
์ด์ „ ์˜ˆ์‹œ์—์„œ ์ด์–ด์„œ, `config.py` ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
์ด์ œ๋Š” ๊ธฐ๋ณธ ์ธ์Šคํ„ด์Šค `settings = Settings()`๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.
@ -134,7 +134,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
์ด์ œ ์ƒˆ๋กœ์šด `config.Settings()`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์˜์กด์„ฑ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
/// tip | ํŒ
@ -146,13 +146,13 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
๊ทธ ๋‹ค์Œ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ์ด๋ฅผ ์˜์กด์„ฑ์œผ๋กœ ์š”๊ตฌํ•˜๊ณ , ํ•„์š”ํ•œ ์–ด๋””์„œ๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
### ์„ค์ •๊ณผ ํ…Œ์ŠคํŠธ { #settings-and-testing }
๊ทธ ๋‹ค์Œ, `get_settings`์— ๋Œ€ํ•œ ์˜์กด์„ฑ override๋ฅผ ๋งŒ๋“ค์–ด ํ…Œ์ŠคํŠธ ์ค‘์— ๋‹ค๋ฅธ ์„ค์ • ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค:
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
์˜์กด์„ฑ override์—์„œ๋Š” ์ƒˆ `Settings` ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ `admin_email`์˜ ์ƒˆ ๊ฐ’์„ ์„ค์ •ํ•˜๊ณ , ๊ทธ ์ƒˆ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
@ -193,11 +193,11 @@ APP_NAME="ChimichangApp"
๊ทธ๋ฆฌ๊ณ  `config.py`๋ฅผ ๋‹ค์Œ์ฒ˜๋Ÿผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
/// tip | ํŒ
`model_config` ์†์„ฑ์€ Pydantic ์„ค์ •์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a>์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.
`model_config` ์†์„ฑ์€ Pydantic ์„ค์ •์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
///
@ -226,11 +226,11 @@ def get_settings():
ํ•˜์ง€๋งŒ ์œ„์— `@lru_cache` ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ, `Settings` ๊ฐ์ฒด๋Š” ์ตœ์ดˆ ํ˜ธ์ถœ ์‹œ ๋”ฑ ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. โœ”๏ธ
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
๊ทธ ๋‹ค์Œ ์š”์ฒญ๋“ค์—์„œ ์˜์กด์„ฑ์œผ๋กœ `get_settings()`๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค, `get_settings()`์˜ ๋‚ด๋ถ€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์„œ ์ƒˆ `Settings` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹ , ์ฒซ ํ˜ธ์ถœ์—์„œ ๋ฐ˜ํ™˜๋œ ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ๊ณ„์† ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
#### `lru_cache` Technical Details { #lru-cache-technical-details }
#### `lru_cache` ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ { #lru-cache-technical-details }
`@lru_cache`๋Š” ๋ฐ์ฝ”๋ ˆ์ด์…˜ํ•œ ํ•จ์ˆ˜๊ฐ€ ๋งค๋ฒˆ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š” ๋Œ€์‹ , ์ฒซ ๋ฒˆ์งธ์— ๋ฐ˜ํ™˜๋œ ๋™์ผํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ๋งค๋ฒˆ ํ•จ์ˆ˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

6
docs/ko/docs/advanced/sub-applications.md

@ -10,7 +10,7 @@
๋จผ์ €, ๋ฉ”์ธ ์ตœ์ƒ์œ„ **FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ทธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
### ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ { #sub-application }
@ -18,7 +18,7 @@
์ด ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์€ ๋˜ ๋‹ค๋ฅธ ํ‘œ์ค€ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด์ง€๋งŒ, "๋งˆ์šดํŠธ"๋  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
### ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ ๋งˆ์šดํŠธ { #mount-the-sub-application }
@ -26,7 +26,7 @@
์ด ๊ฒฝ์šฐ `/subapi` ๊ฒฝ๋กœ์— ๋งˆ์šดํŠธ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
### ์ž๋™ API ๋ฌธ์„œ ํ™•์ธ { #check-the-automatic-api-docs }

2
docs/ko/docs/advanced/templates.md

@ -27,7 +27,7 @@ $ pip install jinja2
* ํ…œํ”Œ๋ฆฟ์„ ๋ฐ˜ํ™˜ํ•  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— `Request` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
* ์ƒ์„ฑํ•œ `templates`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ `TemplateResponse`๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ์˜ ์ด๋ฆ„, ์š”์ฒญ ๊ฐ์ฒด ๋ฐ Jinja2 ํ…œํ”Œ๋ฆฟ ๋‚ด์—์„œ ์‚ฌ์šฉ๋  ํ‚ค-๊ฐ’ ์Œ์ด ํฌํ•จ๋œ "์ปจํ…์ŠคํŠธ" ๋”•์…”๋„ˆ๋ฆฌ๋„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
/// note | ์ฐธ๊ณ 

4
docs/ko/docs/advanced/testing-events.md

@ -2,11 +2,11 @@
ํ…Œ์ŠคํŠธ์—์„œ `lifespan`์„ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, `with` ๋ฌธ๊ณผ ํ•จ๊ป˜ `TestClient`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
["๊ณต์‹ Starlette ๋ฌธ์„œ ์‚ฌ์ดํŠธ์—์„œ ํ…Œ์ŠคํŠธ์—์„œ ๋ผ์ดํ”„์ŠคํŒฌ ์‹คํ–‰ํ•˜๊ธฐ."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๋” ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋” ์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š” `startup` ๋ฐ `shutdown` ์ด๋ฒคํŠธ์˜ ๊ฒฝ์šฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด `TestClient`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}

4
docs/ko/docs/advanced/testing-websockets.md

@ -4,10 +4,10 @@
์ด๋ฅผ ์œ„ํ•ด `with` ๋ฌธ์—์„œ `TestClient`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ WebSocket์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
/// note | ์ฐธ๊ณ 
์ž์„ธํ•œ ๋‚ด์šฉ์€ Starlette์˜ <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">testing WebSockets</a> ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
์ž์„ธํ•œ ๋‚ด์šฉ์€ Starlette์˜ <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">WebSocket ํ…Œ์ŠคํŠธ</a> ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
///

2
docs/ko/docs/advanced/using-request-directly.md

@ -29,7 +29,7 @@
์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์š”์ฒญ์— ์ง์ ‘ ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜* ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `Request` ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•˜๋ฉด **FastAPI**๊ฐ€ ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜์— `Request`๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

18
docs/ko/docs/advanced/websockets.md

@ -24,7 +24,7 @@ $ pip install websockets
๊ทธ๋ฆฌ๊ณ  ๋ฐฑ์—”๋“œ์™€ WebSockets์„ ์‚ฌ์šฉํ•ด ํ†ต์‹ ํ•˜๋ ค๋ฉด ์•„๋งˆ๋„ ํ”„๋ŸฐํŠธ์—”๋“œ์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋กœ WebSocket ๋ฐฑ์—”๋“œ์™€ ์ง์ ‘ ํ†ต์‹ ํ•˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋ฐ”์ผ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋กœ WebSocket ๋ฐฑ์—”๋“œ์™€ ์ง์ ‘ ํ†ต์‹ ํ•˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ˜น์€ WebSocket ์—”๋“œํฌ์ธํŠธ์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -38,13 +38,13 @@ $ pip install websockets
๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” WebSockets์˜ ์„œ๋ฒ„ ์ธก์— ์ง‘์ค‘ํ•˜๊ณ  ๋™์ž‘ํ•˜๋Š” ์˜ˆ์ œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
## `websocket` ์ƒ์„ฑํ•˜๊ธฐ { #create-a-websocket }
**FastAPI** ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ `websocket`์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
**FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ `websocket`์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
@ -58,13 +58,13 @@ $ pip install websockets
WebSocket ๊ฒฝ๋กœ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋Œ€๊ธฐ(`await`)ํ•˜๊ณ  ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
์—ฌ๋Ÿฌ๋ถ„์€ ์ด์ง„ ๋ฐ์ดํ„ฐ, ํ…์ŠคํŠธ, JSON ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ  ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## ์‹œ๋„ํ•ด๋ณด๊ธฐ { #try-it }
ํŒŒ์ผ ์ด๋ฆ„์ด `main.py`๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
ํŒŒ์ผ ์ด๋ฆ„์ด `main.py`๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
<div class="termy">
@ -86,7 +86,7 @@ $ fastapi dev main.py
<img src="/img/tutorial/websockets/image02.png">
๊ทธ๋ฆฌ๊ณ  WebSockets๊ฐ€ ํฌํ•จ๋œ **FastAPI** ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์‘๋‹ต์„ ๋Œ๋ ค์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
๊ทธ๋ฆฌ๊ณ  WebSockets๊ฐ€ ํฌํ•จ๋œ **FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‘๋‹ต์„ ๋Œ๋ ค์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
<img src="/img/tutorial/websockets/image03.png">
@ -121,7 +121,7 @@ WebSocket์ด๊ธฐ ๋•Œ๋ฌธ์— `HTTPException`์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ์ ์ ˆํ•˜์ง€
### ์ข…์†์„ฑ์„ ๊ฐ€์ง„ WebSockets ์‹œ๋„ํ•ด๋ณด๊ธฐ { #try-the-websockets-with-dependencies }
ํŒŒ์ผ ์ด๋ฆ„์ด `main.py`๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
ํŒŒ์ผ ์ด๋ฆ„์ด `main.py`๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
<div class="termy">
@ -154,7 +154,7 @@ $ fastapi dev main.py
WebSocket ์—ฐ๊ฒฐ์ด ๋‹ซํžˆ๋ฉด, `await websocket.receive_text()`๊ฐ€ `WebSocketDisconnect` ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ด ์˜ˆ์ œ์ฒ˜๋Ÿผ ์ด๋ฅผ ์žก์•„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
ํ…Œ์ŠคํŠธํ•ด๋ณด๊ธฐ:

2
docs/ko/docs/advanced/wsgi.md

@ -18,7 +18,7 @@
๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๊ฒฝ๋กœ์— ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
/// note | ์ฐธ๊ณ 

8
docs/ko/docs/alternatives.md

@ -137,7 +137,7 @@ Flask REST framework๋Š” ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์žˆ์ง€๋งŒ, ์‹œ๊ฐ„์„ ๋“ค์—ฌ ์กฐ์‚ฌํ•ด ๋ณธ
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
API ์‹œ์Šคํ…œ์— ํ•„์š”ํ•œ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ์ดํ„ฐ "<abbr title="also called marshalling, conversion - ๋งˆ์ƒฌ๋ง, ๋ณ€ํ™˜์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค">serialization</abbr>"์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ฝ”๋“œ(Python)์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์€ ๊ฐ์ฒด๋ฅผ JSON ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜, `datetime` ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์ž…๋‹ˆ๋‹ค.
API ์‹œ์Šคํ…œ์— ํ•„์š”ํ•œ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ์ดํ„ฐ "<dfn title="๋งˆ์ƒฌ๋ง, ๋ณ€ํ™˜์ด๋ผ๊ณ ๋„ ํ•จ">์ง๋ ฌํ™”</dfn>"์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ฝ”๋“œ(Python)์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์€ ๊ฐ์ฒด๋ฅผ JSON ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜, `datetime` ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์ž…๋‹ˆ๋‹ค.
API์— ๋˜ ํ•˜๋‚˜ ํฌ๊ฒŒ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์€ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค. ํŠน์ • ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์–ด๋–ค ํ•„๋“œ๊ฐ€ `int`์ธ์ง€, ์ž„์˜์˜ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๋Š” ์‹์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํŠนํžˆ ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
@ -145,7 +145,7 @@ API์— ๋˜ ํ•˜๋‚˜ ํฌ๊ฒŒ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์€ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค. ํŠน์ •
์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด Marshmallow๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํ›Œ๋ฅญํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ, ์ €๋„ ์ด์ „์— ๋งŽ์ด ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ Python type hints๊ฐ€ ์กด์žฌํ•˜๊ธฐ ์ „์— ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ <abbr title="the definition of how data should be formed - ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •์˜">schema</abbr>๋ฅผ ์ •์˜ํ•˜๋ ค๋ฉด Marshmallow๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํŠน์ • ์œ ํ‹ธ๋ฆฌํ‹ฐ์™€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ Python type hints๊ฐ€ ์กด์žฌํ•˜๊ธฐ ์ „์— ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ <dfn title="๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •์˜">์Šคํ‚ค๋งˆ</dfn>๋ฅผ ์ •์˜ํ•˜๋ ค๋ฉด Marshmallow๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํŠน์ • ์œ ํ‹ธ๋ฆฌํ‹ฐ์™€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
/// check | **FastAPI**์— ์˜๊ฐ์„ ์ค€ ๊ฒƒ
@ -155,7 +155,7 @@ API์— ๋˜ ํ•˜๋‚˜ ํฌ๊ฒŒ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์€ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค. ํŠน์ •
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
API์— ํ•„์š”ํ•œ ๋˜ ๋‹ค๋ฅธ ํฐ ๊ธฐ๋Šฅ์€ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ <abbr title="reading and converting to Python data - ์ฝ์–ด์„œ Python ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ">parsing</abbr>ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
API์— ํ•„์š”ํ•œ ๋˜ ๋‹ค๋ฅธ ํฐ ๊ธฐ๋Šฅ์€ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ <dfn title="์ฝ์–ด์„œ Python ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ">ํŒŒ์‹ฑ</dfn>ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
Webargs๋Š” Flask๋ฅผ ํฌํ•จํ•œ ์—ฌ๋Ÿฌ framework ์œ„์—์„œ ์ด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
@ -419,7 +419,7 @@ Marshmallow์™€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ benchmark์—์„œ Marshmallow๋ณด
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
Starlette๋Š” ๊ฒฝ๋Ÿ‰ <abbr title="The new standard for building asynchronous Python web applications - ๋น„๋™๊ธฐ Python ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํ‘œ์ค€">ASGI</abbr> framework/toolkit์œผ๋กœ, ๊ณ ์„ฑ๋Šฅ asyncio ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค.
Starlette๋Š” ๊ฒฝ๋Ÿ‰ <dfn title="๋น„๋™๊ธฐ Python ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํ‘œ์ค€">ASGI</dfn> framework/toolkit์œผ๋กœ, ๊ณ ์„ฑ๋Šฅ asyncio ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค.
๋งค์šฐ ๋‹จ์ˆœํ•˜๊ณ  ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ๊ณ , ๋ชจ๋“ˆ์‹ component๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.

10
docs/ko/docs/deployment/docker.md

@ -14,7 +14,7 @@ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•  ๋•Œ ์ผ๋ฐ˜์ ์ธ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ **๋ฆฌ
<summary>Dockerfile Preview ๐Ÿ‘€</summary>
```Dockerfile
FROM python:3.9
FROM python:3.14
WORKDIR /code
@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None):
```{ .dockerfile .annotate }
# (1)!
FROM python:3.9
FROM python:3.14
# (2)!
WORKDIR /code
@ -390,7 +390,7 @@ FastAPI๊ฐ€ ๋‹จ์ผ ํŒŒ์ผ(์˜ˆ: `./app` ๋””๋ ‰ํ„ฐ๋ฆฌ ์—†์ด `main.py`๋งŒ ์žˆ๋Š”
๊ทธ๋Ÿฐ ๋‹ค์Œ `Dockerfile`์—์„œ ํ•ด๋‹น ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๋„๋ก ๊ฒฝ๋กœ๋งŒ ๋งž๊ฒŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
FROM python:3.14
WORKDIR /code
@ -454,7 +454,7 @@ Traefik์€ Docker, Kubernetes ๋“ฑ๊ณผ ํ†ตํ•ฉ๋˜์–ด ์žˆ์–ด, ์ด๋ฅผ ์‚ฌ์šฉํ•ด ์ปจ
## ๋ณต์ œ - ํ”„๋กœ์„ธ์Šค ๊ฐœ์ˆ˜ { #replication-number-of-processes }
**Kubernetes**, Docker Swarm Mode, Nomad ๋“ฑ์˜ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์œผ๋กœ ์—ฌ๋Ÿฌ ๋จธ์‹ ์— ๋ถ„์‚ฐ๋œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” <abbr title="์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ํ•จ๊ป˜ ๋™์ž‘ํ•˜๋„๋ก ๊ตฌ์„ฑ๋œ ๋จธ์‹ ์˜ ๊ทธ๋ฃน">ํด๋Ÿฌ์Šคํ„ฐ</abbr>๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๊ฐ ์ปจํ…Œ์ด๋„ˆ์—์„œ(**์›Œ์ปค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Uvicorn** ๊ฐ™์€) **ํ”„๋กœ์„ธ์Šค ๋งค๋‹ˆ์ €**๋ฅผ ์“ฐ๋Š” ๋Œ€์‹ , **ํด๋Ÿฌ์Šคํ„ฐ ๋ ˆ๋ฒจ**์—์„œ **๋ณต์ œ๋ฅผ ์ฒ˜๋ฆฌ**ํ•˜๊ณ  ์‹ถ์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
**Kubernetes**, Docker Swarm Mode, Nomad ๋“ฑ์˜ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์œผ๋กœ ์—ฌ๋Ÿฌ ๋จธ์‹ ์— ๋ถ„์‚ฐ๋œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” <dfn title="์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ํ•จ๊ป˜ ๋™์ž‘ํ•˜๋„๋ก ๊ตฌ์„ฑ๋œ ๋จธ์‹ ์˜ ๊ทธ๋ฃน">ํด๋Ÿฌ์Šคํ„ฐ</dfn>๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๊ฐ ์ปจํ…Œ์ด๋„ˆ์—์„œ(**์›Œ์ปค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Uvicorn** ๊ฐ™์€) **ํ”„๋กœ์„ธ์Šค ๋งค๋‹ˆ์ €**๋ฅผ ์“ฐ๋Š” ๋Œ€์‹ , **ํด๋Ÿฌ์Šคํ„ฐ ๋ ˆ๋ฒจ**์—์„œ **๋ณต์ œ๋ฅผ ์ฒ˜๋ฆฌ**ํ•˜๊ณ  ์‹ถ์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
Kubernetes ๊ฐ™์€ ๋ถ„์‚ฐ ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์€ ๋ณดํ†ต ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์— ๋Œ€ํ•œ **๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ**์„ ์ง€์›ํ•˜๋ฉด์„œ๋„, **์ปจํ…Œ์ด๋„ˆ ๋ณต์ œ**๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ†ตํ•ฉ๋œ ๋ฐฉ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ **ํด๋Ÿฌ์Šคํ„ฐ ๋ ˆ๋ฒจ**์—์„œ์š”.
@ -499,7 +499,7 @@ HTTPS์— ์‚ฌ์šฉ๋˜๋Š” ๋™์ผํ•œ **TLS ์ข…๋ฃŒ ํ”„๋ก์‹œ** ์ปดํฌ๋„ŒํŠธ๊ฐ€ **๋กœ
๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” `--workers` ์ปค๋งจ๋“œ ๋ผ์ธ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์‹คํ–‰ํ•  ์›Œ์ปค ์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```{ .dockerfile .annotate }
FROM python:3.9
FROM python:3.14
WORKDIR /code

4
docs/ko/docs/deployment/https.md

@ -15,7 +15,7 @@ HTTPS๋Š” ๊ทธ๋ƒฅ โ€œ์ผœ์ ธ ์žˆ๊ฑฐ๋‚˜โ€ ์•„๋‹ˆ๋ฉด โ€œ๊บผ์ ธ ์žˆ๋Š”โ€ ๊ฒƒ์ด๋ผ
์ด์ œ **๊ฐœ๋ฐœ์ž ๊ด€์ **์—์„œ HTTPS๋ฅผ ์ƒ๊ฐํ•  ๋•Œ ์—ผ๋‘์— ๋‘์–ด์•ผ ํ•  ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:
* HTTPS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, **์„œ๋ฒ„**๊ฐ€ **์ œ3์ž**๊ฐ€ ๋ฐœ๊ธ‰ํ•œ **"์ธ์ฆ์„œ(certificates)"**๋ฅผ **๋ณด์œ **ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
* ์ด ์ธ์ฆ์„œ๋Š” ์‹ค์ œ๋กœ ์ œ3์ž๊ฐ€ โ€œ์ƒ์„ฑโ€ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด๊ณ , ์„œ๋ฒ„๊ฐ€ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ œ3์ž๋กœ๋ถ€ํ„ฐ **๋ฐœ๊ธ‰/ํš๋“**ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
* ์ด ์ธ์ฆ์„œ๋Š” ์‹ค์ œ๋กœ '์ƒ์„ฑ'๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ œ3์ž๋กœ๋ถ€ํ„ฐ **๋ฐœ๊ธ‰/ํš๋“**ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
* ์ธ์ฆ์„œ์—๋Š” **์œ ํšจ ๊ธฐ๊ฐ„**์ด ์žˆ์Šต๋‹ˆ๋‹ค.
* ์ฆ‰, **๋งŒ๋ฃŒ**๋ฉ๋‹ˆ๋‹ค.
* ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋ฉด ์ œ3์ž๋กœ๋ถ€ํ„ฐ ๋‹ค์‹œ **๊ฐฑ์‹ **ํ•ด์„œ **์žฌ๋ฐœ๊ธ‰/์žฌํš๋“**ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@ -65,7 +65,7 @@ Let's Encrypt ์ด์ „์—๋Š” ์ด๋Ÿฌํ•œ **HTTPS ์ธ์ฆ์„œ**๊ฐ€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š”
์•„๋งˆ๋„ ์‹œ์ž‘์€ **๋„๋ฉ”์ธ ์ด๋ฆ„**์„ **ํš๋“**ํ•˜๋Š” ๊ฒƒ์ผ ๊ฒ๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ DNS ์„œ๋ฒ„(์•„๋งˆ ๊ฐ™์€ ํด๋ผ์šฐ๋“œ ์ œ๊ณต์—…์ฒด)์—์„œ ์ด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
๋Œ€๊ฐœ ํด๋ผ์šฐ๋“œ ์„œ๋ฒ„(๊ฐ€์ƒ ๋จธ์‹ ) ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ณ , ๊ฑฐ๊ธฐ์—๋Š” <abbr title="That doesn't change - ๋ณ€ํ•˜์ง€ ์•Š์Œ">fixed</abbr> **๊ณต๊ฐœ IP ์ฃผ์†Œ**๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๋Œ€๊ฐœ ํด๋ผ์šฐ๋“œ ์„œ๋ฒ„(๊ฐ€์ƒ ๋จธ์‹ ) ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ณ , ๊ฑฐ๊ธฐ์—๋Š” <dfn title="์‹œ๊ฐ„์ด ์ง€๋‚˜๋„ ๋ณ€ํ•˜์ง€ ์•Š์Œ. ๋™์ ์ด์ง€ ์•Š์Œ">๊ณ ์ •</dfn> **๊ณต๊ฐœ IP ์ฃผ์†Œ**๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
DNS ์„œ๋ฒ„(๋“ค)์—์„œ **๋„๋ฉ”์ธ**์ด ์„œ๋ฒ„์˜ **๊ณต๊ฐœ IP ์ฃผ์†Œ**๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋ ˆ์ฝ”๋“œ(โ€œ`A record`โ€)๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

2
docs/ko/docs/deployment/manually.md

@ -46,7 +46,7 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
์ด์ œ ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
FastAPI๋Š” <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr>๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š”, Python ์›น ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ‘œ์ค€์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. FastAPI๋Š” ASGI ์›น ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.
FastAPI๋Š” <abbr title="Asynchronous Server Gateway Interface - ๋น„๋™๊ธฐ ์„œ๋ฒ„ ๊ฒŒ์ดํŠธ์›จ์ด ์ธํ„ฐํŽ˜์ด์Šค">ASGI</abbr>๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š”, Python ์›น ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ‘œ์ค€์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. FastAPI๋Š” ASGI ์›น ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.
์›๊ฒฉ ์„œ๋ฒ„ ๋จธ์‹ ์—์„œ **FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(๋˜๋Š” ๋‹ค๋ฅธ ASGI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํ•ต์‹ฌ ์š”์†Œ๋Š” **Uvicorn** ๊ฐ™์€ ASGI ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค. `fastapi` ๋ช…๋ น์—๋Š” ๊ธฐ๋ณธ์œผ๋กœ ์ด๊ฒƒ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

12
docs/ko/docs/deployment/server-workers.md

@ -9,13 +9,13 @@
* ๋ฉ”๋ชจ๋ฆฌ
* ์‹œ์ž‘ํ•˜๊ธฐ ์ „์˜ ์ด์ „ ๋‹จ๊ณ„
์ง€๊ธˆ๊นŒ์ง€ ๋ฌธ์„œ์˜ ๋ชจ๋“  ํŠœํ† ๋ฆฌ์–ผ์„ ์ฐธ๊ณ ํ•˜๋ฉด์„œ, `fastapi` ๋ช…๋ น์ฒ˜๋Ÿผ Uvicorn์„ ์‹คํ–‰ํ•˜๋Š” **์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ**์„ ์‚ฌ์šฉํ•ด **๋‹จ์ผ ํ”„๋กœ์„ธ์Šค**๋กœ ์‹คํ–‰ํ•ด ์™”์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
์ง€๊ธˆ๊นŒ์ง€ ๋ฌธ์„œ์˜ ๋ชจ๋“  ํŠœํ† ๋ฆฌ์–ผ์„ ์ฐธ๊ณ ํ•˜๋ฉด์„œ, `fastapi` ๋ช…๋ น์–ด์ฒ˜๋Ÿผ Uvicorn์„ ์‹คํ–‰ํ•˜๋Š” **์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ**์„ ์‚ฌ์šฉํ•ด **๋‹จ์ผ ํ”„๋กœ์„ธ์Šค**๋กœ ์‹คํ–‰ํ•ด ์™”์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•  ๋•Œ๋Š” **๋‹ค์ค‘ ์ฝ”์–ด**๋ฅผ ํ™œ์šฉํ•˜๊ณ  ๋” ๋งŽ์€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก **ํ”„๋กœ์„ธ์Šค ๋ณต์ œ**๋ฅผ ํ•˜๊ณ  ์‹ถ์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
์ด์ „ ์žฅ์˜ [๋ฐฐํฌ ๊ฐœ๋…๋“ค](concepts.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ, ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ „๋žต์ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” `fastapi` ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ `uvicorn` ๋ช…๋ น์„ ์ง์ ‘ ์‚ฌ์šฉํ•ด์„œ, **์›Œ์ปค ํ”„๋กœ์„ธ์Šค**์™€ ํ•จ๊ป˜ **Uvicorn**์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” `fastapi` ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ `uvicorn` ๋ช…๋ น์–ด๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•ด์„œ, **์›Œ์ปค ํ”„๋กœ์„ธ์Šค**์™€ ํ•จ๊ป˜ **Uvicorn**์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
@ -27,11 +27,11 @@ Docker๋‚˜ Kubernetes ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ๋‹ค์Œ ์žฅ
## ์—ฌ๋Ÿฌ ์›Œ์ปค { #multiple-workers }
`--workers` ์ปค๋งจ๋“œ๋ผ์ธ ์˜ต์…˜์œผ๋กœ ์—ฌ๋Ÿฌ ์›Œ์ปค๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
`--workers` ๋ช…๋ น์–ด ์˜ต์…˜์œผ๋กœ ์—ฌ๋Ÿฌ ์›Œ์ปค๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
//// tab | `fastapi`
`fastapi` ๋ช…๋ น์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด:
`fastapi` ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด:
<div class="termy">
@ -81,7 +81,7 @@ $ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration
//// tab | `uvicorn`
`uvicorn` ๋ช…๋ น์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค๋ฉด:
`uvicorn` ๋ช…๋ น์–ด๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค๋ฉด:
<div class="termy">
@ -132,7 +132,7 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
## ์š”์•ฝ { #recap }
`fastapi` ๋˜๋Š” `uvicorn` ๋ช…๋ น์—์„œ `--workers` CLI ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์—ฌ๋Ÿฌ ์›Œ์ปค ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, **๋ฉ€ํ‹ฐ ์ฝ”์–ด CPU**๋ฅผ ํ™œ์šฉํ•ด **์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`fastapi` ๋˜๋Š” `uvicorn` ๋ช…๋ น์–ด์—์„œ `--workers` CLI ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์—ฌ๋Ÿฌ ์›Œ์ปค ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, **๋ฉ€ํ‹ฐ ์ฝ”์–ด CPU**๋ฅผ ํ™œ์šฉํ•ด **์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ๋ฐฐํฌ ๊ฐœ๋…๋“ค์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ **์ž์ฒด ๋ฐฐํฌ ์‹œ์Šคํ…œ**์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋Ÿฌํ•œ ๋„๊ตฌ์™€ ์•„์ด๋””์–ด๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4
docs/ko/docs/deployment/versions.md

@ -34,7 +34,7 @@ fastapi[standard]>=0.112.0,<0.113.0
## ์ด์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „๋“ค { #available-versions }
์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „(์˜ˆ: ํ˜„์žฌ ์ตœ์‹  ๋ฒ„์ „์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด)์€ [Release Notes](../release-notes.md){.internal-link target=_blank}์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „(์˜ˆ: ํ˜„์žฌ ์ตœ์‹  ๋ฒ„์ „์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด)์€ [๋ฆด๋ฆฌ์Šค ๋…ธํŠธ](../release-notes.md){.internal-link target=_blank}์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## ๋ฒ„์ „๋“ค์— ๋Œ€ํ•ด { #about-versions }
@ -66,7 +66,7 @@ fastapi>=0.45.0,<0.46.0
์•ฑ์— ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
**FastAPI**์—์„œ๋Š” ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค(Starlette ๋•๋ถ„์—). ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด ๋ณด์„ธ์š”: [Testing](../tutorial/testing.md){.internal-link target=_blank}
**FastAPI**์—์„œ๋Š” ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค(Starlette ๋•๋ถ„์—). ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด ๋ณด์„ธ์š”: [ํ…Œ์ŠคํŠธ](../tutorial/testing.md){.internal-link target=_blank}
ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ–์ถ˜ ๋’ค์—๋Š” **FastAPI** ๋ฒ„์ „์„ ๋” ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ณ , ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

34
docs/ko/docs/environment-variables.md

@ -19,10 +19,10 @@
<div class="termy">
```console
// You could create an env var MY_NAME with
// ํ™˜๊ฒฝ ๋ณ€์ˆ˜ MY_NAME์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
$ export MY_NAME="Wade Wilson"
// Then you could use it with other programs, like
// ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ:
$ echo "Hello $MY_NAME"
Hello Wade Wilson
@ -37,10 +37,10 @@ Hello Wade Wilson
<div class="termy">
```console
// Create an env var MY_NAME
// ํ™˜๊ฒฝ ๋ณ€์ˆ˜ MY_NAME ์ƒ์„ฑ
$ $Env:MY_NAME = "Wade Wilson"
// Use it with other programs, like
// ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ. ์˜ˆ:
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
@ -78,20 +78,20 @@ print(f"Hello {name} from Python")
<div class="termy">
```console
// Here we don't set the env var yet
// ์—ฌ๊ธฐ์„œ๋Š” ์•„์ง ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค
$ python main.py
// As we didn't set the env var, we get the default value
// ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๊ธฐ๋ณธ๊ฐ’์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค
Hello World from Python
// But if we create an environment variable first
// ํ•˜์ง€๋งŒ ๋จผ์ € ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋ฉด
$ export MY_NAME="Wade Wilson"
// And then call the program again
// ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด
$ python main.py
// Now it can read the environment variable
// ์ด์ œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
Hello Wade Wilson from Python
```
@ -105,20 +105,20 @@ Hello Wade Wilson from Python
<div class="termy">
```console
// Here we don't set the env var yet
// ์—ฌ๊ธฐ์„œ๋Š” ์•„์ง ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค
$ python main.py
// As we didn't set the env var, we get the default value
// ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๊ธฐ๋ณธ๊ฐ’์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค
Hello World from Python
// But if we create an environment variable first
// ํ•˜์ง€๋งŒ ๋จผ์ € ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋ฉด
$ $Env:MY_NAME = "Wade Wilson"
// And then call the program again
// ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด
$ python main.py
// Now it can read the environment variable
// ์ด์ œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
Hello Wade Wilson from Python
```
@ -136,14 +136,14 @@ Hello Wade Wilson from Python
<div class="termy">
```console
// Create an env var MY_NAME in line for this program call
// ์ด ํ”„๋กœ๊ทธ๋žจ ํ˜ธ์ถœ์„ ์œ„ํ•ด ๊ฐ™์€ ์ค„์—์„œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ MY_NAME ์ƒ์„ฑ
$ MY_NAME="Wade Wilson" python main.py
// Now it can read the environment variable
// ์ด์ œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
Hello Wade Wilson from Python
// The env var no longer exists afterwards
// ์ดํ›„์—๋Š” ํ•ด๋‹น ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค
$ python main.py
Hello World from Python

10
docs/ko/docs/features.md

@ -6,7 +6,7 @@
### ๊ฐœ๋ฐฉํ˜• ํ‘œ์ค€์„ ๊ธฐ๋ฐ˜์œผ๋กœ { #based-on-open-standards }
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>: <abbr title="๋˜ํ•œ ๋‹ค์Œ์œผ๋กœ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค: ์—”๋“œํฌ์ธํŠธ, ๋ผ์šฐํŠธ">path</abbr> <abbr title="HTTP ๋ฉ”์†Œ๋“œ(POST, GET, PUT, DELETE ๋“ฑ)๋กœ๋„ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค">operations</abbr>, ๋งค๊ฐœ๋ณ€์ˆ˜, ์š”์ฒญ ๋ณธ๋ฌธ, ๋ณด์•ˆ ๋“ฑ์˜ ์„ ์–ธ์„ ํฌํ•จํ•˜์—ฌ API๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>: <dfn title="๋˜ํ•œ ๋‹ค์Œ์œผ๋กœ๋„ ๋ถˆ๋ฆผ: ์—”๋“œํฌ์ธํŠธ, ๋ผ์šฐํŠธ">๊ฒฝ๋กœ</dfn> <dfn title="HTTP ๋ฉ”์†Œ๋“œ(POST, GET, PUT, DELETE ๋“ฑ)๋กœ๋„ ์•Œ๋ ค์ง">์ฒ˜๋ฆฌ</dfn>, ๋งค๊ฐœ๋ณ€์ˆ˜, ์š”์ฒญ ๋ณธ๋ฌธ, ๋ณด์•ˆ ๋“ฑ์˜ ์„ ์–ธ์„ ํฌํ•จํ•˜์—ฌ API๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
* <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a>๋ฅผ ์‚ฌ์šฉํ•œ ์ž๋™ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ๋ฌธ์„œํ™”(OpenAPI ์ž์ฒด๊ฐ€ JSON Schema๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค).
* ๋‹จ์ˆœํžˆ ๋– ์˜ฌ๋ ค์„œ ๋ง๋ถ™์ธ ๋ ˆ์ด์–ด๊ฐ€ ์•„๋‹ˆ๋ผ, ์„ธ์‹ฌํ•œ ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์นœ ๋’ค ์ด๋Ÿฌํ•œ ํ‘œ์ค€์„ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
* ์ด๋Š” ๋˜ํ•œ ๋‹ค์–‘ํ•œ ์–ธ์–ด๋กœ ์ž๋™ **ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ์ƒ์„ฑ**์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
@ -136,7 +136,7 @@ Python ๊ฐœ๋ฐœ์ž ์„ค๋ฌธ์กฐ์‚ฌ์—์„œ <a href="https://www.jetbrains.com/research/
### ์˜์กด์„ฑ ์ฃผ์ž… { #dependency-injection }
FastAPI๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ๋งค์šฐ ์‰ฝ์ง€๋งŒ, ๋งค์šฐ ๊ฐ•๋ ฅํ•œ <abbr title='๋˜ํ•œ ๋‹ค์Œ์œผ๋กœ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค: "์ปดํฌ๋„ŒํŠธ", "์ž์›", "์„œ๋น„์Šค", "์ œ๊ณต์ž"'><strong>Dependency Injection</strong></abbr> ์‹œ์Šคํ…œ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
FastAPI๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ๋งค์šฐ ์‰ฝ์ง€๋งŒ, ๋งค์šฐ ๊ฐ•๋ ฅํ•œ <dfn title='๋˜ํ•œ ๋‹ค์Œ์œผ๋กœ๋„ ๋ถˆ๋ฆผ: "์ปดํฌ๋„ŒํŠธ", "์ž์›", "์„œ๋น„์Šค", "์ œ๊ณต์ž"'><strong>์˜์กด์„ฑ ์ฃผ์ž…</strong></dfn> ์‹œ์Šคํ…œ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
* ์˜์กด์„ฑ๋„ ์˜์กด์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด, ์˜์กด์„ฑ์˜ ๊ณ„์ธต ๋˜๋Š” **์˜์กด์„ฑ์˜ "๊ทธ๋ž˜ํ”„"**๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
* ๋ชจ๋“  ๊ฒƒ์ด ํ”„๋ ˆ์ž„์›Œํฌ์— ์˜ํ•ด **์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค**.
@ -153,8 +153,8 @@ FastAPI๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ๋งค์šฐ ์‰ฝ์ง€๋งŒ, ๋งค์šฐ ๊ฐ•๋ ฅํ•œ <abbr title='๋˜ํ•œ
### ํ…Œ์ŠคํŠธ๋จ { #tested }
* 100% <abbr title="์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธ๋˜๋Š” ์ฝ”๋“œ์˜ ์–‘">test coverage</abbr>.
* 100% <abbr title="Python ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ, ์ด๋ฅผ ํ†ตํ•ด ํŽธ์ง‘๊ธฐ์™€ ์™ธ๋ถ€ ๋„๊ตฌ๊ฐ€ ๋” ๋‚˜์€ ์ง€์›์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค">type annotated</abbr> ์ฝ”๋“œ ๋ฒ ์ด์Šค.
* 100% <dfn title="์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธ๋˜๋Š” ์ฝ”๋“œ์˜ ์–‘">ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€</dfn>.
* 100% <dfn title="Python ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ, ์ด๋ฅผ ํ†ตํ•ด ํŽธ์ง‘๊ธฐ์™€ ์™ธ๋ถ€ ๋„๊ตฌ๊ฐ€ ๋” ๋‚˜์€ ์ง€์›์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค">ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜</dfn> ์ฝ”๋“œ ๋ฒ ์ด์Šค.
* ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
## Starlette ๊ธฐ๋Šฅ { #starlette-features }
@ -190,7 +190,7 @@ FastAPI๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ๋งค์šฐ ์‰ฝ์ง€๋งŒ, ๋งค์šฐ ๊ฐ•๋ ฅํ•œ <abbr title='๋˜ํ•œ
* **No brainfuck**:
* ์ƒˆ๋กœ์šด ์Šคํ‚ค๋งˆ ์ •์˜ ๋งˆ์ดํฌ๋กœ ์–ธ์–ด๋ฅผ ๋ฐฐ์šธ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
* Python ํƒ€์ž…์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด Pydantic ์‚ฌ์šฉ๋ฒ•๋„ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
* ์—ฌ๋Ÿฌ๋ถ„์˜ **<abbr title="Integrated Development Environment - ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ: ์ฝ”๋“œ ํŽธ์ง‘๊ธฐ์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค">IDE</abbr>/<abbr title="์ฝ”๋“œ ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ">linter</abbr>/๋‡Œ**์™€ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค:
* ์—ฌ๋Ÿฌ๋ถ„์˜ **<abbr title="Integrated Development Environment - ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ: ์ฝ”๋“œ ํŽธ์ง‘๊ธฐ์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค">IDE</abbr>/<dfn title="์ฝ”๋“œ ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ">๋ฆฐํ„ฐ</dfn>/๋‡Œ**์™€ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค:
* pydantic ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ์ •์˜ํ•œ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค์ผ ๋ฟ์ด๋ฏ€๋กœ, ์ž๋™ ์™„์„ฑ, ๋ฆฐํŒ…, mypy, ๊ทธ๋ฆฌ๊ณ  ์ง๊ด€๊นŒ์ง€๋„ ๊ฒ€์ฆ๋œ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
* **๋ณต์žกํ•œ ๊ตฌ์กฐ**๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค:
* ๊ณ„์ธต์ ์ธ Pydantic ๋ชจ๋ธ, Python `typing`์˜ `List`์™€ `Dict` ๋“ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

4
docs/ko/docs/how-to/authentication-error-status-code.md

@ -8,10 +8,10 @@ FastAPI ๋ฒ„์ „ `0.122.0`๋ถ€ํ„ฐ๋Š” ๋” ์ ์ ˆํ•œ HTTP ์ƒํƒœ ์ฝ”๋“œ `401 Unauthor
์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธฐ๋ณธ๊ฐ’์ธ `401 Unauthorized` ์˜ค๋ฅ˜ ๋Œ€์‹  `403 Forbidden` ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” `HTTPBearer`์˜ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
/// tip | ํŒ
ํ•จ์ˆ˜๋Š” ์˜ˆ์™ธ๋ฅผ `raise`ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜ˆ์™ธ ์ธ์Šคํ„ด์Šค๋ฅผ `return`ํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š”(`raise`) ์ž‘์—…์€ ๋‚ด๋ถ€ ์ฝ”๋“œ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—์„œ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.
ํ•จ์ˆ˜๋Š” ์˜ˆ์™ธ๋ฅผ `return`ํ•˜๋Š” ๊ฒƒ์ด์ง€ `raise`ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š”(`raise`) ์ž‘์—…์€ ๋‚ด๋ถ€ ์ฝ”๋“œ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—์„œ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.
///

4
docs/ko/docs/how-to/conditional-openapi.md

@ -4,7 +4,7 @@
## ๋ณด์•ˆ, API ๋ฐ docs์— ๋Œ€ํ•ด์„œ { #about-security-apis-and-docs }
ํ”„๋กœ๋•์…˜์—์„œ, ๋ฌธ์„œํ™”๋œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI)๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ด API๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด *๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค*.
ํ”„๋กœ๋•์…˜์—์„œ, ๋ฌธ์„œํ™”๋œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI)๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ด API๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
์ด๋Š” API์— ์ถ”๊ฐ€์ ์ธ ๋ณด์•ˆ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉฐ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋Š” ์—ฌ์ „ํžˆ ๋™์ผํ•œ ์œ„์น˜์—์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -29,7 +29,7 @@ API๋ฅผ ๋ณดํ˜ธํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•
์˜ˆ๋ฅผ ๋“ค์–ด:
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
์—ฌ๊ธฐ์„œ `openapi_url` ์„ค์ •์„ ๊ธฐ๋ณธ๊ฐ’์ธ `"/openapi.json"`์œผ๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

8
docs/ko/docs/how-to/configure-swagger-ui.md

@ -18,7 +18,7 @@ FastAPI๋Š” ์ด ๊ตฌ์„ฑ์„ **JSON** ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ JavaScript์™€ ํ˜ธํ™˜
๊ทธ๋Ÿฌ๋‚˜ `syntaxHighlight`๋ฅผ `False`๋กœ ์„ค์ •ํ•˜์—ฌ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ๊ธฐ๋Šฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
...๊ทธ๋Ÿผ Swagger UI์—์„œ ๋” ์ด์ƒ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ๊ธฐ๋Šฅ์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค:
@ -28,7 +28,7 @@ FastAPI๋Š” ์ด ๊ตฌ์„ฑ์„ **JSON** ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ JavaScript์™€ ํ˜ธํ™˜
๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ `"syntaxHighlight.theme"` ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ํ…Œ๋งˆ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์ค‘๊ฐ„์— ์ ์ด ํฌํ•จ๋œ ๊ฒƒ์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค).
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
์ด ์„ค์ •์€ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ์ƒ‰์ƒ ํ…Œ๋งˆ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค:
@ -42,11 +42,11 @@ FastAPI๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ํ•ฉํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ณธ ๊ตฌ์„ฑ ๋งค
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
`swagger_ui_parameters` ์ธ์ˆ˜์— ๋‹ค๋ฅธ ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ๊ฐ’ ์ค‘ ์ผ๋ถ€๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`swagger_ui_parameters` ์ธ์ˆ˜์— ๋‹ค๋ฅธ ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ๊ฐ’ ์ค‘ ์–ด๋А ๊ฒƒ์ด๋“  ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, `deepLinking`์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด `swagger_ui_parameters`์— ๋‹ค์Œ ์„ค์ •์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
## ๊ธฐํƒ€ Swagger UI ๋งค๊ฐœ๋ณ€์ˆ˜ { #other-swagger-ui-parameters }

16
docs/ko/docs/how-to/custom-docs-ui-assets.md

@ -8,7 +8,7 @@ API ๋ฌธ์„œ๋Š” **Swagger UI**์™€ **ReDoc**์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ฐ๊ฐ JavaScript์™€
## JavaScript์™€ CSS์šฉ ์ปค์Šคํ…€ CDN { #custom-cdn-for-javascript-and-css }
์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค๋ฅธ <abbr title="Content Delivery Network">CDN</abbr>์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด `https://unpkg.com/`์„ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค๋ฅธ <abbr title="Content Delivery Network - ์ฝ˜ํ…์ธ  ์ „์†ก ๋„คํŠธ์›Œํฌ">CDN</abbr>์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด `https://unpkg.com/`์„ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
์ด๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด ํŠน์ • ๊ตญ๊ฐ€์—์„œ ์ผ๋ถ€ URL์„ ์ œํ•œํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -18,7 +18,7 @@ API ๋ฌธ์„œ๋Š” **Swagger UI**์™€ **ReDoc**์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ฐ๊ฐ JavaScript์™€
๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด `FastAPI` ์•ฑ์„ ์ƒ์„ฑํ•  ๋•Œ ํ•ด๋‹น URL์„ `None`์œผ๋กœ ์„ค์ •ํ•˜์„ธ์š”:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
### ์ปค์Šคํ…€ ๋ฌธ์„œ ํฌํ•จํ•˜๊ธฐ { #include-the-custom-docs }
@ -34,7 +34,7 @@ FastAPI ๋‚ด๋ถ€ ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•ด ๋ฌธ์„œ์šฉ HTML ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ ,
ReDoc๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค...
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
/// tip | ํŒ
@ -50,7 +50,7 @@ Swagger UI๊ฐ€ ์ด ๊ณผ์ •์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฒ˜๋ฆฌํ•ด ์ฃผ์ง€๋งŒ, ์ด๋ฅผ
์ด์ œ ๋ชจ๋“  ๊ฒƒ์ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“œ์„ธ์š”:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
### ํ…Œ์ŠคํŠธํ•˜๊ธฐ { #test-it }
@ -118,7 +118,7 @@ JavaScript์™€ CSS๋ฅผ ์ž์ฒด ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๊ฒƒ์€ ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜คํ”„๋ผ์ธ
* `StaticFiles`๋ฅผ importํ•ฉ๋‹ˆ๋‹ค.
* ํŠน์ • ๊ฒฝ๋กœ์— `StaticFiles()` ์ธ์Šคํ„ด์Šค๋ฅผ "๋งˆ์šดํŠธ(mount)"ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
### ์ •์  ํŒŒ์ผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ { #test-the-static-files }
@ -144,7 +144,7 @@ JavaScript์™€ CSS๋ฅผ ์ž์ฒด ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๊ฒƒ์€ ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜คํ”„๋ผ์ธ
๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด `FastAPI` ์•ฑ์„ ์ƒ์„ฑํ•  ๋•Œ ํ•ด๋‹น URL์„ `None`์œผ๋กœ ์„ค์ •ํ•˜์„ธ์š”:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
### ์ •์  ํŒŒ์ผ์„ ์œ„ํ•œ ์ปค์Šคํ…€ ๋ฌธ์„œ ํฌํ•จํ•˜๊ธฐ { #include-the-custom-docs-for-static-files }
@ -160,7 +160,7 @@ JavaScript์™€ CSS๋ฅผ ์ž์ฒด ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๊ฒƒ์€ ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜คํ”„๋ผ์ธ
ReDoc๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค...
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
/// tip | ํŒ
@ -176,7 +176,7 @@ Swagger UI๊ฐ€ ์ด ๊ณผ์ •์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฒ˜๋ฆฌํ•ด ์ฃผ์ง€๋งŒ, ์ด๋ฅผ
์ด์ œ ๋ชจ๋“  ๊ฒƒ์ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“œ์„ธ์š”:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
### ์ •์  ํŒŒ์ผ UI ํ…Œ์ŠคํŠธํ•˜๊ธฐ { #test-static-files-ui }

10
docs/ko/docs/how-to/extending-openapi.md

@ -43,19 +43,19 @@
๋จผ์ €, ํ‰์†Œ์ฒ˜๋Ÿผ **FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ชจ๋‘ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
### OpenAPI ์Šคํ‚ค๋งˆ ์ƒ์„ฑํ•˜๊ธฐ { #generate-the-openapi-schema }
๊ทธ๋‹ค์Œ `custom_openapi()` ํ•จ์ˆ˜ ์•ˆ์—์„œ, ๋™์ผํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด OpenAPI ์Šคํ‚ค๋งˆ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
### OpenAPI ์Šคํ‚ค๋งˆ ์ˆ˜์ •ํ•˜๊ธฐ { #modify-the-openapi-schema }
์ด์ œ OpenAPI ์Šคํ‚ค๋งˆ์˜ `info` "object"์— ์ปค์Šคํ…€ `x-logo`๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ReDoc ํ™•์žฅ์„ ๋”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
### OpenAPI ์Šคํ‚ค๋งˆ ์บ์‹œํ•˜๊ธฐ { #cache-the-openapi-schema }
@ -65,13 +65,13 @@
์Šคํ‚ค๋งˆ๋Š” ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑ๋˜๊ณ , ์ดํ›„ ์š”์ฒญ์—์„œ๋Š” ๊ฐ™์€ ์บ์‹œ๋œ ์Šคํ‚ค๋งˆ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
### ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ธฐ { #override-the-method }
์ด์ œ `.openapi()` ๋ฉ”์„œ๋“œ๋ฅผ ์ƒˆ ํ•จ์ˆ˜๋กœ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
### ํ™•์ธํ•˜๊ธฐ { #check-it }

2
docs/ko/docs/how-to/graphql.md

@ -35,7 +35,7 @@
๋‹ค์Œ์€ Strawberry๋ฅผ FastAPI์™€ ํ†ตํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
<a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry ๋ฌธ์„œ</a>์—์„œ Strawberry์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4
docs/ko/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md

@ -22,7 +22,7 @@ Pydantic v1์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ค๋ž˜๋œ FastAPI ์•ฑ์ด ์žˆ๋‹ค๋ฉด, ์—ฌ๊ธฐ์„œ๋Š” ์ด
## ๊ณต์‹ ๊ฐ€์ด๋“œ { #official-guide }
Pydantic์—๋Š” v1์—์„œ v2๋กœ์˜ ๊ณต์‹ <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">Migration Guide</a>๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
Pydantic์—๋Š” v1์—์„œ v2๋กœ์˜ ๊ณต์‹ <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ</a>๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์—๋Š” ๋ฌด์—‡์ด ๋ฐ”๋€Œ์—ˆ๋Š”์ง€, ๊ฒ€์ฆ์ด ์ด์ œ ์–ด๋–ป๊ฒŒ ๋” ์ •ํ™•ํ•˜๊ณ  ์—„๊ฒฉํ•ด์กŒ๋Š”์ง€, ๊ฐ€๋Šฅํ•œ ์ฃผ์˜์‚ฌํ•ญ ๋“ฑ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
@ -30,7 +30,7 @@ Pydantic์—๋Š” v1์—์„œ v2๋กœ์˜ ๊ณต์‹ <a href="https://docs.pydantic.dev/lates
## ํ…Œ์ŠคํŠธ { #tests }
์•ฑ์— ๋Œ€ํ•œ [tests](../tutorial/testing.md){.internal-link target=_blank}๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์ง€์†์  ํ†ตํ•ฉ(CI)์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.
์•ฑ์— ๋Œ€ํ•œ [ํ…Œ์ŠคํŠธ](../tutorial/testing.md){.internal-link target=_blank}๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์ง€์†์  ํ†ตํ•ฉ(CI)์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ๋„ ๋ชจ๋“  ๊ฒƒ์ด ๊ธฐ๋Œ€ํ•œ ๋Œ€๋กœ ๊ณ„์† ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2
docs/ko/docs/how-to/separate-openapi-schemas.md

@ -72,7 +72,7 @@
ํ•˜์ง€๋งŒ `Item-Output`์—์„œ๋Š” `description`์ด **ํ•„์ˆ˜์ด๋ฉฐ**, ๋นจ๊ฐ„ ๋ณ„ํ‘œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image04.png">
<img src="/img/tutorial/separate-openapi_schemas/image04.png">
</div>
**Pydantic v2**์˜ ์ด ๊ธฐ๋Šฅ ๋•๋ถ„์— API ๋ฌธ์„œ๋Š” ๋” **์ •๋ฐ€**ํ•ด์ง€๊ณ , ์ž๋™ ์ƒ์„ฑ๋œ ํด๋ผ์ด์–ธํŠธ์™€ SDK๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ๊ฒƒ๋“ค๋„ ๋” ์ •๋ฐ€ํ•ด์ ธ์„œ ๋” ๋‚˜์€ **developer experience**์™€ ์ผ๊ด€์„ฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐ŸŽ‰

10
docs/ko/docs/index.md

@ -40,7 +40,7 @@ FastAPI๋Š” ํ˜„๋Œ€์ ์ด๊ณ , ๋น ๋ฅด๋ฉฐ(๊ณ ์„ฑ๋Šฅ), ํŒŒ์ด์ฌ ํ‘œ์ค€ ํƒ€์ž… ํžŒํŠธ
* **๋น ๋ฆ„**: (Starlette๊ณผ Pydantic ๋•๋ถ„์—) **NodeJS** ๋ฐ **Go**์™€ ๋Œ€๋“ฑํ•  ์ •๋„๋กœ ๋งค์šฐ ๋†’์€ ์„ฑ๋Šฅ. [์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ๋น ๋ฅธ ํŒŒ์ด์ฌ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜](#performance).
* **๋น ๋ฅธ ์ฝ”๋“œ ์ž‘์„ฑ**: ์•ฝ 200%์—์„œ 300%๊นŒ์ง€ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ์†๋„ ์ฆ๊ฐ€. *
* **์ ์€ ๋ฒ„๊ทธ**: ์‚ฌ๋žŒ(๊ฐœ๋ฐœ์ž)์— ์˜ํ•œ ์—๋Ÿฌ ์•ฝ 40% ๊ฐ์†Œ. *
* **์ง๊ด€์ **: ํ›Œ๋ฅญํ•œ ํŽธ์ง‘๊ธฐ ์ง€์›. ๋ชจ๋“  ๊ณณ์—์„œ <abbr title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: auto-complete, autocompletion, IntelliSense">์ž๋™์™„์„ฑ</abbr>. ์ ์€ ๋””๋ฒ„๊น… ์‹œ๊ฐ„.
* **์ง๊ด€์ **: ํ›Œ๋ฅญํ•œ ํŽธ์ง‘๊ธฐ ์ง€์›. <dfn title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: ์ž๋™ ์™„์„ฑ, ์ž๋™์™„์„ฑ, IntelliSense">์ž๋™์™„์„ฑ</dfn>์ด ๋ชจ๋“  ๊ณณ์—์„œ ๋™์ž‘. ์ ์€ ๋””๋ฒ„๊น… ์‹œ๊ฐ„.
* **์‰ฌ์›€**: ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐฐ์šฐ๋„๋ก ์„ค๊ณ„. ์ ์€ ๋ฌธ์„œ ์ฝ๊ธฐ ์‹œ๊ฐ„.
* **์งง์Œ**: ์ฝ”๋“œ ์ค‘๋ณต ์ตœ์†Œํ™”. ๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ ์–ธ์˜ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ. ์ ์€ ๋ฒ„๊ทธ.
* **๊ฒฌ๊ณ ํ•จ**: ์ค€๋น„๋œ ํ”„๋กœ๋•์…˜ ์šฉ ์ฝ”๋“œ๋ฅผ ์–ป์œผ์‹ญ์‹œ์˜ค. ์ž๋™ ๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์™€ ํ•จ๊ป˜.
@ -368,7 +368,7 @@ item: Item
* ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ:
* ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์„ ๋•Œ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ช…ํ™•ํ•œ ์—๋Ÿฌ.
* ๊นŠ์ด ์ค‘์ฒฉ๋œ JSON ๊ฐ์ฒด์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ.
* ์ž…๋ ฅ ๋ฐ์ดํ„ฐ <abbr title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: serialization, parsing, marshalling">๋ณ€ํ™˜</abbr>: ๋„คํŠธ์›Œํฌ์—์„œ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ๋ฐ ํƒ€์ž…์œผ๋กœ ์ „์†ก. ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค:
* ์ž…๋ ฅ ๋ฐ์ดํ„ฐ <dfn title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: ์ง๋ ฌํ™”, ํŒŒ์‹ฑ, ๋งˆ์ƒฌ๋ง">๋ณ€ํ™˜</dfn>: ๋„คํŠธ์›Œํฌ์—์„œ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ๋ฐ ํƒ€์ž…์œผ๋กœ ์ „์†ก. ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค:
* JSON.
* ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜.
* ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜.
@ -376,7 +376,7 @@ item: Item
* ํ—ค๋”.
* ํผ(Forms).
* ํŒŒ์ผ.
* ์ถœ๋ ฅ ๋ฐ์ดํ„ฐ <abbr title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: serialization, parsing, marshalling">๋ณ€ํ™˜</abbr>: ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ๋ฐ ํƒ€์ž…์„ ๋„คํŠธ์›Œํฌ ๋ฐ์ดํ„ฐ๋กœ ์ „ํ™˜(JSON ํ˜•์‹์œผ๋กœ):
* ์ถœ๋ ฅ ๋ฐ์ดํ„ฐ <dfn title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: ์ง๋ ฌํ™”, ํŒŒ์‹ฑ, ๋งˆ์ƒฌ๋ง">๋ณ€ํ™˜</dfn>: ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ๋ฐ ํƒ€์ž…์„ ๋„คํŠธ์›Œํฌ ๋ฐ์ดํ„ฐ๋กœ ์ „ํ™˜(JSON ํ˜•์‹์œผ๋กœ):
* ํŒŒ์ด์ฌ ํƒ€์ž… ๋ณ€ํ™˜ (`str`, `int`, `float`, `bool`, `list`, ๋“ฑ).
* `datetime` ๊ฐ์ฒด.
* `UUID` ๊ฐ์ฒด.
@ -439,7 +439,7 @@ item: Item
* ์„œ๋กœ ๋‹ค๋ฅธ ์žฅ์†Œ์—์„œ **๋งค๊ฐœ๋ณ€์ˆ˜** ์„ ์–ธ: **ํ—ค๋”**, **์ฟ ํ‚ค**, **ํผ ํ•„๋“œ** ๊ทธ๋ฆฌ๊ณ  **ํŒŒ์ผ**.
* `maximum_length` ๋˜๋Š” `regex`์ฒ˜๋Ÿผ **์œ ํšจ์„ฑ ์ œ์•ฝ**ํ•˜๋Š” ๋ฐฉ๋ฒ•.
* ๊ฐ•๋ ฅํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด **<abbr title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: components, resources, providers, services, injectables">์˜์กด์„ฑ ์ฃผ์ž…</abbr>** ์‹œ์Šคํ…œ.
* ๊ฐ•๋ ฅํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด **<dfn title="๋‹ค๋ฅธ ๋ง๋กœ๋Š”: ์ปดํฌ๋„ŒํŠธ, ๋ฆฌ์†Œ์Šค, ํ”„๋กœ๋ฐ”์ด๋”, ์„œ๋น„์Šค, ์ธ์ ํ„ฐ๋ธ”">์˜์กด์„ฑ ์ฃผ์ž…</dfn>** ์‹œ์Šคํ…œ.
* **OAuth2** ์ง€์›์„ ํฌํ•จํ•œ **JWT tokens** ๋ฐ **HTTP Basic**์„ ๊ฐ–๋Š” ๋ณด์•ˆ๊ณผ ์ธ์ฆ.
* (Pydantic ๋•๋ถ„์—) **๊นŠ์€ ์ค‘์ฒฉ JSON ๋ชจ๋ธ**์„ ์„ ์–ธํ•˜๋Š”๋ฐ ๋” ์ง„๋ณดํ•œ (ํ•˜์ง€๋งŒ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‰ฌ์šด) ๊ธฐ์ˆ .
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> ๋ฐ ๊ธฐํƒ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€์˜ **GraphQL** ํ†ตํ•ฉ.
@ -524,7 +524,7 @@ Starlette์ด ์‚ฌ์šฉํ•˜๋Š”:
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient`๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•„์š”.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•„์š”.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()`๊ณผ ํ•จ๊ป˜ form <abbr title="HTTP ์š”์ฒญ์—์„œ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋กœ ๊ฐ€๋Š” ๋ฌธ์ž์—ด ๋ณ€ํ™˜">"parsing"</abbr> ์ง€์›์„ ์›ํ•˜๋ฉด ํ•„์š”.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()`๊ณผ ํ•จ๊ป˜ form <dfn title="HTTP ์š”์ฒญ์—์„œ ์˜จ ๋ฌธ์ž์—ด์„ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜">"ํŒŒ์‹ฑ"</dfn> ์ง€์›์„ ์›ํ•˜๋ฉด ํ•„์š”.
FastAPI๊ฐ€ ์‚ฌ์šฉํ•˜๋Š”:

2
docs/ko/docs/project-generation.md

@ -2,7 +2,7 @@
ํ…œํ”Œ๋ฆฟ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํŠน์ • ์„ค์ •๊ณผ ํ•จ๊ป˜ ์ œ๊ณต๋˜์ง€๋งŒ, ์œ ์—ฐํ•˜๊ณ  ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋””์ž์ธ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ํŠน์„ฑ๋“ค์€ ์—ฌ๋Ÿฌ๋ถ„์ด ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ ์ˆ˜์ •, ์ ์šฉ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ณ , ํ…œํ”Œ๋ฆฟ์ด ์™„๋ฒฝํ•œ ์‹œ์ž‘์ ์ด ๋˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๐Ÿ
๋งŽ์€ ์ดˆ๊ธฐ ์„ค์ •, ๋ณด์•ˆ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ ์ผ๋ถ€ API ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์ด๋ฏธ ์ค€๋น„๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ์—ฌ๋Ÿฌ๋ถ„์€ ์ด ํ…œํ”Œ๋ฆฟ์„ (ํ”„๋กœ์ ํŠธ๋ฅผ) ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋งŽ์€ ์ดˆ๊ธฐ ์„ค์ •, ๋ณด์•ˆ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ ์ผ๋ถ€ API ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์ด๋ฏธ ์ค€๋น„๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ์—ฌ๋Ÿฌ๋ถ„์€ ์ด ํ…œํ”Œ๋ฆฟ์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
GitHub ์ €์žฅ์†Œ: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Full Stack FastAPI ํ…œํ”Œ๋ฆฟ</a>

186
docs/ko/docs/python-types.md

@ -2,7 +2,7 @@
ํŒŒ์ด์ฌ์€ ์„ ํƒ์ ์œผ๋กœ "ํƒ€์ž… ํžŒํŠธ(type hints)"(โ€œtype annotationsโ€๋ผ๊ณ ๋„ ํ•จ)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ **"ํƒ€์ž… ํžŒํŠธ"** ๋˜๋Š” ์• ๋„ˆํ…Œ์ด์…˜์€ ๋ณ€์ˆ˜์˜ <abbr title="for example: str, int, float, bool">ํƒ€์ž…</abbr>์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํŠน์ˆ˜ํ•œ ๊ตฌ๋ฌธ์ž…๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ **"ํƒ€์ž… ํžŒํŠธ"** ๋˜๋Š” ์• ๋„ˆํ…Œ์ด์…˜์€ ๋ณ€์ˆ˜์˜ <dfn title="์˜ˆ: str, int, float, bool">ํƒ€์ž…</dfn>์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํŠน์ˆ˜ํ•œ ๊ตฌ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์„ ์–ธํ•˜๋ฉด ์—๋””ํ„ฐ์™€ ๋„๊ตฌ๊ฐ€ ๋” ๋‚˜์€ ์ง€์›์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -22,7 +22,7 @@
๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋กœ ์‹œ์ž‘ํ•ด๋ด…์‹œ๋‹ค:
{* ../../docs_src/python_types/tutorial001_py39.py *}
{* ../../docs_src/python_types/tutorial001_py310.py *}
์ด ํ”„๋กœ๊ทธ๋žจ์„ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค:
@ -34,9 +34,9 @@ John Doe
* `first_name`๊ณผ `last_name`๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
* `title()`๋กœ ๊ฐ๊ฐ์˜ ์ฒซ ๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
* ๊ฐ€์šด๋ฐ์— ๊ณต๋ฐฑ์„ ๋‘๊ณ  <abbr title="Puts them together, as one. With the contents of one after the other.">์—ฐ๊ฒฐ</abbr>ํ•ฉ๋‹ˆ๋‹ค.
* ๊ฐ€์šด๋ฐ์— ๊ณต๋ฐฑ์„ ๋‘๊ณ  <dfn title="์„œ๋กœ๋ฅผ ํ•˜๋‚˜๋กœ ํ•ฉ์นฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋‚ด์šฉ ๋’ค์— ๋‹ค๋ฅธ ๊ฒƒ์˜ ๋‚ด์šฉ์„ ์ด์–ด ๋ถ™์ž…๋‹ˆ๋‹ค.">์—ฐ๊ฒฐ</dfn>ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
### ์ˆ˜์ •ํ•˜๊ธฐ { #edit-it }
@ -80,7 +80,7 @@ John Doe
์ด๊ฒƒ๋“ค์ด "ํƒ€์ž… ํžŒํŠธ"์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
์ด๊ฒƒ์€ ๋‹ค์Œ์ฒ˜๋Ÿผ ๊ธฐ๋ณธ๊ฐ’์„ ์„ ์–ธํ•˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค:
@ -108,7 +108,7 @@ John Doe
์ด ํ•จ์ˆ˜๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”. ์ด๋ฏธ ํƒ€์ž… ํžŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
์—๋””ํ„ฐ๊ฐ€ ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ž๋™์™„์„ฑ๋งŒ ๋˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์˜ค๋ฅ˜ ๊ฒ€์‚ฌ๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -116,7 +116,7 @@ John Doe
์ด์ œ ๊ณ ์ณ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ , `age`๋ฅผ `str(age)`๋กœ ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
## ํƒ€์ž… ์„ ์–ธ { #declaring-types }
@ -135,29 +135,32 @@ John Doe
* `bool`
* `bytes`
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
### ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” Generic(์ œ๋„ค๋ฆญ) ํƒ€์ž… { #generic-types-with-type-parameters }
### `typing` ๋ชจ๋“ˆ { #typing-module }
`dict`, `list`, `set`, `tuple`์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ๊ฐ’์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚ด๋ถ€ ๊ฐ’์—๋„ ๊ฐ์ž์˜ ํƒ€์ž…์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ `typing` ๋ชจ๋“ˆ์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ importํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์–ด๋–ค ๊ฐ’์ด "์•„๋ฌด ํƒ€์ž…"์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์„ ์–ธํ•˜๋ ค๋ฉด, `typing`์˜ `Any`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
์ด๋ ‡๊ฒŒ ๋‚ด๋ถ€ ํƒ€์ž…์„ ๊ฐ€์ง€๋Š” ํƒ€์ž…์„ "**generic**" ํƒ€์ž…์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚ด๋ถ€ ํƒ€์ž…๊นŒ์ง€ ํฌํ•จํ•ด ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
```python
from typing import Any
์ด๋Ÿฐ ํƒ€์ž…๊ณผ ๋‚ด๋ถ€ ํƒ€์ž…์„ ์„ ์–ธํ•˜๋ ค๋ฉด ํ‘œ์ค€ ํŒŒ์ด์ฌ ๋ชจ๋“ˆ `typing`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ ์ด๋Ÿฌํ•œ ํƒ€์ž… ํžŒํŠธ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
#### ๋” ์ตœ์‹  ๋ฒ„์ „์˜ Python { #newer-versions-of-python }
`typing`์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ๋ฒ•์€ Python 3.6๋ถ€ํ„ฐ ์ตœ์‹  ๋ฒ„์ „๊นŒ์ง€, Python 3.9, Python 3.10 ๋“ฑ์„ ํฌํ•จํ•œ ๋ชจ๋“  ๋ฒ„์ „๊ณผ **ํ˜ธํ™˜**๋ฉ๋‹ˆ๋‹ค.
def some_function(data: Any):
print(data)
```
ํŒŒ์ด์ฌ์ด ๋ฐœ์ „ํ•จ์— ๋”ฐ๋ผ **๋” ์ตœ์‹  ๋ฒ„์ „**์—์„œ๋Š” ์ด๋Ÿฌํ•œ ํƒ€์ž… ์• ๋„ˆํ…Œ์ด์…˜ ์ง€์›์ด ๊ฐœ์„ ๋˜๋ฉฐ, ๋งŽ์€ ๊ฒฝ์šฐ ํƒ€์ž… ์• ๋„ˆํ…Œ์ด์…˜์„ ์„ ์–ธํ•˜๊ธฐ ์œ„ํ•ด `typing` ๋ชจ๋“ˆ์„ importํ•ด์„œ ์‚ฌ์šฉํ•  ํ•„์š”์กฐ์ฐจ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
### Generic(์ œ๋„ค๋ฆญ) ํƒ€์ž… { #generic-types }
ํ”„๋กœ์ ํŠธ์—์„œ ๋” ์ตœ์‹  ๋ฒ„์ „์˜ ํŒŒ์ด์ฌ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ทธ ์ถ”๊ฐ€์ ์ธ ๋‹จ์ˆœํ•จ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ผ๋ถ€ ํƒ€์ž…์€ ๋Œ€๊ด„ํ˜ธ ์•ˆ์— "ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜"๋ฅผ ๋ฐ›์•„ ๋‚ด๋ถ€ ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "๋ฌธ์ž์—ด์˜ ๋ฆฌ์ŠคํŠธ"๋Š” `list[str]`๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
์ด ๋ฌธ์„œ ์ „์ฒด์—๋Š” ๊ฐ ํŒŒ์ด์ฌ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์ฐจ์ด๊ฐ€ ์žˆ์„ ๋•Œ).
์ด๋ ‡๊ฒŒ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์„ **Generic types** ๋˜๋Š” **Generics**๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด "**Python 3.6+**"๋Š” Python 3.6 ์ด์ƒ(3.7, 3.8, 3.9, 3.10 ๋“ฑ ํฌํ•จ)๊ณผ ํ˜ธํ™˜๋œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  "**Python 3.9+**"๋Š” Python 3.9 ์ด์ƒ(3.10 ๋“ฑ ํฌํ•จ)๊ณผ ํ˜ธํ™˜๋œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.
๋Œ€๊ด„ํ˜ธ์™€ ๋‚ด๋ถ€ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ๋™์ผํ•œ ๋‚ด์žฅ ํƒ€์ž…๋“ค์„ ์ œ๋„ค๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
**์ตœ์‹  ๋ฒ„์ „์˜ Python**์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์ตœ์‹  ๋ฒ„์ „์šฉ ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด "**Python 3.10+**"์ฒ˜๋Ÿผ, ๊ฐ€์žฅ **์ข‹๊ณ  ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๋ฌธ๋ฒ•**์„ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
* `list`
* `tuple`
* `set`
* `dict`
#### List { #list }
@ -169,7 +172,7 @@ John Doe
`list`๋Š” ๋‚ด๋ถ€ ํƒ€์ž…์„ ํฌํ•จํ•˜๋Š” ํƒ€์ž…์ด๋ฏ€๋กœ, ๊ทธ ํƒ€์ž…๋“ค์„ ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ๋„ฃ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
/// info | ์ •๋ณด
@ -195,7 +198,7 @@ John Doe
`tuple`๊ณผ `set`๋„ ๋™์ผํ•˜๊ฒŒ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค:
@ -210,7 +213,7 @@ John Doe
๋‘ ๋ฒˆ์งธ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” `dict`์˜ ๊ฐ’์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค:
@ -222,44 +225,20 @@ John Doe
๋ณ€์ˆ˜๊ฐ€ **์—ฌ๋Ÿฌ ํƒ€์ž… ์ค‘ ์–ด๋–ค ๊ฒƒ์ด๋“ ** ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `int` ๋˜๋Š” `str`์ž…๋‹ˆ๋‹ค.
Python 3.6 ์ด์ƒ(3.10 ํฌํ•จ)์—์„œ๋Š” `typing`์˜ `Union` ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ณ , ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…๋“ค์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Python 3.10์—๋Š” ๊ฐ€๋Šฅํ•œ ํƒ€์ž…๋“ค์„ <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>์„ธ๋กœ ๋ง‰๋Œ€(`|`)</abbr>๋กœ ๊ตฌ๋ถ„ํ•ด ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” **์ƒˆ ๋ฌธ๋ฒ•**๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์ •์˜ํ•˜๋ ค๋ฉด ๋‘ ํƒ€์ž…์„ <dfn title='โ€œ๋น„ํŠธ ๋‹จ์œ„ OR ์—ฐ์‚ฐ์žโ€๋ผ๊ณ ๋„ ํ•˜์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ๊ทธ ์˜๋ฏธ์™€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค'>์„ธ๋กœ ๋ง‰๋Œ€(`|`)</dfn>๋กœ ๊ตฌ๋ถ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
//// tab | Python 3.10+
์ด๋Š” ๋‘ ํƒ€์ž… ์ง‘ํ•ฉ์˜ ํ•ฉ์ง‘ํ•ฉ(union) ์•ˆ์˜ ์–ด๋А ๊ฒƒ์ด๋“  ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ "์œ ๋‹ˆ์˜จ"์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
```
////
๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์ด๋Š” `item`์ด `int` ๋˜๋Š” `str`์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.
์ด๋Š” `item`์ด `int` ๋˜๋Š” `str`์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.
#### `None`์ผ ์ˆ˜๋„ ์žˆ์Œ { #possibly-none }
๊ฐ’์ด `str` ๊ฐ™์€ ํƒ€์ž…์ผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, `None`์ผ ์ˆ˜๋„ ์žˆ๋‹ค๊ณ  ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Python 3.6 ์ด์ƒ(3.10 ํฌํ•จ)์—์„œ๋Š” `typing` ๋ชจ๋“ˆ์—์„œ `Optional`์„ importํ•ด์„œ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009_py39.py!}
```
๊ทธ๋ƒฅ `str` ๋Œ€์‹  `Optional[str]`์„ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฐ’์ด ํ•ญ์ƒ `str`์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” `None`์ผ ์ˆ˜๋„ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ์—๋””ํ„ฐ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•˜๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.
`Optional[Something]`์€ ์‚ฌ์‹ค `Union[Something, None]`์˜ ์ถ•์•ฝ์ด๋ฉฐ, ์„œ๋กœ ๋™๋“ฑํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ์ด๋Š” Python 3.10์—์„œ `Something | None`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค:
//// tab | Python 3.10+
```Python hl_lines="1"
@ -268,96 +247,7 @@ Python 3.6 ์ด์ƒ(3.10 ํฌํ•จ)์—์„œ๋Š” `typing` ๋ชจ๋“ˆ์—์„œ `Optional`์„ impo
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009_py39.py!}
```
////
//// tab | Python 3.9+ alternative
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
```
////
#### `Union` ๋˜๋Š” `Optional` ์‚ฌ์šฉํ•˜๊ธฐ { #using-union-or-optional }
Python 3.10 ๋ฏธ๋งŒ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์•„์ฃผ **์ฃผ๊ด€์ ์ธ** ๊ด€์ ์—์„œ์˜ ํŒ์ž…๋‹ˆ๋‹ค:
* ๐Ÿšจ `Optional[SomeType]` ์‚ฌ์šฉ์„ ํ”ผํ•˜์„ธ์š”
* ๋Œ€์‹  โœจ **`Union[SomeType, None]`์„ ์‚ฌ์šฉํ•˜์„ธ์š”** โœจ.
๋‘˜์€ ๋™๋“ฑํ•˜๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๊ฐ™์€ ๊ฒƒ์ด์ง€๋งŒ, `Optional`์ด๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ๊ฐ’์ด ์„ ํƒ ์‚ฌํ•ญ์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `Optional` ๋Œ€์‹  `Union`์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์˜๋ฏธ๋Š” ๊ฐ’์ด ์„ ํƒ ์‚ฌํ•ญ์ด๋ผ๋Š” ๋œป์ด ์•„๋‹ˆ๋ผ, "๊ฐ’์ด `None`์ผ ์ˆ˜ ์žˆ๋‹ค"๋Š” ๋œป์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์„ ํƒ ์‚ฌํ•ญ์ด ์•„๋‹ˆ๊ณ  ์—ฌ์ „ํžˆ ํ•„์ˆ˜์ธ ๊ฒฝ์šฐ์—๋„์š”.
`Union[SomeType, None]`์ด ์˜๋ฏธ๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋“œ๋Ÿฌ๋‚ธ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์ด๊ฑด ๋‹จ์ง€ ๋‹จ์–ด์™€ ์ด๋ฆ„์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋Ÿฐ ๋‹จ์–ด๋“ค์ด ์—ฌ๋Ÿฌ๋ถ„๊ณผ ํŒ€์›์ด ์ฝ”๋“œ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ์‹์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋กœ, ์ด ํ•จ์ˆ˜๋ฅผ ๋ด…์‹œ๋‹ค:
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
๋งค๊ฐœ๋ณ€์ˆ˜ `name`์€ `Optional[str]`๋กœ ์ •์˜๋˜์–ด ์žˆ์ง€๋งŒ, **์„ ํƒ ์‚ฌํ•ญ์ด ์•„๋‹™๋‹ˆ๋‹ค**. ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค:
```Python
say_hi() # Oh, no, this throws an error! ๐Ÿ˜ฑ
```
๊ธฐ๋ณธ๊ฐ’์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— `name` ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” **์—ฌ์ „ํžˆ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค**(*optional*์ด ์•„๋‹˜). ๊ทธ๋Ÿผ์—๋„ `name`์€ ๊ฐ’์œผ๋กœ `None`์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค:
```Python
say_hi(name=None) # This works, None is valid ๐ŸŽ‰
```
์ข‹์€ ์†Œ์‹์€ Python 3.10์„ ์‚ฌ์šฉํ•˜๋ฉด, ํƒ€์ž…์˜ ์œ ๋‹ˆ์˜จ์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ„๋‹จํžˆ `|`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ด๋Ÿฐ ๊ฑฑ์ •์„ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
๊ทธ๋Ÿฌ๋ฉด `Optional`์ด๋‚˜ `Union` ๊ฐ™์€ ์ด๋ฆ„์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
#### Generic(์ œ๋„ค๋ฆญ) ํƒ€์ž… { #generic-types }
๋Œ€๊ด„ํ˜ธ ์•ˆ์— ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ์ด๋Ÿฌํ•œ ํƒ€์ž…๋“ค์€ **Generic types** ๋˜๋Š” **Generics**๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด:
//// tab | Python 3.10+
๋Œ€๊ด„ํ˜ธ์™€ ๋‚ด๋ถ€ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด, ๋™์ผํ•œ ๋‚ด์žฅ ํƒ€์ž…๋“ค์„ ์ œ๋„ค๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* `list`
* `tuple`
* `set`
* `dict`
๊ทธ๋ฆฌ๊ณ  ์ด์ „ ํŒŒ์ด์ฌ ๋ฒ„์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `typing` ๋ชจ๋“ˆ์˜ ๋‹ค์Œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* `Union`
* `Optional`
* ...๊ทธ ๋ฐ–์˜ ๊ฒƒ๋“ค.
Python 3.10์—์„œ๋Š” ์ œ๋„ค๋ฆญ `Union`๊ณผ `Optional`์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์•ˆ์œผ๋กœ, ํƒ€์ž… ์œ ๋‹ˆ์˜จ์„ ์„ ์–ธํ•˜๊ธฐ ์œ„ํ•ด <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>์„ธ๋กœ ๋ง‰๋Œ€(`|`)</abbr>๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ›จ์”ฌ ๋” ์ข‹๊ณ  ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค.
////
//// tab | Python 3.9+
๋Œ€๊ด„ํ˜ธ์™€ ๋‚ด๋ถ€ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด, ๋™์ผํ•œ ๋‚ด์žฅ ํƒ€์ž…๋“ค์„ ์ œ๋„ค๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* `list`
* `tuple`
* `set`
* `dict`
๊ทธ๋ฆฌ๊ณ  `typing` ๋ชจ๋“ˆ์˜ ์ œ๋„ค๋ฆญ๋“ค:
* `Union`
* `Optional`
* ...๊ทธ ๋ฐ–์˜ ๊ฒƒ๋“ค.
////
๊ทธ๋ƒฅ `str` ๋Œ€์‹  `str | None`์„ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฐ’์ด ํ•ญ์ƒ `str`์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” `None`์ผ ์ˆ˜๋„ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ์—๋””ํ„ฐ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•˜๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.
### ํƒ€์ž…์œผ๋กœ์„œ์˜ ํด๋ž˜์Šค { #classes-as-types }
@ -365,11 +255,11 @@ Python 3.10์—์„œ๋Š” ์ œ๋„ค๋ฆญ `Union`๊ณผ `Optional`์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์•ˆ์œผ
์ด๋ฆ„์„ ๊ฐ€์ง„ `Person` ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค:
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
๊ทธ๋Ÿฌ๋ฉด `Person` ํƒ€์ž…์˜ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ, ์—๋””ํ„ฐ์˜ ๋ชจ๋“  ์ง€์›์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -405,19 +295,13 @@ Pydantic ๊ณต์‹ ๋ฌธ์„œ์˜ ์˜ˆ์‹œ:
์ด ๋ชจ๋“  ๊ฒƒ์€ [์ž์Šต์„œ - ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ](tutorial/index.md){.internal-link target=_blank}์—์„œ ์‹ค์ œ๋กœ ๋งŽ์ด ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
/// tip | ํŒ
Pydantic์€ ๊ธฐ๋ณธ๊ฐ’ ์—†์ด `Optional` ๋˜๋Š” `Union[Something, None]`์„ ์‚ฌ์šฉํ•  ๋•Œ ํŠน๋ณ„ํ•œ ๋™์ž‘์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด์„œ๋Š” Pydantic ๋ฌธ์„œ์˜ <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a>์—์„œ ๋” ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///
## ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์• ๋„ˆํ…Œ์ด์…˜์ด ์žˆ๋Š” ํƒ€์ž… ํžŒํŠธ { #type-hints-with-metadata-annotations }
ํŒŒ์ด์ฌ์—๋Š” `Annotated`๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋Ÿฌํ•œ ํƒ€์ž… ํžŒํŠธ์— **์ถ”๊ฐ€ <abbr title="Data about the data, in this case, information about the type, e.g. a description.">๋ฉ”ํƒ€๋ฐ์ดํ„ฐ</abbr>**๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
ํŒŒ์ด์ฌ์—๋Š” `Annotated`๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋Ÿฌํ•œ ํƒ€์ž… ํžŒํŠธ์— **์ถ”๊ฐ€ <dfn title="๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ, ์—ฌ๊ธฐ์„œ๋Š” ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด(์˜ˆ: ์„ค๋ช…)">๋ฉ”ํƒ€๋ฐ์ดํ„ฐ</dfn>**๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
Python 3.9๋ถ€ํ„ฐ `Annotated`๋Š” ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ผ๋ถ€์ด๋ฏ€๋กœ, `typing`์—์„œ importํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`Annotated`๋Š” `typing`์—์„œ importํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
ํŒŒ์ด์ฌ ์ž์ฒด๋Š” ์ด `Annotated`๋กœ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์—๋””ํ„ฐ์™€ ๋‹ค๋ฅธ ๋„๊ตฌ๋“ค์—๊ฒŒ๋Š” ํƒ€์ž…์ด ์—ฌ์ „ํžˆ `str`์ž…๋‹ˆ๋‹ค.

2
docs/ko/docs/resources/index.md

@ -1,3 +1,3 @@
# ๋ฆฌ์†Œ์Šค { #resources }
์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค, ์™ธ๋ถ€ ๋งํฌ ๋“ฑ. โœˆ๏ธ
์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค, ์™ธ๋ถ€ ๋งํฌ, ๊ทธ๋ฆฌ๊ณ  ๋” ๋งŽ์€ ์ž๋ฃŒ. โœˆ๏ธ

11
docs/ko/docs/translation-banner.md

@ -0,0 +1,11 @@
/// details | ๐ŸŒ AI์™€ ์‚ฌ๋žŒ์ด ํ•จ๊ป˜ํ•œ ๋ฒˆ์—ญ
์ด ๋ฒˆ์—ญ์€ ์‚ฌ๋žŒ์˜ ์•ˆ๋‚ด๋ฅผ ๋ฐ›์•„ AI๊ฐ€ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿค
์›๋ฌธ์˜ ์˜๋ฏธ๋ฅผ ์˜คํ•ดํ•˜๊ฑฐ๋‚˜ ๋ถ€์ž์—ฐ์Šค๋Ÿฌ์›Œ ๋ณด์ด๋Š” ๋“ฑ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿค–
[AI LLM์„ ๋” ์ž˜ ์•ˆ๋‚ดํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์„ธ์š”](https://fastapi.tiangolo.com/ko/contributing/#translations).
[์˜๋ฌธ ๋ฒ„์ „](ENGLISH_VERSION_URL)
///

6
docs/ko/docs/tutorial/background-tasks.md

@ -15,7 +15,7 @@ FastAPI์—์„œ๋Š” ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•œ *ํ›„์—* ์‹คํ–‰ํ•  ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…
๋จผ์ € `BackgroundTasks`๋ฅผ ์ž„ํฌํŠธํ•˜๊ณ , `BackgroundTasks` ํƒ€์ž… ์„ ์–ธ์œผ๋กœ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
**FastAPI**๊ฐ€ `BackgroundTasks` ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
@ -31,13 +31,13 @@ FastAPI์—์„œ๋Š” ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•œ *ํ›„์—* ์‹คํ–‰ํ•  ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…
๊ทธ๋ฆฌ๊ณ  ์“ฐ๊ธฐ ์ž‘์—…์€ `async`์™€ `await`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ผ๋ฐ˜ `def`๋กœ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—… ์ถ”๊ฐ€ { #add-the-background-task }
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜* ๋‚ด๋ถ€์—์„œ `.add_task()` ๋ฉ”์„œ๋“œ๋กœ ์ž‘์—… ํ•จ์ˆ˜๋ฅผ *๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…* ๊ฐ์ฒด์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
`.add_task()`๋Š” ๋‹ค์Œ ์ธ์ž๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค:

52
docs/ko/docs/tutorial/bigger-applications.md

@ -58,17 +58,17 @@ from app.routers import items
```bash
.
โ”œโ”€โ”€ app # "app" is a Python package
โ”‚ย ย  โ”œโ”€โ”€ __init__.py # this file makes "app" a "Python package"
โ”‚ย ย  โ”œโ”€โ”€ main.py # "main" module, e.g. import app.main
โ”‚ย ย  โ”œโ”€โ”€ dependencies.py # "dependencies" module, e.g. import app.dependencies
โ”‚ย ย  โ””โ”€โ”€ routers # "routers" is a "Python subpackage"
โ”‚ย ย  โ”‚ โ”œโ”€โ”€ __init__.py # makes "routers" a "Python subpackage"
โ”‚ย ย  โ”‚ โ”œโ”€โ”€ items.py # "items" submodule, e.g. import app.routers.items
โ”‚ย ย  โ”‚ โ””โ”€โ”€ users.py # "users" submodule, e.g. import app.routers.users
โ”‚ย ย  โ””โ”€โ”€ internal # "internal" is a "Python subpackage"
โ”‚ย ย  โ”œโ”€โ”€ __init__.py # makes "internal" a "Python subpackage"
โ”‚ย ย  โ””โ”€โ”€ admin.py # "admin" submodule, e.g. import app.internal.admin
โ”œโ”€โ”€ app # 'app'์€ Python ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค
โ”‚ย ย  โ”œโ”€โ”€ __init__.py # ์ด ํŒŒ์ผ๋กœ 'app'์ด 'Python ํŒจํ‚ค์ง€'๊ฐ€ ๋ฉ๋‹ˆ๋‹ค
โ”‚ย ย  โ”œโ”€โ”€ main.py # 'main' ๋ชจ๋“ˆ, ์˜ˆ: import app.main
โ”‚ย ย  โ”œโ”€โ”€ dependencies.py # 'dependencies' ๋ชจ๋“ˆ, ์˜ˆ: import app.dependencies
โ”‚ย ย  โ””โ”€โ”€ routers # 'routers'๋Š” 'Python ํ•˜์œ„ ํŒจํ‚ค์ง€'์ž…๋‹ˆ๋‹ค
โ”‚ย ย  โ”‚ โ”œโ”€โ”€ __init__.py # ์ด ํŒŒ์ผ๋กœ 'routers'๊ฐ€ 'Python ํ•˜์œ„ ํŒจํ‚ค์ง€'๊ฐ€ ๋ฉ๋‹ˆ๋‹ค
โ”‚ย ย  โ”‚ โ”œโ”€โ”€ items.py # 'items' ์„œ๋ธŒ๋ชจ๋“ˆ, ์˜ˆ: import app.routers.items
โ”‚ย ย  โ”‚ โ””โ”€โ”€ users.py # 'users' ์„œ๋ธŒ๋ชจ๋“ˆ, ์˜ˆ: import app.routers.users
โ”‚ย ย  โ””โ”€โ”€ internal # 'internal'์€ 'Python ํ•˜์œ„ ํŒจํ‚ค์ง€'์ž…๋‹ˆ๋‹ค
โ”‚ย ย  โ”œโ”€โ”€ __init__.py # ์ด ํŒŒ์ผ๋กœ 'internal'์ด 'Python ํ•˜์œ„ ํŒจํ‚ค์ง€'๊ฐ€ ๋ฉ๋‹ˆ๋‹ค
โ”‚ย ย  โ””โ”€โ”€ admin.py # 'admin' ์„œ๋ธŒ๋ชจ๋“ˆ, ์˜ˆ: import app.internal.admin
```
## `APIRouter` { #apirouter }
@ -85,7 +85,7 @@ from app.routers import items
`FastAPI` ํด๋ž˜์Šค์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ importํ•˜๊ณ  "instance"๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### `APIRouter`๋กœ *path operations* ๋งŒ๋“ค๊ธฐ { #path-operations-with-apirouter }
@ -93,7 +93,7 @@ from app.routers import items
`FastAPI` ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
`APIRouter`๋Š” "๋ฏธ๋‹ˆ `FastAPI`" ํด๋ž˜์Šค๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -117,7 +117,7 @@ from app.routers import items
์ด์ œ ๊ฐ„๋‹จํ•œ dependency๋ฅผ ์‚ฌ์šฉํ•ด ์ปค์Šคํ…€ `X-Token` ํ—ค๋”๋ฅผ ์ฝ์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | ํŒ
@ -149,7 +149,7 @@ from app.routers import items
๋”ฐ๋ผ์„œ ๊ฐ *path operation*๋งˆ๋‹ค ๋งค๋ฒˆ ๋ชจ๋‘ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹ , `APIRouter`์— ํ•œ ๋ฒˆ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
๊ฐ *path operation*์˜ ๊ฒฝ๋กœ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ `/`๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋ฏ€๋กœ:
@ -208,7 +208,7 @@ async def read_item(item_id: str):
๊ทธ๋ž˜์„œ dependencies์— ๋Œ€ํ•ด `..`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ƒ๋Œ€ import๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
#### ์ƒ๋Œ€ import๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹ { #how-relative-imports-work }
@ -279,7 +279,7 @@ from ...dependencies import get_token_header
ํ•˜์ง€๋งŒ ํŠน์ • *path operation*์—๋งŒ ์ ์šฉ๋  _์ถ”๊ฐ€_ `tags`๋ฅผ ๋”ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๊ทธ *path operation* ์ „์šฉ์˜ ์ถ”๊ฐ€ `responses`๋„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | ํŒ
@ -305,13 +305,13 @@ from ...dependencies import get_token_header
๋˜ํ•œ ๊ฐ `APIRouter`์˜ dependencies์™€ ๊ฒฐํ•ฉ๋  [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank}๋„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
### `APIRouter` importํ•˜๊ธฐ { #import-the-apirouter }
์ด์ œ `APIRouter`๊ฐ€ ์žˆ๋Š” ๋‹ค๋ฅธ submodule๋“ค์„ importํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
`app/routers/users.py`์™€ `app/routers/items.py` ํŒŒ์ผ์€ ๊ฐ™์€ Python package `app`์— ์†ํ•œ submodule๋“ค์ด๋ฏ€๋กœ, ์  ํ•˜๋‚˜ `.`๋ฅผ ์‚ฌ์šฉํ•ด "์ƒ๋Œ€ import"๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -374,13 +374,13 @@ from .routers.users import router
๋”ฐ๋ผ์„œ ๊ฐ™์€ ํŒŒ์ผ์—์„œ ๋‘˜ ๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก submodule๋“ค์„ ์ง์ ‘ importํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
### `users`์™€ `items`์šฉ `APIRouter` ํฌํ•จํ•˜๊ธฐ { #include-the-apirouters-for-users-and-items }
์ด์ œ submodule `users`์™€ `items`์˜ `router`๋ฅผ ํฌํ•จํ•ด ๋ด…์‹œ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
/// info | ์ •๋ณด
@ -394,7 +394,7 @@ from .routers.users import router
๊ทธ router์˜ ๋ชจ๋“  route๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ผ๋ถ€๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
/// note Technical Details | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
๋‚ด๋ถ€์ ์œผ๋กœ๋Š” `APIRouter`์— ์„ ์–ธ๋œ ๊ฐ *path operation*๋งˆ๋‹ค *path operation*์„ ์‹ค์ œ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
@ -420,13 +420,13 @@ router๋ฅผ ํฌํ•จ(include)ํ•  ๋•Œ ์„ฑ๋Šฅ์„ ๊ฑฑ์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.
์ด ์˜ˆ์‹œ์—์„œ๋Š” ๋งค์šฐ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์กฐ์ง ๋‚ด ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์™€ ๊ณต์œ ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์–ด `prefix`, `dependencies`, `tags` ๋“ฑ์„ `APIRouter`์— ์ง์ ‘ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
ํ•˜์ง€๋งŒ `APIRouter`๋ฅผ ํฌํ•จํ•  ๋•Œ ์ปค์Šคํ…€ `prefix`๋ฅผ ์ง€์ •ํ•ด ๋ชจ๋“  *path operations*๊ฐ€ `/admin`์œผ๋กœ ์‹œ์ž‘ํ•˜๊ฒŒ ํ•˜๊ณ , ์ด ํ”„๋กœ์ ํŠธ์—์„œ ์ด๋ฏธ ๊ฐ€์ง„ `dependencies`๋กœ ๋ณดํ˜ธํ•˜๊ณ , `tags`์™€ `responses`๋„ ํฌํ•จํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
์›๋ž˜ `APIRouter`๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ ๋„ `app.include_router()`์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์„œ ์ด๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์›๋ž˜ `APIRouter`๋Š” ์ˆ˜์ •๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์กฐ์ง ๋‚ด ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ๋™์ผํ•œ `app/internal/admin.py` ํŒŒ์ผ์„ ๊ณ„์† ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -447,11 +447,11 @@ router๋ฅผ ํฌํ•จ(include)ํ•  ๋•Œ ์„ฑ๋Šฅ์„ ๊ฑฑ์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด... ๊ทธ๋ƒฅ ํ•ด๋ด…๋‹ˆ๋‹ค ๐Ÿคท:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
๊ทธ๋ฆฌ๊ณ  `app.include_router()`๋กœ ์ถ”๊ฐ€ํ•œ ๋‹ค๋ฅธ ๋ชจ๋“  *path operations*์™€ ํ•จ๊ป˜ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
/// info | ๋งค์šฐ ๊ธฐ์ˆ ์ ์ธ ์„ธ๋ถ€์‚ฌํ•ญ
**์ฐธ๊ณ **: ์ด๋Š” ๋งค์šฐ ๊ธฐ์ˆ ์ ์ธ ์„ธ๋ถ€์‚ฌํ•ญ์ด๋ผ ์•„๋งˆ **๊ทธ๋ƒฅ ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค**.

4
docs/ko/docs/tutorial/body-fields.md

@ -48,8 +48,8 @@
/// warning | ๊ฒฝ๊ณ 
๋ณ„๋„ ํ‚ค๊ฐ€ ์ „๋‹ฌ๋œ `Field` ๋˜ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ OpenAPI ์Šคํ‚ค๋งˆ์— ๋‚˜ํƒ€๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๋Ÿฐ ํ‚ค๊ฐ€ OpenAPI ๋ช…์„ธ์„œ, [the OpenAPI validator](https://validator.swagger.io/)๊ฐ™์€ ๋ช‡๋ช‡ OpenAPI ๋„๊ตฌ๋“ค์— ํฌํ•จ๋˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—ฌ๋Ÿฌ๋ถ„์ด ์ƒ์„ฑํ•œ ์Šคํ‚ค๋งˆ์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ณ„๋„ ํ‚ค๊ฐ€ ์ „๋‹ฌ๋œ `Field` ๋˜ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ OpenAPI ์Šคํ‚ค๋งˆ์— ๋‚˜ํƒ€๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๋Ÿฐ ํ‚ค๊ฐ€ OpenAPI ๋ช…์„ธ์„œ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹ ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ, [OpenAPI validator](https://validator.swagger.io/) ๊ฐ™์€ ๋ช‡๋ช‡ OpenAPI ๋„๊ตฌ๋“ค์€ ์—ฌ๋Ÿฌ๋ถ„์ด ์ƒ์„ฑํ•œ ์Šคํ‚ค๋งˆ์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///

7
docs/ko/docs/tutorial/body-multiple-params.md

@ -106,13 +106,6 @@
q: str | None = None
```
๋˜๋Š” Python 3.9์—์„œ๋Š”:
```Python
q: Union[str, None] = None
```
์˜ˆ๋ฅผ ๋“ค์–ด:
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}

4
docs/ko/docs/tutorial/body-nested-models.md

@ -164,7 +164,7 @@ images: list[Image]
์ด๋ฅผ ์•„๋ž˜์ฒ˜๋Ÿผ:
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
## ์–ด๋””์„œ๋‚˜ ํŽธ์ง‘๊ธฐ ์ง€์› { #editor-support-everywhere }
@ -194,7 +194,7 @@ Pydantic ๋ชจ๋ธ ๋Œ€์‹  `dict`๋กœ ์ง์ ‘ ์ž‘์—…ํ•œ๋‹ค๋ฉด ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ํŽธ์ง‘
์ด ๊ฒฝ์šฐ, `int` ํ‚ค์™€ `float` ๊ฐ’์„ ๊ฐ€์ง„ ํ•œ ์–ด๋–ค `dict`๋“  ๋ฐ›์•„๋“ค์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
/// tip | ํŒ

8
docs/ko/docs/tutorial/body.md

@ -74,7 +74,7 @@
* ๋งค๊ฐœ๋ณ€์ˆ˜ `item`์— ํฌํ•จ๋œ ์ˆ˜์‹  ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
* ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `Item` ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ชจ๋“  ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์™€ ๊ทธ์— ๋Œ€ํ•œ ํƒ€์ž…์— ๋Œ€ํ•œ ํŽธ์ง‘๊ธฐ ์ง€์›(์™„์„ฑ ๋“ฑ)์„ ๋˜ํ•œ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ชจ๋ธ์„ ์œ„ํ•œ <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> ์ •์˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜๋‹ค๋ฉด ์—ฌ๋Ÿฌ๋ถ„์ด ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ณณ ์–ด๋””์—์„œ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* ์ด๋Ÿฌํ•œ ์Šคํ‚ค๋งˆ๋Š”, ์ƒ์„ฑ๋œ OpenAPI ์Šคํ‚ค๋งˆ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ด๋ฉฐ, ์ž๋™ ๋ฌธ์„œํ™” <abbr title="User Interfaces โ€“ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค">UIs</abbr>์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
* ์ด๋Ÿฌํ•œ ์Šคํ‚ค๋งˆ๋Š”, ์ƒ์„ฑ๋œ OpenAPI ์Šคํ‚ค๋งˆ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ด๋ฉฐ, ์ž๋™ ๋ฌธ์„œํ™” <abbr title="User Interfaces - ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค">UIs</abbr>์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
## ์ž๋™ ๋ฌธ์„œํ™” { #automatic-docs }
@ -141,7 +141,7 @@
**๋ณธ๋ฌธ**, **๊ฒฝ๋กœ** ๊ทธ๋ฆฌ๊ณ  **์ฟผ๋ฆฌ** ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชจ๋‘ ๋™์‹œ์— ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ๊ฐ๊ฐ์„ ์ธ์ง€ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์˜ณ๋ฐ”๋ฅธ ์œ„์น˜์— ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
**FastAPI**๋Š” ๊ฐ๊ฐ์„ ์ธ์ง€ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์— ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
@ -153,9 +153,9 @@
/// note | ์ฐธ๊ณ 
FastAPI๋Š” `q`์˜ ๊ฐ’์ด ํ•„์š”์—†์Œ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๊ฐ’์ด `= None`์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
FastAPI๋Š” `q`์˜ ๊ฐ’์ด ํ•„์š”์—†์Œ์„ ๊ธฐ๋ณธ ๊ฐ’ `= None` ๋•Œ๋ฌธ์— ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Python 3.10+์˜ `str | None` ๋˜๋Š” Python 3.9+์˜ `Union[str, None]`์— ์žˆ๋Š” `Union`์€ FastAPI๊ฐ€ `q` ๊ฐ’์ด ํ•„์ˆ˜๊ฐ€ ์•„๋‹˜์„ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๊ฐ’์ด `= None`์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•„์ˆ˜๊ฐ€ ์•„๋‹˜์„ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
`str | None`์€ FastAPI๊ฐ€ ๊ฐ’์ด ํ•„์ˆ˜์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๊ฐ’์ด `= None`์ด๋ฏ€๋กœ ํ•„์ˆ˜๊ฐ€ ์•„๋‹˜์„ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด ํŽธ์ง‘๊ธฐ๊ฐ€ ๋” ๋‚˜์€ ์ง€์›์„ ์ œ๊ณตํ•˜๊ณ  ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

8
docs/ko/docs/tutorial/cookie-param-models.md

@ -46,7 +46,7 @@
์ผ๋ถ€ ํŠน๋ณ„ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€(ํ”ํ•˜์ง€๋Š” ์•Š๊ฒ ์ง€๋งŒ)์—์„œ๋Š” ์ˆ˜์‹ ํ•˜๋ ค๋Š” ์ฟ ํ‚ค๋ฅผ **์ œํ•œ**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ API๋Š” ์ž์‹ ์˜ <abbr title="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. ๐Ÿช">cookie consent</abbr>๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๊ฐ–๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿคช๐Ÿช
์ด์ œ API๋Š” ์ž์‹ ์˜ <dfn title="ํ˜น์‹œ๋ผ๋„ ์˜คํ•ดํ• ๊นŒ ๋ด ํ•˜๋Š” ๋†๋‹ด์ž…๋‹ˆ๋‹ค. ์ฟ ํ‚ค ๋™์˜์™€๋Š” ์•„๋ฌด ๊ด€๋ จ์ด ์—†์ง€๋งŒ, ์ด์ œ API๋„ ๋ถˆ์Œํ•œ ์ฟ ํ‚ค๋ฅผ ๊ฑฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ์›ƒ๊ธฐ๋„ค์š”. ์ฟ ํ‚ค ํ•˜๋‚˜ ๋“œ์„ธ์š”. ๐Ÿช">์ฟ ํ‚ค ๋™์˜</dfn>๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๊ฐ–๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿคช๐Ÿช
Pydantic์˜ ๋ชจ๋ธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”๊ฐ€(`extra`) ํ•„๋“œ๋ฅผ ๊ธˆ์ง€(`forbid`)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -54,9 +54,9 @@ Pydantic์˜ ๋ชจ๋ธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”๊ฐ€(`extra`) ํ•„๋“œ๋ฅผ ๊ธˆ์ง€(`forb
ํด๋ผ์ด์–ธํŠธ๊ฐ€ **์ถ”๊ฐ€ ์ฟ ํ‚ค**๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ์‹œ๋„ํ•˜๋ฉด, **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋™์˜๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์• ์“ฐ๋Š” ๋ถˆ์Œํ•œ ์ฟ ํ‚ค ๋ฐฐ๋„ˆ(ํŒ์—…)๋“ค, <abbr title="This is another joke. Don't pay attention to me. Have some coffee for your cookie. โ˜•">API๊ฐ€ ๊ฑฐ๋ถ€</abbr>ํ•˜๋Š”๋ฐ๋„. ๐Ÿช
๋™์˜๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์• ์“ฐ๋Š” ๋ถˆ์Œํ•œ ์ฟ ํ‚ค ๋ฐฐ๋„ˆ(ํŒ์—…)๋“ค, <dfn title="์ด๊ฒƒ๋„ ๋†๋‹ด์ž…๋‹ˆ๋‹ค. ์‹ ๊ฒฝ ์“ฐ์ง€ ๋งˆ์„ธ์š”. ์ฟ ํ‚ค์™€ ํ•จ๊ป˜ ์ปคํ”ผ ํ•œ ์ž” ํ•˜์„ธ์š”. โ˜•">API๊ฐ€ ๊ฑฐ๋ถ€</dfn>ํ•˜๋Š”๋ฐ๋„. ๐Ÿช
์˜ˆ๋ฅผ ๋“ค์–ด, ํด๋ผ์ด์–ธํŠธ๊ฐ€ `good-list-please` ๊ฐ’์œผ๋กœ `santa_tracker` ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” `santa_tracker` <abbr title="Santa disapproves the lack of cookies. ๐ŸŽ… Okay, no more cookie jokes.">์ฟ ํ‚ค๊ฐ€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค</abbr>๋Š” **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค:
์˜ˆ๋ฅผ ๋“ค์–ด, ํด๋ผ์ด์–ธํŠธ๊ฐ€ `good-list-please` ๊ฐ’์œผ๋กœ `santa_tracker` ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” `santa_tracker` <dfn title="์‚ฐํƒ€๋Š” ์ฟ ํ‚ค๊ฐ€ ๋ถ€์กฑํ•œ ๊ฒƒ์„ ๋ชป๋งˆ๋•…ํ•ดํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽ… ์ข‹์•„์š”, ์ด์ œ ๋” ์ด์ƒ ์ฟ ํ‚ค ๋†๋‹ด์€ ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.">์ฟ ํ‚ค๊ฐ€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค</dfn>๋Š” **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค:
```json
{
@ -73,4 +73,4 @@ Pydantic์˜ ๋ชจ๋ธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”๊ฐ€(`extra`) ํ•„๋“œ๋ฅผ ๊ธˆ์ง€(`forb
## ์š”์•ฝ { #summary }
**Pydantic ๋ชจ๋ธ**์„ ์‚ฌ์šฉํ•˜์—ฌ **FastAPI**์—์„œ <abbr title="Have a last cookie before you go. ๐Ÿช">**์ฟ ํ‚ค**</abbr>๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
**Pydantic ๋ชจ๋ธ**์„ ์‚ฌ์šฉํ•˜์—ฌ **FastAPI**์—์„œ <dfn title="๊ฐ€์‹œ๊ธฐ ์ „์— ๋งˆ์ง€๋ง‰ ์ฟ ํ‚ค ํ•˜๋‚˜ ๋“œ์„ธ์š”. ๐Ÿช">**์ฟ ํ‚ค**</dfn>๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž

4
docs/ko/docs/tutorial/cookie-params.md

@ -24,13 +24,13 @@
///
/// info | ์ •๋ณด
/// info
์ฟ ํ‚ค๋ฅผ ์„ ์–ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” `Cookie`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ•ด์„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
///
/// info | ์ •๋ณด
/// info
**๋ธŒ๋ผ์šฐ์ €๋Š” ์ฟ ํ‚ค๋ฅผ** ๋‚ด๋ถ€์ ์œผ๋กœ ํŠน๋ณ„ํ•œ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, **JavaScript**๊ฐ€ ์‰ฝ๊ฒŒ ์ฟ ํ‚ค๋ฅผ ๋‹ค๋ฃจ๋„๋ก ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์—ผ๋‘์— ๋‘์„ธ์š”.

4
docs/ko/docs/tutorial/cors.md

@ -46,7 +46,7 @@
* ํŠน์ • HTTP ๋ฉ”์„œ๋“œ(`POST`, `PUT`) ๋˜๋Š” ์™€์ผ๋“œ์นด๋“œ `"*"`๋ฅผ ์‚ฌ์šฉํ•œ ๋ชจ๋“  ๋ฉ”์„œ๋“œ.
* ํŠน์ • HTTP ํ—ค๋” ๋˜๋Š” ์™€์ผ๋“œ์นด๋“œ `"*"`๋ฅผ ์‚ฌ์šฉํ•œ ๋ชจ๋“  ํ—ค๋”.
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
`CORSMiddleware` ๊ตฌํ˜„์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ณธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œํ•œ์ ์ด๋ฏ€๋กœ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ Cross-Domain ์ปจํ…์ŠคํŠธ์—์„œ ํŠน์ • ์ถœ์ฒ˜, ๋ฉ”์„œ๋“œ ๋˜๋Š” ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๋ฉด ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@ -78,7 +78,7 @@
## ๋” ๋งŽ์€ ์ •๋ณด { #more-info }
<abbr title="Cross-Origin Resource Sharing โ€“ ๊ต์ฐจ-์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ">CORS</abbr>์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋Š” <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS ๋ฌธ์„œ</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
<abbr title="Cross-Origin Resource Sharing - ๊ต์ฐจ-์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ">CORS</abbr>์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋Š” <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS ๋ฌธ์„œ</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ

2
docs/ko/docs/tutorial/debugging.md

@ -6,7 +6,7 @@
FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ `uvicorn`์„ ์ง์ ‘ ์ž„ํฌํŠธํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
### `__name__ == "__main__"` ์— ๋Œ€ํ•˜์—ฌ { #about-name-main }

24
docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md

@ -101,7 +101,7 @@ FastAPI๊ฐ€ ์‹ค์ œ๋กœ ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๊ฒƒ์ด "ํ˜ธ์ถœ ๊ฐ€๋Šฅ(callable)"(ํ•จ
์œ„ ์ฝ”๋“œ์—์„œ `CommonQueryParams`๋ฅผ ๋‘ ๋ฒˆ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์— ์ฃผ๋ชฉํ•˜์„ธ์š”:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated ๋ฏธ์‚ฌ์šฉ
/// tip | ํŒ
@ -137,7 +137,7 @@ FastAPI๋Š” ์—ฌ๊ธฐ์—์„œ ์„ ์–ธ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ ์ถ”์ถœํ•˜๊ณ , ์‹ค์ œ๋กœ ์ด
์ด ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ `CommonQueryParams`๋Š” ๋‹ค์Œ์—์„œ:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, ...
@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated ๋ฏธ์‚ฌ์šฉ
/// tip | ํŒ
@ -163,7 +163,7 @@ commons: CommonQueryParams ...
์‹ค์ œ๋กœ๋Š” ์ด๋ ‡๊ฒŒ๋งŒ ์ž‘์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated ๋ฏธ์‚ฌ์šฉ
/// tip | ํŒ
@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams)
ํ•˜์ง€๋งŒ `CommonQueryParams`๋ฅผ ๋‘ ๋ฒˆ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ ๋ฐ˜๋ณต์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated ๋ฏธ์‚ฌ์šฉ
/// tip | ํŒ
@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
๋‹ค์Œ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹ :
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated ๋ฏธ์‚ฌ์šฉ
/// tip | ํŒ
@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
...์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends()]
@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ Annotated ๋ฏธ์‚ฌ์šฉ
/// tip | ํŒ

30
docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md

@ -1,28 +1,28 @@
# ๊ฒฝ๋กœ ์ž‘๋™ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ์˜ ์˜์กด์„ฑ { #dependencies-in-path-operation-decorators }
# ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ์˜ ์˜์กด์„ฑ { #dependencies-in-path-operation-decorators }
๋ช‡๋ช‡ ๊ฒฝ์šฐ์—๋Š”, *๊ฒฝ๋กœ ์ž‘๋™ ํ•จ์ˆ˜* ์•ˆ์—์„œ ์˜์กด์„ฑ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋ช‡๋ช‡ ๊ฒฝ์šฐ์—๋Š”, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜* ์•ˆ์—์„œ ์˜์กด์„ฑ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋˜๋Š” ์˜์กด์„ฑ์ด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ ์‹คํ–‰/ํ•ด๊ฒฐ๋  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—, `Depends`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ *๊ฒฝ๋กœ ์ž‘๋™ ํ•จ์ˆ˜*์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค *๊ฒฝ๋กœ ์ž‘๋™ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies`์˜ `list`๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—, `Depends`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜๋Š” ๋Œ€์‹  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies`์˜ `list`๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## *๊ฒฝ๋กœ ์ž‘๋™ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies` ์ถ”๊ฐ€ํ•˜๊ธฐ { #add-dependencies-to-the-path-operation-decorator }
## *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies` ์ถ”๊ฐ€ํ•˜๊ธฐ { #add-dependencies-to-the-path-operation-decorator }
*๊ฒฝ๋กœ ์ž‘๋™ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*๋Š” `dependencies`๋ผ๋Š” ์„ ํƒ์ ์ธ ์ธ์ž๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*๋Š” ์„ ํƒ์ ์ธ ์ธ์ž `dependencies`๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
`Depends()`๋กœ ๋œ `list`์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค:
`Depends()`๋กœ ๋œ `list`์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
์ด๋Ÿฌํ•œ ์˜์กด์„ฑ๋“ค์€ ๊ธฐ์กด ์˜์กด์„ฑ๋“ค๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‹คํ–‰/ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ’์€ (๋ฌด์—‡์ด๋“  ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด) *๊ฒฝ๋กœ ์ž‘๋™ ํ•จ์ˆ˜*์— ์ œ๊ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ์˜์กด์„ฑ๋“ค์€ ๊ธฐ์กด ์˜์กด์„ฑ๋“ค๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‹คํ–‰/ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ’์€ (๋ฌด์—‡์ด๋“  ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด) *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์— ์ œ๊ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
/// tip | ํŒ
์ผ๋ถ€ ํŽธ์ง‘๊ธฐ์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ  ์˜ค๋ฅ˜๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ž‘๋™ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ ์ด๋Ÿฌํ•œ `dependencies`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ์ง‘๊ธฐ/๋„๊ตฌ ์˜ค๋ฅ˜๋ฅผ ํ”ผํ•˜๋ฉด์„œ๋„ ์‹คํ–‰๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ ์ด๋Ÿฌํ•œ `dependencies`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ์ง‘๊ธฐ/๋„๊ตฌ ์˜ค๋ฅ˜๋ฅผ ํ”ผํ•˜๋ฉด์„œ๋„ ์‹คํ–‰๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณด๊ณ  ๋ถˆํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž์˜ ํ˜ผ๋ž€์„ ๋ฐฉ์ง€ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -44,13 +44,13 @@
(ํ—ค๋”๊ฐ™์€) ์š”์ฒญ ์š”๊ตฌ์‚ฌํ•ญ์ด๋‚˜ ํ•˜์œ„-์˜์กด์„ฑ์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
### ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ { #raise-exceptions }
๋‹ค์Œ ์˜์กด์„ฑ์€ ๊ธฐ์กด ์˜์กด์„ฑ๊ณผ ๋™์ผํ•˜๊ฒŒ ์˜ˆ์™ธ๋ฅผ `raise`ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
### ๊ฐ’ ๋ฐ˜ํ™˜ํ•˜๊ธฐ { #return-values }
@ -58,12 +58,12 @@
๊ทธ๋ž˜์„œ ์ด๋ฏธ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉ๋œ (๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š”) ์ผ๋ฐ˜์ ์ธ ์˜์กด์„ฑ์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๋น„๋ก ๊ฐ’์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์ง€๋งŒ ์˜์กด์„ฑ์€ ์‹คํ–‰๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
## *๊ฒฝ๋กœ ์ž‘๋™* ๋ชจ์Œ์— ๋Œ€ํ•œ ์˜์กด์„ฑ { #dependencies-for-a-group-of-path-operations }
## *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ชจ์Œ์— ๋Œ€ํ•œ ์˜์กด์„ฑ { #dependencies-for-a-group-of-path-operations }
๋‚˜์ค‘์— ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์กฐํ™”ํ•˜๋Š” ๋ฒ•([๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ์—ฌ๋Ÿฌ ํŒŒ์ผ๋“ค](../../tutorial/bigger-applications.md){.internal-link target=_blank})์„ ์ฝ์„ ๋•Œ, *๊ฒฝ๋กœ ์ž‘๋™* ๋ชจ์Œ์— ๋Œ€ํ•œ ๋‹จ์ผ `dependencies` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋ฐฐ์šฐ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‚˜์ค‘์— ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์กฐํ™”ํ•˜๋Š” ๋ฒ•([๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ์—ฌ๋Ÿฌ ํŒŒ์ผ๋“ค](../../tutorial/bigger-applications.md){.internal-link target=_blank})์„ ์ฝ์„ ๋•Œ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ชจ์Œ์— ๋Œ€ํ•œ ๋‹จ์ผ `dependencies` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋ฐฐ์šฐ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
## ์ „์—ญ ์˜์กด์„ฑ { #global-dependencies }
๋‹ค์Œ์œผ๋กœ ๊ฐ *๊ฒฝ๋กœ ์ž‘๋™*์— ์ ์šฉ๋˜๋„๋ก `FastAPI` ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฒ•์„ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‹ค์Œ์œผ๋กœ ๊ฐ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ์ ์šฉ๋˜๋„๋ก `FastAPI` ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฒ•์„ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

24
docs/ko/docs/tutorial/dependencies/dependencies-with-yield.md

@ -1,6 +1,6 @@
# `yield`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜์กด์„ฑ { #dependencies-with-yield }
FastAPI๋Š” <abbr title='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc. โ€“ ๋•Œ๋กœ๋Š” "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" ๋“ฑ์œผ๋กœ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค'>์ž‘์—… ์™„๋ฃŒ ํ›„ ์ถ”๊ฐ€ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š”</abbr> ์˜์กด์„ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
FastAPI๋Š” <dfn title='๋•Œ๋กœ๋Š” "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" ๋“ฑ์œผ๋กœ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค'>์ž‘์—… ์™„๋ฃŒ ํ›„ ์ถ”๊ฐ€ ๋‹จ๊ณ„</dfn>๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์˜์กด์„ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด `return` ๋Œ€์‹  `yield`๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ถ”๊ฐ€๋กœ ์‹คํ–‰ํ•  ๋‹จ๊ณ„ (์ฝ”๋“œ)๋ฅผ ๊ทธ ๋’ค์— ์ž‘์„ฑํ•˜์„ธ์š”.
@ -29,15 +29,15 @@ FastAPI๋Š” <abbr title='sometimes also called "exit code", "cleanup code", "tear
์‘๋‹ต์„ ์ƒ์„ฑํ•˜๊ธฐ ์ „์—๋Š” `yield`๋ฌธ์„ ํฌํ•จํ•˜์—ฌ ๊ทธ ์ด์ „์˜ ์ฝ”๋“œ๋งŒ์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
`yield`๋ฌธ ๋‹ค์Œ์˜ ์ฝ”๋“œ๋Š” ์‘๋‹ต์„ ์ƒ์„ฑํ•œ ํ›„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
/// tip | ํŒ
@ -57,7 +57,7 @@ yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, `finally`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„ ์—†์ด ์ข…๋ฃŒ ๋‹จ๊ณ„๊นŒ ์‹คํ–‰๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
## `yield`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•˜์œ„ ์˜์กด์„ฑ { #sub-dependencies-with-yield }
@ -67,7 +67,7 @@ yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…
์˜ˆ๋ฅผ ๋“ค์–ด, `dependency_c`๋Š” `dependency_b`์— ์˜์กดํ•  ์ˆ˜ ์žˆ๊ณ , `dependency_b`๋Š” `dependency_a`์— ์˜์กดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
์ด๋“ค ๋ชจ๋‘๋Š” `yield`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -75,7 +75,7 @@ yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…
๊ทธ๋ฆฌ๊ณ , `dependency_b`๋Š” ์ข…๋ฃŒ ์ฝ”๋“œ๋ฅผ ์œ„ํ•ด `dependency_a`์˜ ๊ฐ’ (์—ฌ๊ธฐ์„œ๋Š” `dep_a`๋กœ ๋ช…๋ช…) ์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ, `yield`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜์กด์„ฑ๊ณผ `return`์„ ์‚ฌ์šฉํ•˜๋Š” ์˜์กด์„ฑ์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋“ค ์ค‘ ์ผ๋ถ€๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์— ์˜์กดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -109,7 +109,7 @@ yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…
///
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
์˜ˆ์™ธ๋ฅผ ์žก๊ณ  ๊ทธ์— ๊ธฐ๋ฐ˜ํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด, [์‚ฌ์šฉ์ž ์ •์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.
@ -117,7 +117,7 @@ yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…
`yield`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜์กด์„ฑ์—์„œ `except`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์™ธ๋ฅผ ํฌ์ฐฉํ•˜๊ณ  ์˜ˆ์™ธ๋ฅผ ๋‹ค์‹œ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๊ฑฐ๋‚˜ (๋˜๋Š” ์ƒˆ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์œผ๋ฉด), FastAPI๋Š” ์ผ๋ฐ˜์ ์ธ Python์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์˜ˆ์™ธ๊ฐ€ ์žˆ์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„์ฐจ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
์ด ๊ฒฝ์šฐ, `HTTPException`์ด๋‚˜ ์œ ์‚ฌํ•œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๋Š” ๋งˆ๋•…ํžˆ *HTTP 500 Internal Server Error* ์‘๋‹ต์„ ๋ณด๊ฒŒ ๋˜์ง€๋งŒ, ์„œ๋ฒ„์—๋Š” ์–ด๋–ค ์˜ค๋ฅ˜์˜€๋Š”์ง€์— ๋Œ€ํ•œ **๋กœ๊ทธ**๋‚˜ ๋‹ค๋ฅธ ํ‘œ์‹œ๊ฐ€ **์ „ํ˜€ ๋‚จ์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค**. ๐Ÿ˜ฑ
@ -127,7 +127,7 @@ yield๋œ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๋ฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ๋“ค์— ์ฃผ์ž…๋˜๋Š” ๊ฐ’ ์ž…
`raise`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์˜ˆ์™ธ๋ฅผ ๋‹ค์‹œ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
์ด์ œ ํด๋ผ์ด์–ธํŠธ๋Š” ๋™์ผํ•œ *HTTP 500 Internal Server Error* ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋˜์ง€๋งŒ, ์„œ๋ฒ„ ๋กœ๊ทธ์—๋Š” ์‚ฌ์šฉ์ž ์ •์˜ `InternalError`๊ฐ€ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ๐Ÿ˜Ž
@ -190,7 +190,7 @@ participant tasks as Background tasks
ํ•˜์ง€๋งŒ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ๋ฐ˜ํ™˜ํ•œ ๋’ค์—๋Š” ๋” ์ด์ƒ ํ•ด๋‹น ์˜์กด์„ฑ์ด ํ•„์š” ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, `Depends(scope="function")`์„ ์‚ฌ์šฉํ•˜์—ฌ FastAPI์— *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*๊ฐ€ ๋ฐ˜ํ™˜๋œ ํ›„, ํ•˜์ง€๋งŒ **์‘๋‹ต์ด ์ „์†ก๋˜๊ธฐ ์ „์—** ์˜์กด์„ฑ์„ ์ข…๋ฃŒ(๋‹ซ๊ธฐ)ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
`Depends()`๋Š” ๋‹ค์Œ์ด ๋  ์ˆ˜ ์žˆ๋Š” `scope` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค:
@ -269,7 +269,7 @@ Python์—์„œ๋Š” ๋‹ค์Œ์„ ํ†ตํ•ด ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต
**FastAPI**์˜ `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ ๋‚ด์—์„œ
`with` ๋˜๋Š” `async with`๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋“ค์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
/// tip | ํŒ

5
docs/ko/docs/tutorial/dependencies/global-dependencies.md

@ -2,12 +2,11 @@
๋ช‡๋ช‡ ์œ ํ˜•์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies` ์ถ”๊ฐ€ํ•˜๊ธฐ](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}์™€ ์œ ์‚ฌํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ `FastAPI` ์• ํ”Œ๋ฆฌ์ผ€์ผ€์ด์…˜์— ๊ทธ๊ฒƒ๋“ค์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies` ์ถ”๊ฐ€ํ•˜๊ธฐ](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}์™€ ์œ ์‚ฌํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ `FastAPI` ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ทธ๊ฒƒ๋“ค์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ์ ์šฉ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
๊ทธ๋ฆฌ๊ณ  [*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `dependencies` ์ถ”๊ฐ€ํ•˜๊ธฐ](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} ์„น์…˜์˜ ๋ชจ๋“  ์•„์ด๋””์–ด๋Š” ์—ฌ์ „ํžˆ ์ ์šฉ๋˜์ง€๋งŒ, ์ด ๊ฒฝ์šฐ์—๋Š” ์•ฑ์˜ ๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

6
docs/ko/docs/tutorial/dependencies/index.md

@ -1,6 +1,6 @@
# ์˜์กด์„ฑ { #dependencies }
**FastAPI**๋Š” ์•„์ฃผ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ์ง๊ด€์ ์ธ **<abbr title="also known as components, resources, providers, services, injectables">์˜์กด์„ฑ ์ฃผ์ž…</abbr>** ์‹œ์Šคํ…œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ์•„์ฃผ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ์ง๊ด€์ ์ธ **<dfn title="์ปดํฌ๋„ŒํŠธ, ๋ฆฌ์†Œ์Šค, ์ œ๊ณต์ž, ์„œ๋น„์Šค, ์ธ์ ํ„ฐ๋ธ”๋กœ๋„ ์•Œ๋ ค์ ธ ์žˆ์Œ">์˜์กด์„ฑ ์ฃผ์ž…</dfn>** ์‹œ์Šคํ…œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์•„์ฃผ ์‰ฝ๊ฒŒ ์„ค๊ณ„ํ–ˆ์œผ๋ฉฐ, ์–ด๋А ๊ฐœ๋ฐœ์ž๋‚˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€ **FastAPI**๋ฅผ ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
@ -47,7 +47,7 @@
* ์„ ํƒ์ ์ธ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ `q`, `str`์„ ์ž๋ฃŒํ˜•์œผ๋กœ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
* ์„ ํƒ์ ์ธ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ `skip`, `int`๋ฅผ ์ž๋ฃŒํ˜•์œผ๋กœ ๊ฐ€์ง€๋ฉฐ ๊ธฐ๋ณธ ๊ฐ’์€ `0`์ž…๋‹ˆ๋‹ค.
* ์„ ํƒ์ ์ธ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ `limit` that is an `int`, and by default is `100`.
* ์„ ํƒ์ ์ธ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ `limit`, `int`๋ฅผ ์ž๋ฃŒํ˜•์œผ๋กœ ๊ฐ€์ง€๋ฉฐ ๊ธฐ๋ณธ ๊ฐ’์€ `100`์ž…๋‹ˆ๋‹ค.
๊ทธ ํ›„ ์œ„์˜ ๊ฐ’์„ ํฌํ•จํ•œ `dict` ์ž๋ฃŒํ˜•์œผ๋กœ ๋ฐ˜ํ™˜ํ•  ๋ฟ์ž…๋‹ˆ๋‹ค.
@ -71,7 +71,7 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „๋ถ€ํ„ฐ `Annotated`์— ๋Œ€ํ•œ ์ง€์›์„ (๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
๋น„๋ก `Body`, `Query` ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์—ฌ๋Ÿฌ๋ถ„์˜ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์žˆ๋Š” `Depends`๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, `Depends`๋Š” ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
๋น„๋ก `Depends`๋ฅผ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ `Body`, `Query` ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ, `Depends`๋Š” ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
`Depends`์— ๋‹จ์ผ ๋งค๊ฐœ๋ณ€์ˆ˜๋งŒ ์ „๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

6
docs/ko/docs/tutorial/dependencies/sub-dependencies.md

@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
๊ฐ™์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ๋Œ€ํ•ด ์˜์กด์„ฑ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ์„ ์–ธ๋˜๋Š” ๊ฒฝ์šฐ(์˜ˆ: ์—ฌ๋Ÿฌ ์˜์กด์„ฑ์ด ๊ณตํ†ต ํ•˜์œ„ ์˜์กด์„ฑ์„ ๊ฐ–๋Š” ๊ฒฝ์šฐ), **FastAPI**๋Š” ๊ทธ ํ•˜์œ„ ์˜์กด์„ฑ์„ ์š”์ฒญ๋‹น ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๊ฐ™์€ ์š”์ฒญ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์˜์กด์„ฑ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ , ๋ฐ˜ํ™˜๊ฐ’์„ <abbr title="๊ณ„์‚ฐ/์ƒ์„ฑ๋œ ๊ฐ’์„ ์ €์žฅํ•ด ๋‘์—ˆ๋‹ค๊ฐ€, ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ/์‹œ์Šคํ…œ.">"cache"</abbr>์— ์ €์žฅํ•˜๊ณ , ๊ทธ ์š”์ฒญ์—์„œ ํ•ด๋‹น ๊ฐ’์ด ํ•„์š”ํ•œ ๋ชจ๋“  "dependants"์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๊ฐ™์€ ์š”์ฒญ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์˜์กด์„ฑ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ , ๋ฐ˜ํ™˜๊ฐ’์„ <dfn title="๊ณ„์‚ฐ/์ƒ์„ฑ๋œ ๊ฐ’์„ ์ €์žฅํ•ด ๋‘์—ˆ๋‹ค๊ฐ€, ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ/์‹œ์Šคํ…œ.">"์บ์‹œ"</dfn>์— ์ €์žฅํ•˜๊ณ , ๊ทธ ์š”์ฒญ์—์„œ ํ•ด๋‹น ๊ฐ’์ด ํ•„์š”ํ•œ ๋ชจ๋“  "dependants"์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
๊ณ ๊ธ‰ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ, ๊ฐ™์€ ์š”์ฒญ์—์„œ "cached" ๊ฐ’์„ ์“ฐ๋Š” ๋Œ€์‹  ๋งค ๋‹จ๊ณ„๋งˆ๋‹ค(์•„๋งˆ๋„ ์—ฌ๋Ÿฌ ๋ฒˆ) ์˜์กด์„ฑ์ด ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, `Depends`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ `use_cache=False` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
////
//// tab | Python 3.9+ ๋น„ Annotated
//// tab | Python 3.10+ ๋น„ Annotated
/// tip | ํŒ

2
docs/ko/docs/tutorial/encoder.md

@ -12,7 +12,7 @@ JSON ํ˜ธํ™˜ ๊ฐ€๋Šฅ ๋ฐ์ดํ„ฐ๋งŒ ์ˆ˜์‹ ํ•˜๋Š” `fake_db` ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์กด
์˜ˆ๋ฅผ ๋“ค๋ฉด, `datetime` ๊ฐ์ฒด๋Š” JSON๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ด๋ฅผ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ `datetime` ๊ฐ์ฒด๋Š” <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO format</a>์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” `str`๋กœ ๋ณ€ํ™˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ `datetime` ๊ฐ์ฒด๋Š” <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO ํ˜•์‹</a>์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” `str`๋กœ ๋ณ€ํ™˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” Pydantic ๋ชจ๋ธ(์†์„ฑ์ด ์žˆ๋Š” ๊ฐ์ฒด)์„ ๋ฐ›์ง€ ์•Š๊ณ , `dict`๋งŒ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

16
docs/ko/docs/tutorial/extra-models.md

@ -8,11 +8,11 @@
* **์ถœ๋ ฅ ๋ชจ๋ธ**์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง€๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
* **๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ**์€ ์•„๋งˆ๋„ ํ•ด์‹œ ์ฒ˜๋ฆฌ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์งˆ ํ•„์š”๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
/// danger | ์œ„ํ—˜
/// danger
์ ˆ๋Œ€ ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ‰๋ฌธ์œผ๋กœ ์ €์žฅํ•˜์ง€ ๋งˆ์„ธ์š”. ํ•ญ์ƒ ์ดํ›„์— ๊ฒ€์ฆ ๊ฐ€๋Šฅํ•œ "์•ˆ์ „ํ•œ ํ•ด์‹œ(secure hash)"๋กœ ์ €์žฅํ•˜์„ธ์š”.
๋งŒ์•ฝ ์ด๊ฒŒ ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด, [security chapters](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}์—์„œ "password hash"๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์ด๊ฒŒ ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด, [๋ณด์•ˆ ์žฅ](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}์—์„œ "password hash"๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///
@ -132,7 +132,7 @@ UserInDB(
)
```
/// warning | ๊ฒฝ๊ณ 
/// warning
์ถ”๊ฐ€์ ์œผ๋กœ ์ œ๊ณต๋œ ํ•จ์ˆ˜ `fake_password_hasher`์™€ `fake_save_user`๋Š” ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์‹œ์—ฐํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์ œ์ผ ๋ฟ์ด๋ฉฐ, ์‹ค์ œ ๋ณด์•ˆ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
@ -164,7 +164,7 @@ OpenAPI์—์„œ๋Š” ์ด๋ฅผ `anyOf`๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ํ‘œ์ค€ Python ํƒ€์ž… ํžŒํŠธ์ธ <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
/// note | ์ฐธ๊ณ 
/// note
<a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>์„ ์ •์˜ํ•  ๋•Œ๋Š” ๋” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์„ ๋จผ์ € ํฌํ•จํ•˜๊ณ , ๋œ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์„ ๊ทธ ๋’ค์— ๋‚˜์—ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์—์„œ๋Š” `Union[PlaneItem, CarItem]`์—์„œ ๋” ๊ตฌ์ฒด์ ์ธ `PlaneItem`์ด `CarItem`๋ณด๋‹ค ์•ž์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค.
@ -190,9 +190,9 @@ some_variable: PlaneItem | CarItem
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ฐ์ฒด ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ์˜ ์‘๋‹ต์„ ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ํ‘œ์ค€ Python์˜ `typing.List`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”(๋˜๋Š” Python 3.9 ์ด์ƒ์—์„œ๋Š” ๋‹จ์ˆœํžˆ `list`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค):
์ด๋ฅผ ์œ„ํ•ด ํ‘œ์ค€ Python์˜ `list`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”:
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
## ์ž„์˜์˜ `dict` ์‘๋‹ต { #response-with-arbitrary-dict }
@ -200,9 +200,9 @@ Pydantic ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ํ‚ค์™€ ๊ฐ’์˜ ํƒ€์ž…๋งŒ ์„ ์–ธํ•˜์—ฌ ํ‰
์ด๋Š” Pydantic ๋ชจ๋ธ์— ํ•„์š”ํ•œ ์œ ํšจํ•œ ํ•„๋“œ/์†์„ฑ ์ด๋ฆ„์„ ์‚ฌ์ „์— ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ, `typing.Dict`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋˜๋Š” Python 3.9 ์ด์ƒ์—์„œ๋Š” ๋‹จ์ˆœํžˆ `dict`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค):
์ด ๊ฒฝ์šฐ, `dict`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
## ์š”์•ฝ { #recap }

22
docs/ko/docs/tutorial/first-steps.md

@ -2,7 +2,7 @@
๊ฐ€์žฅ ๋‹จ์ˆœํ•œ FastAPI ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/first_steps/tutorial001_py39.py *}
{* ../../docs_src/first_steps/tutorial001_py310.py *}
์œ„ ์ฝ”๋“œ๋ฅผ `main.py`์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
@ -104,7 +104,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
#### OpenAPI์™€ JSON ์Šคํ‚ค๋งˆ { #openapi-and-json-schema }
OpenAPI๋Š” ๋‹น์‹ ์˜ API์— ๋Œ€ํ•œ API ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ์Šคํ‚ค๋งˆ๋Š” JSON ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ์˜ ํ‘œ์ค€์ธ **JSON ์Šคํ‚ค๋งˆ**๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹น์‹ ์˜ API๊ฐ€ ๋ณด๋‚ด๊ณ  ๋ฐ›๋Š” ๋ฐ์ดํ„ฐ์˜ ์ •์˜(๋˜๋Š” "์Šคํ‚ค๋งˆ")๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
OpenAPI๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ API์— ๋Œ€ํ•œ API ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ์Šคํ‚ค๋งˆ๋Š” JSON ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ์˜ ํ‘œ์ค€์ธ **JSON ์Šคํ‚ค๋งˆ**๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ๋ถ„์˜ API๊ฐ€ ๋ณด๋‚ด๊ณ  ๋ฐ›๋Š” ๋ฐ์ดํ„ฐ์˜ ์ •์˜(๋˜๋Š” "์Šคํ‚ค๋งˆ")๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
#### `openapi.json` ํ™•์ธ { #check-the-openapi-json }
@ -183,9 +183,9 @@ Deploying to FastAPI Cloud...
### 1 ๋‹จ๊ณ„: `FastAPI` ์ž„ํฌํŠธ { #step-1-import-fastapi }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
`FastAPI`๋Š” ๋‹น์‹ ์˜ API๋ฅผ ์œ„ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ด์ฌ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
`FastAPI`๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ API๋ฅผ ์œ„ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ด์ฌ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
@ -197,11 +197,11 @@ Deploying to FastAPI Cloud...
### 2 ๋‹จ๊ณ„: `FastAPI` "์ธ์Šคํ„ด์Šค" ์ƒ์„ฑ { #step-2-create-a-fastapi-instance }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
์—ฌ๊ธฐ์—์„œ `app` ๋ณ€์ˆ˜๋Š” `FastAPI` ํด๋ž˜์Šค์˜ "์ธ์Šคํ„ด์Šค"๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ๋‹น์‹ ์˜ ๋ชจ๋“  API๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒํ˜ธ์ž‘์šฉ์˜ ์ฃผ์š” ์ง€์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ชจ๋“  API๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒํ˜ธ์ž‘์šฉ์˜ ์ฃผ์š” ์ง€์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
### 3 ๋‹จ๊ณ„: *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์ƒ์„ฑ { #step-3-create-a-path-operation }
@ -266,12 +266,12 @@ API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ํŠน์ • ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ •
#### *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ* ์ •์˜ { #define-a-path-operation-decorator }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
`@app.get("/")`์€ **FastAPI**์—๊ฒŒ ๋ฐ”๋กœ ์•„๋ž˜์— ์žˆ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋‹ค์Œ์œผ๋กœ ์ด๋™ํ•˜๋Š” ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค:
* ๊ฒฝ๋กœ `/`
* <abbr title="an HTTP GET method"><code>get</code> operation</abbr> ์‚ฌ์šฉ
* <dfn title="HTTP GET ๋ฉ”์†Œ๋“œ"><code>get</code> ์ž‘๋™</dfn> ์‚ฌ์šฉ
/// info | `@decorator` ์ •๋ณด
@ -320,7 +320,7 @@ API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ํŠน์ • ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ •
* **์ž‘๋™**: ์€ `get`์ž…๋‹ˆ๋‹ค.
* **ํ•จ์ˆ˜**: ๋Š” "๋ฐ์ฝ”๋ ˆ์ดํ„ฐ" ์•„๋ž˜์— ์žˆ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค (`@app.get("/")` ์•„๋ž˜).
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
์ด๊ฒƒ์€ ํŒŒ์ด์ฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
@ -332,7 +332,7 @@ URL "`/`"์— ๋Œ€ํ•œ `GET` ์ž‘๋™์„ ์‚ฌ์šฉํ•˜๋Š” ์š”์ฒญ์„ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค **Fa
`async def`์„ ์ด์šฉํ•˜๋Š” ๋Œ€์‹  ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
/// note | ์ฐธ๊ณ 
@ -342,7 +342,7 @@ URL "`/`"์— ๋Œ€ํ•œ `GET` ์ž‘๋™์„ ์‚ฌ์šฉํ•˜๋Š” ์š”์ฒญ์„ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค **Fa
### 5 ๋‹จ๊ณ„: ์ฝ˜ํ…์ธ  ๋ฐ˜ํ™˜ { #step-5-return-the-content }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
`dict`, `list`, ๋‹จ์ผ๊ฐ’์„ ๊ฐ€์ง„ `str`, `int` ๋“ฑ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

16
docs/ko/docs/tutorial/handling-errors.md

@ -25,7 +25,7 @@ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ์— ์˜ค๋ฅ˜๋ฅผ ์•Œ๋ ค์•ผ ํ•˜๋Š” ์ƒํ™ฉ์€ ๋งŽ
### `HTTPException` ๊ฐ€์ ธ์˜ค๊ธฐ { #import-httpexception }
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
### ์ฝ”๋“œ์—์„œ `HTTPException` ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ { #raise-an-httpexception-in-your-code }
@ -39,7 +39,7 @@ Python ์˜ˆ์™ธ์ด๋ฏ€๋กœ `return` ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ `raise` ํ•ฉ๋‹ˆ๋‹ค.
์ด ์˜ˆ์‹œ์—์„œ๋Š”, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ID๋กœ ํ•ญ๋ชฉ์„ ์š”์ฒญํ•˜๋ฉด ์ƒํƒœ ์ฝ”๋“œ `404`๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค:
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
### ๊ฒฐ๊ณผ ์‘๋‹ต { #the-resulting-response }
@ -77,7 +77,7 @@ HTTP ์˜ค๋ฅ˜์— ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์œ ์šฉํ•œ ์ƒํ™ฉ์ด
ํ•˜์ง€๋งŒ ๊ณ ๊ธ‰ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ํ•„์š”ํ•˜๋‹ค๋ฉด ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
## ์ปค์Šคํ…€ ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ ์„ค์น˜ํ•˜๊ธฐ { #install-custom-exception-handlers }
@ -89,7 +89,7 @@ HTTP ์˜ค๋ฅ˜์— ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์œ ์šฉํ•œ ์ƒํ™ฉ์ด
`@app.exception_handler()`๋กœ ์ปค์Šคํ…€ ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
์—ฌ๊ธฐ์„œ `/unicorns/yolo`๋ฅผ ์š”์ฒญํ•˜๋ฉด, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ `UnicornException`์„ `raise`ํ•ฉ๋‹ˆ๋‹ค.
@ -127,7 +127,7 @@ HTTP ์˜ค๋ฅ˜์— ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์œ ์šฉํ•œ ์ƒํ™ฉ์ด
์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ๋Š” `Request`์™€ ์˜ˆ์™ธ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
์ด์ œ `/items/foo`๋กœ ์ด๋™ํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ JSON ์˜ค๋ฅ˜ ๋Œ€์‹ :
@ -159,7 +159,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
์˜ˆ๋ฅผ ๋“ค์–ด, ์ด๋Ÿฐ ์˜ค๋ฅ˜๋“ค์— ๋Œ€ํ•ด JSON ๋Œ€์‹  ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
@ -183,7 +183,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
์•ฑ์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋™์•ˆ body๋ฅผ ๋กœ๊ทธ๋กœ ๋‚จ๊ธฐ๊ณ  ๋””๋ฒ„๊ทธํ•˜๊ฑฐ๋‚˜, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋“ฑ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
์ด์ œ ๋‹ค์Œ์ฒ˜๋Ÿผ ์œ ํšจํ•˜์ง€ ์•Š์€ item์„ ๋ณด๋‚ด๋ณด์„ธ์š”:
@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ **FastAPI**์˜ ๋™์ผํ•œ ๊ธฐ๋ณธ ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ๋„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, `fastapi.exception_handlers`์—์„œ ๊ธฐ๋ณธ ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ฐ€์ ธ์™€ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
์ด ์˜ˆ์‹œ์—์„œ๋Š” ๋งค์šฐ ํ‘œํ˜„๋ ฅ ์žˆ๋Š” ๋ฉ”์‹œ์ง€๋กœ ์˜ค๋ฅ˜๋ฅผ ์ถœ๋ ฅ๋งŒ ํ•˜๊ณ  ์žˆ์ง€๋งŒ, ์š”์ง€๋Š” ์ดํ•ดํ•˜์…จ์„ ๊ฒ๋‹ˆ๋‹ค. ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•œ ๋’ค ๊ธฐ๋ณธ ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ทธ๋Œ€๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4
docs/ko/docs/tutorial/header-param-models.md

@ -2,7 +2,7 @@
๊ด€๋ จ ์žˆ๋Š” **ํ—ค๋” ๋งค๊ฐœ๋ณ€์ˆ˜** ๊ทธ๋ฃน์ด ์žˆ๋Š” ๊ฒฝ์šฐ, **Pydantic ๋ชจ๋ธ**์„ ์ƒ์„ฑํ•˜์—ฌ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด **์—ฌ๋Ÿฌ ์œ„์น˜**์—์„œ **๋ชจ๋ธ์„ ์žฌ์‚ฌ์šฉ** ํ•  ์ˆ˜ ์žˆ๊ณ  ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
์ด๋ฅผ ํ†ตํ•ด **์—ฌ๋Ÿฌ ์œ„์น˜**์—์„œ **๋ชจ๋ธ์„ ์žฌ์‚ฌ์šฉํ• ** ์ˆ˜ ์žˆ๊ณ  ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
/// note | ์ฐธ๊ณ 
@ -36,7 +36,7 @@ Pydantic์˜ ๋ชจ๋ธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”๊ฐ€(`extra`) ํ•„๋“œ๋ฅผ ๊ธˆ์ง€(`forb
ํด๋ผ์ด์–ธํŠธ๊ฐ€ **์ถ”๊ฐ€ ํ—ค๋”**๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ์‹œ๋„ํ•˜๋ฉด, **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ํด๋ผ์ด์–ธํŠธ๊ฐ€ `plumbus` ๊ฐ’์œผ๋กœ `tool` ํ—ค๋”๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด, ํด๋ผ์ด์–ธํŠธ๋Š” ํ—ค๋” ๋งค๊ฐœ๋ณ€์ˆ˜ `tool`์ด ํ—ˆ์šฉ ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค:
์˜ˆ๋ฅผ ๋“ค์–ด, ํด๋ผ์ด์–ธํŠธ๊ฐ€ `plumbus` ๊ฐ’์œผ๋กœ `tool` ํ—ค๋”๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด, ํด๋ผ์ด์–ธํŠธ๋Š” ํ—ค๋” ๋งค๊ฐœ๋ณ€์ˆ˜ `tool`์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค:
```json
{

12
docs/ko/docs/tutorial/metadata.md

@ -18,7 +18,7 @@ OpenAPI ๋ช…์„ธ ๋ฐ ์ž๋™ํ™”๋œ API ๋ฌธ์„œ UI์— ์‚ฌ์šฉ๋˜๋Š” ๋‹ค์Œ ํ•„๋“œ๋ฅผ
๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
/// tip | ํŒ
@ -36,7 +36,7 @@ OpenAPI 3.1.0 ๋ฐ FastAPI 0.99.0๋ถ€ํ„ฐ `license_info`์— `url` ๋Œ€์‹  `identifie
์˜ˆ:
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
## ํƒœ๊ทธ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ { #metadata-for-tags }
@ -58,7 +58,7 @@ OpenAPI 3.1.0 ๋ฐ FastAPI 0.99.0๋ถ€ํ„ฐ `license_info`์— `url` ๋Œ€์‹  `identifie
ํƒœ๊ทธ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ `openapi_tags` ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์„ธ์š”:
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
์„ค๋ช… ์•ˆ์— ๋งˆํฌ๋‹ค์šด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด "login"์€ ๊ตต๊ฒŒ(**login**) ํ‘œ์‹œ๋˜๊ณ , "fancy"๋Š” ๊ธฐ์šธ์ž„๊ผด(_fancy_)๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
@ -72,7 +72,7 @@ OpenAPI 3.1.0 ๋ฐ FastAPI 0.99.0๋ถ€ํ„ฐ `license_info`์— `url` ๋Œ€์‹  `identifie
`tags` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* (๋ฐ `APIRouter`)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ํƒœ๊ทธ์— ํ• ๋‹นํ•˜์„ธ์š”:
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
/// info | ์ •๋ณด
@ -100,7 +100,7 @@ OpenAPI 3.1.0 ๋ฐ FastAPI 0.99.0๋ถ€ํ„ฐ `license_info`์— `url` ๋Œ€์‹  `identifie
์˜ˆ๋ฅผ ๋“ค์–ด, ์ด๋ฅผ `/api/v1/openapi.json`์—์„œ ์ œ๊ณตํ•˜๋„๋ก ์„ค์ •ํ•˜๋ ค๋ฉด:
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
OpenAPI ์Šคํ‚ค๋งˆ๋ฅผ ์™„์ „ํžˆ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด `openapi_url=None`์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์„œํ™” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋„ ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.
@ -117,4 +117,4 @@ OpenAPI ์Šคํ‚ค๋งˆ๋ฅผ ์™„์ „ํžˆ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด `openapi_url=None`์œผ๋กœ
์˜ˆ๋ฅผ ๋“ค์–ด, Swagger UI๋ฅผ `/documentation`์—์„œ ์ œ๊ณตํ•˜๊ณ  ReDoc์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด:
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}

8
docs/ko/docs/tutorial/middleware.md

@ -15,7 +15,7 @@
`yield`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜์กด์„ฑ์ด ์žˆ๋‹ค๋ฉด, exit ์ฝ”๋“œ๋Š” ๋ฏธ๋“ค์›จ์–ด *ํ›„์—* ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…(๋’ค์—์„œ ๋ณด๊ฒŒ ๋  [Background Tasks](background-tasks.md){.internal-link target=_blank} ์„น์…˜์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค)์ด ์žˆ๋‹ค๋ฉด, ๋ชจ๋“  ๋ฏธ๋“ค์›จ์–ด *ํ›„์—* ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…(๋’ค์—์„œ ๋ณด๊ฒŒ ๋  [๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…](background-tasks.md){.internal-link target=_blank} ์„น์…˜์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค)์ด ์žˆ๋‹ค๋ฉด, ๋ชจ๋“  ๋ฏธ๋“ค์›จ์–ด *ํ›„์—* ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
///
@ -31,7 +31,7 @@
* ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•ด๋‹น *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ์ƒ์„ฑํ•œ `response`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
* ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— `response`๋ฅผ ์ถ”๊ฐ€๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
/// tip | ํŒ
@ -57,7 +57,7 @@
์˜ˆ๋ฅผ ๋“ค์–ด, ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„์„ ์ดˆ ๋‹จ์œ„๋กœ ๋‹ด๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ํ—ค๋” `X-Process-Time`์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
/// tip | ํŒ
@ -92,4 +92,4 @@ app.add_middleware(MiddlewareB)
๋‹ค๋ฅธ ๋ฏธ๋“ค์›จ์–ด์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋Š” ๋‚˜์ค‘์— [์ˆ™๋ จ๋œ ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ: ํ–ฅ์ƒ๋œ ๋ฏธ๋“ค์›จ์–ด](../advanced/middleware.md){.internal-link target=_blank}์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ ์„น์…˜์—์„œ ๋ฏธ๋“ค์›จ์–ด๋กœ <abbr title="Cross-Origin Resource Sharing">CORS</abbr>๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‹ค์Œ ์„น์…˜์—์„œ ๋ฏธ๋“ค์›จ์–ด๋กœ <abbr title="Cross-Origin Resource Sharing - ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ">CORS</abbr>๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

8
docs/ko/docs/tutorial/path-operation-configuration.md

@ -46,7 +46,7 @@
**FastAPI**๋Š” ์ผ๋ฐ˜ ๋ฌธ์ž์—ด๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
## ์š”์•ฝ๊ณผ ์„ค๋ช… { #summary-and-description }
@ -56,7 +56,7 @@
## ๋…์ŠคํŠธ๋ง์œผ๋กœ ๋งŒ๋“  ์„ค๋ช… { #description-from-docstring }
์„ค๋ช…์€ ๋ณดํ†ต ๊ธธ์–ด์ง€๊ณ  ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์„ค๋ช…์„ ํ•จ์ˆ˜ <abbr title="๋ฌธ์„œํ™”์— ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€ ์ฒซ ํ‘œํ˜„์‹์˜ ์—ฌ๋Ÿฌ ์ค„ ๋ฌธ์ž์—ด(์–ด๋–ค ๋ณ€์ˆ˜์—๋„ ํ• ๋‹น๋˜์ง€ ์•Š์Œ)">docstring</abbr>์— ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, **FastAPI**๋Š” ๊ทธ๊ณณ์—์„œ ์ด๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.
์„ค๋ช…์€ ๋ณดํ†ต ๊ธธ์–ด์ง€๊ณ  ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์„ค๋ช…์„ ํ•จ์ˆ˜ <dfn title="๋ฌธ์„œํ™”์— ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€ ์ฒซ ํ‘œํ˜„์‹์˜ ์—ฌ๋Ÿฌ ์ค„ ๋ฌธ์ž์—ด(์–ด๋–ค ๋ณ€์ˆ˜์—๋„ ํ• ๋‹น๋˜์ง€ ์•Š์Œ)">๋…์ŠคํŠธ๋ง</dfn>์— ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, **FastAPI**๋Š” ๊ทธ๊ณณ์—์„œ ์ด๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.
๋…์ŠคํŠธ๋ง์—๋Š” <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, (๋…์ŠคํŠธ๋ง์˜ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ) ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•ด์„๋˜๊ณ  ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
@ -90,9 +90,9 @@ OpenAPI๋Š” ๊ฐ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ์‘๋‹ต์— ๊ด€ํ•œ ์„ค๋ช…์„ ์š”๊ตฌํ•  ๊ฒƒ์„
## *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์ง€์›์ค‘๋‹จํ•˜๊ธฐ { #deprecate-a-path-operation }
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š๊ณ  <abbr title="๊ตฌ์‹์ด๋ฉฐ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋จ">deprecated</abbr>๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•œ๋‹ค๋ฉด, `deprecated` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š๊ณ  <dfn title="๊ตฌ์‹์ด๋ฉฐ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋จ">์ง€์›์ค‘๋‹จ</dfn>์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•œ๋‹ค๋ฉด, `deprecated` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์—์„œ ์ง€์›์ค‘๋‹จ์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค:

14
docs/ko/docs/tutorial/path-params-numeric-validations.md

@ -54,11 +54,11 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „์—์„œ `Annotated` ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ (๊ทธ๋ฆฌ๊ณ  ์ด
๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
ํ•˜์ง€๋งŒ `Annotated`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. `Query()`๋‚˜ `Path()`์— ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ˆœ์„œ๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
## ํ•„์š”ํ•œ ๋Œ€๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •๋ ฌํ•˜๊ธฐ, ํŠธ๋ฆญ { #order-the-parameters-as-you-need-tricks }
@ -83,13 +83,13 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „์—์„œ `Annotated` ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ (๊ทธ๋ฆฌ๊ณ  ์ด
ํŒŒ์ด์ฌ์€ `*`์œผ๋กœ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์ง€๋งŒ, ๋’ค๋”ฐ๋ฅด๋Š” ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ‚ค์›Œ๋“œ ์ธ์ž(ํ‚ค-๊ฐ’ ์Œ)๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•จ์„ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” <abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>๋กœ๋„ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์ด ์—†๋”๋ผ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
### `Annotated`๋ฅผ ์“ฐ๋ฉด ๋” ์ข‹์Šต๋‹ˆ๋‹ค { #better-with-annotated }
`Annotated`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์•„๋งˆ `*`๋„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
## ์ˆซ์ž ๊ฒ€์ฆ: ํฌ๊ฑฐ๋‚˜ ๊ฐ™์Œ { #number-validations-greater-than-or-equal }
@ -97,7 +97,7 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „์—์„œ `Annotated` ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ (๊ทธ๋ฆฌ๊ณ  ์ด
์—ฌ๊ธฐ์„œ `ge=1`์ธ ๊ฒฝ์šฐ, `item_id`๋Š” `1`๋ณด๋‹ค "`g`reater than or `e`qual"(ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€) ์ •์ˆ˜ํ˜• ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
## ์ˆซ์ž ๊ฒ€์ฆ: ํฌ๊ฑฐ๋‚˜ ๋ฐ ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์Œ { #number-validations-greater-than-and-less-than-or-equal }
@ -106,7 +106,7 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „์—์„œ `Annotated` ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ (๊ทธ๋ฆฌ๊ณ  ์ด
* `gt`: `g`reater `t`han
* `le`: `l`ess than or `e`qual
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
## ์ˆซ์ž ๊ฒ€์ฆ: ๋ถ€๋™์†Œ์ˆ˜, ํฌ๊ฑฐ๋‚˜ ๋ฐ ์ž‘๊ฑฐ๋‚˜ { #number-validations-floats-greater-than-and-less-than }
@ -118,7 +118,7 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „์—์„œ `Annotated` ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ (๊ทธ๋ฆฌ๊ณ  ์ด
<abbr title="less than"><code>lt</code></abbr> ์—ญ์‹œ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
## ์š”์•ฝ { #recap }

32
docs/ko/docs/tutorial/path-params.md

@ -2,7 +2,7 @@
ํŒŒ์ด์ฌ์˜ ํฌ๋งท ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ๋ฒ•์„ ์ด์šฉํ•˜์—ฌ ๊ฒฝ๋กœ "๋งค๊ฐœ๋ณ€์ˆ˜" ๋˜๋Š” "๋ณ€์ˆ˜"๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ `item_id`์˜ ๊ฐ’์€ ํ•จ์ˆ˜์˜ `item_id` ์ธ์ž๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
@ -16,7 +16,7 @@
ํŒŒ์ด์ฌ ํ‘œ์ค€ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜์— ์žˆ๋Š” ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
์œ„์˜ ์˜ˆ์‹œ์—์„œ, `item_id`๋Š” `int`๋กœ ์„ ์–ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
@ -26,7 +26,7 @@
///
## ๋ฐ์ดํ„ฐ <abbr title="๋‹ค์Œ์œผ๋กœ๋„ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค: ์ง๋ ฌํ™”, ํŒŒ์‹ฑ, ๋งˆ์ƒฌ๋ง">๋ณ€ํ™˜</abbr> { #data-conversion }
## ๋ฐ์ดํ„ฐ <dfn title="๋‹ค์Œ์œผ๋กœ๋„ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค: ์ง๋ ฌํ™”, ํŒŒ์‹ฑ, ๋งˆ์ƒฌ๋ง">๋ณ€ํ™˜</dfn> { #data-conversion }
์ด ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>์„ ์—ด๋ฉด, ๋‹ค์Œ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -38,7 +38,7 @@
ํ•จ์ˆ˜๊ฐ€ ๋ฐ›์€(๋ฐ˜ํ™˜๋„ ํ•˜๋Š”) ๊ฐ’์€ ๋ฌธ์ž์—ด `"3"`์ด ์•„๋‹ˆ๋ผ ํŒŒ์ด์ฌ `int` ํ˜•์ธ `3`์ž…๋‹ˆ๋‹ค.
์ฆ‰, ํƒ€์ž… ์„ ์–ธ์„ ํ•˜๋ฉด **FastAPI**๋Š” ์ž๋™์œผ๋กœ ์š”์ฒญ์„ <abbr title="HTTP ์š”์ฒญ์—์„œ ์ „๋‹ฌ๋˜๋Š” ๋ฌธ์ž์—ด์„ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜">"ํŒŒ์‹ฑ"</abbr>ํ•ฉ๋‹ˆ๋‹ค.
์ฆ‰, ํƒ€์ž… ์„ ์–ธ์„ ํ•˜๋ฉด **FastAPI**๋Š” ์ž๋™์œผ๋กœ ์š”์ฒญ์„ <dfn title="HTTP ์š”์ฒญ์—์„œ ์ „๋‹ฌ๋˜๋Š” ๋ฌธ์ž์—ด์„ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜">"ํŒŒ์‹ฑ"</dfn>ํ•ฉ๋‹ˆ๋‹ค.
///
@ -116,21 +116,21 @@
์‚ฌ์šฉ์ž ID๋ฅผ ์ด์šฉํ•ด ํŠน์ • ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ๋กœ `/users/{user_id}`๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋Š” ์ˆœ์ฐจ์ ์œผ๋กœ ํ‰๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์— `/users/{user_id}` ์ด์ „์— `/users/me`์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๊ฐ€ ๋จผ์ € ์„ ์–ธ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋Š” ์ˆœ์ฐจ์ ์œผ๋กœ ํ‰๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์— `/users/me`์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๊ฐ€ `/users/{user_id}` ์ด์ „์— ๋จผ์ € ์„ ์–ธ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `/users/{user_id}`์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๊ฐ€ `/users/me`์—๋„ ๋งค์นญ๋˜์–ด, ๋งค๊ฐœ๋ณ€์ˆ˜ `user_id`์— `"me"` ๊ฐ’์ด ๋“ค์–ด์™”๋‹ค๊ณ  "์ƒ๊ฐํ•˜๊ฒŒ" ๋ฉ๋‹ˆ๋‹ค.
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
๊ฒฝ๋กœ๊ฐ€ ๋จผ์ € ๋งค์นญ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ๋ฒˆ์งธ ๊ฒƒ์ด ํ•ญ์ƒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
## ์‚ฌ์ „์ •์˜ ๊ฐ’ { #predefined-values }
๋งŒ์•ฝ *๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜*๋ฅผ ๋ฐ›๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ์žˆ์ง€๋งŒ, ๊ฐ€๋Šฅํ•œ ์œ ํšจํ•œ *๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜* ๊ฐ’๋“ค์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํŒŒ์ด์ฌ ํ‘œ์ค€ <abbr title="์—ด๊ฑฐํ˜•(Enumeration)">`Enum`</abbr>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ *๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜*๋ฅผ ๋ฐ›๋Š” *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ์žˆ์ง€๋งŒ, ๊ฐ€๋Šฅํ•œ ์œ ํšจํ•œ *๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜* ๊ฐ’๋“ค์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํŒŒ์ด์ฌ ํ‘œ์ค€ <abbr title="์—ด๊ฑฐํ˜•">`Enum`</abbr>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### `Enum` ํด๋ž˜์Šค ์ƒ์„ฑ { #create-an-enum-class }
@ -140,11 +140,11 @@
๊ฐ€๋Šฅํ•œ ๊ฐ’๋“ค์— ํ•ด๋‹นํ•˜๋Š” ๊ณ ์ •๋œ ๊ฐ’์˜ ํด๋ž˜์Šค ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋“ค์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
/// tip | ํŒ
ํ˜น์‹œ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด, "AlexNet", "ResNet", ๊ทธ๋ฆฌ๊ณ  "LeNet"์€ ๊ทธ์ € ๋จธ์‹  ๋Ÿฌ๋‹ <abbr title="๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ๋”ฅ ๋Ÿฌ๋‹ ๋ชจ๋ธ ์•„ํ‚คํ…์ฒ˜">๋ชจ๋ธ</abbr>๋“ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
ํ˜น์‹œ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด, "AlexNet", "ResNet", ๊ทธ๋ฆฌ๊ณ  "LeNet"์€ ๊ทธ์ € ๋จธ์‹  ๋Ÿฌ๋‹ <dfn title="๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ๋”ฅ ๋Ÿฌ๋‹ ๋ชจ๋ธ ์•„ํ‚คํ…์ฒ˜">๋ชจ๋ธ</dfn>๋“ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
///
@ -152,7 +152,7 @@
์ƒ์„ฑํ•œ ์—ด๊ฑฐํ˜• ํด๋ž˜์Šค(`ModelName`)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ *๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜*๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
### ๋ฌธ์„œ ํ™•์ธ { #check-the-docs }
@ -168,13 +168,13 @@
์ƒ์„ฑํ•œ ์—ด๊ฑฐํ˜• `ModelName`์˜ *์—ด๊ฑฐํ˜• ๋ฉค๋ฒ„*์™€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
#### *์—ด๊ฑฐํ˜• ๊ฐ’* ๊ฐ€์ ธ์˜ค๊ธฐ { #get-the-enumeration-value }
`model_name.value` ๋˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ `your_enum_member.value`๋ฅผ ์ด์šฉํ•˜์—ฌ ์‹ค์ œ ๊ฐ’(์œ„ ์˜ˆ์‹œ์˜ ๊ฒฝ์šฐ `str`)์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
/// tip | ํŒ
@ -188,7 +188,7 @@
ํด๋ผ์ด์–ธํŠธ์— ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ํ•ด๋‹น ๊ฐ’(์ด ๊ฒฝ์šฐ ๋ฌธ์ž์—ด)์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
ํด๋ผ์ด์–ธํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ JSON ์‘๋‹ต์„ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค:
@ -227,7 +227,7 @@ Starlette์˜ ์˜ต์…˜์„ ์ง์ ‘ ์ด์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ URL์„ ์‚ฌ์šฉํ•จ์œผ
๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
/// tip | ํŒ
@ -242,7 +242,7 @@ Starlette์˜ ์˜ต์…˜์„ ์ง์ ‘ ์ด์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ URL์„ ์‚ฌ์šฉํ•จ์œผ
**FastAPI**๋ฅผ ์ด์šฉํ•˜๋ฉด ์งง๊ณ  ์ง๊ด€์ ์ธ ํ‘œ์ค€ ํŒŒ์ด์ฌ ํƒ€์ž… ์„ ์–ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* ํŽธ์ง‘๊ธฐ ์ง€์›: ์˜ค๋ฅ˜ ๊ฒ€์‚ฌ, ์ž๋™์™„์„ฑ ๋“ฑ
* ๋ฐ์ดํ„ฐ "<abbr title="HTTP ์š”์ฒญ์—์„œ ์ „๋‹ฌ๋˜๋Š” ๋ฌธ์ž์—ด์„ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜">parsing</abbr>"
* ๋ฐ์ดํ„ฐ "<dfn title="HTTP ์š”์ฒญ์—์„œ ์ „๋‹ฌ๋˜๋Š” ๋ฌธ์ž์—ด์„ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜">ํŒŒ์‹ฑ</dfn>"
* ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ
* API ์ฃผ์„(Annotation)๊ณผ ์ž๋™ ๋ฌธ์„œ

48
docs/ko/docs/tutorial/query-params-str-validations.md

@ -2,7 +2,7 @@
**FastAPI**๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด ๋ฐ ๊ฒ€์ฆ์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
@ -41,46 +41,22 @@ FastAPI๋Š” 0.95.0 ๋ฒ„์ „์—์„œ `Annotated` ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ (๊ทธ๋ฆฌ๊ณ  ์ด
## `q` ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์— `Annotated` ์‚ฌ์šฉํ•˜๊ธฐ { #use-annotated-in-the-type-for-the-q-parameter }
์ด์ „์— [Python Types Intro](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}์—์„œ `Annotated`๋ฅผ ์‚ฌ์šฉํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ง์”€๋“œ๋ฆฐ ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”?
์ด์ „์— [Python ํƒ€์ž… ์†Œ๊ฐœ](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}์—์„œ `Annotated`๋ฅผ ์‚ฌ์šฉํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ง์”€๋“œ๋ฆฐ ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”?
์ด์ œ FastAPI์—์„œ ์‚ฌ์šฉํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ๐Ÿš€
๋‹ค์Œ๊ณผ ๊ฐ™์€ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค:
//// tab | Python 3.10+
```Python
q: str | None = None
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
์—ฌ๊ธฐ์„œ `Annotated`๋กœ ๊ฐ์‹ธ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งŒ๋“ญ๋‹ˆ๋‹ค:
//// tab | Python 3.10+
```Python
q: Annotated[str | None] = None
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
๋‘ ๋ฒ„์ „ ๋ชจ๋‘ ๊ฐ™์€ ์˜๋ฏธ๋กœ, `q`๋Š” `str` ๋˜๋Š” `None`์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์€ `None`์ž…๋‹ˆ๋‹ค.
์ด์ œ ์žฌ๋ฏธ์žˆ๋Š” ๋ถ€๋ถ„์œผ๋กœ ๋„˜์–ด๊ฐ€ ๋ด…์‹œ๋‹ค. ๐ŸŽ‰
@ -109,7 +85,7 @@ q: Annotated[Union[str, None]] = None
## ๋Œ€์•ˆ(์ด์ „ ๋ฐฉ์‹): ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ `Query` ์‚ฌ์šฉ { #alternative-old-query-as-the-default-value }
์ด์ „ FastAPI ๋ฒ„์ „(<abbr title="before 2023-03">0.95.0</abbr> ์ด์ „)์—์„œ๋Š” `Annotated`์— ๋„ฃ๋Š” ๋Œ€์‹ , ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ `Query`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋ณ€์—์„œ ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์— ์„ค๋ช…ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
์ด์ „ FastAPI ๋ฒ„์ „(<dfn title="2023-03 ์ด์ „">0.95.0</dfn> ์ด์ „)์—์„œ๋Š” `Annotated`์— ๋„ฃ๋Š” ๋Œ€์‹ , ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ `Query`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋ณ€์—์„œ ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์— ์„ค๋ช…ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
/// tip | ํŒ
@ -192,7 +168,7 @@ FastAPI ์—†์ด๋„ **๋‹ค๋ฅธ ๊ณณ์—์„œ** ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ **ํ˜ธ์ถœ**ํ•  ์ˆ˜ ์žˆ๊ณ 
## ์ •๊ทœ์‹ ์ถ”๊ฐ€ { #add-regular-expressions }
๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์ผ์น˜ํ•ด์•ผ ํ•˜๋Š” <abbr title="๋ฌธ์ž์—ด์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ํŒจํ„ด์„ ์ •์˜ํ•˜๋Š” ๋ฌธ์ž๋“ค์˜ ์ˆœ์—ด์ธ ์ •๊ทœ ํ‘œํ˜„์‹(regular expression), regex ๋˜๋Š” regexp์ž…๋‹ˆ๋‹ค.">์ •๊ทœ ํ‘œํ˜„์‹</abbr> `pattern`์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์ผ์น˜ํ•ด์•ผ ํ•˜๋Š” <dfn title="์ •๊ทœ ํ‘œํ˜„์‹(regex ๋˜๋Š” regexp)์€ ๋ฌธ์ž์—ด์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ํŒจํ„ด์„ ์ •์˜ํ•˜๋Š” ๋ฌธ์ž ์‹œํ€€์Šค์ž…๋‹ˆ๋‹ค.">์ •๊ทœ ํ‘œํ˜„์‹</dfn> `pattern`์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@ -212,7 +188,7 @@ FastAPI ์—†์ด๋„ **๋‹ค๋ฅธ ๊ณณ์—์„œ** ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ **ํ˜ธ์ถœ**ํ•  ์ˆ˜ ์žˆ๊ณ 
`q` ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜์— `min_length`๋ฅผ `3`์œผ๋กœ ์„ค์ •ํ•˜๊ณ , ๊ธฐ๋ณธ๊ฐ’์„ `"fixedquery"`๋กœ ์„ ์–ธํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
/// note | ์ฐธ๊ณ 
@ -242,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
๋”ฐ๋ผ์„œ `Query`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ฐ’์„ ํ•„์ˆ˜๋กœ ์„ ์–ธํ•ด์•ผ ํ•  ๋•Œ๋Š”, ๊ธฐ๋ณธ๊ฐ’์„ ์„ ์–ธํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### ํ•„์ˆ˜์ง€๋งŒ `None` ๊ฐ€๋Šฅ { #required-can-be-none }
@ -293,7 +269,7 @@ http://localhost:8000/items/?q=foo&q=bar
์ œ๊ณต๋œ ๊ฐ’์ด ์—†์œผ๋ฉด ๊ธฐ๋ณธ `list` ๊ฐ’์„ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
๋‹ค์Œ์œผ๋กœ ์ด๋™ํ•˜๋ฉด:
@ -316,7 +292,7 @@ http://localhost:8000/items/
`list[str]` ๋Œ€์‹  `list`๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
/// note | ์ฐธ๊ณ 
@ -372,7 +348,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
์ด์ œ๋Š” ๋” ์ด์ƒ ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋งˆ์Œ์— ๋“ค์–ดํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.
์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋™์•ˆ์€ ๋‚จ๊ฒจ๋‘ฌ์•ผ ํ•˜์ง€๋งŒ, ๋ฌธ์„œ์—์„œ <abbr title="obsolete, recommended not to use it โ€“ ๊ตฌ์‹์ด๋ฉฐ, ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ์ถ”์ฒœ">deprecated</abbr>๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋™์•ˆ์€ ๋‚จ๊ฒจ๋‘ฌ์•ผ ํ•˜์ง€๋งŒ, ๋ฌธ์„œ์—์„œ <dfn title="๊ตฌ์‹์ด๋ฉฐ, ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๊ถŒ์žฅํ•จ">์‚ฌ์šฉ ์ค‘๋‹จ๋จ</dfn>์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ ‡๋‹ค๋ฉด `deprecated=True` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `Query`๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค:
@ -402,7 +378,7 @@ Pydantic์—๋Š” <a href="https://docs.pydantic.dev/latest/concepts/validators/#fi
///
์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ์ปค์Šคํ…€ validator๋Š” <abbr title="ISBN means International Standard Book Number โ€“ ๊ตญ์ œ ํ‘œ์ค€ ๋„์„œ ๋ฒˆํ˜ธ">ISBN</abbr> ๋„์„œ ๋ฒˆํ˜ธ์˜ ๊ฒฝ์šฐ ์•„์ดํ…œ ID๊ฐ€ `isbn-`์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ , <abbr title="IMDB (Internet Movie Database) is a website with information about movies โ€“ ์˜ํ™”์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์›น์‚ฌ์ดํŠธ">IMDB</abbr> ์˜ํ™” URL ID์˜ ๊ฒฝ์šฐ `imdb-`๋กœ ์‹œ์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค:
์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ์ปค์Šคํ…€ validator๋Š” <abbr title="International Standard Book Number - ๊ตญ์ œ ํ‘œ์ค€ ๋„์„œ ๋ฒˆํ˜ธ">ISBN</abbr> ๋„์„œ ๋ฒˆํ˜ธ์˜ ๊ฒฝ์šฐ ์•„์ดํ…œ ID๊ฐ€ `isbn-`์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ , <abbr title="Internet Movie Database - ์ธํ„ฐ๋„ท ์˜ํ™” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: ์˜ํ™”์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์›น์‚ฌ์ดํŠธ">IMDB</abbr> ์˜ํ™” URL ID์˜ ๊ฒฝ์šฐ `imdb-`๋กœ ์‹œ์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@ -436,9 +412,9 @@ Pydantic์—๋Š” <a href="https://docs.pydantic.dev/latest/concepts/validators/#fi
#### ์ž„์˜์˜ ํ•ญ๋ชฉ { #a-random-item }
`data.items()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ๋”•์…”๋„ˆ๋ฆฌ ํ•ญ๋ชฉ์˜ ํ‚ค์™€ ๊ฐ’์„ ๋‹ด์€ ํŠœํ”Œ๋กœ ๊ตฌ์„ฑ๋œ <abbr title="๋ฆฌ์ŠคํŠธ, ์„ธํŠธ ๋“ฑ์ฒ˜๋Ÿผ for ๋ฃจํ”„๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ">iterable object</abbr>๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.
`data.items()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ๋”•์…”๋„ˆ๋ฆฌ ํ•ญ๋ชฉ์˜ ํ‚ค์™€ ๊ฐ’์„ ๋‹ด์€ ํŠœํ”Œ๋กœ ๊ตฌ์„ฑ๋œ <dfn title="๋ฆฌ์ŠคํŠธ, ์„ธํŠธ ๋“ฑ์ฒ˜๋Ÿผ for ๋ฃจํ”„๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ">์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด</dfn>๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.
์ด iterable object๋ฅผ `list(data.items())`๋กœ ์ ์ ˆํ•œ `list`๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์ด ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋ฅผ `list(data.items())`๋กœ ์ ์ ˆํ•œ `list`๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ ๋‹ค์Œ `random.choice()`๋กœ ๋ฆฌ์ŠคํŠธ์—์„œ **๋ฌด์ž‘์œ„ ๊ฐ’**์„ ์–ป์–ด `(id, name)` ํ˜•ํƒœ์˜ ํŠœํ”Œ์„ ์–ป์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")` ๊ฐ™์€ ๊ฐ’์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

6
docs/ko/docs/tutorial/query-params.md

@ -2,7 +2,7 @@
๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด "์ฟผ๋ฆฌ" ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ž๋™ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
์ฟผ๋ฆฌ๋Š” URL์—์„œ `?` ํ›„์— ๋‚˜์˜ค๊ณ  `&`์œผ๋กœ ๊ตฌ๋ถ„๋˜๋Š” ํ‚ค-๊ฐ’ ์Œ์˜ ์ง‘ํ•ฉ์ž…๋‹ˆ๋‹ค.
@ -24,7 +24,7 @@ URL์˜ ์ผ๋ถ€์ด๋ฏ€๋กœ "์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ" ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.
๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ ์šฉ๋œ ๋™์ผํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค:
* (๋‹น์—ฐํžˆ) ํŽธ์ง‘๊ธฐ ์ง€์›
* ๋ฐ์ดํ„ฐ <abbr title="converting the string that comes from an HTTP request into Python data">"ํŒŒ์‹ฑ"</abbr>
* ๋ฐ์ดํ„ฐ <dfn title="HTTP ์š”์ฒญ์—์„œ ์˜จ ๋ฌธ์ž์—ด์„ Python ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ">"ํŒŒ์‹ฑ"</dfn>
* ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ
* ์ž๋™ ๋ฌธ์„œํ™”
@ -128,7 +128,7 @@ http://127.0.0.1:8000/items/foo?short=yes
๊ทธ๋Ÿฌ๋‚˜ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ•„์ˆ˜๋กœ ๋งŒ๋“ค๋ ค๋ฉด ๋‹จ์ˆœํžˆ ๊ธฐ๋ณธ๊ฐ’์„ ์„ ์–ธํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
์—ฌ๊ธฐ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ `needy`๋Š” `str`ํ˜•์ธ ํ•„์ˆ˜ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.

14
docs/ko/docs/tutorial/request-files.md

@ -20,13 +20,13 @@ $ pip install python-multipart
`fastapi` ์—์„œ `File` ๊ณผ `UploadFile` ์„ ์ž„ํฌํŠธ ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
## `File` ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์˜ { #define-file-parameters }
`Body` ๋ฐ `Form` ๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ํŒŒ์ผ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
/// info | ์ •๋ณด
@ -54,7 +54,7 @@ File์˜ ๋ณธ๋ฌธ์„ ์„ ์–ธํ•  ๋•Œ, ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋˜๋Š” ๋ณธ
`File` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `UploadFile` ํƒ€์ž…์œผ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
`UploadFile` ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ `bytes` ๊ณผ ๋น„๊ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:
@ -121,7 +121,7 @@ HTML์˜ ํผ๋“ค(`<form></form>`)์ด ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹์€
ํ•˜์ง€๋งŒ ํŒŒ์ผ์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ, `multipart/form-data`๋กœ ์ธ์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค. `File`์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค๋ฉด, **FastAPI**๋Š” ๋ณธ๋ฌธ์˜ ์ ํ•ฉํ•œ ๋ถ€๋ถ„์—์„œ ํŒŒ์ผ์„ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ง€ํ•ฉ๋‹ˆ๋‹ค.
์ธ์ฝ”๋”ฉ๊ณผ ํผ ํ•„๋“œ์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web docs for <code>POST</code></a>๋ฅผ ์ฐธ๊ณ ํ•˜๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
์ธ์ฝ”๋”ฉ๊ณผ ํผ ํ•„๋“œ์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - ๋ชจ์งˆ๋ผ ๊ฐœ๋ฐœ์ž ๋„คํŠธ์›Œํฌ">MDN</abbr> web docs for <code>POST</code></a>๋ฅผ ์ฐธ๊ณ ํ•˜๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
///
@ -143,7 +143,7 @@ HTML์˜ ํผ๋“ค(`<form></form>`)์ด ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹์€
์ถ”๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด ์˜ˆ๋ฅผ ๋“ค์–ด `UploadFile`๊ณผ ํ•จ๊ป˜ `File()`์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
## ๋‹ค์ค‘ ํŒŒ์ผ ์—…๋กœ๋“œ { #multiple-file-uploads }
@ -153,7 +153,7 @@ HTML์˜ ํผ๋“ค(`<form></form>`)์ด ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹์€
์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด , `bytes` ์˜ `List` ๋˜๋Š” `UploadFile` ๋ฅผ ์„ ์–ธํ•˜๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค:
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
์„ ์–ธํ•œ๋Œ€๋กœ, `bytes` ์˜ `list` ๋˜๋Š” `UploadFile` ๋“ค์„ ์ „์†ก๋ฐ›์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
@ -169,7 +169,7 @@ HTML์˜ ํผ๋“ค(`<form></form>`)์ด ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹์€
์ด์ „๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ `UploadFile`์— ๋Œ€ํ•ด์„œ๋„ `File()`์„ ์‚ฌ์šฉํ•ด ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
## ์š”์•ฝ { #recap }

4
docs/ko/docs/tutorial/request-form-models.md

@ -24,7 +24,7 @@ $ pip install python-multipart
**ํผ ํ•„๋“œ**๋กœ ๋ฐ›๊ณ  ์‹ถ์€ ํ•„๋“œ๋ฅผ **Pydantic ๋ชจ๋ธ**๋กœ ์„ ์–ธํ•œ ๋‹ค์Œ, ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ `Form`์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
**FastAPI**๋Š” ์š”์ฒญ์—์„œ ๋ฐ›์€ **ํผ ๋ฐ์ดํ„ฐ**์—์„œ **๊ฐ ํ•„๋“œ**์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ **์ถ”์ถœ**ํ•˜๊ณ  ์ •์˜ํ•œ Pydantic ๋ชจ๋ธ์„ ์ค๋‹ˆ๋‹ค.
@ -48,7 +48,7 @@ $ pip install python-multipart
Pydantic์˜ ๋ชจ๋ธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ `extra` ํ•„๋“œ๋ฅผ `forbid`ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด **์˜ค๋ฅ˜** ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

4
docs/ko/docs/tutorial/request-forms-and-files.md

@ -16,13 +16,13 @@ $ pip install python-multipart
## `File` ๋ฐ `Form` ์ž„ํฌํŠธ { #import-file-and-form }
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
## `File` ๋ฐ `Form` ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์˜ { #define-file-and-form-parameters }
`Body` ๋ฐ `Query`์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ํŒŒ์ผ๊ณผ ํผ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
ํŒŒ์ผ๊ณผ ํผ ํ•„๋“œ๋Š” ํผ ๋ฐ์ดํ„ฐ๋กœ ์—…๋กœ๋“œ๋˜๋ฉฐ, ํŒŒ์ผ๊ณผ ํผ ํ•„๋“œ๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

8
docs/ko/docs/tutorial/request-forms.md

@ -18,17 +18,17 @@ $ pip install python-multipart
`fastapi`์—์„œ `Form`์„ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
## `Form` ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์˜ํ•˜๊ธฐ { #define-form-parameters }
`Body` ๋˜๋Š” `Query`์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ํผ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
์˜ˆ๋ฅผ ๋“ค์–ด, OAuth2 ์‚ฌ์–‘์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜("ํŒจ์Šค์›Œ๋“œ ํ”Œ๋กœ์šฐ"๋ผ๊ณ  ํ•จ)๋กœ `username`๊ณผ `password`๋ฅผ ํผ ํ•„๋“œ๋กœ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
<abbr title="specification">spec</abbr>์—์„œ๋Š” ํ•„๋“œ ์ด๋ฆ„์ด `username` ๋ฐ `password`๋กœ ์ •ํ™•ํ•˜๊ฒŒ ๋ช…๋ช…๋˜์–ด์•ผ ํ•˜๊ณ , JSON์ด ์•„๋‹Œ ํผ ํ•„๋“œ๋กœ ์ „์†กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
<dfn title="์‚ฌ์–‘">์‚ฌ์–‘</dfn>์—์„œ๋Š” ํ•„๋“œ ์ด๋ฆ„์ด `username` ๋ฐ `password`๋กœ ์ •ํ™•ํ•˜๊ฒŒ ๋ช…๋ช…๋˜์–ด์•ผ ํ•˜๊ณ , JSON์ด ์•„๋‹Œ ํผ ํ•„๋“œ๋กœ ์ „์†กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
`Form`์„ ์‚ฌ์šฉํ•˜๋ฉด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ์˜ˆ์ œ, ๋ณ„์นญ(์˜ˆ: `username` ๋Œ€์‹  `user-name`) ๋“ฑ์„ ํฌํ•จํ•˜์—ฌ `Body`(๋ฐ `Query`, `Path`, `Cookie`)์™€ ๋™์ผํ•œ ๊ตฌ์„ฑ์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -56,7 +56,7 @@ HTML ํผ(`<form></form>`)์ด ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์€ ์ผ๋ฐ˜
๊ทธ๋Ÿฌ๋‚˜ ํผ์— ํŒŒ์ผ์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ, `multipart/form-data`๋กœ ์ธ์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์žฅ์—์„œ ํŒŒ์ผ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•ด ์ฝ์„ ๊ฒ๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ์ธ์ฝ”๋”ฉ ๋ฐ ํผ ํ•„๋“œ์— ๋Œ€ํ•ด ๋” ์ฝ๊ณ  ์‹ถ๋‹ค๋ฉด, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><code>POST</code>์— ๋Œ€ํ•œ <abbr title="Mozilla Developer Network">MDN</abbr> ์›น ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”</a>.
์ด๋Ÿฌํ•œ ์ธ์ฝ”๋”ฉ ๋ฐ ํผ ํ•„๋“œ์— ๋Œ€ํ•ด ๋” ์ฝ๊ณ  ์‹ถ๋‹ค๋ฉด, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla ๊ฐœ๋ฐœ์ž ๋„คํŠธ์›Œํฌ">MDN</abbr> ์›น ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š” <code>POST</code>์— ๋Œ€ํ•œ</a>.
///

6
docs/ko/docs/tutorial/response-model.md

@ -183,7 +183,7 @@ FastAPI๋Š” Pydantic์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ, ํด๋ž˜
๊ฐ€์žฅ ํ”ํ•œ ๊ฒฝ์šฐ๋Š” [๊ณ ๊ธ‰ ๋ฌธ์„œ์—์„œ ๋‚˜์ค‘์— ์„ค๋ช…ํ•˜๋Š” ๋Œ€๋กœ Response๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ](../advanced/response-directly.md){.internal-link target=_blank}์ž…๋‹ˆ๋‹ค.
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
์ด ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด `Response` ํด๋ž˜์Šค(๋˜๋Š” ๊ทธ ์„œ๋ธŒํด๋ž˜์Šค)์ด๊ธฐ ๋•Œ๋ฌธ์— FastAPI์—์„œ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
@ -193,7 +193,7 @@ FastAPI๋Š” Pydantic์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ, ํด๋ž˜
ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์— `Response`์˜ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
์ด๋Š” `RedirectResponse`๊ฐ€ `Response`์˜ ์„œ๋ธŒํด๋ž˜์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ๋™์ž‘ํ•˜๋ฉฐ, FastAPI๊ฐ€ ์ด ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
@ -201,7 +201,7 @@ FastAPI๋Š” Pydantic์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ, ํด๋ž˜
ํ•˜์ง€๋งŒ ์œ ํšจํ•œ Pydantic ํƒ€์ž…์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ž„์˜์˜ ๊ฐ์ฒด(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ์ฒด)๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ํ•จ์ˆ˜์—์„œ ๊ทธ๋ ‡๊ฒŒ ์–ด๋…ธํ…Œ์ด์…˜ํ•˜๋ฉด, FastAPI๋Š” ๊ทธ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ๋ถ€ํ„ฐ Pydantic ์‘๋‹ต ๋ชจ๋ธ์„ ๋งŒ๋“ค๋ ค๊ณ  ์‹œ๋„ํ•˜๋‹ค๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ, ์œ ํšจํ•œ Pydantic ํƒ€์ž…์ด ์•„๋‹Œ ํƒ€์ž…์ด ํ•˜๋‚˜ ์ด์ƒ ํฌํ•จ๋œ ์—ฌ๋Ÿฌ ํƒ€์ž… ๊ฐ„์˜ <abbr title='์—ฌ๋Ÿฌ ํƒ€์ž… ๊ฐ„ union์€ "์ด ํƒ€์ž…๋“ค ์ค‘ ์•„๋ฌด๊ฑฐ๋‚˜"๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.'>union</abbr>์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜๋Š” ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค ๐Ÿ’ฅ:
๋˜ํ•œ, ์œ ํšจํ•œ Pydantic ํƒ€์ž…์ด ์•„๋‹Œ ํƒ€์ž…์ด ํ•˜๋‚˜ ์ด์ƒ ํฌํ•จ๋œ ์—ฌ๋Ÿฌ ํƒ€์ž… ๊ฐ„์˜ <dfn title="์—ฌ๋Ÿฌ ํƒ€์ž… ๊ฐ„์˜ union์€ '์ด ํƒ€์ž…๋“ค ์ค‘ ์•„๋ฌด๊ฑฐ๋‚˜'๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.">union</dfn>์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜๋Š” ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค ๐Ÿ’ฅ:
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}

10
docs/ko/docs/tutorial/response-status-code.md

@ -8,7 +8,7 @@
* `@app.delete()`
* ๋“ฑ
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
/// note | ์ฐธ๊ณ 
@ -43,7 +43,7 @@ FastAPI๋Š” ์ด๋ฅผ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ, ์‘๋‹ต ๋ณธ๋ฌธ์ด ์—†๋‹ค๊ณ  ๋ช…์‹œํ•˜๋Š” Open
/// note | ์ฐธ๊ณ 
๋งŒ์•ฝ HTTP ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, ๋‹ค์Œ ์„น์…˜์œผ๋กœ ๋„˜์–ด๊ฐ€์„ธ์š”.
๋งŒ์•ฝ HTTP ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, ๋‹ค์Œ ์„ก์…˜์œผ๋กœ ๋„˜์–ด๊ฐ€์„ธ์š”.
///
@ -66,7 +66,7 @@ HTTP์—์„œ๋Š” ์‘๋‹ต์˜ ์ผ๋ถ€๋กœ 3์ž๋ฆฌ ์ˆซ์ž ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
/// tip | ํŒ
๊ฐ ์ƒํƒœ ์ฝ”๋“œ์™€ ์–ด๋–ค ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์šฉ๋„์ธ์ง€ ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr>์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ์— ๊ด€ํ•œ ๋ฌธ์„œ</a>๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
๊ฐ ์ƒํƒœ ์ฝ”๋“œ์™€ ์–ด๋–ค ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์šฉ๋„์ธ์ง€ ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - ๋ชจ์งˆ๋ผ ๊ฐœ๋ฐœ์ž ๋„คํŠธ์›Œํฌ">MDN</abbr>์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ์— ๊ด€ํ•œ ๋ฌธ์„œ</a>๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
///
@ -74,7 +74,7 @@ HTTP์—์„œ๋Š” ์‘๋‹ต์˜ ์ผ๋ถ€๋กœ 3์ž๋ฆฌ ์ˆซ์ž ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
์ด์ „ ์˜ˆ์‹œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
`201` ์€ "์ƒ์„ฑ๋จ"์„ ์œ„ํ•œ ์ƒํƒœ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
@ -82,7 +82,7 @@ HTTP์—์„œ๋Š” ์‘๋‹ต์˜ ์ผ๋ถ€๋กœ 3์ž๋ฆฌ ์ˆซ์ž ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
`fastapi.status` ์˜ ํŽธ์˜ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
์ด๊ฒƒ๋“ค์€ ๋‹จ์ง€ ํŽธ์˜๋ฅผ ์œ„ํ•œ ๊ฒƒ์œผ๋กœ, ๋™์ผํ•œ ์ˆซ์ž๋ฅผ ๊ฐ–๊ณ  ์žˆ์ง€๋งŒ, ์ด๋ฅผ ํ†ตํ•ด ํŽธ์ง‘๊ธฐ์˜ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์œผ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

2
docs/ko/docs/tutorial/schema-extra-example.md

@ -74,7 +74,7 @@ Pydantic ๋ชจ๋ธ๊ณผ ๊ฐ™์ด `Field()`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถ”๊ฐ€์ ์ธ `examples`๋ฅผ
์ด์™€ ๊ฐ™์ด ํ•˜๋ฉด ์˜ˆ์ œ๋“ค์€ ๊ทธ ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ์˜ ๋‚ด๋ถ€ **JSON ์Šคํ‚ค๋งˆ**์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์ง€๊ธˆ <abbr title="2023-08-26">์ด ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ๊ฐ„</abbr>์—, ๋ฌธ์„œ UI๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ๋งก์€ Swagger UI๋Š” **JSON ์Šคํ‚ค๋งˆ** ์† ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ์—ฌ๋Ÿฌ ์˜ˆ์ œ์˜ ํ‘œํ˜„์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ๋ฐ‘์—์„œ ์ฝ์–ด๋ณด์„ธ์š”.
๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์ง€๊ธˆ <dfn title="2023-08-26">์ด ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ๊ฐ„</dfn>์—, ๋ฌธ์„œ UI๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ๋งก์€ Swagger UI๋Š” **JSON ์Šคํ‚ค๋งˆ** ์† ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ์—ฌ๋Ÿฌ ์˜ˆ์ œ์˜ ํ‘œํ˜„์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ๋ฐ‘์—์„œ ์ฝ์–ด๋ณด์„ธ์š”.
### OpenAPI-ํŠนํ™” `examples` { #openapi-specific-examples }

6
docs/ko/docs/tutorial/security/first-steps.md

@ -20,7 +20,7 @@
์˜ˆ์ œ๋ฅผ ํŒŒ์ผ `main.py`์— ๋ณต์‚ฌํ•˜์„ธ์š”:
{* ../../docs_src/security/tutorial001_an_py39.py *}
{* ../../docs_src/security/tutorial001_an_py310.py *}
## ์‹คํ–‰ํ•˜๊ธฐ { #run-it }
@ -132,7 +132,7 @@ OAuth2๋Š” backend ๋˜๋Š” API๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•˜๋Š” ์„œ๋ฒ„์™€ ๋…๋ฆฝ์ ์ผ
`OAuth2PasswordBearer` ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ `tokenUrl` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ํด๋ผ์ด์–ธํŠธ(์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋˜๋Š” frontend)๊ฐ€ token์„ ๋ฐ›๊ธฐ ์œ„ํ•ด `username`๊ณผ `password`๋ฅผ ๋ณด๋‚ผ URL์ด ๋“ค์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
/// tip | ํŒ
@ -170,7 +170,7 @@ oauth2_scheme(some, parameters)
์ด์ œ `Depends`๋กœ `oauth2_scheme`๋ฅผ ์˜์กด์„ฑ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
์ด ์˜์กด์„ฑ์€ `str`์„ ์ œ๊ณตํ•˜๊ณ , ๊ทธ ๊ฐ’์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์˜ ํŒŒ๋ผ๋ฏธํ„ฐ `token`์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

2
docs/ko/docs/tutorial/security/get-current-user.md

@ -2,7 +2,7 @@
์ด์ „ ์žฅ์—์„œ (์˜์กด์„ฑ ์ฃผ์ž… ์‹œ์Šคํ…œ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ) ๋ณด์•ˆ ์‹œ์Šคํ…œ์€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์— `str`๋กœ `token`์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
ํ•˜์ง€๋งŒ ์ด๋Š” ์—ฌ์ „ํžˆ ๊ทธ๋‹ค์ง€ ์œ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

26
docs/ko/docs/tutorial/security/oauth2-jwt.md

@ -1,6 +1,6 @@
# ํŒจ์Šค์›Œ๋“œ(ํ•ด์‹ฑ ํฌํ•จ)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” OAuth2, JWT ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” Bearer { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
๋ชจ๋“  ๋ณด์•ˆ ํ๋ฆ„์„ ๊ตฌ์„ฑํ–ˆ์œผ๋ฏ€๋กœ, ์ด์ œ <abbr title="JSON Web Tokens">JWT</abbr> ํ† ํฐ๊ณผ ์•ˆ์ „ํ•œ ํŒจ์Šค์›Œ๋“œ ํ•ด์‹ฑ์„ ์‚ฌ์šฉํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹ค์ œ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ชจ๋“  ๋ณด์•ˆ ํ๋ฆ„์„ ๊ตฌ์„ฑํ–ˆ์œผ๋ฏ€๋กœ, ์ด์ œ <abbr title="JSON ์›น ํ† ํฐ">JWT</abbr> ํ† ํฐ๊ณผ ์•ˆ์ „ํ•œ ํŒจ์Šค์›Œ๋“œ ํ•ด์‹ฑ์„ ์‚ฌ์šฉํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹ค์ œ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.
์ด ์ฝ”๋“œ๋Š” ์‹ค์ œ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŒจ์Šค์›Œ๋“œ ํ•ด์‹œ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -42,7 +42,7 @@ $ pip install pyjwt
</div>
/// info
/// info | ์ •๋ณด
RSA๋‚˜ ECDSA ๊ฐ™์€ ์ „์ž ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ๊ณ„ํš์ด๋ผ๋ฉด, cryptography ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ์ธ `pyjwt[crypto]`๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@ -84,7 +84,7 @@ $ pip install "pwdlib[argon2]"
</div>
/// tip
/// tip | ํŒ
`pwdlib`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด **Django**, **Flask** ๋ณด์•ˆ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋˜๋Š” ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ ๋„๊ตฌ๋กœ ์ƒ์„ฑํ•œ ํŒจ์Šค์›Œ๋“œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -100,7 +100,7 @@ $ pip install "pwdlib[argon2]"
๊ถŒ์žฅ ์„ค์ •์œผ๋กœ PasswordHash ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํŒจ์Šค์›Œ๋“œ๋ฅผ ํ•ด์‹ฑํ•˜๊ณ  ๊ฒ€์ฆํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
/// tip
/// tip | ํŒ
pwdlib๋Š” bcrypt ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋„ ์ง€์›ํ•˜์ง€๋งŒ ๋ ˆ๊ฑฐ์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ค๋ž˜๋œ ํ•ด์‹œ๋กœ ์ž‘์—…ํ•ด์•ผ ํ•œ๋‹ค๋ฉด passlib ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
@ -116,9 +116,13 @@ pwdlib๋Š” bcrypt ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋„ ์ง€์›ํ•˜์ง€๋งŒ ๋ ˆ๊ฑฐ์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
/// note
`authenticate_user`๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž์ด๋ฆ„์œผ๋กœ ํ˜ธ์ถœ๋˜๋”๋ผ๋„, ์—ฌ์ „ํžˆ `verify_password`๋ฅผ ๋”๋ฏธ ํ•ด์‹œ์— ๋Œ€ํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž์ด๋ฆ„์ด ์œ ํšจํ•˜๋“  ์•„๋‹ˆ๋“  ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์‘๋‹ตํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด ๋Œ€๋žต ๋™์ผํ•ด์ ธ, ๊ธฐ์กด ์‚ฌ์šฉ์ž์ด๋ฆ„์„ ์—ด๊ฑฐํ•˜๋Š” ๋ฐ ์•…์šฉ๋  ์ˆ˜ ์žˆ๋Š” **ํƒ€์ด๋ฐ ๊ณต๊ฒฉ**์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
/// note | ์ฐธ๊ณ 
์ƒˆ๋กœ์šด (๊ฐ€์งœ) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค `fake_users_db`๋ฅผ ํ™•์ธํ•˜๋ฉด, ์ด์ œ ํ•ด์‹œ ์ฒ˜๋ฆฌ๋œ ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
@ -152,7 +156,7 @@ JWT ํ† ํฐ์„ ์„œ๋ช…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์œ„ํ•œ ๋ณ€์ˆ˜ `ALGORITH
์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
## ์˜์กด์„ฑ ์—…๋ฐ์ดํŠธ { #update-the-dependencies }
@ -162,7 +166,7 @@ JWT ํ† ํฐ์„ ์„œ๋ช…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์œ„ํ•œ ๋ณ€์ˆ˜ `ALGORITH
ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š๋‹ค๋ฉด ์ฆ‰์‹œ HTTP ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
## `/token` *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์—…๋ฐ์ดํŠธ { #update-the-token-path-operation }
@ -170,7 +174,7 @@ JWT ํ† ํฐ์„ ์„œ๋ช…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์œ„ํ•œ ๋ณ€์ˆ˜ `ALGORITH
์‹ค์ œ JWT ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
### JWT "์ฃผ์ฒด(subject)" `sub`์— ๋Œ€ํ•œ ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ { #technical-details-about-the-jwt-subject-sub }
@ -209,7 +213,7 @@ JWT๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ API์—์„œ ์ง์ ‘ ์ž‘์—…์„ ์ˆ˜ํ–‰
Username: `johndoe`
Password: `secret`
/// check
/// check | ํ™•์ธ
์ฝ”๋“œ ์–ด๋””์—๋„ ํ‰๋ฌธ ํŒจ์Šค์›Œ๋“œ "`secret`"์€ ์—†๊ณ , ํ•ด์‹œ๋œ ๋ฒ„์ „๋งŒ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค.
@ -234,7 +238,7 @@ Password: `secret`
<img src="/img/tutorial/security/image10.png">
/// note
/// note | ์ฐธ๊ณ 
`Bearer `๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ’์„ ๊ฐ€์ง„ `Authorization` ํ—ค๋”์— ์ฃผ๋ชฉํ•˜์‹ญ์‹œ์˜ค.

4
docs/ko/docs/tutorial/security/simple-oauth2.md

@ -162,7 +162,7 @@ UserInDB(
/// tip | ํŒ
๋‹ค์Œ ์žฅ์—์„œ๋Š” ํŒจ์Šค์›Œ๋“œ ํ•ด์‹ฑ ๋ฐ <abbr title="JSON Web Tokens">JWT</abbr> ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ณด์•ˆ ๊ตฌํ˜„์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ ์žฅ์—์„œ๋Š” ํŒจ์Šค์›Œ๋“œ ํ•ด์‹ฑ ๋ฐ <abbr title="JSON Web Tokens - JSON ์›น ํ† ํฐ">JWT</abbr> ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ณด์•ˆ ๊ตฌํ˜„์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ ํ•„์š”ํ•œ ์„ธ๋ถ€ ์ •๋ณด์— ์ง‘์ค‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
@ -286,4 +286,4 @@ UserInDB(
์œ ์ผํ•œ ์˜ค์ ์€ ์•„์ง ์‹ค์ œ๋กœ "์•ˆ์ „"ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‹ค์Œ ์žฅ์—์„œ๋Š” ์•ˆ์ „ํ•œ ํŒจ์Šค์›Œ๋“œ ํ•ด์‹ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ <abbr title="JSON Web Tokens">JWT</abbr> ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ ์žฅ์—์„œ๋Š” ์•ˆ์ „ํ•œ ํŒจ์Šค์›Œ๋“œ ํ•ด์‹ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ <abbr title="JSON Web Tokens - JSON ์›น ํ† ํฐ">JWT</abbr> ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

2
docs/ko/docs/tutorial/sql-databases.md

@ -8,7 +8,7 @@
/// tip | ํŒ
๋‹ค๋ฅธ SQL ๋˜๋Š” NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค (์ผ๋ถ€๋Š” <abbr title="Object Relational Mapper: a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">"ORMs"</abbr>์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค), FastAPI๋Š” ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ ๊ฐ•์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
๋‹ค๋ฅธ SQL ๋˜๋Š” NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค (์ผ๋ถ€๋Š” <abbr title="Object Relational Mapper - ๊ฐ์ฒด-๊ด€๊ณ„ ๋งคํผ: ์ผ๋ถ€ ํด๋ž˜์Šค๋Š” SQL ํ…Œ์ด๋ธ”์„, ์ธ์Šคํ„ด์Šค๋Š” ํ•ด๋‹น ํ…Œ์ด๋ธ”์˜ ํ–‰์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์šฉ์–ด">"ORMs"</abbr>์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค), FastAPI๋Š” ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ ๊ฐ•์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
///

2
docs/ko/docs/tutorial/static-files.md

@ -7,7 +7,7 @@
* `StaticFiles`๋ฅผ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค.
* ํŠน์ • ๊ฒฝ๋กœ์— `StaticFiles()` ์ธ์Šคํ„ด์Šค๋ฅผ "๋งˆ์šดํŠธ"ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ

12
docs/ko/docs/tutorial/testing.md

@ -2,7 +2,7 @@
<a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a> ๋•๋ถ„์— **FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ์ผ์€ ์‰ฝ๊ณ  ์ฆ๊ฑฐ์šด ์ผ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
Starlette๋Š” <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ์ด๋Š” Requests๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์นœ์ˆ™ํ•˜๊ณ  ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค.
์ด๋Š” <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ์ด๋Š” Requests๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์นœ์ˆ™ํ•˜๊ณ  ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค.
์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด **FastAPI**์—์„œ <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a>๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -30,7 +30,7 @@ $ pip install httpx
ํ‘œ์ค€์ ์ธ ํŒŒ์ด์ฌ ํ‘œํ˜„์‹์œผ๋กœ ํ™•์ธ์ด ํ•„์š”ํ•œ ๊ณณ์— ๊ฐ„๋‹จํ•œ `assert` ๋ฌธ์žฅ์„ ์ž‘์„ฑํ•˜์„ธ์š”(์—ญ์‹œ ํ‘œ์ค€์ ์ธ `pytest` ๊ด€๋ก€์ž…๋‹ˆ๋‹ค).
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
/// tip | ํŒ
@ -42,7 +42,7 @@ $ pip install httpx
///
/// note Technical Details | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
`from starlette.testclient import TestClient` ์—ญ์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -76,7 +76,7 @@ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ ์™ธ์—๋„ ํ…Œ์ŠคํŠธ์—์„œ
`main.py` ํŒŒ์ผ ์•ˆ์— **FastAPI** app ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/app_testing/app_a_py39/main.py *}
{* ../../docs_src/app_testing/app_a_py310/main.py *}
### ํ…Œ์ŠคํŠธ ํŒŒ์ผ { #testing-file }
@ -92,7 +92,7 @@ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ ์™ธ์—๋„ ํ…Œ์ŠคํŠธ์—์„œ
ํŒŒ์ผ๋“ค์ด ๋™์ผํ•œ ํŒจํ‚ค์ง€์— ์œ„์น˜ํ•ด ์žˆ์œผ๋ฏ€๋กœ, ์ƒ๋Œ€ ์ž„ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ `main` ๋ชจ๋“ˆ(`main.py`)์—์„œ `app` ๊ฐ์ฒด๋ฅผ ์ž„ํฌํŠธ ํ•ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
...๊ทธ๋ฆฌ๊ณ  ์ด์ „์— ์ž‘์„ฑํ–ˆ๋˜ ๊ฒƒ๊ณผ ๊ฐ™์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -115,7 +115,7 @@ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ ์™ธ์—๋„ ํ…Œ์ŠคํŠธ์—์„œ
์ด์ œ **FastAPI** ์•ฑ์ด ์žˆ๋Š” `main.py` ํŒŒ์ผ์— ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ **๊ฒฝ๋กœ ์ฒ˜๋ฆฌ**๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.
๋‹จ์ผ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” `GET` ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” `GET` ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” `POST` ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

24
docs/ko/docs/virtual-environments.md

@ -37,15 +37,15 @@ Python ์„ค์น˜๊นŒ์ง€ ํฌํ•จํ•ด **๋ชจ๋“  ๊ฒƒ์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๋„๊ตฌ**๋ฅผ ๋„์ž…
<div class="termy">
```console
// Go to the home directory
// ํ™ˆ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™
$ cd
// Create a directory for all your code projects
// ๋ชจ๋“  ์ฝ”๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ƒ์„ฑ
$ mkdir code
// Enter into that code directory
// ๊ทธ code ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™
$ cd code
// Create a directory for this project
// ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ƒ์„ฑ
$ mkdir awesome-project
// Enter into that project directory
// ๊ทธ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™
$ cd awesome-project
```
@ -53,7 +53,7 @@ $ cd awesome-project
## ๊ฐ€์ƒ ํ™˜๊ฒฝ ์ƒ์„ฑ { #create-a-virtual-environment }
Python ํ”„๋กœ์ ํŠธ๋ฅผ **์ฒ˜์Œ ์‹œ์ž‘ํ•  ๋•Œ**, **<abbr title="๋‹ค๋ฅธ ์˜ต์…˜๋„ ์žˆ์ง€๋งŒ, ์ด๊ฒƒ์€ ๊ฐ„๋‹จํ•œ ๊ฐ€์ด๋“œ๋ผ์ธ์ž…๋‹ˆ๋‹ค">ํ”„๋กœ์ ํŠธ ๋‚ด๋ถ€</abbr>**์— ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•˜์„ธ์š”.
Python ํ”„๋กœ์ ํŠธ๋ฅผ **์ฒ˜์Œ ์‹œ์ž‘ํ•  ๋•Œ**, ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ **<dfn title="๋‹ค๋ฅธ ์˜ต์…˜๋„ ์žˆ์ง€๋งŒ, ์ด๊ฒƒ์€ ๊ฐ„๋‹จํ•œ ๊ฐ€์ด๋“œ๋ผ์ธ์ž…๋‹ˆ๋‹ค">ํ”„๋กœ์ ํŠธ ๋‚ด๋ถ€</dfn>**์— ์ƒ์„ฑํ•˜์„ธ์š”.
/// tip
@ -166,7 +166,7 @@ $ source .venv/Scripts/activate
ํ•ด๋‹น ํ™˜๊ฒฝ์— **์ƒˆ ํŒจํ‚ค์ง€**๋ฅผ ์„ค์น˜ํ•  ๋•Œ๋งˆ๋‹ค, ํ™˜๊ฒฝ์„ ๋‹ค์‹œ **ํ™œ์„ฑํ™”**ํ•˜์„ธ์š”.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๋‹น ํŒจํ‚ค์ง€๊ฐ€ ์„ค์น˜ํ•œ **ํ„ฐ๋ฏธ๋„(<abbr title="command line interface">CLI</abbr>) ํ”„๋กœ๊ทธ๋žจ**์„ ์‚ฌ์šฉํ•  ๋•Œ, ์ „์—ญ์œผ๋กœ ์„ค์น˜๋˜์–ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋Š”(์•„๋งˆ ํ•„์š”ํ•œ ๋ฒ„์ „๊ณผ๋Š” ๋‹ค๋ฅธ ๋ฒ„์ „์ธ) ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด ์•„๋‹ˆ๋ผ ๊ฐ€์ƒ ํ™˜๊ฒฝ์— ์žˆ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๋‹น ํŒจํ‚ค์ง€๊ฐ€ ์„ค์น˜ํ•œ **ํ„ฐ๋ฏธ๋„(<abbr title="command line interface - ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค">CLI</abbr>) ํ”„๋กœ๊ทธ๋žจ**์„ ์‚ฌ์šฉํ•  ๋•Œ, ์ „์—ญ์œผ๋กœ ์„ค์น˜๋˜์–ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋Š”(์•„๋งˆ ํ•„์š”ํ•œ ๋ฒ„์ „๊ณผ๋Š” ๋‹ค๋ฅธ ๋ฒ„์ „์ธ) ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด ์•„๋‹ˆ๋ผ ๊ฐ€์ƒ ํ™˜๊ฒฝ์— ์žˆ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
///
@ -557,7 +557,7 @@ Python์„ ์„ค์น˜ํ•˜๋ฉด ์ปดํ“จํ„ฐ์— ๋ช‡๋ช‡ ํŒŒ์ผ์ด ๋“ค์–ด ์žˆ๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ
<div class="termy">
```console
// Don't run this now, it's just an example ๐Ÿค“
// ์ง€๊ธˆ์€ ์‹คํ–‰ํ•˜์ง€ ๋งˆ์„ธ์š”, ์˜ˆ์‹œ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค ๐Ÿค“
$ pip install "fastapi[standard]"
---> 100%
```
@ -811,7 +811,7 @@ $ cd ~/code/prisoner-of-azkaban
$ python main.py
// Error importing sirius, it's not installed ๐Ÿ˜ฑ
// sirius ์ž„ํฌํŠธ ์˜ค๋ฅ˜, ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๐Ÿ˜ฑ
Traceback (most recent call last):
File "main.py", line 1, in <module>
import sirius
@ -826,13 +826,13 @@ Traceback (most recent call last):
```console
$ cd ~/code/prisoner-of-azkaban
// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project ๐Ÿ˜Ž
// ๋น„ํ™œ์„ฑํ™”๋ฅผ ์œ„ํ•ด ์ด์ „ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ์„ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์–ด๋””์„œ๋“ , ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋กœ ์ด๋™ํ•œ ๋’ค์—๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜Ž
$ deactivate
// Activate the virtual environment in prisoner-of-azkaban/.venv ๐Ÿš€
// prisoner-of-azkaban/.venv์˜ ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ํ™œ์„ฑํ™”ํ•˜์„ธ์š” ๐Ÿš€
$ source .venv/bin/activate
// Now when you run python, it will find the package sirius installed in this virtual environment โœจ
// ์ด์ œ python์„ ์‹คํ–‰ํ•˜๋ฉด, ์ด ๊ฐ€์ƒ ํ™˜๊ฒฝ์— ์„ค์น˜๋œ sirius ํŒจํ‚ค์ง€๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค โœจ
$ python main.py
I solemnly swear ๐Ÿบ

Loadingโ€ฆ
Cancel
Save