Browse Source

Merge remote-tracking branch 'upstream/master' into fix-links

pull/15967/head
Yurii Motov 3 days ago
parent
commit
832c22b795
  1. 21
      .github/dependabot.yml
  2. 6
      .github/workflows/build-docs.yml
  3. 67
      .github/workflows/bump-pre-commit-hooks.yml
  4. 56
      .github/workflows/contributors.yml
  5. 2
      .github/workflows/create-draft-release.yml
  6. 2
      .github/workflows/deploy-docs.yml
  7. 2
      .github/workflows/label-approved.yml
  8. 2
      .github/workflows/labeler.yml
  9. 2
      .github/workflows/notify-translations.yml
  10. 57
      .github/workflows/people.yml
  11. 2
      .github/workflows/pre-commit.yml
  12. 2
      .github/workflows/prepare-release.yml
  13. 2
      .github/workflows/publish.yml
  14. 2
      .github/workflows/smokeshow.yml
  15. 2
      .github/workflows/sponsors.yml
  16. 8
      .github/workflows/test.yml
  17. 2
      .github/workflows/topic-repos.yml
  18. 4
      .github/workflows/translate.yml
  19. 2
      .pre-commit-config.yaml
  20. 6
      docs/de/docs/tutorial/frontend.md
  21. 18
      docs/en/data/members.yml
  22. 1
      docs/en/data/skip_users.yml
  23. 1
      docs/en/data/topic_repos.yml
  24. 2
      docs/en/docs/external-links.md
  25. 169
      docs/en/docs/fastapi-people.md
  26. 20
      docs/en/docs/help-fastapi.md
  27. 10
      docs/en/docs/management.md
  28. 44
      docs/en/docs/release-notes.md
  29. 2
      docs/en/docs/tutorial/frontend.md
  30. 2
      docs/en/mkdocs.yml
  31. 6
      docs/es/docs/tutorial/frontend.md
  32. 6
      docs/fr/docs/tutorial/frontend.md
  33. 3
      docs/hi/docs/about/index.md
  34. 247
      docs/hi/docs/advanced/additional-responses.md
  35. 41
      docs/hi/docs/advanced/additional-status-codes.md
  36. 163
      docs/hi/docs/advanced/advanced-dependencies.md
  37. 61
      docs/hi/docs/advanced/advanced-python-types.md
  38. 99
      docs/hi/docs/advanced/async-tests.md
  39. 466
      docs/hi/docs/advanced/behind-a-proxy.md
  40. 273
      docs/hi/docs/advanced/custom-response.md
  41. 95
      docs/hi/docs/advanced/dataclasses.md
  42. 165
      docs/hi/docs/advanced/events.md
  43. 192
      docs/hi/docs/advanced/generate-clients.md
  44. 21
      docs/hi/docs/advanced/index.md
  45. 63
      docs/hi/docs/advanced/json-base64-bytes.md
  46. 97
      docs/hi/docs/advanced/middleware.md
  47. 186
      docs/hi/docs/advanced/openapi-callbacks.md
  48. 55
      docs/hi/docs/advanced/openapi-webhooks.md
  49. 166
      docs/hi/docs/advanced/path-operation-advanced-configuration.md
  50. 31
      docs/hi/docs/advanced/response-change-status-code.md
  51. 51
      docs/hi/docs/advanced/response-cookies.md
  52. 83
      docs/hi/docs/advanced/response-directly.md
  53. 41
      docs/hi/docs/advanced/response-headers.md
  54. 107
      docs/hi/docs/advanced/security/http-basic-auth.md
  55. 19
      docs/hi/docs/advanced/security/index.md
  56. 274
      docs/hi/docs/advanced/security/oauth2-scopes.md
  57. 302
      docs/hi/docs/advanced/settings.md
  58. 117
      docs/hi/docs/advanced/stream-data.md
  59. 88
      docs/hi/docs/advanced/strict-content-type.md
  60. 67
      docs/hi/docs/advanced/sub-applications.md
  61. 126
      docs/hi/docs/advanced/templates.md
  62. 53
      docs/hi/docs/advanced/testing-dependencies.md
  63. 12
      docs/hi/docs/advanced/testing-events.md
  64. 13
      docs/hi/docs/advanced/testing-websockets.md
  65. 56
      docs/hi/docs/advanced/using-request-directly.md
  66. 186
      docs/hi/docs/advanced/websockets.md
  67. 51
      docs/hi/docs/advanced/wsgi.md
  68. 24
      docs/hi/docs/deployment/cloud.md
  69. 321
      docs/hi/docs/deployment/concepts.md
  70. 618
      docs/hi/docs/deployment/docker.md
  71. 47
      docs/hi/docs/deployment/fastapicloud.md
  72. 231
      docs/hi/docs/deployment/https.md
  73. 23
      docs/hi/docs/deployment/index.md
  74. 156
      docs/hi/docs/deployment/manually.md
  75. 139
      docs/hi/docs/deployment/server-workers.md
  76. 93
      docs/hi/docs/deployment/versions.md
  77. 298
      docs/hi/docs/environment-variables.md
  78. 87
      docs/hi/docs/help-fastapi.md
  79. 17
      docs/hi/docs/how-to/authentication-error-status-code.md
  80. 56
      docs/hi/docs/how-to/conditional-openapi.md
  81. 70
      docs/hi/docs/how-to/configure-swagger-ui.md
  82. 185
      docs/hi/docs/how-to/custom-docs-ui-assets.md
  83. 109
      docs/hi/docs/how-to/custom-request-and-route.md
  84. 88
      docs/hi/docs/how-to/extending-openapi.md
  85. 43
      docs/hi/docs/how-to/general.md
  86. 60
      docs/hi/docs/how-to/graphql.md
  87. 13
      docs/hi/docs/how-to/index.md
  88. 153
      docs/hi/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
  89. 102
      docs/hi/docs/how-to/separate-openapi-schemas.md
  90. 7
      docs/hi/docs/how-to/testing-database.md
  91. 5
      docs/hi/docs/learn/index.md
  92. 3
      docs/hi/docs/resources/index.md
  93. 86
      docs/hi/docs/tutorial/background-tasks.md
  94. 547
      docs/hi/docs/tutorial/bigger-applications.md
  95. 61
      docs/hi/docs/tutorial/body-fields.md
  96. 169
      docs/hi/docs/tutorial/body-multiple-params.md
  97. 221
      docs/hi/docs/tutorial/body-nested-models.md
  98. 100
      docs/hi/docs/tutorial/body-updates.md
  99. 166
      docs/hi/docs/tutorial/body.md
  100. 76
      docs/hi/docs/tutorial/cookie-param-models.md

21
.github/dependabot.yml

@ -4,7 +4,7 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
cooldown:
default-days: 7
commit-message:
@ -21,7 +21,7 @@ updates:
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
cooldown:
default-days: 7
commit-message:
@ -31,20 +31,3 @@ updates:
dependency-type: "development"
patterns:
- "*"
# pre-commit
- package-ecosystem: "pre-commit"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7
commit-message:
prefix:
labels:
- "internal"
- "dependencies"
- "pre-commit"
groups:
pre-commit:
patterns:
- "*"

6
.github/workflows/build-docs.yml

@ -21,7 +21,7 @@ jobs:
with:
persist-credentials: false
# For pull requests it's not necessary to checkout the code but for the main branch it is
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
id: filter
with:
filters: |
@ -51,7 +51,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
@ -90,7 +90,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

67
.github/workflows/bump-pre-commit-hooks.yml

@ -0,0 +1,67 @@
name: Bump pre-commit hooks
on:
schedule:
- cron: "0 12 1 * *"
workflow_dispatch:
permissions: {}
jobs:
bump-pre-commit-hooks:
if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
persist-credentials: true
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.18"
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Bump pre-commit hooks
run: uv run prek auto-update --freeze --cooldown-days 7
- name: Create pull request
env:
GH_TOKEN: ${{ secrets.FASTAPI_LATEST_CHANGES }}
BASE_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -euo pipefail
if git diff --quiet; then
echo "No pre-commit hook updates available"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
branch="bump-pre-commit-hooks"
git switch -C "$branch"
git add .pre-commit-config.yaml
git commit -m "⬆ Bump pre-commit hooks"
git push --force origin "$branch"
if [ -z "$(gh pr list --head "$branch" --state open --json number --jq '.[].number')" ]; then
gh pr create \
--base "$BASE_BRANCH" \
--head "$branch" \
--title "⬆ Bump pre-commit hooks" \
--body "Bump pre-commit hook versions via \`prek auto-update --freeze --cooldown-days 7\`." \
--label internal \
--label dependencies \
--label pre-commit
else
echo "PR for \"$branch\" already open; branch updated in place."
fi

56
.github/workflows/contributors.yml

@ -1,56 +0,0 @@
name: FastAPI People Contributors
on:
schedule:
- cron: "0 3 1 * *"
workflow_dispatch:
inputs:
debug_enabled:
description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
required: false
default: "false"
permissions: {}
jobs:
job:
if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: true # Required for `git push` in `contributors.py`
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.18"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3.24
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]
- name: FastAPI People Contributors
run: uv run ./scripts/contributors.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]

2
.github/workflows/create-draft-release.yml

@ -31,7 +31,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/deploy-docs.yml

@ -30,7 +30,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/label-approved.yml

@ -27,7 +27,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/labeler.yml

@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
- run: echo "Done adding labels"
# Run this after labeler applied labels

2
.github/workflows/notify-translations.yml

@ -39,7 +39,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

57
.github/workflows/people.yml

@ -1,57 +0,0 @@
name: FastAPI People
on:
schedule:
- cron: "0 14 1 * *"
workflow_dispatch:
inputs:
debug_enabled:
description: Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
required: false
default: "false"
permissions: {}
jobs:
job:
if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: true # Required for `git push` in `people.py`
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.18"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3.24
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }} # zizmor: ignore[secrets-outside-env]
- name: FastAPI People Experts
run: uv run ./scripts/people.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }} # zizmor: ignore[secrets-outside-env]
SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}

2
.github/workflows/pre-commit.yml

@ -43,7 +43,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/prepare-release.yml

@ -43,7 +43,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/publish.yml

@ -27,7 +27,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/smokeshow.yml

@ -26,7 +26,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/sponsors.yml

@ -32,7 +32,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

8
.github/workflows/test.yml

@ -30,7 +30,7 @@ jobs:
with:
persist-credentials: false
# For pull requests it's not necessary to checkout the code but for the main branch it is
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
id: filter
with:
filters: |
@ -115,7 +115,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
@ -179,7 +179,7 @@ jobs:
with:
python-version: "3.13"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
@ -213,7 +213,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.github/workflows/topic-repos.yml

@ -27,7 +27,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

4
.github/workflows/translate.yml

@ -58,7 +58,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
@ -101,7 +101,7 @@ jobs:
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837

2
.pre-commit-config.yaml

@ -15,7 +15,7 @@ repos:
- id: trailing-whitespace
- repo: https://github.com/crate-ci/typos
rev: 37bb98842b0d8c4ffebdb75301a13db0267cef89 # v1.47.2
rev: bee27e3a4fd1ea2111cf90ab89cd076c870fce14 # frozen: v1.48.0
hooks:
- id: typos
args: [--force-exclude]

6
docs/de/docs/tutorial/frontend.md

@ -126,6 +126,12 @@ In diesem Beispiel werden Frontend-Pfade unter `/app` bereitgestellt.
Alle regulären *Pfadoperationen* in der App haben weiterhin Vorrang, auch in anderen Routern.
## Abhängigkeiten und Middleware { #dependencies-and-middleware }
Frontend-Responses laufen innerhalb der normalen **FastAPI**-Anwendung, daher gilt HTTP-Middleware für sie.
Abhängigkeiten aus der App, aus einem `APIRouter` und aus `include_router()` gelten ebenfalls für Frontend-Responses. Das kann nützlich sein, um ein Frontend mit Cookie-Authentifizierung oder Ähnlichem zu schützen.
## Nur statischer Build-Output { #static-build-output-only }
`app.frontend()` liefert Dateien aus, die bereits von Ihrem Frontend-Build generiert wurden.

18
docs/en/data/members.yml

@ -2,21 +2,21 @@ members:
- login: tiangolo
avatar_url: https://avatars.githubusercontent.com/u/1326112
url: https://github.com/tiangolo
- login: Kludex
avatar_url: https://avatars.githubusercontent.com/u/7353520
url: https://github.com/Kludex
- login: alejsdev
avatar_url: https://avatars.githubusercontent.com/u/90076947
url: https://github.com/alejsdev
- login: svlandeg
avatar_url: https://avatars.githubusercontent.com/u/8796347
url: https://github.com/svlandeg
- login: YuriiMotov
avatar_url: https://avatars.githubusercontent.com/u/109919500
url: https://github.com/YuriiMotov
- login: svlandeg
avatar_url: https://avatars.githubusercontent.com/u/8796347
url: https://github.com/svlandeg
- login: alejsdev
avatar_url: https://avatars.githubusercontent.com/u/90076947
url: https://github.com/alejsdev
- login: patrick91
avatar_url: https://avatars.githubusercontent.com/u/667029
url: https://github.com/patrick91
- login: luzzodev
avatar_url: https://avatars.githubusercontent.com/u/27291415
url: https://github.com/luzzodev
- login: Kludex
avatar_url: https://avatars.githubusercontent.com/u/7353520
url: https://github.com/Kludex

1
docs/en/data/skip_users.yml

@ -1,3 +1,4 @@
users:
- tiangolo
- codecov
- github-actions

1
docs/en/data/topic_repos.yml

@ -1,3 +1,4 @@
repos:
- name: headroom
html_url: https://github.com/headroomlabs-ai/headroom
stars: 55017

2
docs/en/docs/external-links.md

@ -23,7 +23,7 @@ But now that FastAPI is the backend framework with the most GitHub stars across
Most starred [GitHub repositories with the topic `fastapi`](https://github.com/topics/fastapi):
{% for repo in topic_repos %}
{% for repo in topic_repos.repos %}
<a href={{repo.html_url}} target="_blank">★ {{repo.stars}} - {{repo.name}}</a> by <a href={{repo.owner_html_url}} target="_blank">@{{repo.owner_login}}</a>.

169
docs/en/docs/fastapi-people.md

@ -1,7 +1,4 @@
---
hide:
- navigation
include_yaml:
github_sponsors: data/github_sponsors.yml
people: data/people.yml
@ -33,22 +30,6 @@ This is me:
I'm the creator of **FastAPI**. You can read more about that in [Help FastAPI - Follow the author](help-fastapi.md#follow-the-author).
...But here I want to show you the community.
---
**FastAPI** receives a lot of support from the community. And I want to highlight their contributions.
These are the people that:
* [Help others with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github).
* Create or review Pull Requests.
* Help [manage the repository](https://tiangolo.com/open-source/management-tasks/) (team members).
All these tasks help maintain the repository.
A round of applause to them. 👏 🙇
## Team
This is the current list of team members. 😎
@ -65,113 +46,19 @@ They have different levels of involvement and permissions, they can perform [rep
</div>
Although the team members have the permissions to perform privileged tasks, all the help from others maintaining FastAPI is very much appreciated! 🙇‍♂️
## FastAPI Experts
These are the users that have been [helping others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github). 🙇
They have proven to be **FastAPI Experts** by helping many others. ✨
/// tip
You could become an official FastAPI Expert too!
Just [help others with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github). 🤓
///
You can see the **FastAPI Experts** for:
* [Last Month](#fastapi-experts-last-month) 🤓
* [3 Months](#fastapi-experts-3-months) 😎
* [6 Months](#fastapi-experts-6-months) 🧐
* [1 Year](#fastapi-experts-1-year) 🧑‍🔬
* [**All Time**](#fastapi-experts-all-time) 🧙
### FastAPI Experts - Last Month
These are the users that have been [helping others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github) during the last month. 🤓
<div class="user-list user-list-center">
{% for user in people.last_month_experts[:10] %}
{% if user.login not in skip_users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
{% endif %}
{% endfor %}
</div>
### FastAPI Experts - 3 Months
These are the users that have been [helping others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github) during the last 3 months. 😎
<div class="user-list user-list-center">
{% for user in people.three_months_experts[:10] %}
{% if user.login not in skip_users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
{% endif %}
{% endfor %}
</div>
For a long time, answering questions from the community in GitHub Discussions was done by other community volunteers.
### FastAPI Experts - 6 Months
They proved they are **FastAPI Experts** by helping many others. ✨
These are the users that have been [helping others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github) during the last 6 months. 🧐
Here's the hall of fame of the first FastAPI Experts:
<div class="user-list user-list-center">
{% for user in people.six_months_experts[:10] %}
{% for user in people.experts[:30] %}
{% if user.login not in skip_users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
{% endif %}
{% endfor %}
</div>
### FastAPI Experts - 1 Year
These are the users that have been [helping others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github) during the last year. 🧑‍🔬
<div class="user-list user-list-center">
{% for user in people.one_year_experts[:20] %}
{% if user.login not in skip_users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
{% endif %}
{% endfor %}
</div>
### FastAPI Experts - All Time
Here are the all time **FastAPI Experts**. 🤓🤯
These are the users that have [helped others the most with questions in GitHub](help-fastapi.md#help-others-with-questions-in-github) through *all time*. 🧙
<div class="user-list user-list-center">
{% for user in people.experts[:50] %}
{% if user.login not in skip_users %}
{% if user.login not in skip_users.users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div>
@ -183,17 +70,19 @@ These are the users that have [helped others the most with questions in GitHub](
## Top Contributors
Here are the **Top Contributors**. 👷
Currently, most of the code changes in FastAPI are done by the team.
But over the years, there have also been many contributions made by others.
These users have created the most Pull Requests that have been *merged*.
They contributed source code, documentation, etc. 📦
They have contributed source code, documentation, etc. 📦
Here's the hall of fame of the first **Top Contributors**. 👷
<div class="user-list user-list-center">
{% for user in (contributors.values() | list)[:50] %}
{% for user in (contributors.values() | list)[:30] %}
{% if user.login not in skip_users %}
{% if user.login not in skip_users.users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Pull Requests: {{ user.count }}</div></div>
@ -207,14 +96,16 @@ There are hundreds of other contributors, you can see them all in the [FastAPI G
## Top Translation Reviewers
These users are the **Top Translation Reviewers**. 🕵️
Currently, translations are done using AI tools, steered by the FastAPI team and native speakers.
Translation reviewers have the **power to approve translations** of the documentation. Without them, there wouldn't be documentation in several other languages.
At some point, FastAPI had some documentation pages that community members translated into other languages by hand.
Here's the hall of fame of the first **Top Translation Reviewers**. 🕵️
<div class="user-list user-list-center">
{% for user in (translation_reviewers.values() | list)[:50] %}
{% for user in (translation_reviewers.values() | list)[:30] %}
{% if user.login not in skip_users %}
{% if user.login not in skip_users.users %}
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Reviews: {{ user.count }}</div></div>
@ -226,9 +117,7 @@ Translation reviewers have the **power to approve translations** of the document
## Sponsors
These are the **Sponsors**. 😎
They are supporting my work with **FastAPI** (and others), mainly through [GitHub Sponsors](https://github.com/sponsors/tiangolo).
**Sponsors** support **FastAPI** and friends, mainly through [GitHub Sponsors](https://github.com/sponsors/tiangolo). ✨
{% if sponsors %}
@ -283,12 +172,22 @@ They are supporting my work with **FastAPI** (and others), mainly through [GitHu
## About the data - technical details
The main intention of this page is to highlight the effort of the community to help others.
The main intention of this page has been to highlight the effort of the community to help others, especially efforts that were normally less visible and, in many cases, more arduous, like helping others with questions and reviewing Pull Requests with translations.
It also highlights contributions from sponsors.
The data used to be calculated continuously, each month.
As of July 2026, most of the work has been done by (paid) team members for quite some time.
GitHub Discussions are answered mostly by team members.
Most of the code changes are done by team members.
Especially including efforts that are normally less visible, and in many cases more arduous, like helping others with questions and reviewing Pull Requests with translations.
And translations are continuously done for the entire documentation in multiple languages, using AI tools, managed by team members.
The data is calculated each month, you can read the [source code here](https://github.com/fastapi/fastapi/tree/master/scripts).
Additionally, in recent months, there's been an overwhelming amount of AI spam, mainly to cheat the FastAPI Experts system or to get a PR merged by any means and thereby be considered a contributor. You can read more about the point of view in [Automated Code and AI](https://tiangolo.com/open-source/contributing/#automated-code-and-ai).
Here I'm also highlighting contributions from sponsors.
Because of this, the data for the FastAPI Experts, Top Contributors, and Top Translation Reviewers is no longer continuously updated.
I also reserve the right to update the algorithm, sections, thresholds, etc (just in case 🤷).
This section is currently kept as a tribute to the humans that helped shape what FastAPI is today. 🙌

20
docs/en/docs/help-fastapi.md

@ -45,20 +45,6 @@ You can follow [me (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com), th
* [@tiangolo.com on **Bluesky**](https://bsky.app/profile/tiangolo.com)
* [@tiangolo on **LinkedIn**](https://www.linkedin.com/in/tiangolo/).
## Help others with questions in GitHub { #help-others-with-questions-in-github }
You can try and help others with their questions in [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered).
In many cases you might already know the answer for those questions. 🤓
If you are helping a lot of people with their questions, you will become an official [FastAPI Expert](fastapi-people.md#fastapi-experts). 🎉
Just remember, the most important point is: try to be kind. 🤗
### How to Help { #how-to-help }
Follow the [guide on how to help](https://tiangolo.com/open-source/help/#help-others-with-questions-in-github) here.
## Ask Questions { #ask-questions }
You can [create a new question](https://github.com/fastapi/fastapi/discussions/new?category=questions) in the GitHub repository, for example to:
@ -85,3 +71,9 @@ Keep in mind that as chats allow more "free conversation", it's easy to ask ques
In GitHub, the template will guide you to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking.
Conversations in the chat systems are also not as easily searchable as in GitHub, they get lost.
## Try FastAPI Cloud { #try-fastapi-cloud }
The main funding for FastAPI and friends comes from [**FastAPI Cloud**](https://fastapicloud.com), a platform to deploy FastAPI applications in a simple and fast way, with a single command, `fastapi deploy`.
FastAPI Cloud is built by the same team behind FastAPI. You can try it and consider it for your projects.

10
docs/en/docs/management.md

@ -13,13 +13,3 @@ I normally give the final review to each PR before merging them. I make the fina
There's a team of people that help manage and maintain the project. 😎
Learn more about it in [tiangolo.com - GitHub FastAPI](https://tiangolo.com/github-fastapi/).
## FastAPI Experts
The people that help others the most in GitHub Discussions can become [**FastAPI Experts**](./fastapi-people.md#fastapi-experts).
This is normally the best way to contribute to the project.
## External Help
External help is very much appreciated. There are many ways to [help](./help-fastapi.md). ☕️

44
docs/en/docs/release-notes.md

@ -7,14 +7,58 @@ hide:
## Latest Changes
### Docs
* 📝 Restructure FastAPI People and related pages. PR [#16015](https://github.com/fastapi/fastapi/pull/16015) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔥 Remove now-obsolete scripts to generate data for FastAPI People. PR [#16016](https://github.com/fastapi/fastapi/pull/16016) by [@tiangolo](https://github.com/tiangolo).
## 0.139.2 (2026-07-16)
### Fixes
* 🐛 Refactor router route building to make it thread-safe, mainly relevant for tests running in parallel threads (uncommon). PR [#16013](https://github.com/fastapi/fastapi/pull/16013) by [@tiangolo](https://github.com/tiangolo).
## 0.139.1 (2026-07-16)
### Fixes
* 🐛 Fix frontend fallback support for doted paths like `/users/john.doe`. PR [#16011](https://github.com/fastapi/fastapi/pull/16011) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Fix topic repository list not being displayed and `skip_users` not being applied. PR [#15995](https://github.com/fastapi/fastapi/pull/15995) by [@YuriiMotov](https://github.com/YuriiMotov).
### Translations
* 🌐 Update translations for tr (update-outdated). PR [#16005](https://github.com/fastapi/fastapi/pull/16005) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh-hant (update-outdated). PR [#15996](https://github.com/fastapi/fastapi/pull/15996) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for fr (update-outdated). PR [#16006](https://github.com/fastapi/fastapi/pull/16006) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for de (update-outdated). PR [#15999](https://github.com/fastapi/fastapi/pull/15999) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (update-outdated). PR [#16004](https://github.com/fastapi/fastapi/pull/16004) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh (update-outdated). PR [#16001](https://github.com/fastapi/fastapi/pull/16001) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (update-outdated). PR [#16003](https://github.com/fastapi/fastapi/pull/16003) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ja (update-outdated). PR [#15998](https://github.com/fastapi/fastapi/pull/15998) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (update-outdated). PR [#16000](https://github.com/fastapi/fastapi/pull/16000) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (update-outdated). PR [#15997](https://github.com/fastapi/fastapi/pull/15997) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ru (update-outdated). PR [#16002](https://github.com/fastapi/fastapi/pull/16002) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for hi (add-missing). PR [#15990](https://github.com/fastapi/fastapi/pull/15990) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for hi (add-missing). PR [#15925](https://github.com/fastapi/fastapi/pull/15925) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for hi (add-missing). PR [#15797](https://github.com/fastapi/fastapi/pull/15797) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update `llm-prompt.md` for Hindi. PR [#15810](https://github.com/fastapi/fastapi/pull/15810) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Fix language-specific translation prompt for Russian language. PR [#15924](https://github.com/fastapi/fastapi/pull/15924) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* ⬆ Bump the python-packages group across 1 directory with 6 updates. PR [#15981](https://github.com/fastapi/fastapi/pull/15981) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump typing-extensions from 4.15.0 to 4.16.0. PR [#15982](https://github.com/fastapi/fastapi/pull/15982) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump the github-actions group across 1 directory with 4 updates. PR [#15983](https://github.com/fastapi/fastapi/pull/15983) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pre-commit hooks. PR [#15985](https://github.com/fastapi/fastapi/pull/15985) by [@tiangolo](https://github.com/tiangolo).
* 👷 Use `FASTAPI_LATEST_CHANGES` token in `bump-pre-commit-hooks` workflow. PR [#15984](https://github.com/fastapi/fastapi/pull/15984) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👷 Add GH workflow to bump pre-commit hook versions. PR [#15873](https://github.com/fastapi/fastapi/pull/15873) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🔧 Set Dependabot schedule interval to "monthly". PR [#15874](https://github.com/fastapi/fastapi/pull/15874) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump CodSpeedHQ/action from 4.17.6 to 4.18.1 in the github-actions group. PR [#15950](https://github.com/fastapi/fastapi/pull/15950) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump the python-packages group with 8 updates. PR [#15952](https://github.com/fastapi/fastapi/pull/15952) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Update sponsors: add TutorCruncher. PR [#15947](https://github.com/fastapi/fastapi/pull/15947) by [@tiangolo](https://github.com/tiangolo).

2
docs/en/docs/tutorial/frontend.md

@ -52,7 +52,7 @@ For that, use `fallback="index.html"`:
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
**FastAPI** uses this fallback only for `GET` and `HEAD` requests that look like browser navigation. Missing files like JavaScript, CSS, and images still return `404`.
**FastAPI** uses this fallback only for `GET` and `HEAD` requests that explicitly accept HTML with `Accept: text/html` or `Accept: application/xhtml+xml`, as browser navigation requests normally do. Missing files like JavaScript, CSS, and images still return `404`.
Requests with other methods, like `POST` or `PUT`, to paths that only match the frontend fallback also return `404`. Regular **FastAPI** *path operations* still have higher priority than frontend routes.

2
docs/en/mkdocs.yml

@ -223,9 +223,9 @@ nav:
- reference/staticfiles.md
- reference/templating.md
- reference/testclient.md
- fastapi-people.md
- "":
- resources/index.md
- fastapi-people.md
- help-fastapi.md
- contributing.md
- translations.md

6
docs/es/docs/tutorial/frontend.md

@ -126,6 +126,12 @@ En este ejemplo, los paths frontend se sirven bajo `/app`.
Cualquier *path operation* regular en la app seguirá teniendo prioridad, incluso en otros routers.
## Dependencias y Middleware { #dependencies-and-middleware }
Las responses frontend se ejecutan dentro de la aplicación **FastAPI** normal, así que el middleware HTTP se aplica a ellas.
Las dependencias de la app, de un `APIRouter` y de `include_router()` también se aplican a las responses frontend. Esto puede ser útil para proteger un frontend con autenticación por cookie o similar.
## Solo salida estática del build { #static-build-output-only }
`app.frontend()` sirve archivos ya generados por tu build del frontend.

6
docs/fr/docs/tutorial/frontend.md

@ -126,6 +126,12 @@ Dans cet exemple, les chemins frontend sont servis sous `/app`.
Tous les *chemins d'accès* réguliers dans l'application seront toujours prioritaires, y compris dans d'autres routers.
## Dépendances et middleware { #dependencies-and-middleware }
Les réponses frontend s'exécutent au sein de l'application **FastAPI** normale, donc le middleware HTTP s'applique à elles.
Les dépendances de l'application, d'un `APIRouter` et de `include_router()` s'appliquent également aux réponses frontend. Cela peut être utile pour protéger un frontend avec une authentification par cookie ou similaire.
## Sortie de build statique uniquement { #static-build-output-only }
`app.frontend()` sert des fichiers déjà générés par votre build frontend.

3
docs/hi/docs/about/index.md

@ -0,0 +1,3 @@
# परिचय { #about }
FastAPI, इसके design, प्रेरणा और और भी बहुत कुछ के बारे में। 🤓

247
docs/hi/docs/advanced/additional-responses.md

@ -0,0 +1,247 @@
# OpenAPI में अतिरिक्त Responses { #additional-responses-in-openapi }
/// warning | चेतावनी
यह एक काफ़ी advanced विषय है।
अगर आप **FastAPI** के साथ शुरुआत कर रहे हैं, तो शायद आपको इसकी ज़रूरत न पड़े।
///
आप अतिरिक्त status codes, media types, descriptions आदि के साथ अतिरिक्त responses घोषित कर सकते हैं।
ये अतिरिक्त responses OpenAPI schema में शामिल किए जाएँगे, इसलिए वे API docs में भी दिखाई देंगे।
लेकिन उन अतिरिक्त responses के लिए आपको यह सुनिश्चित करना होगा कि आप अपने status code और content के साथ सीधे `JSONResponse` जैसा कोई `Response` return करें।
## `model` के साथ अतिरिक्त Response { #additional-response-with-model }
आप अपने *path operation decorators* को `responses` parameter दे सकते हैं।
यह एक `dict` प्राप्त करता है: keys प्रत्येक response के status codes होते हैं (जैसे `200`), और values अन्य `dict`s होते हैं जिनमें उनमें से प्रत्येक की जानकारी होती है।
इनमें से प्रत्येक response `dict` में `model` key हो सकती है, जिसमें `response_model` की तरह एक Pydantic model होता है।
**FastAPI** उस model को लेगा, उसका JSON Schema generate करेगा और उसे OpenAPI में सही जगह शामिल करेगा।
उदाहरण के लिए, status code `404` और Pydantic model `Message` के साथ एक और response घोषित करने के लिए, आप लिख सकते हैं:
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
/// note | नोट
ध्यान रखें कि आपको सीधे `JSONResponse` return करना होगा।
///
/// note | नोट
`model` key OpenAPI का हिस्सा नहीं है।
**FastAPI** वहाँ से Pydantic model लेगा, JSON Schema generate करेगा, और उसे सही जगह रखेगा।
सही जगह है:
* `content` key में, जिसकी value एक और JSON object (`dict`) होती है जिसमें शामिल है:
* media type वाली एक key, जैसे `application/json`, जिसकी value एक और JSON object होती है, जिसमें शामिल है:
* एक key `schema`, जिसकी value model से JSON Schema होती है, यही सही जगह है।
* **FastAPI** इसे सीधे शामिल करने के बजाय आपके OpenAPI में किसी अन्य जगह मौजूद global JSON Schemas का reference यहाँ जोड़ता है। इस तरह, अन्य applications और clients उन JSON Schemas को सीधे उपयोग कर सकते हैं, बेहतर code generation tools प्रदान कर सकते हैं, आदि।
///
इस *path operation* के लिए OpenAPI में generate किए गए responses होंगे:
```JSON hl_lines="3-12"
{
"responses": {
"404": {
"description": "Additional Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Message"
}
}
}
},
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Item"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
```
Schemas को OpenAPI schema के अंदर किसी दूसरी जगह reference किया गया है:
```JSON hl_lines="4-16"
{
"components": {
"schemas": {
"Message": {
"title": "Message",
"required": [
"message"
],
"type": "object",
"properties": {
"message": {
"title": "Message",
"type": "string"
}
}
},
"Item": {
"title": "Item",
"required": [
"id",
"value"
],
"type": "object",
"properties": {
"id": {
"title": "Id",
"type": "string"
},
"value": {
"title": "Value",
"type": "string"
}
}
},
"ValidationError": {
"title": "ValidationError",
"required": [
"loc",
"msg",
"type"
],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"type": "string"
}
},
"msg": {
"title": "Message",
"type": "string"
},
"type": {
"title": "Error Type",
"type": "string"
}
}
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
}
}
}
}
}
}
}
```
## मुख्य response के लिए अतिरिक्त media types { #additional-media-types-for-the-main-response }
आप इसी `responses` parameter का उपयोग करके उसी मुख्य response के लिए अलग-अलग media types जोड़ सकते हैं।
उदाहरण के लिए, आप `image/png` का एक अतिरिक्त media type जोड़ सकते हैं, यह घोषित करते हुए कि आपका *path operation* एक JSON object (media type `application/json` के साथ) या एक PNG image return कर सकता है:
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
/// note | नोट
ध्यान दें कि आपको image को सीधे `FileResponse` का उपयोग करके return करना होगा।
///
/// note | नोट
जब तक आप अपने `responses` parameter में स्पष्ट रूप से कोई अलग media type specify नहीं करते, FastAPI मान लेगा कि response का media type मुख्य response class (default `application/json`) जैसा ही है।
लेकिन अगर आपने custom response class specify की है जिसका media type `None` है, तो FastAPI किसी भी ऐसे अतिरिक्त response के लिए `application/json` का उपयोग करेगा जिसके साथ कोई associated model है।
///
## जानकारी को मिलाना { #combining-information }
आप कई जगहों से response जानकारी को भी मिला सकते हैं, जिसमें `response_model`, `status_code`, और `responses` parameters शामिल हैं।
आप default status code `200` (या ज़रूरत पड़ने पर custom code) का उपयोग करके `response_model` घोषित कर सकते हैं, और फिर उसी response के लिए अतिरिक्त जानकारी सीधे OpenAPI schema में `responses` के अंदर घोषित कर सकते हैं।
**FastAPI** `responses` से अतिरिक्त जानकारी बनाए रखेगा, और उसे आपके model से JSON Schema के साथ मिला देगा।
उदाहरण के लिए, आप status code `404` वाला एक response घोषित कर सकते हैं जो Pydantic model का उपयोग करता है और जिसमें custom `description` है।
और status code `200` वाला एक response, जो आपके `response_model` का उपयोग करता है, लेकिन जिसमें custom `example` शामिल है:
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
यह सब मिलाकर आपके OpenAPI में शामिल किया जाएगा, और API docs में दिखाया जाएगा:
<img src="/img/tutorial/additional-responses/image01.png">
## पहले से परिभाषित responses और custom responses को मिलाएँ { #combine-predefined-responses-and-custom-ones }
आप कुछ पहले से परिभाषित responses रखना चाह सकते हैं जो कई *path operations* पर लागू होते हैं, लेकिन आप उन्हें प्रत्येक *path operation* के लिए ज़रूरी custom responses के साथ मिलाना चाहते हैं।
ऐसे मामलों के लिए, आप `**dict_to_unpack` के साथ `dict` को "unpacking" करने की Python technique का उपयोग कर सकते हैं:
```Python
old_dict = {
"old key": "old value",
"second old key": "second old value",
}
new_dict = {**old_dict, "new key": "new value"}
```
यहाँ, `new_dict` में `old_dict` के सभी key-value pairs के साथ नया key-value pair भी होगा:
```Python
{
"old key": "old value",
"second old key": "second old value",
"new key": "new value",
}
```
आप इस technique का उपयोग अपने *path operations* में कुछ पहले से परिभाषित responses को reuse करने और उन्हें अतिरिक्त custom responses के साथ मिलाने के लिए कर सकते हैं।
उदाहरण के लिए:
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
## OpenAPI responses के बारे में अधिक जानकारी { #more-information-about-openapi-responses }
Responses में आप ठीक-ठीक क्या शामिल कर सकते हैं, यह देखने के लिए आप OpenAPI specification में ये sections देख सकते हैं:
* [OpenAPI Responses Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), इसमें `Response Object` शामिल है।
* [OpenAPI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), आप इसमें से कुछ भी सीधे अपने `responses` parameter के अंदर प्रत्येक response में शामिल कर सकते हैं। जिसमें `description`, `headers`, `content` (इसी के अंदर आप अलग-अलग media types और JSON Schemas घोषित करते हैं), और `links` शामिल हैं।

41
docs/hi/docs/advanced/additional-status-codes.md

@ -0,0 +1,41 @@
# अतिरिक्त Status Codes { #additional-status-codes }
default रूप से, **FastAPI** responses को `JSONResponse` का उपयोग करके return करेगा, जिसमें आपके *path operation* से return किया गया content उस `JSONResponse` के अंदर रखा जाएगा।
यह default status code या वह status code उपयोग करेगा जो आपने अपने *path operation* में set किया है।
## अतिरिक्त status codes { #additional-status-codes_1 }
अगर आप मुख्य status code के अलावा अतिरिक्त status codes return करना चाहते हैं, तो आप सीधे `Response`, जैसे `JSONResponse`, return करके और अतिरिक्त status code को सीधे set करके ऐसा कर सकते हैं।
उदाहरण के लिए, मान लीजिए कि आप एक ऐसा *path operation* रखना चाहते हैं जो items को update करने की अनुमति देता है, और सफल होने पर HTTP status code 200 "OK" return करता है।
लेकिन आप यह भी चाहते हैं कि यह नए items को स्वीकार करे। और जब items पहले मौजूद नहीं थे, तो यह उन्हें बनाता है, और HTTP status code 201 "Created" return करता है।
ऐसा करने के लिए, `JSONResponse` import करें, और अपना content वहीं सीधे return करें, साथ में अपनी पसंद का `status_code` set करें:
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
/// warning | चेतावनी
जब आप सीधे `Response` return करते हैं, जैसे ऊपर के उदाहरण में, तो वह सीधे return किया जाएगा।
इसे किसी model आदि के साथ serialize नहीं किया जाएगा।
सुनिश्चित करें कि इसमें वही data है जो आप चाहते हैं, और values valid JSON हैं (अगर आप `JSONResponse` उपयोग कर रहे हैं)।
///
/// note | तकनीकी विवरण
आप `from starlette.responses import JSONResponse` भी उपयोग कर सकते हैं।
**FastAPI** आपकी सुविधा के लिए, developer के रूप में, वही `starlette.responses` `fastapi.responses` के रूप में प्रदान करता है। लेकिन उपलब्ध अधिकांश responses सीधे Starlette से आते हैं। `status` के साथ भी यही है।
///
## OpenAPI और API docs { #openapi-and-api-docs }
अगर आप अतिरिक्त status codes और responses सीधे return करते हैं, तो वे OpenAPI schema (API docs) में शामिल नहीं होंगे, क्योंकि FastAPI के पास पहले से यह जानने का तरीका नहीं है कि आप क्या return करने वाले हैं।
लेकिन आप इसे अपने code में document कर सकते हैं, उपयोग करके: [अतिरिक्त Responses](additional-responses.md)।

163
docs/hi/docs/advanced/advanced-dependencies.md

@ -0,0 +1,163 @@
# Advanced Dependencies { #advanced-dependencies }
## Parameterized dependencies { #parameterized-dependencies }
अब तक हमने जो भी dependencies देखी हैं, वे एक निश्चित function या class हैं।
लेकिन ऐसे मामले हो सकते हैं जहाँ आप dependency पर parameters सेट कर पाना चाहें, बिना कई अलग-अलग functions या classes declare किए।
कल्पना करें कि हम एक ऐसी dependency रखना चाहते हैं जो जाँचती है कि query parameter `q` में कुछ निश्चित content है या नहीं।
लेकिन हम उस निश्चित content को parameterize कर पाना चाहते हैं।
## एक "callable" instance { #a-callable-instance }
Python में किसी class के instance को "callable" बनाने का एक तरीका है।
खुद class को नहीं (जो पहले से ही callable होती है), बल्कि उस class के एक instance को।
ऐसा करने के लिए, हम एक method `__call__` declare करते हैं:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
इस मामले में, यही `__call__` है जिसे **FastAPI** अतिरिक्त parameters और sub-dependencies की जाँच के लिए उपयोग करेगा, और बाद में आपकी *path operation function* में parameter को value पास करने के लिए यही call किया जाएगा।
## Instance को parameterize करें { #parameterize-the-instance }
और अब, हम `__init__` का उपयोग करके instance के parameters declare कर सकते हैं जिन्हें हम dependency को "parameterize" करने के लिए उपयोग कर सकते हैं:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
इस मामले में, **FastAPI** कभी भी `__init__` को छुएगा या उसकी परवाह नहीं करेगा, हम इसे सीधे अपने code में उपयोग करेंगे।
## एक instance बनाएँ { #create-an-instance }
हम इस class का एक instance इस तरह बना सकते हैं:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
और इस तरह हम अपनी dependency को "parameterize" कर पाते हैं, जिसमें अब `"bar"` उसके अंदर है, attribute `checker.fixed_content` के रूप में।
## Instance को dependency के रूप में उपयोग करें { #use-the-instance-as-a-dependency }
फिर, हम `Depends(FixedContentQueryChecker)` के बजाय इस `checker` को `Depends(checker)` में उपयोग कर सकते हैं, क्योंकि dependency class खुद नहीं, बल्कि instance `checker` है।
और dependency को solve करते समय, **FastAPI** इस `checker` को इस तरह call करेगा:
```Python
checker(q="somequery")
```
...और जो भी यह return करेगा उसे हमारी *path operation function* में dependency की value के रूप में parameter `fixed_content_included` में पास करेगा:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
/// tip | सुझाव
यह सब थोड़ा बनावटी लग सकता है। और अभी यह बहुत स्पष्ट नहीं हो सकता कि यह कैसे उपयोगी है।
ये उदाहरण जानबूझकर सरल रखे गए हैं, लेकिन दिखाते हैं कि यह सब कैसे काम करता है।
Security वाले chapters में utility functions हैं जिन्हें इसी तरीके से implement किया गया है।
अगर आपने यह सब समझ लिया है, तो आप पहले से जानते हैं कि security के लिए वे utility tools अंदर से कैसे काम करते हैं।
///
## `yield`, `HTTPException`, `except` और Background Tasks वाली Dependencies { #dependencies-with-yield-httpexception-except-and-background-tasks }
/// warning | चेतावनी
सबसे अधिक संभावना है कि आपको इन तकनीकी विवरणों की आवश्यकता नहीं है।
ये विवरण मुख्य रूप से तब उपयोगी हैं जब आपके पास 0.121.0 से पुरानी FastAPI application थी और आपको `yield` वाली dependencies के साथ समस्याएँ आ रही हैं।
///
`yield` वाली dependencies समय के साथ अलग-अलग use cases को संभालने और कुछ समस्याएँ ठीक करने के लिए विकसित हुई हैं, यहाँ बदले हुए व्यवहार का सारांश है।
### `yield` और `scope` वाली Dependencies { #dependencies-with-yield-and-scope }
Version 0.121.0 में, FastAPI ने `yield` वाली dependencies के लिए `Depends(scope="function")` का support जोड़ा।
`Depends(scope="function")` का उपयोग करने पर, `yield` के बाद का exit code *path operation function* के समाप्त होते ही, response client को वापस भेजे जाने से पहले execute होता है।
और `Depends(scope="request")` (default) का उपयोग करने पर, `yield` के बाद का exit code response भेजे जाने के बाद execute होता है।
आप इसके बारे में docs में [Dependencies with `yield` - Early exit and `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope) में अधिक पढ़ सकते हैं।
### `yield` और `StreamingResponse` वाली Dependencies, तकनीकी विवरण { #dependencies-with-yield-and-streamingresponse-technical-details }
FastAPI 0.118.0 से पहले, यदि आप `yield` वाली dependency उपयोग करते थे, तो यह *path operation function* के return करने के बाद लेकिन response भेजने से ठीक पहले exit code run करती थी।
इरादा यह था कि आवश्यक से अधिक समय तक resources को पकड़े रखने से बचा जाए, response के network से गुजरने की प्रतीक्षा करते हुए।
इस बदलाव का अर्थ यह भी था कि यदि आपने `StreamingResponse` return किया, तो `yield` वाली dependency का exit code पहले ही run हो चुका होता।
उदाहरण के लिए, यदि आपके पास `yield` वाली dependency में database session था, तो `StreamingResponse` data stream करते समय उस session का उपयोग नहीं कर पाता क्योंकि `yield` के बाद वाले exit code में session पहले ही बंद हो चुका होता।
यह व्यवहार 0.118.0 में revert कर दिया गया, ताकि `yield` के बाद का exit code response भेजे जाने के बाद execute हो।
/// note | ध्यान दें
जैसा कि आप नीचे देखेंगे, यह version 0.106.0 से पहले के व्यवहार से बहुत मिलता-जुलता है, लेकिन कई सुधारों और corner cases के लिए bug fixes के साथ।
///
#### Early Exit Code वाले Use Cases { #use-cases-with-early-exit-code }
कुछ specific conditions वाले use cases हैं जिन्हें response भेजने से पहले `yield` वाली dependencies का exit code run करने के पुराने व्यवहार से लाभ हो सकता है।
उदाहरण के लिए, कल्पना करें कि आपके पास ऐसा code है जो `yield` वाली dependency में database session का उपयोग केवल user verify करने के लिए करता है, लेकिन database session फिर *path operation function* में कभी उपयोग नहीं होता, केवल dependency में उपयोग होता है, **और** response भेजे जाने में लंबा समय लेता है, जैसे `StreamingResponse` जो data धीरे-धीरे भेजता है, लेकिन किसी कारण से database का उपयोग नहीं करता।
इस मामले में, database session तब तक पकड़ा रहेगा जब तक response भेजना समाप्त नहीं हो जाता, लेकिन यदि आप इसका उपयोग नहीं करते हैं, तो इसे पकड़े रखना आवश्यक नहीं होगा।
यह इस तरह दिख सकता है:
{* ../../docs_src/dependencies/tutorial013_an_py310.py *}
Exit code, यानी `Session` का automatic closing, यहाँ:
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}
...response द्वारा slow data भेजना समाप्त करने के बाद run होगा:
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}
लेकिन क्योंकि `generate_stream()` database session का उपयोग नहीं करता, response भेजते समय session को खुला रखना वास्तव में आवश्यक नहीं है।
यदि आपके पास SQLModel (या SQLAlchemy) का उपयोग करते हुए यह specific use case है, तो आप session को तब explicit रूप से बंद कर सकते हैं जब आपको इसकी आगे आवश्यकता न हो:
{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *}
इस तरह session database connection release कर देगा, ताकि अन्य requests उसका उपयोग कर सकें।
यदि आपके पास कोई अलग use case है जिसे `yield` वाली dependency से early exit करने की आवश्यकता है, तो कृपया अपने specific use case और dependencies with `yield` के लिए early closing से आपको क्यों लाभ होगा, इसके साथ एक [GitHub Discussion Question](https://github.com/fastapi/fastapi/discussions/new?category=questions) बनाएँ।
यदि dependencies with `yield` में early closing के लिए compelling use cases होते हैं, तो मैं early closing में opt in करने का नया तरीका जोड़ने पर विचार करूँगा।
### `yield` और `except` वाली Dependencies, तकनीकी विवरण { #dependencies-with-yield-and-except-technical-details }
FastAPI 0.110.0 से पहले, यदि आप `yield` वाली dependency उपयोग करते थे, और फिर उस dependency में `except` के साथ exception capture करते थे, और exception को फिर से raise नहीं करते थे, तो exception automatic रूप से किसी भी exception handlers या internal server error handler को raise/forward कर दिया जाता था।
यह version 0.110.0 में बदला गया ताकि handler के बिना forwarded exceptions (internal server errors) से होने वाली unhandled memory consumption ठीक की जा सके, और इसे regular Python code के व्यवहार के साथ consistent बनाया जा सके।
### Background Tasks और `yield` वाली Dependencies, तकनीकी विवरण { #background-tasks-and-dependencies-with-yield-technical-details }
FastAPI 0.106.0 से पहले, `yield` के बाद exceptions raise करना संभव नहीं था, `yield` वाली dependencies में exit code response भेजे जाने के *बाद* execute होता था, इसलिए [Exception Handlers](../tutorial/handling-errors.md#install-custom-exception-handlers) पहले ही run हो चुके होते।
इसे मुख्य रूप से इस तरह design किया गया था ताकि dependencies द्वारा "yielded" किए गए उन्हीं objects को background tasks के अंदर उपयोग किया जा सके, क्योंकि exit code background tasks के समाप्त होने के बाद execute होता था।
यह FastAPI 0.106.0 में बदला गया, इस इरादे से कि response के network से गुजरने की प्रतीक्षा करते समय resources को पकड़े न रखा जाए।
/// tip | सुझाव
इसके अतिरिक्त, background task सामान्यतः logic का एक independent set होता है जिसे अलग से संभाला जाना चाहिए, अपने स्वयं के resources के साथ (जैसे उसका अपना database connection)।
इसलिए, इस तरह आपके पास शायद अधिक साफ़ code होगा।
///
यदि आप इस व्यवहार पर निर्भर थे, तो अब आपको background tasks के लिए resources background task के अंदर ही बनाने चाहिए, और internally केवल ऐसा data उपयोग करना चाहिए जो `yield` वाली dependencies के resources पर निर्भर न हो।
उदाहरण के लिए, उसी database session का उपयोग करने के बजाय, आप background task के अंदर एक नया database session बनाएँगे, और इस नए session का उपयोग करके database से objects प्राप्त करेंगे। और फिर database से object को background task function में parameter के रूप में पास करने के बजाय, आप उस object की ID पास करेंगे और फिर background task function के अंदर object को फिर से प्राप्त करेंगे।

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

@ -0,0 +1,61 @@
# उन्नत Python Types { #advanced-python-types }
Python types के साथ काम करते समय यहाँ कुछ अतिरिक्त विचार हैं जो उपयोगी हो सकते हैं।
## `Union` या `Optional` का उपयोग { #using-union-or-optional }
अगर आपका code किसी कारण से `|` का उपयोग नहीं कर सकता, उदाहरण के लिए अगर यह type annotation में नहीं बल्कि `response_model=` जैसी किसी चीज़ में है, तो vertical bar (`|`) का उपयोग करने के बजाय आप `typing` से `Union` का उपयोग कर सकते हैं।
उदाहरण के लिए, आप declare कर सकते हैं कि कोई चीज़ `str` या `None` हो सकती है:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing` में `Optional` के साथ यह declare करने का एक shortcut भी है कि कोई चीज़ `None` हो सकती है।
मेरे बहुत **subjective** दृष्टिकोण से एक tip यहाँ है:
* 🚨 `Optional[SomeType]` का उपयोग करने से बचें
* इसके बजाय ✨ **`Union[SomeType, None]` का उपयोग करें** ✨।
दोनों equivalent हैं और अंदर से वे समान हैं, लेकिन मैं `Optional` के बजाय `Union` की सलाह दूँगा क्योंकि "**optional**" शब्द से ऐसा लग सकता है कि value optional है, जबकि इसका वास्तविक अर्थ है "यह `None` हो सकता है", भले ही यह optional न हो और अभी भी required हो।
मुझे लगता है कि `Union[SomeType, None]` अपने अर्थ के बारे में अधिक explicit है।
यह बस शब्दों और नामों की बात है। लेकिन ये शब्द इस बात को प्रभावित कर सकते हैं कि आप और आपके teammates code के बारे में कैसे सोचते हैं।
एक उदाहरण के रूप में, इस function को लेते हैं:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
parameter `name` को `Optional[str]` के रूप में define किया गया है, लेकिन यह **optional नहीं है**, आप function को parameter के बिना call नहीं कर सकते:
```Python
say_hi() # अरे नहीं, यह error throw करता है! 😱
```
`name` parameter **अभी भी required** है (*optional* नहीं) क्योंकि इसमें default value नहीं है। फिर भी, `name` value के रूप में `None` स्वीकार करता है:
```Python
say_hi(name=None) # यह काम करता है, None valid है 🎉
```
अच्छी खबर यह है कि अधिकतर मामलों में, आप types के unions को define करने के लिए बस `|` का उपयोग कर पाएँगे:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
इसलिए, सामान्यतः आपको `Optional` और `Union` जैसे नामों के बारे में चिंता करने की ज़रूरत नहीं होती। 😎

99
docs/hi/docs/advanced/async-tests.md

@ -0,0 +1,99 @@
# Async Tests { #async-tests }
आपने पहले ही देखा है कि दिए गए `TestClient` का उपयोग करके अपनी **FastAPI** applications को कैसे test किया जाता है। अब तक, आपने केवल synchronous tests लिखना देखा है, `async` functions का उपयोग किए बिना।
अपने tests में asynchronous functions का उपयोग कर पाना उपयोगी हो सकता है, उदाहरण के लिए, जब आप अपने database को asynchronously query कर रहे हों। कल्पना करें कि आप अपनी FastAPI application को requests भेजना test करना चाहते हैं और फिर verify करना चाहते हैं कि आपके backend ने async database library का उपयोग करते हुए database में सही data सफलतापूर्वक लिखा है।
आइए देखें कि हम इसे कैसे काम करवा सकते हैं।
## pytest.mark.anyio { #pytest-mark-anyio }
अगर हम अपने tests में asynchronous functions call करना चाहते हैं, तो हमारे test functions asynchronous होने चाहिए। AnyIO इसके लिए एक अच्छा plugin प्रदान करता है, जो हमें specify करने देता है कि कुछ test functions को asynchronously call किया जाना है।
## HTTPX { #httpx }
भले ही आपकी **FastAPI** application `async def` के बजाय सामान्य `def` functions का उपयोग करती हो, यह अंदर से फिर भी एक `async` application होती है।
`TestClient` अंदर कुछ magic करता है ताकि standard pytest का उपयोग करते हुए आपकी सामान्य `def` test functions में asynchronous FastAPI application को call किया जा सके। लेकिन जब हम इसे asynchronous functions के अंदर उपयोग करते हैं, तो वह magic अब काम नहीं करता। अपने tests को asynchronously चलाने पर, हम अपने test functions के अंदर `TestClient` का उपयोग नहीं कर सकते।
`TestClient` [HTTPX](https://www.python-httpx.org) पर आधारित है, और सौभाग्य से, हम API को test करने के लिए इसे सीधे उपयोग कर सकते हैं।
## उदाहरण { #example }
एक सरल उदाहरण के लिए, आइए [बड़ी Applications](../tutorial/bigger-applications.md) और [Testing](../tutorial/testing.md) में वर्णित file structure जैसी एक structure पर विचार करें:
```
.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py
```
file `main.py` में यह होगा:
{* ../../docs_src/async_tests/app_a_py310/main.py *}
file `test_main.py` में `main.py` के लिए tests होंगे, यह अब कुछ ऐसा दिख सकता है:
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
## इसे चलाएँ { #run-it }
आप अपने tests को हमेशा की तरह इस तरह चला सकते हैं:
<div class="termy">
```console
$ pytest
---> 100%
```
</div>
## विस्तार से { #in-detail }
marker `@pytest.mark.anyio` pytest को बताता है कि इस test function को asynchronously call किया जाना चाहिए:
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
/// tip | सुझाव
ध्यान दें कि test function अब पहले की तरह `TestClient` का उपयोग करते समय केवल `def` नहीं, बल्कि `async def` है।
///
फिर हम app के साथ एक `AsyncClient` बना सकते हैं, और `await` का उपयोग करते हुए इसमें async requests भेज सकते हैं।
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
यह इसके बराबर है:
```Python
response = client.get('/')
```
...जिसका उपयोग हम `TestClient` के साथ अपनी requests बनाने के लिए करते थे।
/// tip | सुझाव
ध्यान दें कि हम नए `AsyncClient` के साथ async/await का उपयोग कर रहे हैं - request asynchronous है।
///
/// warning | चेतावनी
अगर आपकी application lifespan events पर निर्भर करती है, तो `AsyncClient` इन events को trigger नहीं करेगा। यह सुनिश्चित करने के लिए कि वे trigger हों, [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage) से `LifespanManager` का उपयोग करें।
///
## अन्य asynchronous function calls { #other-asynchronous-function-calls }
क्योंकि testing function अब asynchronous है, आप अब अपने tests में अपनी FastAPI application को requests भेजने के अलावा अन्य `async` functions को भी call (और `await`) कर सकते हैं, ठीक वैसे ही जैसे आप उन्हें अपने code में कहीं और call करते हैं।
/// tip | सुझाव
अगर अपने tests में asynchronous function calls integrate करते समय आपको `RuntimeError: Task attached to a different loop` मिलता है (जैसे [MongoDB's MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop) का उपयोग करते समय), तो याद रखें कि जिन objects को event loop की जरूरत होती है, उन्हें केवल async functions के भीतर ही instantiate करें, जैसे कि `@app.on_event("startup")` callback।
///

466
docs/hi/docs/advanced/behind-a-proxy.md

@ -0,0 +1,466 @@
# Proxy के पीछे { #behind-a-proxy }
कई स्थितियों में, आप अपने FastAPI app के सामने Traefik या Nginx जैसा **proxy** उपयोग करेंगे।
ये proxies HTTPS certificates और दूसरी चीज़ें संभाल सकते हैं।
## Proxy Forwarded Headers { #proxy-forwarded-headers }
आपकी application के सामने मौजूद **proxy** आम तौर पर requests को आपके **server** तक भेजने से पहले तुरंत कुछ headers सेट करेगा, ताकि server को पता चल सके कि request proxy द्वारा **forwarded** की गई थी, उसे मूल (public) URL पता चल सके, जिसमें domain शामिल हो, कि वह HTTPS उपयोग कर रहा है, आदि।
**server** program (उदाहरण के लिए **FastAPI CLI** के जरिए **Uvicorn**) इन headers को समझने में सक्षम है, और फिर वह जानकारी आपकी application को पास कर सकता है।
लेकिन security के लिए, क्योंकि server को यह नहीं पता कि वह किसी trusted proxy के पीछे है, वह उन headers को interpret नहीं करेगा।
/// note | तकनीकी विवरण
Proxy headers हैं:
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
///
### Proxy Forwarded Headers सक्षम करें { #enable-proxy-forwarded-headers }
आप FastAPI CLI को *CLI Option* `--forwarded-allow-ips` के साथ शुरू कर सकते हैं और वे IP addresses पास कर सकते हैं जिन पर उन forwarded headers को पढ़ने के लिए भरोसा किया जाना चाहिए।
अगर आप इसे `--forwarded-allow-ips="*"` पर सेट करते हैं, तो यह सभी incoming IPs पर भरोसा करेगा।
अगर आपका **server** किसी trusted **proxy** के पीछे है और केवल proxy ही उससे बात करता है, तो इससे वह उस **proxy** का जो भी IP है, उसे accept करेगा।
<div class="termy">
```console
$ fastapi run --forwarded-allow-ips="*"
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### HTTPS के साथ Redirects { #redirects-with-https }
उदाहरण के लिए, मान लें कि आप एक *path operation* `/items/` define करते हैं:
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
अगर client `/items` पर जाने की कोशिश करता है, तो default रूप से, उसे `/items/` पर redirect किया जाएगा।
लेकिन *CLI Option* `--forwarded-allow-ips` सेट करने से पहले यह `http://localhost:8000/items/` पर redirect कर सकता है।
लेकिन शायद आपकी application `https://mysuperapp.com` पर hosted है, और redirection `https://mysuperapp.com/items/` पर होना चाहिए।
अब `--proxy-headers` सेट करने से FastAPI सही location पर redirect कर पाएगा। 😎
```
https://mysuperapp.com/items/
```
/// tip | सुझाव
अगर आप HTTPS के बारे में और जानना चाहते हैं, तो guide [HTTPS के बारे में](../deployment/https.md) देखें।
///
### Proxy Forwarded Headers कैसे काम करते हैं { #how-proxy-forwarded-headers-work }
यहाँ client और **application server** के बीच **proxy** द्वारा forwarded headers जोड़ने का एक visual representation है:
```mermaid
sequenceDiagram
participant Client
participant Proxy as Proxy/Load Balancer
participant Server as FastAPI Server
Client->>Proxy: HTTPS Request<br/>Host: mysuperapp.com<br/>Path: /items
Note over Proxy: Proxy adds forwarded headers
Proxy->>Server: HTTP Request<br/>X-Forwarded-For: [client IP]<br/>X-Forwarded-Proto: https<br/>X-Forwarded-Host: mysuperapp.com<br/>Path: /items
Note over Server: Server interprets headers<br/>(if --forwarded-allow-ips is set)
Server->>Proxy: HTTP Response<br/>with correct HTTPS URLs
Proxy->>Client: HTTPS Response
```
**proxy** मूल client request को intercept करता है और request को **application server** तक पास करने से पहले खास *forwarded* headers (`X-Forwarded-*`) जोड़ता है।
ये headers मूल request के बारे में वह जानकारी सुरक्षित रखते हैं जो अन्यथा खो जाती:
* **X-Forwarded-For**: मूल client का IP address
* **X-Forwarded-Proto**: मूल protocol (`https`)
* **X-Forwarded-Host**: मूल host (`mysuperapp.com`)
जब **FastAPI CLI** को `--forwarded-allow-ips` के साथ configured किया जाता है, तो यह इन headers पर भरोसा करता है और उनका उपयोग करता है, उदाहरण के लिए redirects में सही URLs generate करने के लिए।
## Stripped path prefix वाला Proxy { #proxy-with-a-stripped-path-prefix }
आपके पास ऐसा proxy हो सकता है जो आपकी application में एक path prefix जोड़ता हो।
इन मामलों में आप अपनी application configure करने के लिए `root_path` का उपयोग कर सकते हैं।
`root_path` ASGI specification द्वारा प्रदान किया गया एक mechanism है (जिस पर FastAPI, Starlette के जरिए, बना है)।
`root_path` का उपयोग इन specific cases को handle करने के लिए किया जाता है।
और इसका उपयोग sub-applications mount करते समय internally भी किया जाता है।
इस case में, stripped path prefix वाला proxy होने का मतलब है कि आप अपने code में `/app` पर एक path declare कर सकते हैं, लेकिन फिर आप ऊपर एक layer (proxy) जोड़ते हैं जो आपकी **FastAPI** application को `/api/v1` जैसे path के नीचे रखेगी।
इस case में, मूल path `/app` वास्तव में `/api/v1/app` पर serve किया जाएगा।
हालाँकि आपका सारा code यह मानकर लिखा गया है कि सिर्फ `/app` है।
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
और proxy app server (शायद FastAPI CLI के जरिए Uvicorn) तक request भेजने से पहले तुरंत **path prefix** को **"strip"** कर देगा, आपकी application को यह भरोसा दिलाते हुए कि वह `/app` पर serve हो रही है, ताकि आपको prefix `/api/v1` शामिल करने के लिए अपना सारा code update न करना पड़े।
यहाँ तक, सब कुछ सामान्य रूप से काम करेगा।
लेकिन फिर, जब आप integrated docs UI (frontend) खोलेंगे, तो वह OpenAPI schema को `/api/v1/openapi.json` के बजाय `/openapi.json` पर पाने की अपेक्षा करेगा।
इसलिए, frontend (जो browser में चलता है) `/openapi.json` तक पहुँचने की कोशिश करेगा और OpenAPI schema प्राप्त नहीं कर पाएगा।
क्योंकि हमारे app के लिए `/api/v1` का path prefix वाला proxy है, frontend को OpenAPI schema `/api/v1/openapi.json` पर fetch करना होगा।
```mermaid
graph LR
browser("Browser")
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
server["Server on http://127.0.0.1:8000/app"]
browser --> proxy
proxy --> server
```
/// tip | सुझाव
IP `0.0.0.0` आम तौर पर यह बताने के लिए उपयोग किया जाता है कि program उस machine/server में उपलब्ध सभी IPs पर listen करता है।
///
Docs UI को OpenAPI schema में यह declare करने की भी ज़रूरत होगी कि यह API `server` `/api/v1` (proxy के पीछे) पर स्थित है। उदाहरण के लिए:
```JSON hl_lines="4-8"
{
"openapi": "3.1.0",
// यहाँ और चीज़ें
"servers": [
{
"url": "/api/v1"
}
],
"paths": {
// यहाँ और चीज़ें
}
}
```
इस उदाहरण में, "Proxy" कुछ **Traefik** जैसा हो सकता है। और server **Uvicorn** के साथ FastAPI CLI जैसा हो सकता है, जो आपकी FastAPI application चला रहा है।
### `root_path` प्रदान करना { #providing-the-root-path }
इसे हासिल करने के लिए, आप command line option `--root-path` इस तरह उपयोग कर सकते हैं:
<div class="termy">
```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
अगर आप Hypercorn उपयोग करते हैं, तो उसमें भी option `--root-path` है।
/// note | तकनीकी विवरण
ASGI specification इस use case के लिए `root_path` define करती है।
और `--root-path` command line option वही `root_path` प्रदान करता है।
///
### वर्तमान `root_path` जाँचना { #checking-the-current-root-path }
आप प्रत्येक request के लिए आपकी application द्वारा उपयोग किया गया वर्तमान `root_path` प्राप्त कर सकते हैं, यह `scope` dictionary का हिस्सा है (जो ASGI spec का हिस्सा है)।
यहाँ हम इसे केवल demonstration purposes के लिए message में शामिल कर रहे हैं।
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
फिर, अगर आप Uvicorn को इस तरह शुरू करते हैं:
<div class="termy">
```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Response कुछ ऐसा होगा:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
### FastAPI app में `root_path` सेट करना { #setting-the-root-path-in-the-fastapi-app }
वैकल्पिक रूप से, अगर आपके पास `--root-path` या equivalent जैसा command line option देने का तरीका नहीं है, तो आप अपनी FastAPI app बनाते समय `root_path` parameter सेट कर सकते हैं:
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
`root_path` को `FastAPI` में पास करना, Uvicorn या Hypercorn को `--root-path` command line option पास करने के equivalent होगा।
### `root_path` के बारे में { #about-root-path }
ध्यान रखें कि server (Uvicorn) उस `root_path` का उपयोग app को पास करने के अलावा किसी और चीज़ के लिए नहीं करेगा।
लेकिन अगर आप अपने browser में [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app) पर जाते हैं, तो आपको normal response दिखाई देगा:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
इसलिए, यह `http://127.0.0.1:8000/api/v1/app` पर access किए जाने की अपेक्षा नहीं करेगा।
Uvicorn अपेक्षा करेगा कि proxy Uvicorn को `http://127.0.0.1:8000/app` पर access करे, और फिर ऊपर extra `/api/v1` prefix जोड़ना proxy की जिम्मेदारी होगी।
## Stripped path prefix वाले proxies के बारे में { #about-proxies-with-a-stripped-path-prefix }
ध्यान रखें कि stripped path prefix वाला proxy इसे configure करने के तरीकों में से केवल एक है।
शायद कई cases में default यह होगा कि proxy के पास stripped path prefix नहीं होगा।
ऐसे case में (बिना stripped path prefix के), proxy कुछ `https://myawesomeapp.com` जैसा listen करेगा, और फिर अगर browser `https://myawesomeapp.com/api/v1/app` पर जाता है और आपका server (जैसे Uvicorn) `http://127.0.0.1:8000` पर listen करता है, तो proxy (बिना stripped path prefix के) Uvicorn को उसी path पर access करेगा: `http://127.0.0.1:8000/api/v1/app`
## Traefik के साथ local testing { #testing-locally-with-traefik }
आप [Traefik](https://docs.traefik.io/) का उपयोग करके stripped path prefix के साथ experiment आसानी से locally चला सकते हैं।
[Traefik download करें](https://github.com/containous/traefik/releases), यह एक single binary है, आप compressed file extract कर सकते हैं और इसे सीधे terminal से चला सकते हैं।
फिर `traefik.toml` नाम की file बनाएँ जिसमें यह हो:
```TOML hl_lines="3"
[entryPoints]
[entryPoints.http]
address = ":9999"
[providers]
[providers.file]
filename = "routes.toml"
```
यह Traefik को port 9999 पर listen करने और दूसरी file `routes.toml` उपयोग करने के लिए कहता है।
/// tip | सुझाव
हम standard HTTP port 80 के बजाय port 9999 उपयोग कर रहे हैं ताकि आपको इसे admin (`sudo`) privileges के साथ न चलाना पड़े।
///
अब वह दूसरी file `routes.toml` बनाएँ:
```TOML hl_lines="5 12 20"
[http]
[http.middlewares]
[http.middlewares.api-stripprefix.stripPrefix]
prefixes = ["/api/v1"]
[http.routers]
[http.routers.app-http]
entryPoints = ["http"]
service = "app"
rule = "PathPrefix(`/api/v1`)"
middlewares = ["api-stripprefix"]
[http.services]
[http.services.app]
[http.services.app.loadBalancer]
[[http.services.app.loadBalancer.servers]]
url = "http://127.0.0.1:8000"
```
यह file Traefik को path prefix `/api/v1` उपयोग करने के लिए configure करती है।
और फिर Traefik अपनी requests को `http://127.0.0.1:8000` पर चल रहे आपके Uvicorn पर redirect करेगा।
अब Traefik शुरू करें:
<div class="termy">
```console
$ ./traefik --configFile=traefik.toml
INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
```
</div>
और अब `--root-path` option का उपयोग करके अपना app शुरू करें:
<div class="termy">
```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Responses जाँचें { #check-the-responses }
अब, अगर आप Uvicorn के port वाले URL पर जाते हैं: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), तो आपको normal response दिखाई देगा:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
/// tip | सुझाव
ध्यान दें कि भले ही आप इसे `http://127.0.0.1:8000/app` पर access कर रहे हैं, यह option `--root-path` से लिया गया `/api/v1` का `root_path` दिखाता है।
///
और अब Traefik के port वाले URL को खोलें, जिसमें path prefix शामिल है: [http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app)।
हमें वही response मिलता है:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
लेकिन इस बार proxy द्वारा प्रदान किए गए prefix path वाले URL पर: `/api/v1`
बेशक, यहाँ विचार यह है कि हर कोई app को proxy के जरिए access करेगा, इसलिए path prefix `/api/v1` वाला version "correct" है।
और बिना path prefix वाला version (`http://127.0.0.1:8000/app`), जो सीधे Uvicorn द्वारा प्रदान किया गया है, केवल _proxy_ (Traefik) के access के लिए होगा।
यह दिखाता है कि Proxy (Traefik) path prefix का उपयोग कैसे करता है और server (Uvicorn) option `--root-path` से `root_path` का उपयोग कैसे करता है।
### Docs UI जाँचें { #check-the-docs-ui }
लेकिन यहाँ मज़ेदार हिस्सा है। ✨
App को access करने का "official" तरीका उस path prefix वाले proxy के जरिए होगा जिसे हमने define किया है। इसलिए, जैसा कि हम अपेक्षा करेंगे, अगर आप Uvicorn द्वारा सीधे serve किया गया docs UI try करते हैं, URL में path prefix के बिना, तो यह काम नहीं करेगा, क्योंकि यह proxy के जरिए access किए जाने की अपेक्षा करता है।
आप इसे [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) पर देख सकते हैं:
<img src="/img/tutorial/behind-a-proxy/image01.png">
लेकिन अगर हम port `9999` वाले proxy का उपयोग करके "official" URL पर, `/api/v1/docs` पर docs UI access करते हैं, तो यह सही तरीके से काम करता है! 🎉
आप इसे [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) पर देख सकते हैं:
<img src="/img/tutorial/behind-a-proxy/image02.png">
बिल्कुल जैसा हम चाहते थे। ✔️
ऐसा इसलिए है क्योंकि FastAPI इस `root_path` का उपयोग OpenAPI में default `server` बनाने के लिए करता है, जिसमें `root_path` द्वारा दिया गया URL होता है।
## अतिरिक्त servers { #additional-servers }
/// warning | चेतावनी
यह एक अधिक advanced use case है। चाहें तो इसे skip कर सकते हैं।
///
Default रूप से, **FastAPI** OpenAPI schema में `root_path` के URL वाला एक `server` बनाएगा।
लेकिन आप अन्य alternative `servers` भी प्रदान कर सकते हैं, उदाहरण के लिए अगर आप चाहते हैं कि *वही* docs UI staging और production environment दोनों के साथ interact करे।
अगर आप `servers` की custom list पास करते हैं और कोई `root_path` है (क्योंकि आपकी API proxy के पीछे रहती है), तो **FastAPI** list की शुरुआत में इस `root_path` के साथ एक "server" insert करेगा।
उदाहरण के लिए:
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
यह इस तरह का OpenAPI schema generate करेगा:
```JSON hl_lines="5-7"
{
"openapi": "3.1.0",
// यहाँ और चीज़ें
"servers": [
{
"url": "/api/v1"
},
{
"url": "https://stag.example.com",
"description": "Staging environment"
},
{
"url": "https://prod.example.com",
"description": "Production environment"
}
],
"paths": {
// यहाँ और चीज़ें
}
}
```
/// tip | सुझाव
ध्यान दें कि `/api/v1` के `url` value वाला auto-generated server `root_path` से लिया गया है।
///
[http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) पर docs UI में यह ऐसा दिखेगा:
<img src="/img/tutorial/behind-a-proxy/image03.png">
/// tip | सुझाव
Docs UI आपके द्वारा चुने गए server के साथ interact करेगा।
///
/// note | तकनीकी विवरण
OpenAPI specification में `servers` property optional है।
अगर आप `servers` parameter specify नहीं करते और `root_path` `/` के बराबर है, तो generated OpenAPI schema में `servers` property default रूप से पूरी तरह omit कर दी जाएगी, जो `/` के `url` value वाले single server के equivalent है।
///
### `root_path` से automatic server disable करें { #disable-automatic-server-from-root-path }
अगर आप नहीं चाहते कि **FastAPI** `root_path` का उपयोग करके automatic server शामिल करे, तो आप parameter `root_path_in_servers=False` उपयोग कर सकते हैं:
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
और फिर यह उसे OpenAPI schema में शामिल नहीं करेगा।
## Sub-application mount करना { #mounting-a-sub-application }
अगर आपको `root_path` वाले proxy का उपयोग करते हुए भी sub-application mount करनी है (जैसा कि [Sub Applications - Mounts](sub-applications.md) में बताया गया है), तो आप इसे सामान्य रूप से कर सकते हैं, जैसा कि आप अपेक्षा करेंगे।
FastAPI internally `root_path` का smart तरीके से उपयोग करेगा, इसलिए यह बस काम करेगा। ✨

273
docs/hi/docs/advanced/custom-response.md

@ -0,0 +1,273 @@
# कस्टम Response - HTML, Stream, File, अन्य { #custom-response-html-stream-file-others }
Default रूप से, **FastAPI** JSON responses लौटाएगा।
आप [सीधे Response लौटाएँ](response-directly.md) में दिखाए गए अनुसार सीधे `Response` लौटाकर इसे override कर सकते हैं।
लेकिन अगर आप सीधे `Response` लौटाते हैं (या कोई subclass, जैसे `JSONResponse`), तो data अपने आप convert नहीं होगा (भले ही आप `response_model` declare करें), और documentation अपने आप generate नहीं होगी (उदाहरण के लिए, generated OpenAPI के हिस्से के रूप में HTTP header `Content-Type` में specific "media type" शामिल करना)।
लेकिन आप *path operation decorator* में `response_class` parameter का उपयोग करके वह `Response` भी declare कर सकते हैं जिसे आप उपयोग करना चाहते हैं (जैसे कोई भी `Response` subclass)।
आप अपनी *path operation function* से जो contents लौटाते हैं, उन्हें उस `Response` के अंदर रख दिया जाएगा।
/// note | नोट
यदि आप बिना media type वाली response class का उपयोग करते हैं, तो FastAPI अपेक्षा करेगा कि आपके response में कोई content न हो, इसलिए यह अपने generated OpenAPI docs में response format को document नहीं करेगा।
///
## JSON Responses { #json-responses }
Default रूप से FastAPI JSON responses लौटाता है।
यदि आप [Response Model](../tutorial/response-model.md) declare करते हैं तो FastAPI Pydantic का उपयोग करके data को JSON में serialize करने के लिए उसका उपयोग करेगा।
यदि आप response model declare नहीं करते हैं, तो FastAPI [JSON Compatible Encoder](../tutorial/encoder.md) में समझाए गए `jsonable_encoder` का उपयोग करेगा और उसे `JSONResponse` में रखेगा।
यदि आप JSON media type (`application/json`) के साथ `response_class` declare करते हैं, जैसा कि `JSONResponse` के साथ होता है, तो आपके द्वारा लौटाया गया data आपकी *path operation decorator* में declare किए गए किसी भी Pydantic `response_model` के साथ अपने आप convert (और filter) हो जाएगा। लेकिन data Pydantic के साथ JSON bytes में serialize नहीं होगा, इसके बजाय इसे `jsonable_encoder` के साथ convert किया जाएगा और फिर `JSONResponse` class को pass किया जाएगा, जो Python की standard JSON library का उपयोग करके इसे bytes में serialize करेगी।
### JSON Performance { #json-performance }
संक्षेप में, यदि आप maximum performance चाहते हैं, तो [Response Model](../tutorial/response-model.md) का उपयोग करें और *path operation decorator* में `response_class` declare न करें।
{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
## HTML Response { #html-response }
**FastAPI** से सीधे HTML के साथ response लौटाने के लिए, `HTMLResponse` का उपयोग करें।
* `HTMLResponse` import करें।
* अपने *path operation decorator* के parameter `response_class` के रूप में `HTMLResponse` pass करें।
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// note | नोट
Parameter `response_class` का उपयोग response के "media type" को define करने के लिए भी किया जाएगा।
इस मामले में, HTTP header `Content-Type` को `text/html` पर set किया जाएगा।
और इसे OpenAPI में इसी तरह document किया जाएगा।
///
### `Response` लौटाएँ { #return-a-response }
जैसा कि [सीधे Response लौटाएँ](response-directly.md) में देखा गया है, आप अपनी *path operation* में response को सीधे लौटाकर भी override कर सकते हैं।
ऊपर वाला वही उदाहरण, जो `HTMLResponse` लौटाता है, इस तरह दिख सकता है:
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning | चेतावनी
आपकी *path operation function* द्वारा सीधे लौटाया गया `Response` OpenAPI में document नहीं होगा (उदाहरण के लिए, `Content-Type` document नहीं होगा) और automatic interactive docs में visible नहीं होगा।
///
/// note | नोट
बेशक, वास्तविक `Content-Type` header, status code, आदि, आपके द्वारा लौटाए गए `Response` object से आएँगे।
///
### OpenAPI में document करें और `Response` override करें { #document-in-openapi-and-override-response }
यदि आप function के अंदर से response को override करना चाहते हैं लेकिन साथ ही OpenAPI में "media type" document करना चाहते हैं, तो आप `response_class` parameter का उपयोग कर सकते हैं और `Response` object भी लौटा सकते हैं।
तब `response_class` का उपयोग केवल OpenAPI *path operation* को document करने के लिए किया जाएगा, लेकिन आपका `Response` जैसा है वैसा ही उपयोग किया जाएगा।
#### सीधे `HTMLResponse` लौटाएँ { #return-an-htmlresponse-directly }
उदाहरण के लिए, यह कुछ ऐसा हो सकता है:
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
इस उदाहरण में, function `generate_html_response()` पहले से ही HTML को `str` में लौटाने के बजाय `Response` generate करके लौटाता है।
`generate_html_response()` को call करने का result लौटाकर, आप पहले से ही एक `Response` लौटा रहे हैं जो default **FastAPI** behavior को override करेगा।
लेकिन क्योंकि आपने `response_class` में भी `HTMLResponse` pass किया है, **FastAPI** को पता होगा कि इसे OpenAPI और interactive docs में `text/html` के साथ HTML के रूप में कैसे document करना है:
<img src="/img/tutorial/custom-response/image01.png">
## उपलब्ध responses { #available-responses }
यहाँ कुछ उपलब्ध responses दिए गए हैं।
ध्यान रखें कि आप कुछ और लौटाने के लिए `Response` का उपयोग कर सकते हैं, या custom sub-class भी बना सकते हैं।
/// note | तकनीकी विवरण
आप `from starlette.responses import HTMLResponse` भी उपयोग कर सकते हैं।
**FastAPI** आपकी सुविधा के लिए, developer के रूप में, वही `starlette.responses` `fastapi.responses` के रूप में प्रदान करता है। लेकिन अधिकांश उपलब्ध responses सीधे Starlette से आते हैं।
///
### `Response` { #response }
मुख्य `Response` class, बाकी सभी responses इससे inherit करते हैं।
आप इसे सीधे लौटा सकते हैं।
यह निम्नलिखित parameters accept करता है:
* `content` - एक `str` या `bytes`
* `status_code` - एक `int` HTTP status code।
* `headers` - strings का एक `dict`
* `media_type` - media type बताने वाला एक `str`। उदाहरण के लिए `"text/html"`
FastAPI (असल में Starlette) अपने आप एक Content-Length header शामिल करेगा। यह `media_type` के आधार पर Content-Type header भी शामिल करेगा और text types के लिए charset append करेगा।
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
कुछ text या bytes लेता है और HTML response लौटाता है, जैसा आपने ऊपर पढ़ा।
### `PlainTextResponse` { #plaintextresponse }
कुछ text या bytes लेता है और plain text response लौटाता है।
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
कुछ data लेता है और `application/json` encoded response लौटाता है।
जैसा आपने ऊपर पढ़ा, यह **FastAPI** में उपयोग किया जाने वाला default response है।
/// note | तकनीकी विवरण
लेकिन यदि आप response model या return type declare करते हैं, तो उसका उपयोग सीधे data को JSON में serialize करने के लिए किया जाएगा, और JSON के लिए सही media type वाला response सीधे लौटाया जाएगा, `JSONResponse` class का उपयोग किए बिना।
यह best performance पाने का ideal तरीका है।
///
### `RedirectResponse` { #redirectresponse }
HTTP redirect लौटाता है। Default रूप से 307 status code (Temporary Redirect) का उपयोग करता है।
आप सीधे `RedirectResponse` लौटा सकते हैं:
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
या आप इसे `response_class` parameter में उपयोग कर सकते हैं:
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
यदि आप ऐसा करते हैं, तो आप अपनी *path operation* function से URL सीधे लौटा सकते हैं।
इस मामले में, उपयोग किया गया `status_code` `RedirectResponse` के लिए default वाला होगा, जो `307` है।
---
आप `status_code` parameter को `response_class` parameter के साथ combine करके भी उपयोग कर सकते हैं:
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
एक async generator या सामान्य generator/iterator (`yield` वाली function) लेता है और response body को stream करता है।
{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
/// note | तकनीकी विवरण
एक `async` task केवल तब cancel किया जा सकता है जब वह किसी `await` तक पहुँचता है। यदि कोई `await` नहीं है, तो generator (`yield` वाली function) ठीक से cancel नहीं हो सकता और cancellation request किए जाने के बाद भी चलना जारी रख सकता है।
चूँकि इस छोटे उदाहरण को किसी `await` statement की आवश्यकता नहीं है, हम event loop को cancellation handle करने का अवसर देने के लिए `await anyio.sleep(0)` जोड़ते हैं।
यह बड़े या infinite streams के साथ और भी अधिक महत्वपूर्ण होगा।
///
/// tip | टिप
सीधे `StreamingResponse` लौटाने के बजाय, आपको शायद [Stream Data](./stream-data.md) में दिए गए style का पालन करना चाहिए, यह कहीं अधिक सुविधाजनक है और आपके लिए पर्दे के पीछे cancellation handle करता है।
यदि आप JSON Lines stream कर रहे हैं, तो [Stream JSON Lines](../tutorial/stream-json-lines.md) tutorial का पालन करें।
///
### `FileResponse` { #fileresponse }
एक file को response के रूप में asynchronously stream करता है।
Instantiate करने के लिए अन्य response types की तुलना में अलग set of arguments लेता है:
* `path` - stream की जाने वाली file का file path।
* `headers` - dictionary के रूप में शामिल किए जाने वाले कोई भी custom headers।
* `media_type` - media type बताने वाली string। यदि unset है, तो media type infer करने के लिए filename या path का उपयोग किया जाएगा।
* `filename` - यदि set है, तो इसे response `Content-Disposition` में शामिल किया जाएगा।
File responses में उपयुक्त `Content-Length`, `Last-Modified` और `ETag` headers शामिल होंगे।
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
आप `response_class` parameter का उपयोग भी कर सकते हैं:
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
इस मामले में, आप अपनी *path operation* function से file path सीधे लौटा सकते हैं।
## Custom response class { #custom-response-class }
आप `Response` से inherit करके और उसका उपयोग करके अपनी खुद की custom response class बना सकते हैं।
उदाहरण के लिए, मान लें कि आप कुछ settings के साथ [`orjson`](https://github.com/ijl/orjson) का उपयोग करना चाहते हैं।
मान लें आप चाहते हैं कि यह indented और formatted JSON लौटाए, इसलिए आप orjson option `orjson.OPT_INDENT_2` का उपयोग करना चाहते हैं।
आप `CustomORJSONResponse` बना सकते हैं। आपको मुख्य रूप से `Response.render(content)` method बनाना है जो content को `bytes` के रूप में लौटाता है:
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
अब यह लौटाने के बजाय:
```json
{"message": "Hello World"}
```
...यह response लौटाएगा:
```json
{
"message": "Hello World"
}
```
बेशक, JSON formatting की तुलना में इसका लाभ उठाने के लिए आपको शायद कहीं बेहतर तरीके मिलेंगे। 😉
### `orjson` या Response Model { #orjson-or-response-model }
यदि आप performance खोज रहे हैं, तो शायद `orjson` response की तुलना में [Response Model](../tutorial/response-model.md) का उपयोग करना आपके लिए बेहतर होगा।
Response model के साथ, FastAPI data को JSON में serialize करने के लिए Pydantic का उपयोग करेगा, intermediate steps के बिना, जैसे `jsonable_encoder` के साथ convert करना, जो किसी भी अन्य मामले में होता।
और अंदर से, Pydantic JSON में serialize करने के लिए `orjson` जैसे ही underlying Rust mechanisms का उपयोग करता है, इसलिए response model के साथ आपको पहले से ही best performance मिल जाएगी।
## Default response class { #default-response-class }
**FastAPI** class instance या `APIRouter` बनाते समय आप specify कर सकते हैं कि default रूप से कौन-सी response class उपयोग करनी है।
इसे define करने वाला parameter `default_response_class` है।
नीचे दिए गए उदाहरण में, **FastAPI** सभी *path operations* में JSON के बजाय default रूप से `HTMLResponse` का उपयोग करेगा।
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip | टिप
आप पहले की तरह *path operations* में अब भी `response_class` override कर सकते हैं।
///
## अतिरिक्त documentation { #additional-documentation }
आप `responses` का उपयोग करके OpenAPI में media type और कई अन्य details भी declare कर सकते हैं: [OpenAPI में अतिरिक्त Responses](additional-responses.md)।

95
docs/hi/docs/advanced/dataclasses.md

@ -0,0 +1,95 @@
# Dataclasses का उपयोग { #using-dataclasses }
FastAPI **Pydantic** के ऊपर बनाया गया है, और मैंने आपको दिखाया है कि requests और responses घोषित करने के लिए Pydantic models का उपयोग कैसे करें।
लेकिन FastAPI उसी तरह [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) का उपयोग भी support करता है:
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
यह अभी भी **Pydantic** की वजह से support किया जाता है, क्योंकि इसमें [`dataclasses` के लिए internal support](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel) है।
इसलिए, ऊपर दिए गए code में भी, जो Pydantic का स्पष्ट रूप से उपयोग नहीं करता, FastAPI उन standard dataclasses को Pydantic की अपनी तरह की dataclasses में बदलने के लिए Pydantic का उपयोग कर रहा है।
और निश्चित रूप से, यह इन्हें भी support करता है:
* data validation
* data serialization
* data documentation, आदि।
यह Pydantic models की तरह ही काम करता है। और अंदर से यह वास्तव में उसी तरह, Pydantic का उपयोग करके हासिल किया जाता है।
/// note | नोट
ध्यान रखें कि dataclasses वह सब कुछ नहीं कर सकतीं जो Pydantic models कर सकते हैं।
इसलिए, आपको अभी भी Pydantic models का उपयोग करना पड़ सकता है।
लेकिन अगर आपके पास बहुत सारी dataclasses पहले से मौजूद हैं, तो FastAPI का उपयोग करके web API को power देने के लिए उनका उपयोग करने की यह एक अच्छी तरकीब है। 🤓
///
## `response_model` में Dataclasses { #dataclasses-in-response-model }
आप `response_model` parameter में भी `dataclasses` का उपयोग कर सकते हैं:
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
dataclass अपने आप Pydantic dataclass में बदल जाएगी।
इस तरह, उसका schema API docs के user interface में दिखाई देगा:
<img src="/img/tutorial/dataclasses/image01.png">
## Nested Data Structures में Dataclasses { #dataclasses-in-nested-data-structures }
आप nested data structures बनाने के लिए `dataclasses` को अन्य type annotations के साथ भी जोड़ सकते हैं।
कुछ मामलों में, आपको अभी भी Pydantic के `dataclasses` वाले version का उपयोग करना पड़ सकता है। उदाहरण के लिए, अगर automatically generated API documentation में errors हों।
उस स्थिति में, आप standard `dataclasses` को बस `pydantic.dataclasses` से बदल सकते हैं, जो एक drop-in replacement है:
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. हम अभी भी standard `dataclasses` से `field` import करते हैं।
2. `pydantic.dataclasses`, `dataclasses` के लिए एक drop-in replacement है।
3. `Author` dataclass में `Item` dataclasses की एक list शामिल है।
4. `Author` dataclass को `response_model` parameter के रूप में उपयोग किया गया है।
5. आप request body के रूप में dataclasses के साथ अन्य standard type annotations का उपयोग कर सकते हैं।
इस मामले में, यह `Item` dataclasses की एक list है।
6. यहाँ हम एक dictionary return कर रहे हैं जिसमें `items` है, जो dataclasses की एक list है।
FastAPI अभी भी data को JSON में <dfn title="data को ऐसे format में बदलना जिसे भेजा जा सके">serialize करने</dfn> में सक्षम है।
7. यहाँ `response_model`, `Author` dataclasses की list के type annotation का उपयोग कर रहा है।
फिर से, आप `dataclasses` को standard type annotations के साथ जोड़ सकते हैं।
8. ध्यान दें कि यह *path operation function* `async def` की बजाय सामान्य `def` का उपयोग करता है।
हमेशा की तरह, FastAPI में आप आवश्यकता के अनुसार `def` और `async def` को जोड़ सकते हैं।
अगर आपको यह याद दिलाने की आवश्यकता है कि किसे कब उपयोग करना है, तो [`async` और `await`](../async.md#in-a-hurry) के docs में _"जल्दी में हैं?"_ section देखें।
9. यह *path operation function* dataclasses return नहीं कर रहा है (हालाँकि कर सकता था), बल्कि internal data वाली dictionaries की list return कर रहा है।
FastAPI response को बदलने के लिए `response_model` parameter (जिसमें dataclasses शामिल हैं) का उपयोग करेगा।
आप जटिल data structures बनाने के लिए `dataclasses` को कई अलग-अलग combinations में अन्य type annotations के साथ जोड़ सकते हैं।
अधिक विशिष्ट विवरण देखने के लिए ऊपर दिए गए in-code annotation tips देखें।
## और जानें { #learn-more }
आप `dataclasses` को अन्य Pydantic models के साथ भी जोड़ सकते हैं, उनसे inherit कर सकते हैं, उन्हें अपने models में शामिल कर सकते हैं, आदि।
अधिक जानने के लिए, [dataclasses के बारे में Pydantic docs](https://docs.pydantic.dev/latest/concepts/dataclasses/) देखें।
## Version { #version }
यह FastAPI version `0.67.0` से उपलब्ध है। 🔖

165
docs/hi/docs/advanced/events.md

@ -0,0 +1,165 @@
# Lifespan Events { #lifespan-events }
आप ऐसी logic (code) define कर सकते हैं जिसे application के **starts up** होने से पहले execute किया जाना चाहिए। इसका मतलब है कि यह code application के **requests receive करना शुरू करने से पहले**, **एक बार** execute होगा।
उसी तरह, आप ऐसी logic (code) define कर सकते हैं जिसे application के **shutting down** होने पर execute किया जाना चाहिए। इस मामले में, यह code संभवतः **कई requests** handle करने के **बाद**, **एक बार** execute होगा।
क्योंकि यह code application के requests लेना **शुरू** करने से पहले, और requests handle करना **पूरा** करने के तुरंत बाद execute होता है, यह पूरी application **lifespan** को cover करता है (शब्द "lifespan" थोड़ी देर में महत्वपूर्ण होगा 😉)।
यह उन **resources** को setup करने के लिए बहुत उपयोगी हो सकता है जिनकी आपको पूरी app में जरूरत होती है, और जो requests के बीच **shared** होते हैं, और/या जिन्हें आपको बाद में **clean up** करना होता है। उदाहरण के लिए, database connection pool, या कोई shared machine learning model load करना।
## Use Case { #use-case }
आइए एक उदाहरण **use case** से शुरू करते हैं और फिर देखते हैं कि इसे इससे कैसे solve किया जाए।
मान लीजिए कि आपके पास कुछ **machine learning models** हैं जिन्हें आप requests handle करने के लिए use करना चाहते हैं। 🤖
वही models requests के बीच shared हैं, इसलिए, यह हर request के लिए एक model, या हर user के लिए एक model या ऐसा कुछ नहीं है।
मान लीजिए कि model load करने में **काफी समय लग सकता है**, क्योंकि उसे disk से बहुत सारा **data** read करना होता है। इसलिए आप इसे हर request के लिए नहीं करना चाहते।
आप इसे module/file के top level पर load कर सकते हैं, लेकिन इसका मतलब यह भी होगा कि अगर आप सिर्फ एक simple automated test run कर रहे हैं, तब भी यह **model load** करेगा, और फिर वह test **slow** होगा क्योंकि code के किसी independent part को run कर पाने से पहले उसे model load होने का इंतजार करना पड़ेगा।
यही हम solve करेंगे, चलिए model को requests handle होने से पहले load करते हैं, लेकिन केवल application के requests receive करना शुरू करने से ठीक पहले, code load होते समय नहीं।
## Lifespan { #lifespan }
आप `FastAPI` app के `lifespan` parameter और एक "context manager" (मैं अभी दिखाऊंगा कि यह क्या है) का use करके यह *startup* और *shutdown* logic define कर सकते हैं।
आइए एक उदाहरण से शुरू करते हैं और फिर इसे detail में देखते हैं।
हम `yield` के साथ एक async function `lifespan()` इस तरह create करते हैं:
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
यहां हम `yield` से पहले machine learning models वाली dictionary में (fake) model function रखकर model load करने वाली महंगी *startup* operation को simulate कर रहे हैं। यह code application के **requests लेना शुरू करने से पहले**, *startup* के दौरान execute होगा।
और फिर, `yield` के तुरंत बाद, हम model unload करते हैं। यह code application के **requests handle करना पूरा करने के बाद**, *shutdown* से ठीक पहले execute होगा। उदाहरण के लिए, यह memory या GPU जैसे resources release कर सकता है।
/// tip | सुझाव
`shutdown` तब होगा जब आप application को **stop** कर रहे होंगे।
शायद आपको कोई नया version start करना हो, या आप इसे चलाते-चलाते बस थक गए हों। 🤷
///
### Lifespan function { #lifespan-function }
ध्यान देने वाली पहली चीज यह है कि हम `yield` के साथ एक async function define कर रहे हैं। यह `yield` वाली Dependencies से बहुत मिलता-जुलता है।
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
function का पहला हिस्सा, `yield` से पहले वाला, application start होने से **पहले** execute होगा।
और `yield` के बाद वाला हिस्सा application के finish हो जाने के **बाद** execute होगा।
### Async Context Manager { #async-context-manager }
अगर आप check करें, तो function को `@asynccontextmanager` से decorate किया गया है।
यह function को "**async context manager**" नाम की चीज में convert करता है।
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
Python में एक **context manager** ऐसी चीज है जिसे आप `with` statement में use कर सकते हैं, उदाहरण के लिए, `open()` को context manager की तरह use किया जा सकता है:
```Python
with open("file.txt") as file:
file.read()
```
Python के नए versions में, एक **async context manager** भी है। आप इसे `async with` के साथ use करेंगे:
```Python
async with lifespan(app):
await do_stuff()
```
जब आप ऊपर की तरह कोई context manager या async context manager create करते हैं, तो यह क्या करता है कि `with` block में enter करने से पहले, यह `yield` से पहले वाला code execute करेगा, और `with` block से exit करने के बाद, यह `yield` के बाद वाला code execute करेगा।
ऊपर हमारे code example में, हम इसे सीधे use नहीं करते, बल्कि FastAPI को pass करते हैं ताकि वह इसे use कर सके।
`FastAPI` app का `lifespan` parameter एक **async context manager** लेता है, इसलिए हम अपना नया `lifespan` async context manager उसे pass कर सकते हैं।
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
## Alternative Events (deprecated) { #alternative-events-deprecated }
/// warning | चेतावनी
*startup* और *shutdown* को handle करने का recommended तरीका ऊपर बताए गए अनुसार `FastAPI` app के `lifespan` parameter का use करना है। अगर आप `lifespan` parameter provide करते हैं, तो `startup` और `shutdown` event handlers अब call नहीं किए जाएंगे। यह पूरा `lifespan` होगा या पूरे events, दोनों नहीं।
आप शायद यह हिस्सा skip कर सकते हैं।
///
इस logic को *startup* के दौरान और *shutdown* के दौरान execute करने के लिए define करने का एक alternative तरीका है।
आप event handlers (functions) define कर सकते हैं जिन्हें application के starts up होने से पहले, या application के shutting down होने पर execute किया जाना चाहिए।
इन functions को `async def` या normal `def` के साथ declare किया जा सकता है।
### `startup` event { #startup-event }
application start होने से पहले run होने वाला function add करने के लिए, इसे event `"startup"` के साथ declare करें:
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
इस मामले में, `startup` event handler function items "database" (बस एक `dict`) को कुछ values के साथ initialize करेगा।
आप एक से अधिक event handler function add कर सकते हैं।
और आपकी application requests receive करना तब तक शुरू नहीं करेगी जब तक सभी `startup` event handlers complete नहीं हो जाते।
### `shutdown` event { #shutdown-event }
application के shutting down होने पर run होने वाला function add करने के लिए, इसे event `"shutdown"` के साथ declare करें:
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
यहां, `shutdown` event handler function एक text line `"Application shutdown"` को `log.txt` file में write करेगा।
/// note | नोट
`open()` function में, `mode="a"` का मतलब "append" होता है, इसलिए, line उस file में जो भी है उसके बाद add की जाएगी, पिछले contents को overwrite किए बिना।
///
/// tip | सुझाव
ध्यान दें कि इस मामले में हम एक standard Python `open()` function use कर रहे हैं जो एक file के साथ interact करता है।
इसलिए, इसमें I/O (input/output) शामिल है, जिसके लिए चीजों के disk पर write होने का "waiting" करना पड़ता है।
लेकिन `open()` `async` और `await` use नहीं करता।
इसलिए, हम event handler function को `async def` के बजाय standard `def` के साथ declare करते हैं।
///
### `startup` और `shutdown` साथ में { #startup-and-shutdown-together }
इस बात की काफी संभावना है कि आपके *startup* और *shutdown* की logic connected हो, आप शायद कुछ start करना और फिर उसे finish करना, कोई resource acquire करना और फिर उसे release करना, आदि चाहें।
इसे अलग-अलग functions में करना, जो logic या variables को साथ में share नहीं करते, अधिक कठिन है क्योंकि आपको values को global variables या इसी तरह की tricks में store करना पड़ेगा।
इसी वजह से, अब इसके बजाय ऊपर explain किए गए `lifespan` को use करने की recommendation है।
## Technical Details { #technical-details }
जिज्ञासु nerds के लिए बस एक technical detail। 🤓
अंदर से, ASGI technical specification में, यह [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html) का हिस्सा है, और यह `startup` और `shutdown` नाम के events define करता है।
/// note | नोट
आप Starlette `lifespan` handlers के बारे में [Starlette की Lifespan docs](https://www.starlette.dev/lifespan/) में और पढ़ सकते हैं।
इसमें यह भी शामिल है कि lifespan state को कैसे handle किया जाए जिसे आपके code के अन्य areas में use किया जा सकता है।
///
## Sub Applications { #sub-applications }
🚨 ध्यान रखें कि ये lifespan events (startup और shutdown) केवल main application के लिए execute होंगे, [Sub Applications - Mounts](sub-applications.md) के लिए नहीं।

192
docs/hi/docs/advanced/generate-clients.md

@ -0,0 +1,192 @@
# SDKs जेनरेट करना { #generating-sdks }
क्योंकि **FastAPI** **OpenAPI** specification पर आधारित है, इसकी APIs को एक standard format में वर्णित किया जा सकता है जिसे कई tools समझते हैं।
इससे up-to-date **documentation**, कई भाषाओं में client libraries (<abbr title="Software Development Kits - सॉफ़्टवेयर Development Kits">**SDKs**</abbr>), और **testing** या **automation workflows** जेनरेट करना आसान हो जाता है, जो आपके code के साथ sync में रहते हैं।
इस guide में, आप सीखेंगे कि अपने FastAPI backend के लिए **TypeScript SDK** कैसे जेनरेट करें।
## Open Source SDK Generators { #open-source-sdk-generators }
एक versatile विकल्प [OpenAPI Generator](https://openapi-generator.tech/) है, जो **कई programming languages** को support करता है और आपकी OpenAPI specification से SDKs जेनरेट कर सकता है।
**TypeScript clients** के लिए, [Hey API](https://heyapi.dev/) एक purpose-built solution है, जो TypeScript ecosystem के लिए optimized experience प्रदान करता है।
आप [OpenAPI.Tools](https://openapi.tools/#sdk) पर और SDK generators खोज सकते हैं।
/// tip | सुझाव
FastAPI अपने-आप **OpenAPI 3.1** specifications जेनरेट करता है, इसलिए आपके द्वारा उपयोग किया जाने वाला कोई भी tool इस version को support करना चाहिए।
///
## TypeScript SDK बनाएँ { #create-a-typescript-sdk }
आइए एक सरल FastAPI application से शुरू करें:
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
ध्यान दें कि *path operations* उन models को define करते हैं जिनका उपयोग वे request payload और response payload के लिए करते हैं, `Item` और `ResponseMessage` models का उपयोग करके।
### API Docs { #api-docs }
यदि आप `/docs` पर जाते हैं, तो आप देखेंगे कि इसमें requests में भेजे जाने और responses में प्राप्त होने वाले data के लिए **schemas** हैं:
<img src="/img/tutorial/generate-clients/image01.png">
आप वे schemas देख सकते हैं क्योंकि उन्हें app में models के साथ declare किया गया था।
वह जानकारी app के **OpenAPI schema** में उपलब्ध होती है, और फिर API docs में दिखाई जाती है।
Models से वही जानकारी जो OpenAPI में शामिल होती है, **client code जेनरेट करने** के लिए उपयोग की जा सकती है।
### Hey API { #hey-api }
जब हमारे पास models के साथ एक FastAPI app हो, तो हम Hey API का उपयोग करके TypeScript client जेनरेट कर सकते हैं। ऐसा करने का सबसे तेज़ तरीका npx के माध्यम से है।
```sh
npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
```
यह `./src/client` में TypeScript SDK जेनरेट करेगा।
आप उनकी website पर [`@hey-api/openapi-ts` install करना](https://heyapi.dev/openapi-ts/get-started) सीख सकते हैं और [generated output](https://heyapi.dev/openapi-ts/output) के बारे में पढ़ सकते हैं।
### SDK का उपयोग करना { #using-the-sdk }
अब आप client code को import करके उपयोग कर सकते हैं। यह कुछ ऐसा दिख सकता है, ध्यान दें कि आपको methods के लिए autocompletion मिलता है:
<img src="/img/tutorial/generate-clients/image02.png">
आपको भेजने के लिए payload के लिए भी autocompletion मिलेगा:
<img src="/img/tutorial/generate-clients/image03.png">
/// tip | सुझाव
`name` और `price` के लिए autocompletion पर ध्यान दें, जिसे FastAPI application में, `Item` model में define किया गया था।
///
आपके द्वारा भेजे जाने वाले data के लिए inline errors होंगे:
<img src="/img/tutorial/generate-clients/image04.png">
Response object में भी autocompletion होगा:
<img src="/img/tutorial/generate-clients/image05.png">
## Tags के साथ FastAPI App { #fastapi-app-with-tags }
कई मामलों में, आपका FastAPI app बड़ा होगा, और आप शायद *path operations* के अलग-अलग groups को separate करने के लिए tags का उपयोग करेंगे।
उदाहरण के लिए, आपके पास **items** के लिए एक section और **users** के लिए दूसरा section हो सकता है, और उन्हें tags द्वारा separate किया जा सकता है:
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
### Tags के साथ TypeScript Client जेनरेट करें { #generate-a-typescript-client-with-tags }
यदि आप tags का उपयोग करने वाले FastAPI app के लिए client जेनरेट करते हैं, तो यह सामान्यतः client code को भी tags के आधार पर separate करेगा।
इस तरह, आप client code के लिए चीज़ों को सही तरह से ordered और grouped रख पाएँगे:
<img src="/img/tutorial/generate-clients/image06.png">
इस मामले में, आपके पास हैं:
* `ItemsService`
* `UsersService`
### Client Method Names { #client-method-names }
अभी, जेनरेट किए गए method names जैसे `createItemItemsPost` बहुत साफ़ नहीं दिखते:
```TypeScript
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
```
...ऐसा इसलिए है क्योंकि client generator प्रत्येक *path operation* के लिए OpenAPI internal **operation ID** का उपयोग करता है।
OpenAPI required करता है कि प्रत्येक operation ID सभी *path operations* में unique हो, इसलिए FastAPI उस operation ID को जेनरेट करने के लिए **function name**, **path**, और **HTTP method/operation** का उपयोग करता है, क्योंकि इस तरह यह सुनिश्चित कर सकता है कि operation IDs unique हैं।
लेकिन मैं आगे आपको दिखाऊँगा कि इसे कैसे बेहतर बनाया जाए। 🤓
## Custom Operation IDs और बेहतर Method Names { #custom-operation-ids-and-better-method-names }
आप इन operation IDs को **जेनरेट** करने के तरीके को **modify** कर सकते हैं ताकि वे clients में सरल हों और **सरल method names** हों।
इस मामले में, आपको किसी दूसरे तरीके से सुनिश्चित करना होगा कि प्रत्येक operation ID **unique** हो।
उदाहरण के लिए, आप सुनिश्चित कर सकते हैं कि प्रत्येक *path operation* में एक tag हो, और फिर **tag** और *path operation* **name** (function name) के आधार पर operation ID जेनरेट करें।
### Custom Generate Unique ID Function { #custom-generate-unique-id-function }
FastAPI प्रत्येक *path operation* के लिए एक **unique ID** का उपयोग करता है, जिसका उपयोग **operation ID** के लिए और requests या responses के लिए आवश्यक किसी भी custom models के names के लिए भी किया जाता है।
आप उस function को customize कर सकते हैं। यह एक `APIRoute` लेता है और एक string output करता है।
उदाहरण के लिए, यहाँ यह पहले tag (आपके पास शायद केवल एक tag होगा) और *path operation* name (function name) का उपयोग कर रहा है।
फिर आप उस custom function को `generate_unique_id_function` parameter के रूप में **FastAPI** को pass कर सकते हैं:
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
### Custom Operation IDs के साथ TypeScript Client जेनरेट करें { #generate-a-typescript-client-with-custom-operation-ids }
अब, यदि आप client को फिर से जेनरेट करते हैं, तो आप देखेंगे कि इसमें बेहतर method names हैं:
<img src="/img/tutorial/generate-clients/image07.png">
जैसा कि आप देखते हैं, method names में अब tag और फिर function name है, अब वे URL path और HTTP operation की जानकारी शामिल नहीं करते।
### Client Generator के लिए OpenAPI Specification को Preprocess करें { #preprocess-the-openapi-specification-for-the-client-generator }
जेनरेट किए गए code में अभी भी कुछ **duplicated information** है।
हम पहले से जानते हैं कि यह method **items** से संबंधित है क्योंकि वह शब्द `ItemsService` (tag से लिया गया) में है, लेकिन method name में भी tag name prefixed है। 😕
हम शायद इसे सामान्य रूप से OpenAPI के लिए रखना चाहेंगे, क्योंकि यह सुनिश्चित करेगा कि operation IDs **unique** हैं।
लेकिन generated client के लिए, हम clients जेनरेट करने से ठीक पहले OpenAPI operation IDs को **modify** कर सकते हैं, ताकि उन method names को अधिक अच्छे और **cleaner** बनाया जा सके।
हम OpenAPI JSON को `openapi.json` file में download कर सकते हैं और फिर इस तरह के script से **उस prefixed tag को remove** कर सकते हैं:
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
//// tab | Node.js
```Javascript
{!> ../../docs_src/generate_clients/tutorial004.js!}
```
////
इसके साथ, operation IDs को `items-get_items` जैसी चीज़ों से बदलकर सिर्फ़ `get_items` कर दिया जाएगा, इस तरह client generator सरल method names जेनरेट कर सकता है।
### Preprocessed OpenAPI के साथ TypeScript Client जेनरेट करें { #generate-a-typescript-client-with-the-preprocessed-openapi }
क्योंकि अंतिम परिणाम अब `openapi.json` file में है, आपको अपनी input location update करनी होगी:
```sh
npx @hey-api/openapi-ts -i ./openapi.json -o src/client
```
नया client जेनरेट करने के बाद, अब आपके पास **clean method names** होंगे, सभी **autocompletion**, **inline errors**, आदि के साथ:
<img src="/img/tutorial/generate-clients/image08.png">
## लाभ { #benefits }
Automatically generated clients का उपयोग करते समय, आपको इन चीज़ों के लिए **autocompletion** मिलेगा:
* Methods.
* body में request payloads, query parameters, आदि।
* Response payloads.
आपके पास हर चीज़ के लिए **inline errors** भी होंगे।
और जब भी आप backend code update करते हैं, और frontend को **regenerate** करते हैं, तो इसमें methods के रूप में कोई भी नए *path operations* उपलब्ध होंगे, पुराने remove हो जाएँगे, और कोई भी अन्य change generated code में reflect होगा। 🤓
इसका मतलब यह भी है कि यदि कुछ बदलता है, तो वह client code में अपने-आप **reflect** होगा। और यदि आप client को **build** करते हैं, तो यदि उपयोग किए गए data में कोई **mismatch** है, तो यह error देगा।
इसलिए, आप development cycle में बहुत जल्दी **कई errors detect** कर लेंगे, बजाय इसके कि errors के production में आपके अंतिम users को दिखने का इंतज़ार करना पड़े और फिर यह debug करने की कोशिश करनी पड़े कि समस्या कहाँ है। ✨

21
docs/hi/docs/advanced/index.md

@ -0,0 +1,21 @@
# उन्नत उपयोगकर्ता गाइड { #advanced-user-guide }
## अतिरिक्त feature { #additional-features }
मुख्य [ट्यूटोरियल - उपयोगकर्ता गाइड](../tutorial/index.md) आपको **FastAPI** के सभी मुख्य feature का अवलोकन देने के लिए पर्याप्त होना चाहिए।
अगले sections में आप अन्य विकल्प, configurations, और अतिरिक्त feature देखेंगे।
/// tip | सुझाव
अगले sections **ज़रूरी नहीं कि "उन्नत"** हों।
और संभव है कि आपके उपयोग के मामले के लिए समाधान उनमें से किसी एक में हो।
///
## पहले ट्यूटोरियल पढ़ें { #read-the-tutorial-first }
आप मुख्य [ट्यूटोरियल - उपयोगकर्ता गाइड](../tutorial/index.md) से मिली जानकारी के साथ भी **FastAPI** के ज़्यादातर feature का उपयोग कर सकते हैं।
और अगले sections मानते हैं कि आपने इसे पहले ही पढ़ लिया है, और यह भी मानते हैं कि आप उन मुख्य विचारों को जानते हैं।

63
docs/hi/docs/advanced/json-base64-bytes.md

@ -0,0 +1,63 @@
# Base64 के रूप में Bytes वाला JSON { #json-with-bytes-as-base64 }
अगर आपके app को JSON data receive और send करना है, लेकिन आपको उसमें binary data शामिल करना है, तो आप उसे base64 के रूप में encode कर सकते हैं।
## Base64 बनाम Files { #base64-vs-files }
पहले यह विचार करें कि क्या आप binary data upload करने के लिए [Request Files](../tutorial/request-files.md) और binary data भेजने के लिए [कस्टम Response - FileResponse](./custom-response.md#fileresponse) का उपयोग कर सकते हैं, बजाय इसके कि उसे JSON में encode किया जाए।
JSON में केवल UTF-8 encoded strings हो सकती हैं, इसलिए उसमें raw bytes नहीं हो सकते।
Base64 binary data को strings में encode कर सकता है, लेकिन ऐसा करने के लिए उसे मूल binary data की तुलना में अधिक characters का उपयोग करना पड़ता है, इसलिए यह सामान्य files की तुलना में आमतौर पर कम efficient होगा।
Base64 का उपयोग केवल तभी करें जब आपको निश्चित रूप से JSON में binary data शामिल करना हो, और आप उसके लिए files का उपयोग नहीं कर सकते।
## Pydantic `bytes` { #pydantic-bytes }
आप `bytes` fields वाला एक Pydantic model declare कर सकते हैं, और फिर model config में `val_json_bytes` का उपयोग करके उसे बता सकते हैं कि input JSON data को *validate* करने के लिए base64 का उपयोग करे; उस validation के हिस्से के रूप में यह base64 string को bytes में decode करेगा।
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}
अगर आप `/docs` देखें, तो वे दिखाएँगे कि field `data` base64 encoded bytes की अपेक्षा करता है:
<div class="screenshot">
<img src="/img/tutorial/json-base64-bytes/image01.png">
</div>
आप इस तरह का request भेज सकते हैं:
```json
{
"description": "Some data",
"data": "aGVsbG8="
}
```
/// tip | सुझाव
`aGVsbG8=` `hello` की base64 encoding है।
///
और फिर Pydantic base64 string को decode करेगा और आपको model के `data` field में मूल bytes देगा।
आपको इस तरह का response मिलेगा:
```json
{
"description": "Some data",
"content": "hello"
}
```
## Output Data के लिए Pydantic `bytes` { #pydantic-bytes-for-output-data }
आप output data के लिए model config में `ser_json_bytes` के साथ `bytes` fields का भी उपयोग कर सकते हैं, और JSON response generate करते समय Pydantic bytes को base64 के रूप में *serialize* करेगा।
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}
## Input और Output Data के लिए Pydantic `bytes` { #pydantic-bytes-for-input-and-output-data }
और बेशक, JSON data receive और send करते समय आप उसी model को base64 उपयोग करने के लिए configure कर सकते हैं, ताकि input (*validate*) को `val_json_bytes` के साथ और output (*serialize*) को `ser_json_bytes` के साथ handle किया जा सके।
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}

97
docs/hi/docs/advanced/middleware.md

@ -0,0 +1,97 @@
# उन्नत Middleware { #advanced-middleware }
मुख्य tutorial में आपने पढ़ा कि अपनी application में [Custom Middleware](../tutorial/middleware.md) कैसे जोड़ें।
और फिर आपने यह भी पढ़ा कि [`CORSMiddleware` के साथ CORS](../tutorial/cors.md) को कैसे handle करें।
इस section में हम देखेंगे कि अन्य middleware का उपयोग कैसे करें।
## ASGI middleware जोड़ना { #adding-asgi-middlewares }
क्योंकि **FastAPI** Starlette पर आधारित है और <abbr title="Asynchronous Server Gateway Interface - asynchronous सर्वर गेटवे इंटरफ़ेस">ASGI</abbr> specification को implement करता है, आप कोई भी ASGI middleware उपयोग कर सकते हैं।
किसी middleware को काम करने के लिए FastAPI या Starlette के लिए बना होना required नहीं है, जब तक वह ASGI spec का पालन करता है।
सामान्यतः, ASGI middleware ऐसी classes होती हैं जो पहले argument के रूप में एक ASGI app प्राप्त करने की अपेक्षा करती हैं।
इसलिए, third-party ASGI middleware के documentation में वे शायद आपको कुछ ऐसा करने के लिए कहेंगे:
```Python
from unicorn import UnicornMiddleware
app = SomeASGIApp()
new_app = UnicornMiddleware(app, some_config="rainbow")
```
लेकिन FastAPI (वास्तव में Starlette) इसे करने का एक सरल तरीका प्रदान करता है, जो सुनिश्चित करता है कि internal middleware server errors को handle करें और custom exception handlers सही तरीके से काम करें।
इसके लिए, आप `app.add_middleware()` का उपयोग करते हैं (जैसे CORS के उदाहरण में)।
```Python
from fastapi import FastAPI
from unicorn import UnicornMiddleware
app = FastAPI()
app.add_middleware(UnicornMiddleware, some_config="rainbow")
```
`app.add_middleware()` पहले argument के रूप में एक middleware class प्राप्त करता है और middleware को pass किए जाने वाले कोई भी अतिरिक्त arguments भी प्राप्त करता है।
## एकीकृत middleware { #integrated-middlewares }
**FastAPI** common use cases के लिए कई middleware शामिल करता है, आगे हम देखेंगे कि उनका उपयोग कैसे करें।
/// note | तकनीकी विवरण
अगले उदाहरणों के लिए, आप `from starlette.middleware.something import SomethingMiddleware` भी उपयोग कर सकते हैं।
**FastAPI** `fastapi.middleware` में कई middleware सिर्फ आपकी, developer की, सुविधा के लिए प्रदान करता है। लेकिन उपलब्ध अधिकांश middleware सीधे Starlette से आते हैं।
///
## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
यह enforce करता है कि सभी incoming requests या तो `https` या `wss` हों।
`http` या `ws` पर आने वाली कोई भी incoming request इसके बजाय secure scheme पर redirect कर दी जाएगी।
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
यह enforce करता है कि सभी incoming requests में `Host` header सही तरीके से set हो, ताकि HTTP Host Header attacks से बचाव हो सके।
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
निम्नलिखित arguments supported हैं:
* `allowed_hosts` - domain names की एक सूची जिन्हें hostnames के रूप में allow किया जाना चाहिए। `*.example.com` जैसे Wildcard domains subdomains को match करने के लिए supported हैं। किसी भी hostname को allow करने के लिए या तो `allowed_hosts=["*"]` उपयोग करें या middleware को omit करें।
* `www_redirect` - यदि True पर set किया गया है, तो allowed hosts के non-www versions पर आने वाली requests उनके www counterparts पर redirect कर दी जाएँगी। Default `True` है।
यदि कोई incoming request सही तरीके से validate नहीं होती है तो `400` response भेजा जाएगा।
## `GZipMiddleware` { #gzipmiddleware }
ऐसी किसी भी request के लिए GZip responses handle करता है जिसमें `Accept-Encoding` header में `"gzip"` शामिल हो।
middleware standard और streaming दोनों responses को handle करेगा।
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
निम्नलिखित arguments supported हैं:
* `minimum_size` - इस minimum size से छोटे responses को GZip न करें, size bytes में है। Default `500` है।
* `compresslevel` - GZip compression के दौरान उपयोग किया जाता है। यह 1 से 9 तक की range में एक integer है। Default `9` है। कम value से compression तेज़ होता है लेकिन file sizes बड़ी होती हैं, जबकि अधिक value से compression धीमा होता है लेकिन file sizes छोटी होती हैं।
## अन्य middleware { #other-middlewares }
कई अन्य ASGI middleware हैं।
उदाहरण के लिए:
* [Uvicorn का `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
अन्य उपलब्ध middleware देखने के लिए [Starlette के Middleware docs](https://www.starlette.dev/middleware/) और [ASGI Awesome List](https://github.com/florimondmanca/awesome-asgi) देखें।

186
docs/hi/docs/advanced/openapi-callbacks.md

@ -0,0 +1,186 @@
# OpenAPI Callbacks { #openapi-callbacks }
आप एक ऐसी API बना सकते हैं जिसमें एक *path operation* हो जो किसी और के द्वारा बनाई गई *external API* को request trigger कर सके (शायद वही developer जो आपकी API का *उपयोग* करेगा)।
जब आपकी API app *external API* को call करती है, उस प्रक्रिया को "callback" कहा जाता है। क्योंकि external developer द्वारा लिखा गया software आपकी API को request भेजता है और फिर आपकी API *call back* करती है, यानी किसी *external API* को request भेजती है (जो शायद उसी developer द्वारा बनाई गई थी)।
इस स्थिति में, आप यह document करना चाह सकते हैं कि वह external API कैसी *होनी चाहिए*। उसमें कौन-सा *path operation* होना चाहिए, उसे कौन-सा body expect करना चाहिए, उसे कौन-सा response लौटाना चाहिए, आदि।
## Callbacks वाली एक app { #an-app-with-callbacks }
आइए इसे एक उदाहरण के साथ देखते हैं।
कल्पना करें कि आप एक ऐसी app develop करते हैं जो invoices बनाने देती है।
इन invoices में एक `id`, `title` (optional), `customer`, और `total` होगा।
आपकी API का user (एक external developer) आपकी API में POST request के साथ एक invoice बनाएगा।
फिर आपकी API (कल्पना करें):
* invoice को external developer के किसी customer को भेजेगी।
* पैसे collect करेगी।
* API user (external developer) को वापस एक notification भेजेगी।
* यह (*आपकी API* से) उस external developer द्वारा दी गई किसी *external API* को POST request भेजकर किया जाएगा (यही "callback" है)।
## सामान्य **FastAPI** app { #the-normal-fastapi-app }
Callback जोड़ने से पहले, पहले देखते हैं कि सामान्य API app कैसी दिखेगी।
इसमें एक *path operation* होगा जो एक `Invoice` body receive करेगा, और एक query parameter `callback_url` होगा जिसमें callback के लिए URL होगा।
यह हिस्सा काफ़ी सामान्य है, अधिकतर code शायद आपको पहले से परिचित होगा:
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
/// tip | सुझाव
`callback_url` query parameter एक Pydantic [Url](https://docs.pydantic.dev/latest/api/networks/) type का उपयोग करता है।
///
केवल नई चीज़ है *path operation decorator* के argument के रूप में `callbacks=invoices_callback_router.routes`। आगे हम देखेंगे कि यह क्या है।
## Callback को document करना { #documenting-the-callback }
वास्तविक callback code आपकी अपनी API app पर बहुत अधिक निर्भर करेगा।
और यह एक app से दूसरी app में काफ़ी अलग हो सकता है।
यह code की सिर्फ़ एक या दो lines भी हो सकती हैं, जैसे:
```Python
callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
```
लेकिन संभवतः callback का सबसे महत्वपूर्ण हिस्सा यह सुनिश्चित करना है कि आपका API user (external developer) *external API* को सही तरह से implement करे, उस data के अनुसार जिसे *आपकी API* callback के request body में भेजने वाली है, आदि।
तो, अब हम वह code जोड़ेंगे जो document करेगा कि *आपकी API* से callback receive करने के लिए वह *external API* कैसी दिखनी चाहिए।
यह documentation आपकी API में `/docs` पर Swagger UI में दिखाई देगी, और यह external developers को बताएगी कि *external API* कैसे बनानी है।
यह उदाहरण callback को स्वयं implement नहीं करता (वह केवल code की एक line हो सकती है), केवल documentation वाला हिस्सा करता है।
/// tip | सुझाव
वास्तविक callback सिर्फ़ एक HTTP request है।
Callback को स्वयं implement करते समय, आप [HTTPX](https://www.python-httpx.org) या [Requests](https://requests.readthedocs.io/) जैसी किसी चीज़ का उपयोग कर सकते हैं।
///
## Callback documentation code लिखें { #write-the-callback-documentation-code }
यह code आपकी app में execute नहीं होगा, हमें इसकी आवश्यकता केवल यह *document* करने के लिए है कि वह *external API* कैसी दिखनी चाहिए।
लेकिन, आप पहले से जानते हैं कि **FastAPI** के साथ किसी API के लिए automatic documentation आसानी से कैसे बनाई जाती है।
इसलिए हम उसी ज्ञान का उपयोग करके document करेंगे कि *external API* कैसी दिखनी चाहिए... उन *path operation(s)* को बनाकर जिन्हें external API को implement करना चाहिए (जिन्हें आपकी API call करेगी)।
/// tip | सुझाव
Callback को document करने के लिए code लिखते समय, यह कल्पना करना उपयोगी हो सकता है कि आप वही *external developer* हैं। और इस समय आप *external API* implement कर रहे हैं, *अपनी API* नहीं।
इस दृष्टिकोण को अस्थायी रूप से अपनाना (*external developer* का) आपको यह अधिक स्पष्ट महसूस कराने में मदद कर सकता है कि उस *external API* के लिए parameters, body के लिए Pydantic model, response के लिए model, आदि कहाँ रखने हैं।
///
### Callback `APIRouter` बनाएँ { #create-a-callback-apirouter }
पहले एक नया `APIRouter` बनाएँ जिसमें एक या अधिक callbacks होंगे।
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
### Callback *path operation* बनाएँ { #create-the-callback-path-operation }
Callback *path operation* बनाने के लिए वही `APIRouter` उपयोग करें जो आपने ऊपर बनाया था।
यह बिल्कुल सामान्य FastAPI *path operation* जैसा दिखना चाहिए:
* इसमें शायद उस body की declaration होनी चाहिए जिसे इसे receive करना है, जैसे `body: InvoiceEvent`
* और इसमें उस response की declaration भी हो सकती है जिसे इसे लौटाना चाहिए, जैसे `response_model=InvoiceEventReceived`
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
सामान्य *path operation* से 2 मुख्य अंतर हैं:
* इसमें कोई वास्तविक code होना required नहीं है, क्योंकि आपकी app इस code को कभी call नहीं करेगी। इसका उपयोग केवल *external API* को document करने के लिए किया जाता है। इसलिए, function में केवल `pass` हो सकता है।
* *path* में एक [OpenAPI 3 expression](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (नीचे और देखें) हो सकता है, जहाँ यह *आपकी API* को भेजी गई original request के parameters और parts के साथ variables का उपयोग कर सकता है।
### Callback path expression { #the-callback-path-expression }
Callback *path* में एक [OpenAPI 3 expression](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) हो सकता है जो *आपकी API* को भेजी गई original request के parts शामिल कर सकता है।
इस case में, यह `str` है:
```Python
"{$callback_url}/invoices/{$request.body.id}"
```
तो, यदि आपका API user (external developer) *आपकी API* को request भेजता है:
```
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
```
इस JSON body के साथ:
```JSON
{
"id": "2expen51ve",
"customer": "Mr. Richie Rich",
"total": "9999"
}
```
तो *आपकी API* invoice को process करेगी, और बाद में किसी समय, `callback_url` (*external API*) को callback request भेजेगी:
```
https://www.external.org/events/invoices/2expen51ve
```
ऐसे JSON body के साथ जिसमें कुछ इस तरह होगा:
```JSON
{
"description": "Payment celebration",
"paid": true
}
```
और यह उस *external API* से इस तरह के JSON body वाले response की अपेक्षा करेगी:
```JSON
{
"ok": true
}
```
/// tip | सुझाव
ध्यान दें कि उपयोग किए गए callback URL में `callback_url` (`https://www.external.org/events`) में query parameter के रूप में प्राप्त URL और JSON body के अंदर से invoice `id` (`2expen51ve`) दोनों शामिल हैं।
///
### Callback router जोड़ें { #add-the-callback-router }
इस समय आपके पास ऊपर बनाए गए callback router में required *callback path operation(s)* हैं (वे operation जिन्हें *external developer* को *external API* में implement करना चाहिए)।
अब *आपकी API के path operation decorator* में parameter `callbacks` का उपयोग करके उस callback router से attribute `.routes` pass करें:
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
/// tip | सुझाव
ध्यान दें कि आप router स्वयं (`invoices_callback_router`) को `callbacks=` में pass नहीं कर रहे हैं, बल्कि उसकी `.routes` को pass कर रहे हैं, जैसे `invoices_callback_router.routes`। FastAPI उन routes का उपयोग callback OpenAPI documentation generate करने के लिए करेगा।
///
### Docs देखें { #check-the-docs }
अब आप अपनी app start कर सकते हैं और [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) पर जा सकते हैं।
आपको अपनी docs में अपने *path operation* के लिए एक "Callbacks" section दिखेगा, जो दिखाता है कि *external API* कैसी दिखनी चाहिए:
<img src="/img/tutorial/openapi-callbacks/image01.png">

55
docs/hi/docs/advanced/openapi-webhooks.md

@ -0,0 +1,55 @@
# OpenAPI Webhooks { #openapi-webhooks }
ऐसे मामले होते हैं जहाँ आप अपने API **users** को बताना चाहते हैं कि आपकी app कुछ data के साथ (एक request भेजते हुए) *उनकी* app को कॉल कर सकती है, सामान्यतः किसी प्रकार के **event** की **सूचना** देने के लिए।
इसका मतलब है कि आपके users द्वारा आपकी API को requests भेजने की सामान्य प्रक्रिया के बजाय, **आपकी API** (या आपकी app) **उनके system को requests भेज** सकती है (उनकी API, उनकी app को)।
इसे सामान्यतः **webhook** कहा जाता है।
## Webhooks के चरण { #webhooks-steps }
सामान्यतः प्रक्रिया यह होती है कि **आप अपने code में define करते हैं** कि आप कौन-सा message भेजेंगे, यानी **request का body**
आप यह भी किसी तरीके से define करते हैं कि आपकी app किन **क्षणों** पर वे requests या events भेजेगी।
और **आपके users** किसी तरीके से (उदाहरण के लिए कहीं किसी web dashboard में) वह **URL** define करते हैं जहाँ आपकी app को वे requests भेजनी चाहिए।
Webhooks के लिए URLs को register करने की सारी **logic** और वास्तव में उन requests को भेजने का code आपके ऊपर है। आप इसे **अपने खुद के code** में जैसे चाहें वैसे लिखते हैं।
## **FastAPI** और OpenAPI के साथ webhooks का दस्तावेज़ीकरण { #documenting-webhooks-with-fastapi-and-openapi }
**FastAPI** के साथ, OpenAPI का उपयोग करते हुए, आप इन webhooks के नाम, आपकी app द्वारा भेजे जा सकने वाले HTTP operations के प्रकार (जैसे `POST`, `PUT`, आदि) और आपकी app द्वारा भेजे जाने वाले request **bodies** define कर सकते हैं।
इससे आपके users के लिए आपकी **webhook** requests प्राप्त करने के लिए **अपनी APIs implement करना** बहुत आसान हो सकता है, वे शायद अपने कुछ API code को autogenerate भी कर सकें।
/// note | नोट
Webhooks OpenAPI 3.1.0 और उससे ऊपर में उपलब्ध हैं, और FastAPI `0.99.0` और उससे ऊपर द्वारा समर्थित हैं।
///
## Webhooks वाली app { #an-app-with-webhooks }
जब आप एक **FastAPI** application बनाते हैं, तो एक `webhooks` attribute होता है जिसका उपयोग आप *webhooks* define करने के लिए कर सकते हैं, उसी तरह जैसे आप *path operations* define करते हैं, उदाहरण के लिए `@app.webhooks.post()` के साथ।
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
आप जिन webhooks को define करते हैं वे **OpenAPI** schema और automatic **docs UI** में आ जाएँगे।
/// note | नोट
`app.webhooks` object वास्तव में सिर्फ़ एक `APIRouter` है, वही type जिसका उपयोग आप अपनी app को multiple files के साथ structure करते समय करेंगे।
///
ध्यान दें कि webhooks के साथ आप वास्तव में कोई *path* declare नहीं कर रहे हैं (जैसे `/items/`), वहाँ आप जो text pass करते हैं वह केवल webhook का एक **identifier** है (event का नाम), उदाहरण के लिए `@app.webhooks.post("new-subscription")` में, webhook का नाम `new-subscription` है।
ऐसा इसलिए है क्योंकि उम्मीद की जाती है कि **आपके users** उस वास्तविक **URL path** को किसी और तरीके से define करेंगे जहाँ वे webhook request प्राप्त करना चाहते हैं (जैसे कोई web dashboard)।
### Docs देखें { #check-the-docs }
अब आप अपनी app start कर सकते हैं और [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) पर जा सकते हैं।
आप देखेंगे कि आपके docs में सामान्य *path operations* हैं और अब कुछ **webhooks** भी हैं:
<img src="/img/tutorial/openapi-webhooks/image01.png">

166
docs/hi/docs/advanced/path-operation-advanced-configuration.md

@ -0,0 +1,166 @@
# Path Operation की उन्नत Configuration { #path-operation-advanced-configuration }
## OpenAPI operationId { #openapi-operationid }
/// warning | चेतावनी
अगर आप OpenAPI में "expert" नहीं हैं, तो शायद आपको इसकी ज़रूरत नहीं है।
///
आप अपने *path operation* में उपयोग किए जाने वाले OpenAPI `operationId` को parameter `operation_id` के साथ सेट कर सकते हैं।
आपको यह सुनिश्चित करना होगा कि यह प्रत्येक operation के लिए unique हो।
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### *path operation function* के नाम को operationId के रूप में उपयोग करना { #using-the-path-operation-function-name-as-the-operationid }
अगर आप अपने APIs के function नामों को `operationId`s के रूप में उपयोग करना चाहते हैं, तो आप `FastAPI` को एक custom `generate_unique_id_function` पास कर सकते हैं।
यह function प्रत्येक `APIRoute` प्राप्त करता है और उस path operation के लिए उपयोग करने वाला `operationId` return करता है।
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2,5:6,9] *}
/// warning | चेतावनी
अगर आप ऐसा करते हैं, तो आपको यह सुनिश्चित करना होगा कि आपके प्रत्येक *path operation functions* का नाम unique हो।
भले ही वे अलग-अलग modules (Python files) में हों।
///
## OpenAPI से बाहर रखना { #exclude-from-openapi }
किसी *path operation* को generated OpenAPI schema से बाहर रखने के लिए (और इस प्रकार, automatic documentation systems से भी), parameter `include_in_schema` का उपयोग करें और इसे `False` पर सेट करें:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## Docstring से उन्नत description { #advanced-description-from-docstring }
आप OpenAPI के लिए किसी *path operation function* की docstring से उपयोग की जाने वाली lines को सीमित कर सकते हैं।
एक `\f` (एक escaped "form feed" character) जोड़ने से **FastAPI** इस बिंदु पर OpenAPI के लिए उपयोग किए जाने वाले output को truncate कर देता है।
यह documentation में नहीं दिखेगा, लेकिन अन्य tools (जैसे Sphinx) बाकी हिस्से का उपयोग कर सकेंगे।
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
## अतिरिक्त Responses { #additional-responses }
आपने शायद देखा होगा कि किसी *path operation* के लिए `response_model` और `status_code` कैसे declare किए जाते हैं।
यह किसी *path operation* के मुख्य response के बारे में metadata define करता है।
आप उनके models, status codes आदि के साथ अतिरिक्त responses भी declare कर सकते हैं।
इसके बारे में documentation में यहाँ एक पूरा chapter है, आप इसे [OpenAPI में अतिरिक्त Responses](additional-responses.md) पर पढ़ सकते हैं।
## OpenAPI Extra { #openapi-extra }
जब आप अपने application में कोई *path operation* declare करते हैं, तो **FastAPI** उस *path operation* के बारे में relevant metadata को automatically generate करता है, जिसे OpenAPI schema में शामिल किया जाता है।
/// note | तकनीकी विवरण
OpenAPI specification में इसे [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object) कहा जाता है।
///
इसमें *path operation* के बारे में सारी जानकारी होती है और इसका उपयोग automatic documentation generate करने के लिए किया जाता है।
इसमें `tags`, `parameters`, `requestBody`, `responses` आदि शामिल होते हैं।
यह *path operation*-specific OpenAPI schema सामान्यतः **FastAPI** द्वारा automatically generate किया जाता है, लेकिन आप इसे extend भी कर सकते हैं।
/// tip | सुझाव
यह एक low level extension point है।
अगर आपको केवल अतिरिक्त responses declare करने की ज़रूरत है, तो ऐसा करने का एक अधिक सुविधाजनक तरीका [OpenAPI में अतिरिक्त Responses](additional-responses.md) के साथ है।
///
आप parameter `openapi_extra` का उपयोग करके किसी *path operation* के लिए OpenAPI schema को extend कर सकते हैं।
### OpenAPI Extensions { #openapi-extensions }
यह `openapi_extra` उपयोगी हो सकता है, उदाहरण के लिए, [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) declare करने के लिए:
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
अगर आप automatic API docs खोलते हैं, तो आपका extension specific *path operation* के नीचे दिखाई देगा।
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
और अगर आप resulting OpenAPI (आपकी API में `/openapi.json` पर) देखते हैं, तो आपको अपना extension specific *path operation* के हिस्से के रूप में भी दिखाई देगा:
```JSON hl_lines="22"
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"summary": "Read Items",
"operationId": "read_items_items__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"x-aperture-labs-portal": "blue"
}
}
}
}
```
### Custom OpenAPI *path operation* schema { #custom-openapi-path-operation-schema }
`openapi_extra` में मौजूद dictionary को *path operation* के लिए automatically generated OpenAPI schema के साथ deeply merge किया जाएगा।
तो, आप automatically generated schema में अतिरिक्त data जोड़ सकते हैं।
उदाहरण के लिए, आप FastAPI की Pydantic के साथ automatic features का उपयोग किए बिना, अपने code से request को read और validate करने का निर्णय ले सकते हैं, लेकिन फिर भी आप OpenAPI schema में request को define करना चाह सकते हैं।
आप यह `openapi_extra` के साथ कर सकते हैं:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
इस उदाहरण में, हमने कोई Pydantic model declare नहीं किया। वास्तव में, request body को JSON के रूप में <dfn title="किसी plain format, जैसे bytes, से Python objects में बदला गया">parsed</dfn> भी नहीं किया गया है, इसे सीधे `bytes` के रूप में read किया गया है, और function `magic_data_reader()` किसी तरीके से इसे parse करने का ज़िम्मेदार होगा।
फिर भी, हम request body के लिए expected schema declare कर सकते हैं।
### Custom OpenAPI content type { #custom-openapi-content-type }
इसी trick का उपयोग करके, आप JSON Schema define करने के लिए Pydantic model का उपयोग कर सकते हैं, जिसे फिर *path operation* के लिए custom OpenAPI schema section में शामिल किया जाता है।
और आप ऐसा तब भी कर सकते हैं जब request में data type JSON न हो।
उदाहरण के लिए, इस application में हम Pydantic models से JSON Schema निकालने के लिए FastAPI की integrated functionality या JSON के लिए automatic validation का उपयोग नहीं करते हैं। वास्तव में, हम request content type को JSON नहीं, बल्कि YAML के रूप में declare कर रहे हैं:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
फिर भी, हालांकि हम default integrated functionality का उपयोग नहीं कर रहे हैं, हम अभी भी उस data के लिए JSON Schema manually generate करने के लिए Pydantic model का उपयोग कर रहे हैं जिसे हम YAML में receive करना चाहते हैं।
फिर हम request को सीधे उपयोग करते हैं, और body को `bytes` के रूप में extract करते हैं। इसका मतलब है कि FastAPI request payload को JSON के रूप में parse करने की कोशिश भी नहीं करेगा।
और फिर अपने code में, हम उस YAML content को सीधे parse करते हैं, और फिर हम YAML content को validate करने के लिए फिर से उसी Pydantic model का उपयोग कर रहे हैं:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip | सुझाव
यहाँ हम उसी Pydantic model को reuse करते हैं।
लेकिन इसी तरह, हम इसे किसी और तरीके से भी validate कर सकते थे।
///

31
docs/hi/docs/advanced/response-change-status-code.md

@ -0,0 +1,31 @@
# Response - Status Code बदलें { #response-change-status-code }
आपने शायद पहले पढ़ा होगा कि आप एक default [Response Status Code](../tutorial/response-status-code.md) सेट कर सकते हैं।
लेकिन कुछ मामलों में आपको default से अलग status code लौटाना पड़ता है।
## उपयोग का मामला { #use-case }
उदाहरण के लिए, कल्पना करें कि आप default रूप से "OK" `200` का HTTP status code लौटाना चाहते हैं।
लेकिन अगर data मौजूद नहीं था, तो आप उसे बनाना चाहते हैं, और "CREATED" `201` का HTTP status code लौटाना चाहते हैं।
लेकिन फिर भी आप `response_model` के साथ लौटाए गए data को filter और convert कर पाने में सक्षम रहना चाहते हैं।
ऐसे मामलों के लिए, आप `Response` parameter का उपयोग कर सकते हैं।
## `Response` parameter का उपयोग करें { #use-a-response-parameter }
आप अपनी *path operation function* में `Response` type का parameter घोषित कर सकते हैं (जैसा कि आप cookies और headers के लिए कर सकते हैं)।
और फिर आप उस *temporary* response object में `status_code` सेट कर सकते हैं।
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
और फिर आप अपनी ज़रूरत का कोई भी object लौटा सकते हैं, जैसा कि आप सामान्य रूप से करते हैं (एक `dict`, एक database model, आदि)।
और अगर आपने `response_model` घोषित किया है, तो यह आपके लौटाए गए object को filter और convert करने के लिए अभी भी उपयोग किया जाएगा।
**FastAPI** उस *temporary* response का उपयोग status code (साथ ही cookies और headers) निकालने के लिए करेगा, और उन्हें अंतिम response में डाल देगा जिसमें आपके द्वारा लौटाया गया value होगा, जिसे किसी भी `response_model` द्वारा filter किया गया होगा।
आप dependencies में भी `Response` parameter घोषित कर सकते हैं, और उनमें status code सेट कर सकते हैं। लेकिन ध्यान रखें कि आख़िरी बार जो सेट किया जाएगा, वही प्रभावी होगा।

51
docs/hi/docs/advanced/response-cookies.md

@ -0,0 +1,51 @@
# Response Cookies { #response-cookies }
## `Response` parameter का उपयोग करें { #use-a-response-parameter }
आप अपने *path operation function* में `Response` प्रकार का parameter घोषित कर सकते हैं।
और फिर आप उस *temporary* response object में cookies set कर सकते हैं।
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
और फिर आप अपनी ज़रूरत का कोई भी object return कर सकते हैं, जैसा कि आप सामान्य रूप से करते हैं (एक `dict`, database model, आदि)।
और अगर आपने `response_model` घोषित किया है, तो आपके द्वारा return किए गए object को filter और convert करने के लिए उसका अभी भी उपयोग किया जाएगा।
**FastAPI** उस *temporary* response का उपयोग cookies (साथ ही headers और status code) निकालने के लिए करेगा, और उन्हें final response में डाल देगा जिसमें आपके द्वारा return किया गया value होगा, किसी भी `response_model` द्वारा filter किया हुआ।
आप dependencies में भी `Response` parameter घोषित कर सकते हैं, और उनमें cookies (और headers) set कर सकते हैं।
## सीधे `Response` return करें { #return-a-response-directly }
आप अपने code में सीधे `Response` return करते समय भी cookies बना सकते हैं।
ऐसा करने के लिए, आप [सीधे Response Return करें](response-directly.md) में बताए अनुसार एक response बना सकते हैं।
फिर उसमें Cookies set करें, और फिर उसे return करें:
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip | सुझाव
ध्यान रखें कि अगर आप `Response` parameter का उपयोग करने के बजाय सीधे response return करते हैं, तो FastAPI उसे सीधे return करेगा।
इसलिए, आपको यह सुनिश्चित करना होगा कि आपका data सही प्रकार का है। उदाहरण के लिए, अगर आप `JSONResponse` return कर रहे हैं, तो वह JSON के साथ compatible हो।
और यह भी कि आप कोई ऐसा data नहीं भेज रहे हैं जिसे `response_model` द्वारा filter किया जाना चाहिए था।
///
### अधिक जानकारी { #more-info }
/// note | तकनीकी विवरण
आप `from starlette.responses import Response` या `from starlette.responses import JSONResponse` का भी उपयोग कर सकते हैं।
**FastAPI** आपकी सुविधा के लिए, developer के रूप में, वही `starlette.responses` `fastapi.responses` के रूप में प्रदान करता है। लेकिन उपलब्ध अधिकांश responses सीधे Starlette से आते हैं।
और क्योंकि `Response` का उपयोग अक्सर headers और cookies set करने के लिए किया जा सकता है, **FastAPI** इसे `fastapi.Response` पर भी प्रदान करता है।
///
सभी उपलब्ध parameters और options देखने के लिए, [Starlette में documentation](https://www.starlette.dev/responses/#set-cookie) देखें।

83
docs/hi/docs/advanced/response-directly.md

@ -0,0 +1,83 @@
# सीधे एक Response लौटाएँ { #return-a-response-directly }
जब आप **FastAPI** *path operation* बनाते हैं, तो सामान्यतः आप उससे कोई भी data लौटा सकते हैं: एक `dict`, एक `list`, एक Pydantic model, एक database model, आदि।
अगर आप [Response Model](../tutorial/response-model.md) declare करते हैं, तो FastAPI Pydantic का उपयोग करके data को JSON में serialize करने के लिए उसका उपयोग करेगा।
अगर आप response model declare नहीं करते, तो FastAPI [JSON Compatible Encoder](../tutorial/encoder.md) में समझाए गए `jsonable_encoder` का उपयोग करेगा और उसे एक `JSONResponse` में रखेगा।
आप सीधे एक `JSONResponse` भी बना सकते हैं और उसे लौटा सकते हैं।
/// tip | सुझाव
आम तौर पर सीधे `JSONResponse` लौटाने की तुलना में [Response Model](../tutorial/response-model.md) का उपयोग करने पर performance काफी बेहतर होगी, क्योंकि उस तरीके से यह Rust में Pydantic का उपयोग करके data serialize करता है।
///
## एक `Response` लौटाएँ { #return-a-response }
आप एक `Response` या उसकी कोई भी sub-class लौटा सकते हैं।
/// note | नोट
`JSONResponse` खुद `Response` की एक sub-class है।
///
और जब आप एक `Response` लौटाते हैं, तो **FastAPI** उसे सीधे pass कर देगा।
यह Pydantic models के साथ कोई data conversion नहीं करेगा, contents को किसी भी type में convert नहीं करेगा, आदि।
यह आपको बहुत अधिक **flexibility** देता है। आप कोई भी data type लौटा सकते हैं, किसी भी data declaration या validation को override कर सकते हैं, आदि।
यह आपको बहुत अधिक **responsibility** भी देता है। आपको यह सुनिश्चित करना होगा कि आप जो data लौटा रहे हैं वह सही है, सही format में है, वह serialize किया जा सकता है, आदि।
## `Response` में `jsonable_encoder` का उपयोग करना { #using-the-jsonable-encoder-in-a-response }
क्योंकि **FastAPI** आपके लौटाए गए `Response` में कोई बदलाव नहीं करता, आपको सुनिश्चित करना होगा कि उसके contents इसके लिए तैयार हैं।
उदाहरण के लिए, आप किसी Pydantic model को पहले `dict` में convert किए बिना `JSONResponse` में नहीं रख सकते, जिसमें सभी data types (जैसे `datetime`, `UUID`, आदि) JSON-compatible types में convert किए गए हों।
ऐसे मामलों के लिए, response को pass करने से पहले आप अपने data को convert करने के लिए `jsonable_encoder` का उपयोग कर सकते हैं:
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | तकनीकी विवरण
आप `from starlette.responses import JSONResponse` का भी उपयोग कर सकते हैं।
**FastAPI** आपकी सुविधा के लिए, developer के रूप में, वही `starlette.responses` `fastapi.responses` के रूप में उपलब्ध कराता है। लेकिन उपलब्ध अधिकांश responses सीधे Starlette से आते हैं।
///
## custom `Response` लौटाना { #returning-a-custom-response }
ऊपर दिया गया उदाहरण वे सभी हिस्से दिखाता है जिनकी आपको जरूरत है, लेकिन यह अभी बहुत उपयोगी नहीं है, क्योंकि आप सीधे `item` लौटा सकते थे, और **FastAPI** उसे आपके लिए `JSONResponse` में रख देता, उसे `dict` में convert करता, आदि। यह सब default रूप से होता है।
अब, देखते हैं कि आप इसका उपयोग custom response लौटाने के लिए कैसे कर सकते हैं।
मान लें कि आप एक [XML](https://en.wikipedia.org/wiki/XML) response लौटाना चाहते हैं।
आप अपना XML content एक string में रख सकते हैं, उसे `Response` में रख सकते हैं, और उसे लौटा सकते हैं:
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## Response Model कैसे काम करता है { #how-a-response-model-works }
जब आप किसी path operation में [Response Model - Return Type](../tutorial/response-model.md) declare करते हैं, तो **FastAPI** Pydantic का उपयोग करके data को JSON में serialize करने के लिए उसका उपयोग करेगा।
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
क्योंकि यह Rust side पर होगा, performance regular Python और `JSONResponse` class के साथ किए जाने की तुलना में काफी बेहतर होगी।
`response_model` या return type का उपयोग करते समय, FastAPI data को convert करने के लिए `jsonable_encoder` का उपयोग नहीं करेगा (जो धीमा होता), और न ही `JSONResponse` class का उपयोग करेगा।
इसके बजाय यह response model (या return type) का उपयोग करके Pydantic के साथ generate किए गए JSON bytes लेता है और JSON के लिए सही media type (`application/json`) के साथ सीधे एक `Response` लौटाता है।
## नोट्स { #notes }
जब आप सीधे एक `Response` लौटाते हैं, तो उसका data अपने-आप validate, convert (serialize), या document नहीं किया जाता।
लेकिन आप फिर भी उसे [OpenAPI में अतिरिक्त Responses](additional-responses.md) में बताए अनुसार document कर सकते हैं।
बाद के sections में आप देख सकते हैं कि automatic data conversion, documentation, आदि रखते हुए इन custom `Response`s का उपयोग/declare कैसे करें।

41
docs/hi/docs/advanced/response-headers.md

@ -0,0 +1,41 @@
# Response Headers { #response-headers }
## `Response` parameter का उपयोग करें { #use-a-response-parameter }
आप अपने *path operation function* में `Response` प्रकार का parameter घोषित कर सकते हैं (जैसा कि आप cookies के लिए कर सकते हैं)।
और फिर आप उस *अस्थायी* response object में headers सेट कर सकते हैं।
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
और फिर आप अपनी ज़रूरत का कोई भी object return कर सकते हैं, जैसा कि आप सामान्य रूप से करते हैं (एक `dict`, database model, आदि)।
और अगर आपने `response_model` घोषित किया है, तो वह अब भी आपके return किए गए object को filter और convert करने के लिए उपयोग किया जाएगा।
**FastAPI** headers (साथ ही cookies और status code) निकालने के लिए उस *अस्थायी* response का उपयोग करेगा, और उन्हें अंतिम response में डाल देगा जिसमें आपके द्वारा return किया गया value होता है, जिसे किसी भी `response_model` द्वारा filter किया गया होता है।
आप dependencies में भी `Response` parameter घोषित कर सकते हैं, और उनमें headers (और cookies) सेट कर सकते हैं।
## सीधे `Response` return करें { #return-a-response-directly }
जब आप सीधे `Response` return करते हैं, तब भी आप headers जोड़ सकते हैं।
[सीधे Response Return करें](response-directly.md) में वर्णित तरीके से response बनाएँ और headers को एक अतिरिक्त parameter के रूप में पास करें:
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
/// note | तकनीकी विवरण
आप `from starlette.responses import Response` या `from starlette.responses import JSONResponse` का भी उपयोग कर सकते हैं।
**FastAPI** आपकी, developer की, सुविधा के लिए वही `starlette.responses` `fastapi.responses` के रूप में प्रदान करता है। लेकिन उपलब्ध अधिकांश responses सीधे Starlette से आते हैं।
और क्योंकि `Response` का उपयोग अक्सर headers और cookies सेट करने के लिए किया जा सकता है, **FastAPI** इसे `fastapi.Response` पर भी प्रदान करता है।
///
## Custom Headers { #custom-headers }
ध्यान रखें कि custom proprietary headers को [`X-` prefix का उपयोग करके](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) जोड़ा जा सकता है।
लेकिन अगर आपके पास custom headers हैं जिन्हें आप चाहते हैं कि browser में कोई client देख सके, तो आपको उन्हें अपनी CORS configurations में जोड़ना होगा ([CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md) में और पढ़ें), इसके लिए [Starlette के CORS docs](https://www.starlette.dev/middleware/#corsmiddleware) में documented parameter `expose_headers` का उपयोग करें।

107
docs/hi/docs/advanced/security/http-basic-auth.md

@ -0,0 +1,107 @@
# HTTP Basic Auth { #http-basic-auth }
सबसे सरल मामलों के लिए, आप HTTP Basic Auth का उपयोग कर सकते हैं।
HTTP Basic Auth में, application एक header की अपेक्षा करता है जिसमें username और password होता है।
अगर उसे यह नहीं मिलता, तो यह HTTP 401 "Unauthorized" error लौटाता है।
और `WWW-Authenticate` header लौटाता है जिसका value `Basic` होता है, और एक optional `realm` parameter होता है।
यह browser को username और password के लिए integrated prompt दिखाने को कहता है।
फिर, जब आप वह username और password टाइप करते हैं, तो browser उन्हें header में अपने-आप भेज देता है।
## Simple HTTP Basic Auth { #simple-http-basic-auth }
* `HTTPBasic` और `HTTPBasicCredentials` import करें।
* `HTTPBasic` का उपयोग करके एक "`security` scheme" बनाएँ।
* अपने *path operation* में dependency के साथ उस `security` का उपयोग करें।
* यह `HTTPBasicCredentials` type का एक object लौटाता है:
* इसमें भेजे गए `username` और `password` होते हैं।
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
जब आप पहली बार URL खोलने की कोशिश करते हैं (या docs में "Execute" button पर क्लिक करते हैं), तो browser आपसे आपका username और password पूछेगा:
<img src="/img/tutorial/security/image12.png">
## Username जाँचें { #check-the-username }
यहाँ एक अधिक complete example है।
यह जाँचने के लिए dependency का उपयोग करें कि username और password सही हैं या नहीं।
इसके लिए, username और password जाँचने के लिए Python standard module [`secrets`](https://docs.python.org/3/library/secrets.html) का उपयोग करें।
`secrets.compare_digest()` को `bytes` या ऐसा `str` लेना होता है जिसमें केवल ASCII characters (English वाले) हों, इसका मतलब है कि यह `á` जैसे characters के साथ काम नहीं करेगा, जैसे `Sebastián` में।
इसे handle करने के लिए, हम पहले `username` और `password` को UTF-8 से encode करके `bytes` में convert करते हैं।
फिर हम `secrets.compare_digest()` का उपयोग करके यह सुनिश्चित कर सकते हैं कि `credentials.username` `"stanleyjobson"` है, और `credentials.password` `"swordfish"` है।
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
यह इसके समान होगा:
```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# कोई error लौटाएँ
...
```
लेकिन `secrets.compare_digest()` का उपयोग करने से यह "timing attacks" नाम के attacks के एक type के विरुद्ध सुरक्षित रहेगा।
### Timing Attacks { #timing-attacks }
लेकिन "timing attack" क्या होता है?
मान लीजिए कुछ attackers username और password का अनुमान लगाने की कोशिश कर रहे हैं।
और वे username `johndoe` और password `love123` के साथ एक request भेजते हैं।
तब आपकी application में Python code कुछ इस तरह के बराबर होगा:
```Python
if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
...
```
लेकिन जैसे ही Python `johndoe` में पहले `j` की तुलना `stanleyjobson` में पहले `s` से करता है, यह `False` लौटा देगा, क्योंकि उसे पहले से पता है कि ये दोनों strings समान नहीं हैं, यह सोचते हुए कि "बाकी अक्षरों की तुलना करके और computation खर्च करने की जरूरत नहीं है"। और आपकी application कहेगी "Incorrect username or password"।
लेकिन फिर attackers username `stanleyjobsox` और password `love123` के साथ कोशिश करते हैं।
और आपका application code कुछ ऐसा करता है:
```Python
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
...
```
Python को यह समझने से पहले कि दोनों strings समान नहीं हैं, `stanleyjobsox` और `stanleyjobson` दोनों में पूरे `stanleyjobso` की तुलना करनी पड़ेगी। इसलिए "Incorrect username or password" का reply वापस देने में कुछ extra microseconds लगेंगे।
#### जवाब देने में लगा समय attackers की मदद करता है { #the-time-to-answer-helps-the-attackers }
उस समय, यह देखकर कि server ने "Incorrect username or password" response भेजने में कुछ microseconds ज्यादा लिए, attackers जान जाएँगे कि उन्होंने _कुछ_ सही पाया है, शुरुआती अक्षरों में से कुछ सही थे।
और फिर वे यह जानते हुए फिर कोशिश कर सकते हैं कि यह शायद `johndoe` की तुलना में `stanleyjobsox` से ज्यादा मिलता-जुलता है।
#### एक "professional" attack { #a-professional-attack }
बेशक, attackers यह सब हाथ से नहीं करेंगे, वे इसे करने के लिए एक program लिखेंगे, संभवतः प्रति सेकंड हजारों या लाखों tests के साथ। और उन्हें एक समय में बस एक extra सही अक्षर मिलेगा।
लेकिन ऐसा करते हुए, कुछ minutes या hours में attackers ने हमारी application की "help" से सही username और password का अनुमान लगा लिया होगा, सिर्फ जवाब देने में लगे समय का उपयोग करके।
#### इसे `secrets.compare_digest()` से ठीक करें { #fix-it-with-secrets-compare-digest }
लेकिन हमारे code में हम वास्तव में `secrets.compare_digest()` का उपयोग कर रहे हैं।
संक्षेप में, `stanleyjobsox` की तुलना `stanleyjobson` से करने में उतना ही समय लगेगा जितना `johndoe` की तुलना `stanleyjobson` से करने में लगता है। और password के लिए भी वही।
इस तरह, अपने application code में `secrets.compare_digest()` का उपयोग करके, यह security attacks की इस पूरी range के विरुद्ध सुरक्षित रहेगा।
### Error लौटाएँ { #return-the-error }
यह detect करने के बाद कि credentials incorrect हैं, status code 401 (वही जो तब लौटाया जाता है जब कोई credentials provide नहीं किए जाते) के साथ एक `HTTPException` लौटाएँ और browser को login prompt फिर से दिखाने के लिए `WWW-Authenticate` header जोड़ें:
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}

19
docs/hi/docs/advanced/security/index.md

@ -0,0 +1,19 @@
# उन्नत सुरक्षा { #advanced-security }
## अतिरिक्त Features { #additional-features }
[Tutorial - User Guide: Security](../../tutorial/security/index.md) में शामिल चीज़ों के अलावा सुरक्षा संभालने के लिए कुछ अतिरिक्त features हैं।
/// tip | सुझाव
अगले sections **ज़रूरी नहीं कि "उन्नत" ही हों**
और यह संभव है कि आपके use case के लिए समाधान उनमें से किसी एक में हो।
///
## पहले Tutorial पढ़ें { #read-the-tutorial-first }
अगले sections मानकर चलते हैं कि आपने मुख्य [Tutorial - User Guide: Security](../../tutorial/security/index.md) पहले ही पढ़ लिया है।
वे सभी समान concepts पर आधारित हैं, लेकिन कुछ अतिरिक्त functionalities की अनुमति देते हैं।

274
docs/hi/docs/advanced/security/oauth2-scopes.md

@ -0,0 +1,274 @@
# OAuth2 scopes { #oauth2-scopes }
आप **FastAPI** के साथ OAuth2 scopes सीधे उपयोग कर सकते हैं, वे निर्बाध रूप से काम करने के लिए एकीकृत हैं।
यह आपको OAuth2 standard का पालन करते हुए, आपकी OpenAPI application (और API docs) में एक अधिक fine-grained permission system रखने की अनुमति देगा।
Scopes के साथ OAuth2 वह mechanism है जिसे कई बड़े authentication providers, जैसे Facebook, Google, GitHub, Microsoft, X (Twitter), आदि उपयोग करते हैं। वे इसका उपयोग users और applications को विशिष्ट permissions देने के लिए करते हैं।
हर बार जब आप Facebook, Google, GitHub, Microsoft, X (Twitter) के साथ "log in with" करते हैं, वह application scopes के साथ OAuth2 का उपयोग कर रही होती है।
इस section में आप देखेंगे कि अपनी **FastAPI** application में उसी scopes वाले OAuth2 के साथ authentication और authorization को कैसे manage करें।
/// warning | चेतावनी
यह थोड़ा-बहुत advanced section है। यदि आप अभी शुरू कर रहे हैं, तो आप इसे छोड़ सकते हैं।
आपको अनिवार्य रूप से OAuth2 scopes की आवश्यकता नहीं है, और आप authentication और authorization को जैसे चाहें handle कर सकते हैं।
लेकिन scopes के साथ OAuth2 को आपकी API (OpenAPI के साथ) और आपकी API docs में अच्छी तरह integrate किया जा सकता है।
फिर भी, आप उन scopes, या किसी भी अन्य security/authorization requirement को अपने code में अपनी आवश्यकता के अनुसार enforce करते हैं।
कई मामलों में, scopes के साथ OAuth2 overkill हो सकता है।
लेकिन यदि आप जानते हैं कि आपको इसकी आवश्यकता है, या आप curious हैं, तो पढ़ते रहें।
///
## OAuth2 scopes और OpenAPI { #oauth2-scopes-and-openapi }
OAuth2 specification "scopes" को spaces से अलग की गई strings की list के रूप में define करती है।
इनमें से प्रत्येक string का content किसी भी format में हो सकता है, लेकिन उसमें spaces नहीं होने चाहिए।
ये scopes "permissions" को दर्शाते हैं।
OpenAPI में (जैसे API docs), आप "security schemes" define कर सकते हैं।
जब इनमें से कोई security scheme OAuth2 का उपयोग करती है, तो आप scopes declare और उपयोग भी कर सकते हैं।
प्रत्येक "scope" बस एक string है (spaces के बिना)।
वे सामान्यतः विशिष्ट security permissions declare करने के लिए उपयोग किए जाते हैं, उदाहरण के लिए:
* `users:read` या `users:write` आम examples हैं।
* `instagram_basic` Facebook / Instagram द्वारा उपयोग किया जाता है।
* `https://www.googleapis.com/auth/drive` Google द्वारा उपयोग किया जाता है।
/// note | नोट
OAuth2 में "scope" बस एक string है जो required विशिष्ट permission declare करती है।
इससे फर्क नहीं पड़ता कि इसमें `:` जैसे अन्य characters हैं या यह एक URL है।
वे details implementation specific हैं।
OAuth2 के लिए वे बस strings हैं।
///
## Global view { #global-view }
पहले, आइए जल्दी से देखें कि मुख्य **Tutorial - User Guide** में [Password के साथ OAuth2 (और hashing), JWT tokens के साथ Bearer](../../tutorial/security/oauth2-jwt.md) के examples से कौन से parts बदलते हैं। अब OAuth2 scopes का उपयोग करते हुए:
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
अब आइए उन बदलावों को step by step review करें।
## OAuth2 Security scheme { #oauth2-security-scheme }
पहला बदलाव यह है कि अब हम OAuth2 security scheme को दो उपलब्ध scopes, `me` और `items`, के साथ declare कर रहे हैं।
`scopes` parameter एक `dict` receive करता है जिसमें प्रत्येक scope key के रूप में और description value के रूप में होती है:
{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *}
क्योंकि अब हम उन scopes को declare कर रहे हैं, वे API docs में तब दिखाई देंगे जब आप log-in/authorize करेंगे।
और आप select कर सकेंगे कि आप किन scopes को access देना चाहते हैं: `me` और `items`
यह वही mechanism है जिसका उपयोग तब होता है जब आप Facebook, Google, GitHub, आदि के साथ log in करते समय permissions देते हैं:
<img src="/img/tutorial/security/image11.png">
## Scopes के साथ JWT token { #jwt-token-with-scopes }
अब, token *path operation* को modify करें ताकि requested scopes return हों।
हम अभी भी वही `OAuth2PasswordRequestForm` उपयोग कर रहे हैं। इसमें `scopes` property शामिल है जिसमें `str` की `list` होती है, और request में received प्रत्येक scope होता है।
और हम scopes को JWT token के part के रूप में return करते हैं।
/// danger | खतरा
सरलता के लिए, यहाँ हम received scopes को सीधे token में जोड़ रहे हैं।
लेकिन आपकी application में, security के लिए, आपको सुनिश्चित करना चाहिए कि आप केवल वे scopes जोड़ें जिन्हें user वास्तव में रख सकता है, या जिन्हें आपने predefine किया है।
///
{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *}
## *path operations* और dependencies में scopes declare करें { #declare-scopes-in-path-operations-and-dependencies }
अब हम declare करते हैं कि `/users/me/items/` के लिए *path operation* को scope `items` required है।
इसके लिए, हम `fastapi` से `Security` import और उपयोग करते हैं।
आप dependencies declare करने के लिए `Security` का उपयोग कर सकते हैं (बिल्कुल `Depends` की तरह), लेकिन `Security` एक parameter `scopes` भी receive करता है जिसमें scopes (strings) की list होती है।
इस case में, हम dependency function `get_current_active_user` को `Security` में pass करते हैं (उसी तरह जैसे हम `Depends` के साथ करते)।
लेकिन हम scopes की एक `list` भी pass करते हैं, इस case में केवल एक scope के साथ: `items` (इसमें और भी हो सकते थे)।
और dependency function `get_current_active_user` sub-dependencies भी declare कर सकता है, न केवल `Depends` के साथ बल्कि `Security` के साथ भी। अपना sub-dependency function (`get_current_user`) और अधिक scope requirements declare करते हुए।
इस case में, इसे scope `me` required है (इसे एक से अधिक scope required हो सकते थे)।
/// note | नोट
आपको अलग-अलग जगहों पर अलग-अलग scopes जोड़ना अनिवार्य नहीं है।
हम यहाँ यह demonstrate करने के लिए कर रहे हैं कि **FastAPI** अलग-अलग levels पर declared scopes को कैसे handle करता है।
///
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
/// note | तकनीकी विवरण
`Security` वास्तव में `Depends` का subclass है, और इसमें केवल एक extra parameter है जिसे हम बाद में देखेंगे।
लेकिन `Depends` के बजाय `Security` का उपयोग करके, **FastAPI** जान जाएगा कि यह security scopes declare कर सकता है, उन्हें internally उपयोग कर सकता है, और API को OpenAPI के साथ document कर सकता है।
लेकिन जब आप `fastapi` से `Query`, `Path`, `Depends`, `Security` और अन्य import करते हैं, तो वे वास्तव में functions हैं जो special classes return करते हैं।
///
## `SecurityScopes` का उपयोग करें { #use-securityscopes }
अब dependency `get_current_user` को update करें।
यह वही है जिसका उपयोग ऊपर की dependencies द्वारा किया जाता है।
यहीं हम पहले बनाई गई उसी OAuth2 scheme का उपयोग कर रहे हैं, इसे dependency के रूप में declare करते हुए: `oauth2_scheme`
क्योंकि इस dependency function की अपनी कोई scope requirements नहीं हैं, हम `oauth2_scheme` के साथ `Depends` उपयोग कर सकते हैं, जब हमें security scopes specify करने की आवश्यकता नहीं है तो हमें `Security` उपयोग करने की आवश्यकता नहीं है।
हम `SecurityScopes` type का एक special parameter भी declare करते हैं, जिसे `fastapi.security` से import किया गया है।
यह `SecurityScopes` class `Request` के समान है (`Request` का उपयोग request object को सीधे प्राप्त करने के लिए किया गया था)।
{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
## `scopes` का उपयोग करें { #use-the-scopes }
Parameter `security_scopes` का type `SecurityScopes` होगा।
इसमें property `scopes` होगी जिसमें एक list होगी, जिसमें स्वयं और इसे sub-dependency के रूप में उपयोग करने वाली सभी dependencies द्वारा required सभी scopes शामिल होंगे। इसका मतलब है, सभी "dependants"... यह confusing लग सकता है, इसे नीचे फिर से समझाया गया है।
`security_scopes` object (`SecurityScopes` class का) एक `scope_str` attribute भी provide करता है जिसमें एक single string होती है, जिसमें वे scopes spaces से अलग होते हैं (हम इसका उपयोग करेंगे)।
हम एक `HTTPException` बनाते हैं जिसे हम बाद में कई points पर reuse (`raise`) कर सकते हैं।
इस exception में, हम required scopes (यदि कोई हों) को spaces से अलग की गई string के रूप में शामिल करते हैं (`scope_str` का उपयोग करके)। हम scopes वाली उस string को `WWW-Authenticate` header में रखते हैं (यह spec का part है)।
{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}
## `username` और data shape verify करें { #verify-the-username-and-data-shape }
हम verify करते हैं कि हमें `username` मिलता है, और scopes extract करते हैं।
और फिर हम उस data को Pydantic model के साथ validate करते हैं (`ValidationError` exception को catch करते हुए), और यदि JWT token पढ़ने या Pydantic के साथ data validate करने में error मिलता है, तो हम पहले बनाया हुआ `HTTPException` raise करते हैं।
इसके लिए, हम Pydantic model `TokenData` को नई property `scopes` के साथ update करते हैं।
Pydantic के साथ data validate करके हम यह सुनिश्चित कर सकते हैं कि हमारे पास, उदाहरण के लिए, scopes के साथ बिल्कुल `str` की `list` और `username` के साथ `str` है।
उदाहरण के लिए, `dict`, या कुछ और नहीं, क्योंकि यह बाद में किसी point पर application को break कर सकता है, जिससे यह security risk बन सकता है।
हम यह भी verify करते हैं कि हमारे पास उस username वाला user है, और यदि नहीं, तो हम वही exception raise करते हैं जो हमने पहले बनाया था।
{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *}
## `scopes` verify करें { #verify-the-scopes }
अब हम verify करते हैं कि इस dependency और सभी dependants (जिसमें *path operations* शामिल हैं) द्वारा required सभी scopes, received token में provided scopes में शामिल हैं, अन्यथा `HTTPException` raise करते हैं।
इसके लिए, हम `security_scopes.scopes` का उपयोग करते हैं, जिसमें इन सभी scopes की `list` `str` के रूप में होती है।
{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *}
## Dependency tree और scopes { #dependency-tree-and-scopes }
आइए इस dependency tree और scopes को फिर से review करें।
क्योंकि `get_current_active_user` dependency में `get_current_user` sub-dependency के रूप में है, `get_current_active_user` पर declared scope `"me"` required scopes की उस list में शामिल होगा जो `get_current_user` को pass किए गए `security_scopes.scopes` में होती है।
*path operation* स्वयं भी एक scope, `"items"`, declare करता है, इसलिए यह भी `get_current_user` को pass किए गए `security_scopes.scopes` की list में होगा।
Dependencies और scopes की hierarchy इस तरह दिखती है:
* *path operation* `read_own_items` में है:
* Dependency के साथ required scopes `["items"]`:
* `get_current_active_user`:
* Dependency function `get_current_active_user` में है:
* Dependency के साथ required scopes `["me"]`:
* `get_current_user`:
* Dependency function `get_current_user` में है:
* स्वयं द्वारा required कोई scopes नहीं।
* `oauth2_scheme` का उपयोग करने वाली dependency।
* `SecurityScopes` type का एक `security_scopes` parameter:
* इस `security_scopes` parameter में property `scopes` है जिसमें ऊपर declared इन सभी scopes वाली `list` है, इसलिए:
* *path operation* `read_own_items` के लिए `security_scopes.scopes` में `["me", "items"]` होगा।
* *path operation* `read_users_me` के लिए `security_scopes.scopes` में `["me"]` होगा, क्योंकि यह dependency `get_current_active_user` में declared है।
* *path operation* `read_system_status` के लिए `security_scopes.scopes` में `[]` (कुछ नहीं) होगा, क्योंकि उसने `scopes` के साथ कोई `Security` declare नहीं किया, और उसकी dependency, `get_current_user`, भी कोई `scopes` declare नहीं करती।
/// tip | सुझाव
यहाँ महत्वपूर्ण और "magic" बात यह है कि प्रत्येक *path operation* के लिए `get_current_user` के पास check करने हेतु `scopes` की अलग list होगी।
यह सब उस specific *path operation* के dependency tree में प्रत्येक *path operation* और प्रत्येक dependency में declared `scopes` पर निर्भर करता है।
///
## `SecurityScopes` के बारे में अधिक details { #more-details-about-securityscopes }
आप `SecurityScopes` का उपयोग किसी भी point पर, और multiple जगहों पर कर सकते हैं, इसका "root" dependency पर होना ज़रूरी नहीं है।
इसमें हमेशा current `Security` dependencies और **उस specific** *path operation* तथा **उस specific** dependency tree के सभी dependants में declared security scopes होंगे।
क्योंकि `SecurityScopes` में dependants द्वारा declared सभी scopes होंगे, आप इसका उपयोग यह verify करने के लिए कर सकते हैं कि token में required scopes हैं, एक central dependency function में, और फिर अलग-अलग *path operations* में अलग-अलग scope requirements declare कर सकते हैं।
उन्हें प्रत्येक *path operation* के लिए independently check किया जाएगा।
## इसे check करें { #check-it }
यदि आप API docs खोलते हैं, तो आप authenticate कर सकते हैं और specify कर सकते हैं कि आप किन scopes को authorize करना चाहते हैं।
<img src="/img/tutorial/security/image11.png">
यदि आप कोई scope select नहीं करते हैं, तो आप "authenticated" होंगे, लेकिन जब आप `/users/me/` या `/users/me/items/` access करने की कोशिश करेंगे तो आपको error मिलेगा कि आपके पास पर्याप्त permissions नहीं हैं। आप फिर भी `/status/` access कर पाएंगे।
और यदि आप scope `me` select करते हैं लेकिन scope `items` नहीं, तो आप `/users/me/` access कर पाएंगे लेकिन `/users/me/items/` नहीं।
ऐसा ही किसी third party application के साथ होगा जो user द्वारा provided token के साथ इन *path operations* में से किसी एक को access करने की कोशिश करती, यह इस पर निर्भर करता है कि user ने application को कितनी permissions दीं।
## Third party integrations के बारे में { #about-third-party-integrations }
इस example में हम OAuth2 "password" flow का उपयोग कर रहे हैं।
यह तब appropriate है जब हम अपनी ही application में log in कर रहे हों, शायद अपने ही frontend के साथ।
क्योंकि हम इस पर भरोसा कर सकते हैं कि यह `username` और `password` receive करे, क्योंकि हम इसे control करते हैं।
लेकिन यदि आप ऐसी OAuth2 application बना रहे हैं जिससे दूसरे connect करेंगे (अर्थात, यदि आप Facebook, Google, GitHub, आदि के बराबर authentication provider बना रहे हैं) तो आपको अन्य flows में से किसी एक का उपयोग करना चाहिए।
सबसे common implicit flow है।
सबसे secure code flow है, लेकिन इसे implement करना अधिक complex है क्योंकि इसमें अधिक steps required हैं। क्योंकि यह अधिक complex है, कई providers अंततः implicit flow suggest करते हैं।
/// note | नोट
यह common है कि प्रत्येक authentication provider अपने flows को अलग तरीके से name करता है, ताकि इसे अपने brand का part बना सके।
लेकिन अंततः, वे वही OAuth2 standard implement कर रहे होते हैं।
///
**FastAPI** में इन सभी OAuth2 authentication flows के लिए utilities `fastapi.security.oauth2` में शामिल हैं।
## Decorator `dependencies` में `Security` { #security-in-decorator-dependencies }
जिस तरह आप decorator के `dependencies` parameter में `Depends` की `list` define कर सकते हैं (जैसा कि [path operation decorators में Dependencies](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md) में समझाया गया है), आप वहाँ `scopes` के साथ `Security` भी उपयोग कर सकते हैं।

302
docs/hi/docs/advanced/settings.md

@ -0,0 +1,302 @@
# Settings और Environment Variables { #settings-and-environment-variables }
कई मामलों में आपकी application को कुछ बाहरी settings या configurations की ज़रूरत हो सकती है, उदाहरण के लिए secret keys, database credentials, email services के लिए credentials, आदि।
इनमें से ज़्यादातर settings variable होती हैं (बदल सकती हैं), जैसे database URLs। और कई sensitive हो सकती हैं, जैसे secrets।
इसी कारण उन्हें आम तौर पर environment variables में दिया जाता है जिन्हें application पढ़ती है।
/// tip | सुझाव
Environment variables को समझने के लिए आप [Environment Variables](../environment-variables.md) पढ़ सकते हैं।
///
## Types और validation { #types-and-validation }
ये environment variables केवल text strings को handle कर सकते हैं, क्योंकि ये Python के बाहर होते हैं और इन्हें दूसरे programs और system के बाकी हिस्सों के साथ compatible होना होता है (और अलग-अलग operating systems, जैसे Linux, Windows, और macOS के साथ भी)।
इसका मतलब है कि Python में किसी environment variable से पढ़ी गई कोई भी value एक `str` होगी, और किसी अलग type में कोई भी conversion या कोई भी validation code में करनी होगी।
## Pydantic `Settings` { #pydantic-settings }
सौभाग्य से, Pydantic environment variables से आने वाली इन settings को handle करने के लिए एक बेहतरीन utility देता है: [Pydantic: Settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)।
### `pydantic-settings` install करें { #install-pydantic-settings }
सबसे पहले, सुनिश्चित करें कि आप अपना [virtual environment](../virtual-environments.md) बनाते हैं, उसे activate करते हैं, और फिर `pydantic-settings` package install करते हैं:
<div class="termy">
```console
$ pip install pydantic-settings
---> 100%
```
</div>
जब आप `all` extras को install करते हैं, तो यह भी शामिल आता है:
<div class="termy">
```console
$ pip install "fastapi[all]"
---> 100%
```
</div>
### `Settings` object बनाएँ { #create-the-settings-object }
Pydantic से `BaseSettings` import करें और एक sub-class बनाएँ, बिल्कुल Pydantic model की तरह।
Pydantic models की तरह ही, आप type annotations के साथ class attributes घोषित करते हैं, और संभवतः default values भी।
आप वे सभी validation features और tools इस्तेमाल कर सकते हैं जिन्हें आप Pydantic models के लिए इस्तेमाल करते हैं, जैसे अलग-अलग data types और `Field()` के साथ अतिरिक्त validations।
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
/// tip | सुझाव
अगर आप जल्दी copy और paste करने के लिए कुछ चाहते हैं, तो यह example इस्तेमाल न करें, नीचे वाला आखिरी example इस्तेमाल करें।
///
फिर, जब आप उस `Settings` class का instance बनाते हैं (इस case में, `settings` object में), Pydantic environment variables को case-insensitive तरीके से पढ़ेगा, इसलिए upper-case variable `APP_NAME` भी attribute `app_name` के लिए पढ़ा जाएगा।
इसके बाद यह data को convert और validate करेगा। इसलिए, जब आप उस `settings` object का उपयोग करेंगे, तो आपके पास उन types का data होगा जिन्हें आपने घोषित किया था (जैसे `items_per_user` एक `int` होगा)।
### `settings` का उपयोग करें { #use-the-settings }
फिर आप अपनी application में नए `settings` object का उपयोग कर सकते हैं:
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
### Server चलाएँ { #run-the-server }
इसके बाद, आप configurations को environment variables के रूप में pass करते हुए server चलाएँगे, उदाहरण के लिए आप `ADMIN_EMAIL` और `APP_NAME` set कर सकते हैं:
<div class="termy">
```console
$ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
/// tip | सुझाव
एक ही command के लिए कई env vars set करने के लिए बस उन्हें space से अलग करें, और उन सभी को command से पहले रखें।
///
और फिर `admin_email` setting `"[email protected]"` पर set हो जाएगी।
`app_name` `"ChimichangApp"` होगा।
और `items_per_user` अपनी default value `50` बनाए रखेगा।
## किसी दूसरे module में Settings { #settings-in-another-module }
आप उन settings को किसी दूसरे module file में रख सकते हैं, जैसा आपने [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md) में देखा था।
उदाहरण के लिए, आपके पास `config.py` file हो सकती है:
{* ../../docs_src/settings/app01_py310/config.py *}
और फिर उसे `main.py` file में उपयोग करें:
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
/// tip | सुझाव
आपको एक `__init__.py` file की भी ज़रूरत होगी, जैसा आपने [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md) में देखा था।
///
## Dependency में Settings { #settings-in-a-dependency }
कुछ मौकों पर settings को dependency से देना उपयोगी हो सकता है, बजाय इसके कि `settings` के साथ एक global object हो जिसे हर जगह इस्तेमाल किया जाए।
यह testing के दौरान विशेष रूप से उपयोगी हो सकता है, क्योंकि dependency को अपनी custom settings से override करना बहुत आसान है।
### Config file { #the-config-file }
पिछले example से आगे बढ़ते हुए, आपकी `config.py` file इस तरह दिख सकती है:
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
ध्यान दें कि अब हम default instance `settings = Settings()` नहीं बनाते।
### Main app file { #the-main-app-file }
अब हम एक dependency बनाते हैं जो नया `config.Settings()` return करती है।
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
/// tip | सुझाव
हम थोड़ी देर में `@lru_cache` पर चर्चा करेंगे।
अभी के लिए आप मान सकते हैं कि `get_settings()` एक normal function है।
///
और फिर हम इसे *path operation function* से dependency के रूप में require कर सकते हैं और जहाँ भी ज़रूरत हो वहाँ इस्तेमाल कर सकते हैं।
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
### Settings और testing { #settings-and-testing }
फिर testing के दौरान `get_settings` के लिए dependency override बनाकर अलग settings object देना बहुत आसान होगा:
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
Dependency override में हम नया `Settings` object बनाते समय `admin_email` के लिए नई value set करते हैं, और फिर उस नए object को return करते हैं।
फिर हम test कर सकते हैं कि इसका उपयोग हुआ है।
## `.env` file पढ़ना { #reading-a-env-file }
अगर आपके पास कई settings हैं जो संभवतः बहुत बदलती हैं, शायद अलग-अलग environments में, तो उन्हें एक file में रखना और फिर वहाँ से ऐसे पढ़ना उपयोगी हो सकता है जैसे वे environment variables हों।
यह practice इतनी आम है कि इसका एक नाम है, ये environment variables आम तौर पर `.env` file में रखे जाते हैं, और file को "dotenv" कहा जाता है।
/// tip | सुझाव
dot (`.`) से शुरू होने वाली file Unix-like systems, जैसे Linux और macOS में hidden file होती है।
लेकिन dotenv file का वास्तव में वही exact filename होना ज़रूरी नहीं है।
///
Pydantic के पास external library का उपयोग करके इस प्रकार की files से पढ़ने के लिए support है। आप [Pydantic Settings: Dotenv (.env) support](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support) पर और पढ़ सकते हैं।
/// tip | सुझाव
इसे काम करने के लिए, आपको `pip install python-dotenv` करना होगा।
///
### `.env` file { #the-env-file }
आपके पास इस तरह की `.env` file हो सकती है:
```bash
ADMIN_EMAIL="[email protected]"
APP_NAME="ChimichangApp"
```
### `.env` से settings पढ़ें { #read-settings-from-env }
और फिर अपनी `config.py` को update करें:
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
/// tip | सुझाव
`model_config` attribute केवल Pydantic configuration के लिए उपयोग किया जाता है। आप [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/) पर और पढ़ सकते हैं।
///
यहाँ हम आपकी Pydantic `Settings` class के अंदर config `env_file` define करते हैं, और value को उस dotenv file के filename पर set करते हैं जिसे हम उपयोग करना चाहते हैं।
### `lru_cache` के साथ `Settings` को केवल एक बार बनाना { #creating-the-settings-only-once-with-lru-cache }
Disk से file पढ़ना सामान्यतः costly (slow) operation होता है, इसलिए आप शायद इसे केवल एक बार करना चाहेंगे और फिर हर request के लिए पढ़ने के बजाय उसी settings object को reuse करना चाहेंगे।
लेकिन हर बार जब हम करते हैं:
```Python
Settings()
```
तो एक नया `Settings` object बनेगा, और बनते समय यह `.env` file को फिर से पढ़ेगा।
अगर dependency function बस ऐसी होती:
```Python
def get_settings():
return Settings()
```
तो हम हर request के लिए वह object बनाते, और हर request के लिए `.env` file पढ़ते। ⚠️
लेकिन क्योंकि हम ऊपर `@lru_cache` decorator इस्तेमाल कर रहे हैं, `Settings` object केवल एक बार बनाया जाएगा, पहली बार जब इसे call किया जाएगा। ✔️
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
फिर अगले requests के लिए dependencies में `get_settings()` की किसी भी बाद की call पर, `get_settings()` के internal code को execute करने और नया `Settings` object बनाने के बजाय, यह वही object return करेगा जो पहली call पर return किया गया था, बार-बार।
#### `lru_cache` Technical Details { #lru-cache-technical-details }
`@lru_cache` जिस function को decorate करता है उसे modify करता है ताकि वह हर बार function का code execute करके फिर से compute करने के बजाय वही value return करे जो पहली बार return की गई थी।
इसलिए, उसके नीचे वाला function arguments के प्रत्येक combination के लिए एक बार execute होगा। और फिर उन arguments के प्रत्येक combination द्वारा return की गई values बार-बार उपयोग की जाएँगी, जब भी function को ठीक उसी arguments combination के साथ call किया जाएगा।
उदाहरण के लिए, अगर आपके पास एक function है:
```Python
@lru_cache
def say_hi(name: str, salutation: str = "Ms."):
return f"Hello {salutation} {name}"
```
आपका program इस तरह execute हो सकता है:
```mermaid
sequenceDiagram
participant code as Code
participant function as say_hi()
participant execute as Execute function
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Camila")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: return stored result
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick", salutation="Mr.")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Rick")
function ->> code: return stored result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: return stored result
end
```
हमारी dependency `get_settings()` के case में, function कोई arguments भी नहीं लेती, इसलिए यह हमेशा वही value return करती है।
इस तरह, यह लगभग ऐसे behave करती है जैसे यह बस एक global variable हो। लेकिन क्योंकि यह dependency function का उपयोग करती है, इसलिए हम testing के लिए इसे आसानी से override कर सकते हैं।
`@lru_cache` `functools` का हिस्सा है, जो Python की standard library का हिस्सा है। आप इसके बारे में [Python docs for `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache) में और पढ़ सकते हैं।
## Recap { #recap }
आप अपनी application की settings या configurations को handle करने के लिए Pydantic Settings का उपयोग कर सकते हैं, Pydantic models की पूरी power के साथ।
* Dependency का उपयोग करके आप testing को सरल बना सकते हैं।
* आप इसके साथ `.env` files का उपयोग कर सकते हैं।
* `@lru_cache` का उपयोग करने से आप हर request के लिए dotenv file को बार-बार पढ़ने से बच सकते हैं, साथ ही testing के दौरान इसे override करने की अनुमति भी मिलती है।

117
docs/hi/docs/advanced/stream-data.md

@ -0,0 +1,117 @@
# Data Stream करें { #stream-data }
अगर आप ऐसा data stream करना चाहते हैं जिसे JSON के रूप में संरचित किया जा सके, तो आपको [JSON Lines Stream करें](../tutorial/stream-json-lines.md)।
लेकिन अगर आप **शुद्ध binary data** या strings stream करना चाहते हैं, तो यह आप ऐसे कर सकते हैं।
/// note | नोट
FastAPI 0.134.0 में जोड़ा गया।
///
## उपयोग के मामले { #use-cases }
आप इसका उपयोग तब कर सकते हैं जब आप शुद्ध strings stream करना चाहते हों, उदाहरण के लिए सीधे किसी **AI LLM** service के output से।
आप इसका उपयोग **बड़ी binary files** stream करने के लिए भी कर सकते हैं, जहाँ आप data के प्रत्येक chunk को पढ़ते समय stream करते हैं, बिना पूरे data को एक साथ memory में पढ़े।
आप इसी तरह **video** या **audio** भी stream कर सकते हैं, यह process और send करते समय generate भी किया जा सकता है।
## `yield` के साथ एक `StreamingResponse` { #a-streamingresponse-with-yield }
अगर आप अपने *path operation function* में `response_class=StreamingResponse` declare करते हैं, तो आप data के प्रत्येक chunk को क्रम से भेजने के लिए `yield` का उपयोग कर सकते हैं।
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
FastAPI data के प्रत्येक chunk को `StreamingResponse` को जैसा है वैसा ही देगा, यह उसे JSON या किसी समान चीज़ में convert करने की कोशिश नहीं करेगा।
### Non-async *path operation functions* { #non-async-path-operation-functions }
आप regular `def` functions (`async` के बिना) का भी उपयोग कर सकते हैं, और उसी तरह `yield` का उपयोग कर सकते हैं।
{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *}
### Annotation नहीं { #no-annotation }
Streaming binary data के लिए आपको return type annotation declare करने की वास्तव में आवश्यकता नहीं है।
क्योंकि FastAPI data को Pydantic के साथ JSON में convert करने या किसी भी तरह serialize करने की कोशिश नहीं करेगा, इस मामले में type annotation केवल आपके editor और tools के उपयोग के लिए है, FastAPI इसका उपयोग नहीं करेगा।
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
इसका मतलब यह भी है कि `StreamingResponse` के साथ आपके पास type annotations से स्वतंत्र होकर data bytes को ठीक वैसे produce और encode करने की **स्वतंत्रता** और **ज़िम्मेदारी** है, जैसे उन्हें भेजा जाना चाहिए। 🤓
### Bytes Stream करें { #stream-bytes }
मुख्य उपयोग मामलों में से एक strings के बजाय `bytes` stream करना होगा, और आप निश्चित रूप से ऐसा कर सकते हैं।
{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *}
## एक Custom `PNGStreamingResponse` { #a-custom-pngstreamingresponse }
ऊपर के उदाहरणों में, data bytes stream किए गए थे, लेकिन response में `Content-Type` header नहीं था, इसलिए client को पता नहीं था कि उसे किस प्रकार का data मिल रहा है।
आप `StreamingResponse` की एक custom sub-class बना सकते हैं जो `Content-Type` header को उस प्रकार के data पर set करती है जिसे आप stream कर रहे हैं।
उदाहरण के लिए, आप एक `PNGStreamingResponse` बना सकते हैं जो `media_type` attribute का उपयोग करके `Content-Type` header को `image/png` पर set करता है:
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
फिर आप अपने *path operation function* में `response_class=PNGStreamingResponse` में इस नई class का उपयोग कर सकते हैं:
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
### एक File का Simulation करें { #simulate-a-file }
इस उदाहरण में, हम `io.BytesIO` के साथ एक file simulate कर रहे हैं, जो एक file-like object है जो केवल memory में रहता है, लेकिन हमें वही interface उपयोग करने देता है।
उदाहरण के लिए, हम इसके contents consume करने के लिए इस पर iterate कर सकते हैं, जैसे हम किसी file के साथ कर सकते हैं।
{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *}
/// note | तकनीकी विवरण
अन्य दो variables, `image_base64` और `binary_image`, Base64 में encoded एक image हैं, और फिर bytes में convert किए गए हैं, ताकि फिर उन्हें `io.BytesIO` को pass किया जा सके।
सिर्फ इसलिए ताकि इस उदाहरण के लिए यह उसी file में रह सके और आप इसे copy करके जैसा है वैसा ही run कर सकें। 🥚
///
`with` block का उपयोग करके, हम यह सुनिश्चित करते हैं कि generator function (`yield` वाला function) पूरा होने के बाद file-like object बंद हो जाए। यानी, response भेजना पूरा होने के बाद।
इस विशिष्ट उदाहरण में यह उतना महत्वपूर्ण नहीं होगा क्योंकि यह एक fake in-memory file है (`io.BytesIO` के साथ), लेकिन एक वास्तविक file के साथ, यह सुनिश्चित करना महत्वपूर्ण होगा कि इसके साथ काम पूरा होने के बाद file बंद हो जाए।
### Files और Async { #files-and-async }
अधिकांश मामलों में, file-like objects default रूप से async और await के साथ compatible नहीं होते।
उदाहरण के लिए, उनके पास `await file.read()` या `async for chunk in file` नहीं होता।
और कई मामलों में, उन्हें पढ़ना एक blocking operation होगा (जो event loop को block कर सकता है), क्योंकि उन्हें disk या network से पढ़ा जाता है।
/// note | नोट
ऊपर दिया गया उदाहरण वास्तव में एक exception है, क्योंकि `io.BytesIO` object पहले से memory में है, इसलिए उसे पढ़ना किसी चीज़ को block नहीं करेगा।
लेकिन कई मामलों में किसी file या file-like object को पढ़ना block करेगा।
///
event loop को block करने से बचने के लिए, आप बस *path operation function* को `async def` के बजाय regular `def` के साथ declare कर सकते हैं, इस तरह FastAPI इसे main loop को block करने से बचाने के लिए threadpool worker पर run करेगा।
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
/// tip | सुझाव
अगर आपको किसी async function के अंदर से blocking code call करना हो, या किसी blocking function के अंदर से async function call करना हो, तो आप [Asyncer](https://asyncer.tiangolo.com) का उपयोग कर सकते हैं, जो FastAPI की एक sibling library है।
///
### `yield from` { #yield-from }
जब आप किसी चीज़ पर iterate कर रहे हों, जैसे किसी file-like object पर, और फिर प्रत्येक item के लिए `yield` कर रहे हों, तो आप प्रत्येक item को सीधे yield करने और `for` loop को skip करने के लिए `yield from` का भी उपयोग कर सकते हैं।
यह FastAPI के लिए विशेष नहीं है, यह सिर्फ Python है, लेकिन यह जानने लायक एक अच्छा trick है। 😎
{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *}

88
docs/hi/docs/advanced/strict-content-type.md

@ -0,0 +1,88 @@
# सख्त Content-Type जाँच { #strict-content-type-checking }
default रूप से, **FastAPI** JSON request bodies के लिए सख्त `Content-Type` header जाँच का उपयोग करता है, इसका मतलब है कि body को JSON के रूप में parse करने के लिए JSON requests में वैध `Content-Type` header (जैसे `application/json`) **होना ही चाहिए**
## CSRF जोखिम { #csrf-risk }
यह default व्यवहार एक बहुत विशिष्ट परिस्थिति में **Cross-Site Request Forgery (CSRF)** हमलों के एक वर्ग से सुरक्षा प्रदान करता है।
ये हमले इस बात का फायदा उठाते हैं कि browsers scripts को बिना कोई CORS preflight check किए requests भेजने देते हैं, जब वे:
* `Content-Type` header नहीं रखते (जैसे `Blob` body के साथ `fetch()` का उपयोग करना)
* और कोई authentication credentials नहीं भेजते।
इस प्रकार का हमला मुख्य रूप से तब relevant होता है जब:
* application स्थानीय रूप से चल रही हो (जैसे `localhost` पर) या किसी internal network में
* और application में कोई authentication न हो, वह यह मानती हो कि उसी network से आने वाली कोई भी request भरोसेमंद हो सकती है।
## उदाहरण हमला { #example-attack }
कल्पना करें कि आप एक local AI agent चलाने का तरीका बनाते हैं।
यह यहाँ एक API प्रदान करता है
```
http://localhost:8000/v1/agents/multivac
```
यहाँ एक frontend भी है
```
http://localhost:8000
```
/// tip | सुझाव
ध्यान दें कि दोनों का host समान है।
///
फिर frontend का उपयोग करके आप AI agent से अपनी ओर से काम करवा सकते हैं।
क्योंकि यह **स्थानीय रूप से** चल रहा है, और खुले internet पर नहीं है, आप **कोई authentication setup न करने** का निर्णय लेते हैं, बस local network तक access पर भरोसा करते हुए।
फिर आपके users में से कोई इसे install करके locally चला सकता है।
फिर वे कोई malicious website खोल सकते हैं, जैसे कुछ इस तरह
```
https://evilhackers.example.com
```
और वह malicious website `Blob` body के साथ `fetch()` का उपयोग करके local API पर requests भेजती है
```
http://localhost:8000/v1/agents/multivac
```
भले ही malicious website और local app का host अलग हो, browser CORS preflight request trigger नहीं करेगा क्योंकि:
* यह बिना किसी authentication के चल रहा है, इसे कोई credentials भेजने की जरूरत नहीं है।
* browser को लगता है कि यह JSON नहीं भेज रहा है (`Content-Type` header गायब होने के कारण)।
फिर malicious website local AI agent से user के ex-boss को गुस्से भरे messages भेजवा सकती है... या उससे भी बुरा। 😅
## खुला Internet { #open-internet }
अगर आपकी app खुले internet पर है, तो आप "network पर भरोसा" नहीं करेंगे और किसी को भी बिना authentication के privileged requests भेजने नहीं देंगे।
Attackers सीधे आपकी API पर requests भेजने के लिए script चला सकते हैं, browser interaction की कोई जरूरत नहीं, इसलिए आप शायद पहले से ही किसी भी privileged endpoints को secure कर रहे होंगे।
उस स्थिति में **यह हमला / जोखिम आप पर लागू नहीं होता**
यह जोखिम और हमला मुख्य रूप से तब relevant होता है जब app **local network** पर चलती है और वही **एकमात्र मानी गई सुरक्षा** होती है।
## Content-Type के बिना Requests की अनुमति देना { #allowing-requests-without-content-type }
अगर आपको ऐसे clients को support करना है जो `Content-Type` header नहीं भेजते, तो आप `strict_content_type=False` set करके strict checking disable कर सकते हैं:
{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *}
इस setting के साथ, जिन requests में `Content-Type` header नहीं होगा, उनकी body JSON के रूप में parse की जाएगी, जो FastAPI के पुराने versions जैसा ही व्यवहार है।
/// note | नोट
यह व्यवहार और configuration FastAPI 0.132.0 में जोड़ा गया था।
///

67
docs/hi/docs/advanced/sub-applications.md

@ -0,0 +1,67 @@
# Sub Applications - Mounts { #sub-applications-mounts }
अगर आपको दो स्वतंत्र FastAPI applications चाहिए, जिनका अपना स्वतंत्र OpenAPI और अपनी docs UIs हों, तो आप एक मुख्य app रख सकते हैं और एक (या अधिक) sub-application(s) को "mount" कर सकते हैं।
## **FastAPI** application को Mount करना { #mounting-a-fastapi-application }
"Mounting" का मतलब है किसी विशिष्ट path में पूरी तरह "स्वतंत्र" application जोड़ना, जो फिर उस path के अंतर्गत सब कुछ handle करने का ध्यान रखता है, उस sub-application में घोषित _path operations_ के साथ।
### Top-level application { #top-level-application }
सबसे पहले, मुख्य, top-level **FastAPI** application और उसके *path operations* बनाएँ:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
### Sub-application { #sub-application }
फिर, अपनी sub-application और उसके *path operations* बनाएँ।
यह sub-application बस एक और standard FastAPI application है, लेकिन यही वह है जिसे "mounted" किया जाएगा:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
### Sub-application को mount करें { #mount-the-sub-application }
अपने top-level application, `app`, में sub-application, `subapi`, को mount करें।
इस मामले में, इसे path `/subapi` पर mount किया जाएगा:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
### Automatic API docs देखें { #check-the-automatic-api-docs }
अब, `fastapi` command चलाएँ:
<div class="termy">
```console
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
और docs को [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) पर खोलें।
आप मुख्य app के लिए automatic API docs देखेंगे, जिसमें केवल उसके अपने _path operations_ शामिल होंगे:
<img src="/img/tutorial/sub-applications/image01.png">
और फिर, sub-application के लिए docs को [http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs) पर खोलें।
आप sub-application के लिए automatic API docs देखेंगे, जिसमें केवल उसके अपने _path operations_ शामिल होंगे, सभी सही sub-path prefix `/subapi` के अंतर्गत:
<img src="/img/tutorial/sub-applications/image02.png">
अगर आप दोनों user interfaces में से किसी के साथ interact करने की कोशिश करते हैं, तो वे सही तरह काम करेंगे, क्योंकि browser हर specific app या sub-app से बात कर पाएगा।
### तकनीकी विवरण: `root_path` { #technical-details-root-path }
जब आप ऊपर बताए गए तरीके से कोई sub-application mount करते हैं, तो FastAPI sub-application के लिए mount path communicate करने का ध्यान रखेगा, ASGI specification के एक mechanism का उपयोग करके जिसे `root_path` कहा जाता है।
इस तरह, sub-application को पता होगा कि docs UI के लिए उस path prefix का उपयोग करना है।
और sub-application की अपनी mounted sub-applications भी हो सकती हैं और सब कुछ सही तरह काम करेगा, क्योंकि FastAPI इन सभी `root_path`s को अपने आप handle करता है।
आप `root_path` के बारे में और इसे स्पष्ट रूप से कैसे उपयोग करें, यह [Behind a Proxy](behind-a-proxy.md) वाले section में और सीखेंगे।

126
docs/hi/docs/advanced/templates.md

@ -0,0 +1,126 @@
# Templates { #templates }
आप **FastAPI** के साथ अपनी पसंद का कोई भी template engine उपयोग कर सकते हैं।
एक आम विकल्प Jinja2 है, वही जिसे Flask और अन्य tools उपयोग करते हैं।
इसे आसानी से configure करने के लिए utilities उपलब्ध हैं जिन्हें आप सीधे अपने **FastAPI** application में उपयोग कर सकते हैं (Starlette द्वारा प्रदान की गई)।
## Dependencies install करें { #install-dependencies }
सुनिश्चित करें कि आप एक [virtual environment](../virtual-environments.md) बनाएँ, उसे activate करें, और `jinja2` install करें:
<div class="termy">
```console
$ pip install jinja2
---> 100%
```
</div>
## `Jinja2Templates` का उपयोग करना { #using-jinja2templates }
* `Jinja2Templates` import करें।
* एक `templates` object बनाएँ जिसे आप बाद में फिर से उपयोग कर सकें।
* उस *path operation* में एक `Request` parameter declare करें जो एक template return करेगा।
* आपने जो `templates` बनाया है, उसका उपयोग करके एक `TemplateResponse` render और return करें; template का नाम, request object, और key-value pairs वाली एक "context" dictionary pass करें, जिनका उपयोग Jinja2 template के अंदर किया जाएगा।
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
/// note | नोट
FastAPI 0.108.0, Starlette 0.29.0 से पहले, `name` पहला parameter था।
साथ ही, उससे पहले के versions में, `request` object को Jinja2 के context में key-value pairs के हिस्से के रूप में pass किया जाता था।
///
/// tip | सुझाव
`response_class=HTMLResponse` declare करने से docs UI यह जान पाएगा कि response HTML होगा।
///
/// note | तकनीकी विवरण
आप `from starlette.templating import Jinja2Templates` भी उपयोग कर सकते हैं।
**FastAPI** आपकी सुविधा के लिए, developer के रूप में, वही `starlette.templating` `fastapi.templating` के रूप में प्रदान करता है। लेकिन उपलब्ध अधिकांश responses सीधे Starlette से आते हैं। `Request` और `StaticFiles` के साथ भी यही है।
///
## Templates लिखना { #writing-templates }
फिर आप `templates/item.html` पर एक template लिख सकते हैं, उदाहरण के लिए:
```jinja hl_lines="7"
{!../../docs_src/templates/templates/item.html!}
```
### Template Context Values { #template-context-values }
उस HTML में जिसमें यह शामिल है:
{% raw %}
```jinja
Item ID: {{ id }}
```
{% endraw %}
...यह आपके द्वारा pass किए गए "context" `dict` से लिया गया `id` दिखाएगा:
```Python
{"id": id}
```
उदाहरण के लिए, `42` की ID के साथ, यह render होगा:
```html
Item ID: 42
```
### Template `url_for` Arguments { #template-url-for-arguments }
आप template के अंदर `url_for()` का भी उपयोग कर सकते हैं, यह arguments के रूप में वही arguments लेता है जो आपके *path operation function* द्वारा उपयोग किए जाते।
इसलिए, इस section के साथ:
{% raw %}
```jinja
<a href="{{ url_for('read_item', id=id) }}">
```
{% endraw %}
...यह उसी URL का link generate करेगा जिसे *path operation function* `read_item(id=id)` handle करेगा।
उदाहरण के लिए, `42` की ID के साथ, यह render होगा:
```html
<a href="/items/42">
```
## Templates और static files { #templates-and-static-files }
आप template के अंदर `url_for()` का भी उपयोग कर सकते हैं, और इसे, उदाहरण के लिए, उन `StaticFiles` के साथ उपयोग कर सकते हैं जिन्हें आपने `name="static"` के साथ mount किया है।
```jinja hl_lines="4"
{!../../docs_src/templates/templates/item.html!}
```
इस उदाहरण में, यह `static/styles.css` पर मौजूद CSS file से link करेगा:
```CSS hl_lines="4"
{!../../docs_src/templates/static/styles.css!}
```
और क्योंकि आप `StaticFiles` उपयोग कर रहे हैं, वह CSS file आपके **FastAPI** application द्वारा URL `/static/styles.css` पर automatic रूप से serve की जाएगी।
## अधिक विवरण { #more-details }
अधिक विवरण के लिए, जिसमें templates को test करना भी शामिल है, [templates पर Starlette के docs](https://www.starlette.dev/templates/) देखें।

53
docs/hi/docs/advanced/testing-dependencies.md

@ -0,0 +1,53 @@
# Overrides के साथ Dependencies की Testing { #testing-dependencies-with-overrides }
## Testing के दौरान dependencies को override करना { #overriding-dependencies-during-testing }
कुछ scenarios होते हैं जहाँ आप testing के दौरान किसी dependency को override करना चाह सकते हैं।
आप नहीं चाहते कि original dependency चले (और न ही उसकी कोई sub-dependencies चलें)।
इसके बजाय, आप एक अलग dependency देना चाहते हैं जो केवल tests के दौरान इस्तेमाल होगी (संभवतः केवल कुछ खास tests में), और वह एक ऐसा value देगी जिसे वहाँ इस्तेमाल किया जा सके जहाँ original dependency का value इस्तेमाल किया जाता था।
### Use cases: external service { #use-cases-external-service }
एक उदाहरण यह हो सकता है कि आपके पास एक external authentication provider हो जिसे आपको call करना हो।
आप उसे एक token भेजते हैं और वह एक authenticated user लौटाता है।
यह provider आपसे प्रति request शुल्क ले सकता है, और इसे call करने में tests के लिए एक fixed mock user रखने की तुलना में कुछ अतिरिक्त समय लग सकता है।
आप शायद external provider को एक बार test करना चाहेंगे, लेकिन हर चलने वाले test के लिए उसे call करना जरूरी नहीं होगा।
इस मामले में, आप उस dependency को override कर सकते हैं जो उस provider को call करती है, और अपनी tests के लिए एक custom dependency इस्तेमाल कर सकते हैं जो एक mock user लौटाती है।
### `app.dependency_overrides` attribute का उपयोग करें { #use-the-app-dependency-overrides-attribute }
इन मामलों के लिए, आपकी **FastAPI** application में एक attribute `app.dependency_overrides` होता है, यह एक simple `dict` है।
Testing के लिए किसी dependency को override करने के लिए, आप key के रूप में original dependency (एक function) रखते हैं, और value के रूप में अपना dependency override (दूसरा function) रखते हैं।
और फिर **FastAPI** original dependency की बजाय उस override को call करेगा।
{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *}
/// tip | सुझाव
आप अपनी **FastAPI** application में कहीं भी इस्तेमाल की गई dependency के लिए dependency override set कर सकते हैं।
Original dependency किसी *path operation function*, किसी *path operation decorator* (जब आप return value का उपयोग नहीं करते), किसी `.include_router()` call आदि में इस्तेमाल हो सकती है।
FastAPI फिर भी उसे override कर पाएगा।
///
फिर आप `app.dependency_overrides` को एक खाली `dict` पर set करके अपने overrides reset कर सकते हैं (उन्हें हटा सकते हैं):
```Python
app.dependency_overrides = {}
```
/// tip | सुझाव
यदि आप किसी dependency को केवल कुछ tests के दौरान override करना चाहते हैं, तो आप test की शुरुआत में (test function के अंदर) override set कर सकते हैं और अंत में (test function के अंत में) उसे reset कर सकते हैं।
///

12
docs/hi/docs/advanced/testing-events.md

@ -0,0 +1,12 @@
# Testing Events: lifespan और startup - shutdown { #testing-events-lifespan-and-startup-shutdown }
जब आपको अपने tests में `lifespan` चलाने की ज़रूरत हो, तो आप `with` statement के साथ `TestClient` का उपयोग कर सकते हैं:
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
आप इसके बारे में अधिक विवरण ["आधिकारिक Starlette documentation site में tests में lifespan चलाना।"](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) में पढ़ सकते हैं।
deprecated `startup` और `shutdown` event के लिए, आप `TestClient` का उपयोग इस प्रकार कर सकते हैं:
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}

13
docs/hi/docs/advanced/testing-websockets.md

@ -0,0 +1,13 @@
# WebSockets की Testing { #testing-websockets }
आप WebSockets को test करने के लिए उसी `TestClient` का उपयोग कर सकते हैं।
इसके लिए, आप `TestClient` को एक `with` statement में उपयोग करते हैं, WebSocket से connect करते हुए:
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
/// note | नोट
अधिक जानकारी के लिए, Starlette की documentation में [WebSockets की testing](https://www.starlette.dev/testclient/#testing-websocket-sessions) देखें।
///

56
docs/hi/docs/advanced/using-request-directly.md

@ -0,0 +1,56 @@
# Request को सीधे इस्तेमाल करना { #using-the-request-directly }
अब तक, आप request के जिन हिस्सों की ज़रूरत है, उन्हें उनके types के साथ declare करते रहे हैं।
Data लेना:
* path से parameters के रूप में।
* Headers।
* Cookies।
* आदि।
और ऐसा करके, **FastAPI** उस data को validate कर रहा है, उसे convert कर रहा है और आपकी API के लिए documentation अपने-आप generate कर रहा है।
लेकिन ऐसी स्थितियाँ होती हैं जहाँ आपको `Request` object को सीधे access करने की ज़रूरत हो सकती है।
## `Request` object के बारे में विवरण { #details-about-the-request-object }
क्योंकि **FastAPI** असल में नीचे से **Starlette** है, जिसके ऊपर कई tools की एक layer है, इसलिए जब ज़रूरत हो, आप Starlette के [`Request`](https://www.starlette.dev/requests/) object को सीधे इस्तेमाल कर सकते हैं।
इसका मतलब यह भी होगा कि अगर आप `Request` object से सीधे data लेते हैं (उदाहरण के लिए, body पढ़ते हैं), तो FastAPI उसे validate, convert या document नहीं करेगा (OpenAPI के साथ, automatic API user interface के लिए)।
हालाँकि कोई भी अन्य parameter जो सामान्य रूप से declare किया गया हो (उदाहरण के लिए, Pydantic model के साथ body), वह फिर भी validate, convert, annotate आदि होगा।
लेकिन कुछ विशिष्ट मामले हैं जहाँ `Request` object लेना उपयोगी होता है।
## `Request` object को सीधे इस्तेमाल करें { #use-the-request-object-directly }
मान लीजिए कि आप अपनी *path operation function* के अंदर client का IP address/host लेना चाहते हैं।
इसके लिए आपको request को सीधे access करना होगा।
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
`Request` type वाले *path operation function* parameter को declare करके, **FastAPI** जान जाएगा कि उस parameter में `Request` pass करना है।
/// tip | सुझाव
ध्यान दें कि इस मामले में, हम request parameter के साथ एक path parameter declare कर रहे हैं।
इसलिए, path parameter extract किया जाएगा, validate किया जाएगा, specified type में convert किया जाएगा और OpenAPI के साथ annotate किया जाएगा।
इसी तरह, आप किसी भी अन्य parameter को सामान्य रूप से declare कर सकते हैं, और साथ ही `Request` भी प्राप्त कर सकते हैं।
///
## `Request` documentation { #request-documentation }
आप [`Request` object के बारे में official Starlette documentation site](https://www.starlette.dev/requests/) पर और विवरण पढ़ सकते हैं।
/// note | तकनीकी विवरण
आप `from starlette.requests import Request` भी इस्तेमाल कर सकते हैं।
**FastAPI** इसे सीधे सिर्फ आपकी, developer की, सुविधा के लिए प्रदान करता है। लेकिन यह सीधे Starlette से आता है।
///

186
docs/hi/docs/advanced/websockets.md

@ -0,0 +1,186 @@
# WebSockets { #websockets }
आप **FastAPI** के साथ [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) का उपयोग कर सकते हैं।
## `websockets` install करें { #install-websockets }
सुनिश्चित करें कि आप एक [virtual environment](../virtual-environments.md) बनाएँ, उसे activate करें, और `websockets` install करें (एक Python library जो "WebSocket" protocol का उपयोग आसान बनाती है):
<div class="termy">
```console
$ pip install websockets
---> 100%
```
</div>
## WebSockets client { #websockets-client }
### production में { #in-production }
आपके production system में, संभवतः आपके पास React, Vue.js या Angular जैसे आधुनिक framework से बना frontend होगा।
और अपने backend के साथ WebSockets का उपयोग करके संवाद करने के लिए आप संभवतः अपने frontend की utilities का उपयोग करेंगे।
या आपके पास एक native mobile application हो सकती है जो सीधे native code में आपके WebSocket backend से संवाद करती हो।
या आपके पास WebSocket endpoint से संवाद करने का कोई और तरीका हो सकता है।
---
लेकिन इस उदाहरण के लिए, हम कुछ JavaScript के साथ एक बहुत सरल HTML document का उपयोग करेंगे, सब कुछ एक लंबी string के अंदर।
बेशक, यह optimal नहीं है और आप इसे production के लिए उपयोग नहीं करेंगे।
production में आपके पास ऊपर दिए गए विकल्पों में से एक होगा।
लेकिन WebSockets के server-side पर ध्यान केंद्रित करने और एक working उदाहरण पाने का यह सबसे सरल तरीका है:
{* ../../docs_src/websockets_/tutorial001_py310.py hl[2,6:38,41:43] *}
## एक `websocket` बनाएँ { #create-a-websocket }
अपने **FastAPI** application में, एक `websocket` बनाएँ:
{* ../../docs_src/websockets_/tutorial001_py310.py hl[1,46:47] *}
/// note | तकनीकी विवरण
आप `from starlette.websockets import WebSocket` का भी उपयोग कर सकते हैं।
**FastAPI** वही `WebSocket` सीधे उपलब्ध कराता है, सिर्फ़ आपकी सुविधा के लिए, developer के रूप में। लेकिन यह सीधे Starlette से आता है।
///
## messages का await करें और messages भेजें { #await-for-messages-and-send-messages }
अपने WebSocket route में आप messages के लिए `await` कर सकते हैं और messages भेज सकते हैं।
{* ../../docs_src/websockets_/tutorial001_py310.py hl[48:52] *}
आप binary, text, और JSON data receive और send कर सकते हैं।
## इसे आज़माएँ { #try-it }
अपना code `main.py` file में रखें और फिर अपना application चलाएँ:
<div class="termy">
```console
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
अपने browser में [http://127.0.0.1:8000](http://127.0.0.1:8000) खोलें।
आपको ऐसा एक सरल page दिखेगा:
<img src="/img/tutorial/websockets/image01.png">
आप input box में messages टाइप कर सकते हैं, और उन्हें भेज सकते हैं:
<img src="/img/tutorial/websockets/image02.png">
और WebSockets के साथ आपका **FastAPI** application जवाब देगा:
<img src="/img/tutorial/websockets/image03.png">
आप कई messages भेज (और receive कर) सकते हैं:
<img src="/img/tutorial/websockets/image04.png">
और वे सभी उसी WebSocket connection का उपयोग करेंगे।
## `Depends` और अन्य का उपयोग { #using-depends-and-others }
WebSocket endpoints में आप `fastapi` से import कर सकते हैं और उपयोग कर सकते हैं:
* `Depends`
* `Security`
* `Cookie`
* `Header`
* `Path`
* `Query`
वे अन्य FastAPI endpoints/*path operations* की तरह ही काम करते हैं:
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
/// note | नोट
क्योंकि यह एक WebSocket है, इसलिए `HTTPException` raise करना वास्तव में उचित नहीं है, इसके बजाय हम `WebSocketException` raise करते हैं।
आप [specification में परिभाषित valid codes](https://tools.ietf.org/html/rfc6455#section-7.4.1) में से एक closing code का उपयोग कर सकते हैं।
///
### dependencies के साथ WebSockets आज़माएँ { #try-the-websockets-with-dependencies }
अपना application चलाएँ:
<div class="termy">
```console
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
अपने browser में [http://127.0.0.1:8000](http://127.0.0.1:8000) खोलें।
वहाँ आप सेट कर सकते हैं:
* path में उपयोग किया गया "Item ID"।
* query parameter के रूप में उपयोग किया गया "Token"।
/// tip | सुझाव
ध्यान दें कि query `token` को एक dependency द्वारा handle किया जाएगा।
///
इसके साथ आप WebSocket connect कर सकते हैं और फिर messages भेज और receive कर सकते हैं:
<img src="/img/tutorial/websockets/image05.png">
## disconnections और कई clients को handle करना { #handling-disconnections-and-multiple-clients }
जब WebSocket connection बंद होता है, तो `await websocket.receive_text()` एक `WebSocketDisconnect` exception raise करेगा, जिसे आप इस उदाहरण की तरह catch और handle कर सकते हैं।
{* ../../docs_src/websockets_/tutorial003_py310.py hl[79:81] *}
इसे आज़माने के लिए:
* app को कई browser tabs में खोलें।
* उनसे messages लिखें।
* फिर tabs में से एक को बंद करें।
इससे `WebSocketDisconnect` exception raise होगा, और बाकी सभी clients को ऐसा message मिलेगा:
```
Client #1596980209979 left the chat
```
/// tip | सुझाव
ऊपर दिया गया app एक minimal और सरल उदाहरण है, जो दिखाता है कि कई WebSocket connections को messages कैसे handle और broadcast किए जाएँ।
लेकिन ध्यान रखें कि, चूँकि सब कुछ memory में, एक ही list में handle किया जाता है, यह केवल तब तक काम करेगा जब तक process चल रहा है, और केवल एक single process के साथ काम करेगा।
अगर आपको कुछ ऐसा चाहिए जिसे FastAPI के साथ integrate करना आसान हो लेकिन जो अधिक robust हो, Redis, PostgreSQL या अन्य द्वारा supported हो, तो [encode/broadcaster](https://github.com/encode/broadcaster) देखें।
///
## अधिक जानकारी { #more-info }
विकल्पों के बारे में अधिक जानने के लिए, इनके लिए Starlette का documentation देखें:
* [`WebSocket` class](https://www.starlette.dev/websockets/)।
* [Class-based WebSocket handling](https://www.starlette.dev/endpoints/#websocketendpoint)।

51
docs/hi/docs/advanced/wsgi.md

@ -0,0 +1,51 @@
# WSGI शामिल करना - Flask, Django, अन्य { #including-wsgi-flask-django-others }
आप WSGI applications को mount कर सकते हैं, जैसा आपने [Sub Applications - Mounts](sub-applications.md), [Proxy के पीछे](behind-a-proxy.md) में देखा।
इसके लिए, आप `WSGIMiddleware` का उपयोग कर सकते हैं और इसे अपनी WSGI application को wrap करने के लिए इस्तेमाल कर सकते हैं, उदाहरण के लिए, Flask, Django, आदि।
## `WSGIMiddleware` का उपयोग करना { #using-wsgimiddleware }
/// note | नोट
इसके लिए `a2wsgi` install करना required है, उदाहरण के लिए `pip install a2wsgi` के साथ।
///
आपको `a2wsgi` से `WSGIMiddleware` import करना होगा।
फिर WSGI (जैसे Flask) app को middleware के साथ wrap करें।
और फिर उसे किसी path के अंतर्गत mount करें।
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
/// note | नोट
पहले, `fastapi.middleware.wsgi` से `WSGIMiddleware` का उपयोग करने की सलाह दी जाती थी, लेकिन अब यह deprecated है।
इसके बजाय `a2wsgi` package का उपयोग करने की सलाह दी जाती है। उपयोग वही रहता है।
बस यह सुनिश्चित करें कि आपके पास `a2wsgi` package install है और आप `a2wsgi` से `WSGIMiddleware` को सही ढंग से import करते हैं।
///
## इसे जाँचें { #check-it }
अब, path `/v1/` के अंतर्गत हर request को Flask application द्वारा handle किया जाएगा।
और बाकी को **FastAPI** द्वारा handle किया जाएगा।
यदि आप इसे run करते हैं और [http://localhost:8000/v1/](http://localhost:8000/v1/) पर जाते हैं, तो आपको Flask से response दिखाई देगा:
```txt
Hello, World from Flask!
```
और यदि आप [http://localhost:8000/v2](http://localhost:8000/v2) पर जाते हैं, तो आपको FastAPI से response दिखाई देगा:
```JSON
{
"message": "Hello World"
}
```

24
docs/hi/docs/deployment/cloud.md

@ -0,0 +1,24 @@
# Cloud Providers पर FastAPI Deploy करें { #deploy-fastapi-on-cloud-providers }
आप अपनी FastAPI application deploy करने के लिए वस्तुतः **किसी भी cloud provider** का उपयोग कर सकते हैं।
अधिकांश मामलों में, मुख्य cloud providers के पास उनके साथ FastAPI deploy करने के लिए guides होती हैं।
## FastAPI Cloud { #fastapi-cloud }
**[FastAPI Cloud](https://fastapicloud.com)** को **FastAPI** के पीछे मौजूद उसी author और team ने बनाया है।
यह न्यूनतम प्रयास के साथ API को **build**, **deploy**, और **access** करने की प्रक्रिया को सरल बनाता है।
यह FastAPI के साथ apps बनाने वाले उसी **developer experience** को उन्हें cloud पर **deploy** करने में भी लाता है। 🎉
FastAPI Cloud, *FastAPI and friends* open source projects का प्राथमिक sponsor और funding provider है। ✨
## Cloud Providers - Sponsors { #cloud-providers-sponsors }
कुछ अन्य cloud providers भी ✨ [**FastAPI को sponsor करते हैं**](https://github.com/sponsors/tiangolo) ✨। 🙇
आप उनकी guides का पालन करने और उनकी services आज़माने के लिए उन पर भी विचार कर सकते हैं:
* [Render](https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi)
* [Railway](https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi)

321
docs/hi/docs/deployment/concepts.md

@ -0,0 +1,321 @@
# Deployments की अवधारणाएँ { #deployments-concepts }
जब आप एक **FastAPI** application, या वास्तव में किसी भी प्रकार की web API, deploy करते हैं, तो कई अवधारणाएँ होती हैं जिनकी आपको शायद परवाह होगी, और उनका उपयोग करके आप अपनी application को **deploy करने** का **सबसे उपयुक्त** तरीका ढूँढ सकते हैं।
कुछ महत्वपूर्ण अवधारणाएँ हैं:
* सुरक्षा - HTTPS
* startup पर चलना
* Restarts
* Replication (चल रहे processes की संख्या)
* Memory
* शुरू करने से पहले के पिछले steps
हम देखेंगे कि ये **deployments** को कैसे प्रभावित करेंगे।
अंत में, अंतिम उद्देश्य यह है कि आप अपने **API clients को serve** कर सकें, वह भी ऐसे तरीके से जो **सुरक्षित** हो, **disruptions से बचाए**, और **compute resources** (जैसे remote servers/virtual machines) का यथासंभव कुशलता से उपयोग करे। 🚀
मैं यहाँ इन **अवधारणाओं** के बारे में थोड़ा और बताऊँगा, और उम्मीद है कि इससे आपको वह **intuition** मिलेगी जिसकी आपको अपनी API को बहुत अलग-अलग environments में deploy करने का निर्णय लेने के लिए आवश्यकता होगी, संभवतः ऐसे **future** environments में भी जो अभी मौजूद नहीं हैं।
इन अवधारणाओं पर विचार करके, आप **अपनी खुद की APIs** को deploy करने का सबसे अच्छा तरीका **evaluate और design** कर पाएँगे।
अगले chapters में, मैं आपको FastAPI applications deploy करने के लिए अधिक **ठोस recipes** दूँगा।
लेकिन अभी के लिए, आइए इन महत्वपूर्ण **conceptual ideas** को देखें। ये अवधारणाएँ किसी भी अन्य प्रकार की web API पर भी लागू होती हैं। 💡
## सुरक्षा - HTTPS { #security-https }
[HTTPS के बारे में पिछले chapter](https.md) में हमने सीखा कि HTTPS आपकी API के लिए encryption कैसे प्रदान करता है।
हमने यह भी देखा कि HTTPS सामान्यतः आपके application server से **external** एक component, एक **TLS Termination Proxy**, द्वारा प्रदान किया जाता है।
और **HTTPS certificates renew** करने का प्रभारी कुछ होना चाहिए, यह वही component हो सकता है या कुछ अलग भी हो सकता है।
### HTTPS के लिए उदाहरण Tools { #example-tools-for-https }
TLS Termination Proxy के रूप में आप जिन tools का उपयोग कर सकते हैं, उनमें से कुछ हैं:
* Traefik
* Certificate renewals को अपने-आप संभालता है ✨
* Caddy
* Certificate renewals को अपने-आप संभालता है ✨
* Nginx
* Certificate renewals के लिए Certbot जैसे external component के साथ
* HAProxy
* Certificate renewals के लिए Certbot जैसे external component के साथ
* Nginx जैसे Ingress Controller के साथ Kubernetes
* Certificate renewals के लिए cert-manager जैसे external component के साथ
* Cloud provider द्वारा उनकी services के हिस्से के रूप में internally संभाला गया (नीचे पढ़ें 👇)
एक और विकल्प यह है कि आप एक **cloud service** का उपयोग कर सकते हैं जो HTTPS setup करने सहित अधिक काम करती है। इसमें कुछ restrictions हो सकती हैं या आपसे अधिक charge लिया जा सकता है, आदि। लेकिन उस स्थिति में, आपको स्वयं TLS Termination Proxy setup नहीं करना पड़ेगा।
अगले chapters में मैं आपको कुछ ठोस उदाहरण दिखाऊँगा।
---
फिर विचार करने के लिए अगले concepts उस program के बारे में हैं जो आपकी वास्तविक API चला रहा है (जैसे Uvicorn)।
## Program और Process { #program-and-process }
हम चल रहे "**process**" के बारे में बहुत बात करेंगे, इसलिए यह स्पष्ट होना उपयोगी है कि इसका क्या अर्थ है, और "**program**" शब्द से इसका क्या अंतर है।
### Program क्या है { #what-is-a-program }
**Program** शब्द का उपयोग आम तौर पर कई चीजों का वर्णन करने के लिए किया जाता है:
* वह **code** जो आप लिखते हैं, **Python files**
* वह **file** जिसे operating system द्वारा **execute** किया जा सकता है, उदाहरण के लिए: `python`, `python.exe` या `uvicorn`
* कोई विशेष program जब वह operating system पर **चल रहा** हो, CPU का उपयोग कर रहा हो, और memory में चीजें store कर रहा हो। इसे **process** भी कहा जाता है।
### Process क्या है { #what-is-a-process }
**Process** शब्द सामान्यतः अधिक विशिष्ट तरीके से उपयोग किया जाता है, केवल उस चीज़ के लिए जो operating system में चल रही होती है (जैसे ऊपर के अंतिम point में):
* कोई विशेष program जब वह operating system पर **चल रहा** हो।
* यह न तो file को refer करता है, न code को, यह **विशेष रूप से** उस चीज़ को refer करता है जिसे operating system द्वारा **execute** और manage किया जा रहा है।
* कोई भी program, कोई भी code, **केवल तभी कुछ कर सकता है** जब उसे **execute** किया जा रहा हो। यानी, जब कोई **process चल रहा** हो।
* Process को आपके द्वारा, या operating system द्वारा **terminate** (या "kill") किया जा सकता है। उस point पर, वह चलना/execute होना बंद कर देता है, और वह **अब कुछ नहीं कर सकता**
* आपके computer पर चल रही प्रत्येक application के पीछे कोई process होता है, प्रत्येक running program, प्रत्येक window, आदि। और computer चालू होने पर सामान्यतः कई processes **एक ही समय में** चल रहे होते हैं।
* **एक ही program** के **multiple processes** एक ही समय में चल सकते हैं।
यदि आप अपने operating system में "task manager" या "system monitor" (या समान tools) देखते हैं, तो आप उनमें से कई processes चलते हुए देख पाएँगे।
और, उदाहरण के लिए, आप शायद देखेंगे कि एक ही browser program (Firefox, Chrome, Edge, आदि) को चलाने वाले multiple processes हैं। वे सामान्यतः प्रति tab एक process चलाते हैं, साथ में कुछ अन्य extra processes भी।
<img class="shadow" src="/img/deployment/concepts/image01.png">
---
अब जब हम **process** और **program** शब्दों के बीच अंतर जानते हैं, तो deployments के बारे में बात जारी रखते हैं।
## startup पर चलना { #running-on-startup }
अधिकांश मामलों में, जब आप एक web API बनाते हैं, तो आप चाहते हैं कि वह **हमेशा चलती रहे**, बिना interruption के, ताकि आपके clients हमेशा उसे access कर सकें। यह निश्चित रूप से तब तक है जब तक आपके पास कोई विशेष कारण न हो कि आप उसे केवल कुछ स्थितियों में ही चलाना चाहते हैं, लेकिन अधिकांश समय आप चाहते हैं कि वह लगातार चलती रहे और **available** रहे।
### Remote Server में { #in-a-remote-server }
जब आप एक remote server (एक cloud server, एक virtual machine, आदि) setup करते हैं, तो सबसे सरल चीज़ जो आप कर सकते हैं वह है `fastapi run` (जो Uvicorn का उपयोग करता है) या कुछ समान, manually, ठीक उसी तरह जैसे आप local development करते समय करते हैं।
और यह काम करेगा और **development के दौरान** उपयोगी होगा।
लेकिन यदि server से आपका connection खो जाता है, तो **running process** शायद मर जाएगा।
और यदि server restart होता है (उदाहरण के लिए updates के बाद, या cloud provider से migrations के बाद) तो आप शायद **इसे notice नहीं करेंगे**। और इसके कारण, आपको यह भी पता नहीं चलेगा कि आपको process को manually restart करना है। इसलिए, आपकी API बस dead ही रहेगी। 😱
### Startup पर Automatically चलाना { #run-automatically-on-startup }
सामान्यतः, आप शायद चाहेंगे कि server program (जैसे Uvicorn) server startup पर automatically start हो, और किसी **human intervention** की आवश्यकता के बिना, ताकि आपकी API के साथ हमेशा एक process चल रहा हो (जैसे Uvicorn आपकी FastAPI app चला रहा हो)।
### अलग Program { #separate-program }
इसे हासिल करने के लिए, आपके पास सामान्यतः एक **अलग program** होगा जो सुनिश्चित करेगा कि आपकी application startup पर चले। और कई मामलों में, यह यह भी सुनिश्चित करेगा कि अन्य components या applications भी चलें, उदाहरण के लिए, एक database।
### Startup पर चलाने के लिए उदाहरण Tools { #example-tools-to-run-at-startup }
इस काम को करने वाले tools के कुछ उदाहरण हैं:
* Docker
* Kubernetes
* Docker Compose
* Docker in Swarm Mode
* Systemd
* Supervisor
* Cloud provider द्वारा उनकी services के हिस्से के रूप में internally संभाला गया
* अन्य...
अगले chapters में मैं आपको अधिक ठोस उदाहरण दूँगा।
## Restarts { #restarts }
यह सुनिश्चित करने जैसा कि आपकी application startup पर चले, आप शायद यह भी सुनिश्चित करना चाहेंगे कि failures के बाद उसे **restart** किया जाए।
### हम गलतियाँ करते हैं { #we-make-mistakes }
हम, मनुष्य के रूप में, हर समय **गलतियाँ** करते हैं। Software में लगभग *हमेशा* अलग-अलग जगहों पर **bugs** छिपे होते हैं। 🐛
और हम developers उन bugs को खोजते हुए और नई features implement करते हुए code को बेहतर बनाते रहते हैं (संभवतः नए bugs भी जोड़ते हुए 😅)।
### छोटे Errors Automatically संभाले जाते हैं { #small-errors-automatically-handled }
FastAPI के साथ web APIs बनाते समय, यदि हमारे code में कोई error है, तो FastAPI सामान्यतः उसे उस single request तक सीमित रखेगा जिसने error trigger किया। 🛡
Client को उस request के लिए **500 Internal Server Error** मिलेगा, लेकिन application पूरी तरह crash होने के बजाय अगली requests के लिए काम करती रहेगी।
### बड़े Errors - Crashes { #bigger-errors-crashes }
फिर भी, ऐसे मामले हो सकते हैं जहाँ हम कुछ code लिखते हैं जो **पूरी application को crash** कर देता है, जिससे Uvicorn और Python crash हो जाते हैं। 💥
और फिर भी, आप शायद नहीं चाहेंगे कि application केवल इसलिए dead रहे क्योंकि एक जगह error था, आप शायद चाहेंगे कि वह कम से कम उन *path operations* के लिए **चलती रहे** जो broken नहीं हैं।
### Crash के बाद Restart { #restart-after-crash }
लेकिन उन मामलों में जहाँ वास्तव में खराब errors running **process** को crash कर देते हैं, आप चाहेंगे कि एक external component process को **restart** करने का प्रभारी हो, कम से कम कुछ बार...
/// tip | सुझाव
...हालाँकि यदि पूरी application बस **तुरंत crash** हो रही है तो शायद उसे हमेशा restart करते रहने का कोई अर्थ नहीं है। लेकिन ऐसे मामलों में, आप शायद इसे development के दौरान, या कम से कम deployment के ठीक बाद notice करेंगे।
तो आइए मुख्य मामलों पर focus करें, जहाँ यह **future** में कुछ विशेष मामलों में पूरी तरह crash हो सकती है, और फिर भी उसे restart करना समझ में आता है।
///
आप शायद चाहेंगे कि आपकी application को restart करने का प्रभारी एक **external component** हो, क्योंकि उस point तक, Uvicorn और Python वाली वही application पहले ही crash हो चुकी होती है, इसलिए उसी app के उसी code में ऐसा कुछ नहीं होता जो इसके बारे में कुछ कर सके।
### Automatically Restart करने के लिए उदाहरण Tools { #example-tools-to-restart-automatically }
अधिकांश मामलों में, वही tool जो **startup पर program चलाने** के लिए उपयोग होता है, automatic **restarts** संभालने के लिए भी उपयोग होता है।
उदाहरण के लिए, इसे ये संभाल सकते हैं:
* Docker
* Kubernetes
* Docker Compose
* Docker in Swarm Mode
* Systemd
* Supervisor
* Cloud provider द्वारा उनकी services के हिस्से के रूप में internally संभाला गया
* अन्य...
## Replication - Processes और Memory { #replication-processes-and-memory }
FastAPI application के साथ, Uvicorn चलाने वाले `fastapi` command जैसे server program का उपयोग करते हुए, उसे **एक process** में एक बार चलाना multiple clients को concurrently serve कर सकता है।
लेकिन कई मामलों में, आप एक ही समय में कई worker processes चलाना चाहेंगे।
### Multiple Processes - Workers { #multiple-processes-workers }
यदि आपके पास single process द्वारा handle किए जा सकने से अधिक clients हैं (उदाहरण के लिए यदि virtual machine बहुत बड़ी नहीं है) और server के CPU में **multiple cores** हैं, तो आप एक ही application के साथ **multiple processes** एक ही समय में चला सकते हैं, और सभी requests को उनके बीच distribute कर सकते हैं।
जब आप उसी API program के **multiple processes** चलाते हैं, तो उन्हें आम तौर पर **workers** कहा जाता है।
### Worker Processes और Ports { #worker-processes-and-ports }
Docs [About HTTPS](https.md) से याद करें कि server में port और IP address के एक combination पर केवल एक process listen कर सकता है?
यह अभी भी सही है।
इसलिए, एक ही समय में **multiple processes** रखने में सक्षम होने के लिए, एक **single process port पर listening** होना चाहिए जो फिर communication को किसी तरीके से प्रत्येक worker process तक transmit करे।
### प्रति Process Memory { #memory-per-process }
अब, जब program memory में चीजें load करता है, उदाहरण के लिए, किसी variable में machine learning model, या किसी बड़े file की contents किसी variable में, तो वह सब server की **memory (RAM) का थोड़ा हिस्सा consume** करता है।
और multiple processes सामान्यतः **कोई memory share नहीं करते**। इसका मतलब है कि प्रत्येक running process की अपनी चीजें, variables, और memory होती है। और यदि आप अपने code में बड़ी मात्रा में memory consume कर रहे हैं, तो **प्रत्येक process** उतनी ही memory consume करेगा।
### Server Memory { #server-memory }
उदाहरण के लिए, यदि आपका code **1 GB size** वाला Machine Learning model load करता है, तो जब आप अपनी API के साथ एक process चलाते हैं, तो वह कम से कम 1 GB RAM consume करेगा। और यदि आप **4 processes** (4 workers) start करते हैं, तो प्रत्येक 1 GB RAM consume करेगा। इसलिए कुल मिलाकर, आपकी API **4 GB RAM** consume करेगी।
और यदि आपके remote server या virtual machine में केवल 3 GB RAM है, तो 4 GB से अधिक RAM load करने की कोशिश problems पैदा करेगी। 🚨
### Multiple Processes - एक उदाहरण { #multiple-processes-an-example }
इस उदाहरण में, एक **Manager Process** है जो दो **Worker Processes** start और control करता है।
यह Manager Process शायद IP में **port** पर listen करने वाला होगा। और यह सभी communication को worker processes तक transmit करेगा।
वे worker processes वे होंगे जो आपकी application चला रहे होंगे, वे **request** प्राप्त करने और **response** return करने के लिए मुख्य computations करेंगे, और वे RAM में variables में डाली गई कोई भी चीज़ load करेंगे।
<img src="/img/deployment/concepts/process-ram.drawio.svg">
और निश्चित रूप से, उसी machine पर आपकी application के अलावा शायद **अन्य processes** भी चल रहे होंगे।
एक दिलचस्प detail यह है कि प्रत्येक process द्वारा **उपयोग किए गए CPU** का percentage समय के साथ बहुत **बदल** सकता है, लेकिन **memory (RAM)** सामान्यतः कम या ज्यादा **stable** रहती है।
यदि आपके पास एक API है जो हर बार comparable amount की computations करती है और आपके पास बहुत सारे clients हैं, तो **CPU utilization** शायद *stable भी रहेगा* (लगातार तेजी से ऊपर-नीचे जाने के बजाय)।
### Replication Tools और Strategies के उदाहरण { #examples-of-replication-tools-and-strategies }
इसे हासिल करने के कई approaches हो सकते हैं, और मैं अगले chapters में specific strategies के बारे में अधिक बताऊँगा, उदाहरण के लिए Docker और containers के बारे में बात करते समय।
विचार करने की मुख्य constraint यह है कि **public IP** में **port** को handle करने वाला एक **single** component होना चाहिए। और फिर उसके पास replicated **processes/workers** तक communication **transmit** करने का कोई तरीका होना चाहिए।
यहाँ कुछ संभावित combinations और strategies हैं:
* **Uvicorn** `--workers` के साथ
* एक Uvicorn **process manager** **IP** और **port** पर listen करेगा, और यह **multiple Uvicorn worker processes** start करेगा।
* **Kubernetes** और अन्य distributed **container systems**
* **Kubernetes** layer में कुछ **IP** और **port** पर listen करेगा। Replication **multiple containers** रखने से होगी, प्रत्येक में **एक Uvicorn process** चल रहा होगा।
* **Cloud services** जो यह आपके लिए संभालती हैं
* Cloud service शायद **आपके लिए replication handle** करेगी। यह संभवतः आपको **चलाने के लिए process**, या उपयोग करने के लिए **container image** define करने देगी, किसी भी स्थिति में, यह बहुत संभवतः **एक single Uvicorn process** होगा, और cloud service उसे replicate करने की प्रभारी होगी।
/// tip | सुझाव
यदि **containers**, Docker, या Kubernetes के बारे में इनमें से कुछ items अभी अधिक समझ में नहीं आते हैं तो चिंता न करें।
मैं future chapter में container images, Docker, Kubernetes, आदि के बारे में अधिक बताऊँगा: [Containers में FastAPI - Docker](docker.md)।
///
## शुरू करने से पहले के पिछले Steps { #previous-steps-before-starting }
कई मामले ऐसे होते हैं जहाँ आप अपनी application **start करने से पहले** कुछ steps perform करना चाहते हैं।
उदाहरण के लिए, आप **database migrations** चलाना चाह सकते हैं।
लेकिन अधिकांश मामलों में, आप इन steps को केवल **एक बार** perform करना चाहेंगे।
इसलिए, आप application start करने से पहले उन **previous steps** को perform करने के लिए एक **single process** रखना चाहेंगे।
और आपको यह सुनिश्चित करना होगा कि उन previous steps को चलाने वाला एक ही process हो, *भले ही* बाद में आप application के लिए **multiple processes** (multiple workers) start करें। यदि वे steps **multiple processes** द्वारा चलाए गए, तो वे उन्हें **parallel** में चलाकर काम को **duplicate** कर देंगे, और यदि steps database migration जैसी delicate चीज़ हैं, तो वे एक-दूसरे के साथ conflicts पैदा कर सकते हैं।
बेशक, कुछ मामले ऐसे होते हैं जहाँ previous steps को multiple times चलाने में कोई समस्या नहीं होती, उस स्थिति में इसे handle करना बहुत आसान होता है।
/// tip | सुझाव
साथ ही, ध्यान रखें कि आपके setup पर निर्भर करते हुए, कुछ मामलों में आपकी application start करने से पहले आपको **शायद किसी previous steps की आवश्यकता भी न हो**
उस स्थिति में, आपको इनमें से किसी भी चीज़ की चिंता नहीं करनी होगी। 🤷
///
### Previous Steps Strategies के उदाहरण { #examples-of-previous-steps-strategies }
यह इस बात पर **बहुत अधिक निर्भर** करेगा कि आप **अपना system कैसे deploy** करते हैं, और यह शायद programs start करने, restarts handle करने, आदि के तरीके से जुड़ा होगा।
यहाँ कुछ संभावित ideas हैं:
* Kubernetes में एक "Init Container" जो आपके app container से पहले चलता है
* एक bash script जो previous steps चलाती है और फिर आपकी application start करती है
* आपको फिर भी *उस* bash script को start/restart करने, errors detect करने, आदि का तरीका चाहिए होगा।
/// tip | सुझाव
Containers के साथ ऐसा करने के लिए मैं future chapter में अधिक ठोस उदाहरण दूँगा: [Containers में FastAPI - Docker](docker.md)।
///
## Resource Utilization { #resource-utilization }
आपके server(s) एक **resource** हैं, जिन्हें आप अपने programs के साथ consume या **utilize** कर सकते हैं, CPUs पर computation time और उपलब्ध RAM memory का उपयोग करके।
आप system resources का कितना हिस्सा consume/utilize करना चाहते हैं? "बहुत ज्यादा नहीं" सोचना आसान हो सकता है, लेकिन वास्तव में, आप शायद **crash किए बिना जितना संभव हो उतना** consume करना चाहेंगे।
यदि आप 3 servers के लिए भुगतान कर रहे हैं लेकिन उनकी RAM और CPU का केवल थोड़ा सा उपयोग कर रहे हैं, तो आप शायद **पैसा बर्बाद कर रहे हैं** 💸, और शायद **server की electric power बर्बाद कर रहे हैं** 🌎, आदि।
उस स्थिति में, केवल 2 servers रखना और उनके resources (CPU, memory, disk, network bandwidth, आदि) का उच्च percentage उपयोग करना बेहतर हो सकता है।
दूसरी ओर, यदि आपके पास 2 servers हैं और आप उनके **CPU और RAM का 100%** उपयोग कर रहे हैं, तो किसी point पर एक process अधिक memory माँगेगा, और server को disk को "memory" के रूप में उपयोग करना पड़ेगा (जो हजारों गुना धीमा हो सकता है), या वह **crash** भी हो सकता है। या किसी process को कुछ computation करनी हो सकती है और उसे CPU के फिर से free होने तक wait करना पड़ेगा।
इस मामले में, **एक extra server** लेना और उस पर कुछ processes चलाना बेहतर होगा ताकि उन सभी के पास **पर्याप्त RAM और CPU time** हो।
यह भी संभावना है कि किसी कारण से आपकी API के usage में **spike** हो। शायद यह viral हो गई, या शायद कुछ अन्य services या bots इसका उपयोग शुरू कर दें। और आप उन मामलों में safe रहने के लिए extra resources रखना चाह सकते हैं।
आप target करने के लिए एक **arbitrary number** रख सकते हैं, उदाहरण के लिए, resource utilization का **50% से 90% के बीच** कुछ। बात यह है कि ये शायद वे मुख्य चीजें हैं जिन्हें आप measure करना और अपने deployments tweak करने के लिए उपयोग करना चाहेंगे।
आप अपने server में उपयोग किए गए CPU और RAM या प्रत्येक process द्वारा उपयोग की गई मात्रा देखने के लिए `htop` जैसे simple tools का उपयोग कर सकते हैं। या आप अधिक complex monitoring tools का उपयोग कर सकते हैं, जो servers में distributed हो सकते हैं, आदि।
## Recap { #recap }
आपने यहाँ कुछ मुख्य अवधारणाएँ पढ़ी हैं जिन्हें अपनी application को कैसे deploy करना है, यह तय करते समय आपको शायद ध्यान में रखना होगा:
* सुरक्षा - HTTPS
* startup पर चलना
* Restarts
* Replication (चल रहे processes की संख्या)
* Memory
* शुरू करने से पहले के पिछले steps
इन ideas को समझना और उन्हें apply करना आपको अपने deployments configure और tweak करते समय कोई भी decisions लेने के लिए आवश्यक intuition देना चाहिए। 🤓
अगले sections में, मैं आपको उन संभावित strategies के अधिक ठोस उदाहरण दूँगा जिनका आप पालन कर सकते हैं। 🚀

618
docs/hi/docs/deployment/docker.md

@ -0,0 +1,618 @@
# Containers में FastAPI - Docker { #fastapi-in-containers-docker }
FastAPI applications deploy करते समय एक आम तरीका **Linux container image** बनाना है। यह सामान्यतः [**Docker**](https://www.docker.com/) का उपयोग करके किया जाता है। फिर आप उस container image को कुछ संभावित तरीकों में से किसी एक में deploy कर सकते हैं।
Linux containers का उपयोग करने के कई लाभ हैं, जिनमें **security**, **replicability**, **simplicity**, और अन्य शामिल हैं।
/// tip | टिप
जल्दी में हैं और यह सब पहले से जानते हैं? नीचे दिए गए [`Dockerfile` पर जाएँ 👇](#build-a-docker-image-for-fastapi).
///
<details>
<summary>Dockerfile Preview 👀</summary>
```Dockerfile
FROM python:3.14
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
# यदि Nginx या Traefik जैसे proxy के पीछे चला रहे हैं तो --proxy-headers जोड़ें
# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"]
```
</details>
## Container क्या है { #what-is-a-container }
Containers (मुख्य रूप से Linux containers) applications को उनकी सभी dependencies और आवश्यक files सहित package करने का एक बहुत **lightweight** तरीका हैं, जबकि उन्हें उसी system में दूसरे containers (दूसरी applications या components) से isolated रखा जाता है।
Linux containers host (machine, virtual machine, cloud server, आदि) के उसी Linux kernel का उपयोग करके चलते हैं। इसका मतलब बस इतना है कि वे बहुत lightweight होते हैं (पूरे operating system को emulate करने वाली full virtual machines की तुलना में)।
इस तरह, containers **कम resources** consume करते हैं, लगभग उतने ही जितने processes को सीधे चलाने में लगते हैं (virtual machine बहुत अधिक consume करेगी)।
Containers के अपने **isolated** running processes (आमतौर पर सिर्फ एक process), file system, और network भी होते हैं, जिससे deployment, security, development, आदि सरल हो जाते हैं।
## Container Image क्या है { #what-is-a-container-image }
एक **container** एक **container image** से चलाया जाता है।
Container image उन सभी files, environment variables, और default command/program का **static** version होता है जो container में मौजूद होना चाहिए। यहाँ **Static** का मतलब है कि container **image** चल नहीं रही है, execute नहीं हो रही है, यह सिर्फ packaged files और metadata है।
"**container image**" जो stored static contents है, उसके विपरीत, "**container**" सामान्यतः running instance को संदर्भित करता है, वह चीज़ जो **execute** हो रही है।
जब **container** start होकर running होता है (**container image** से start किया गया), तो यह files, environment variables, आदि बना या बदल सकता है। वे बदलाव केवल उस container में मौजूद होंगे, लेकिन underlying container image में persist नहीं होंगे (disk पर save नहीं होंगे)।
Container image की तुलना **program** file और contents से की जा सकती है, जैसे `python` और कोई file `main.py`
और **container** स्वयं (**container image** के विपरीत) image का वास्तविक running instance है, जिसकी तुलना **process** से की जा सकती है। वास्तव में, container केवल तब running होता है जब उसमें **process running** हो (और आमतौर पर यह केवल एक single process होता है)। जब उसमें कोई process running नहीं रहता, तो container stop हो जाता है।
## Container Images { #container-images }
Docker **container images** और **containers** बनाने और manage करने के मुख्य tools में से एक रहा है।
और एक public [Docker Hub](https://hub.docker.com/) है जिसमें कई tools, environments, databases, और applications के लिए पहले से बनी **official container images** हैं।
उदाहरण के लिए, एक official [Python Image](https://hub.docker.com/_/python) है।
और databases जैसी अलग-अलग चीज़ों के लिए कई अन्य images हैं, उदाहरण के लिए:
* [PostgreSQL](https://hub.docker.com/_/postgres)
* [MySQL](https://hub.docker.com/_/mysql)
* [MongoDB](https://hub.docker.com/_/mongo)
* [Redis](https://hub.docker.com/_/redis), आदि।
पहले से बनी container image का उपयोग करके अलग-अलग tools को **combine** और use करना बहुत आसान है। उदाहरण के लिए, नया database try करने के लिए। अधिकतर मामलों में, आप **official images** का उपयोग कर सकते हैं, और उन्हें सिर्फ environment variables से configure कर सकते हैं।
इस तरह, कई मामलों में आप containers और Docker के बारे में सीख सकते हैं और उस knowledge को कई अलग-अलग tools और components के साथ reuse कर सकते हैं।
तो, आप अलग-अलग चीज़ों के साथ **multiple containers** चलाएँगे, जैसे database, Python application, React frontend application वाला web server, और उन्हें उनके internal network के माध्यम से connect करेंगे।
सभी container management systems (जैसे Docker या Kubernetes) में ये networking features integrated होते हैं।
## Containers और Processes { #containers-and-processes }
एक **container image** सामान्यतः अपने metadata में default program या command शामिल करती है जिसे **container** start होने पर run किया जाना चाहिए, और उस program को pass किए जाने वाले parameters। यह बहुत हद तक वैसा ही है जैसा command line में होता।
जब कोई **container** start होता है, तो वह उस command/program को run करेगा (हालाँकि आप इसे override करके कोई अलग command/program run करवा सकते हैं)।
Container तब तक running रहता है जब तक **main process** (command या program) running रहता है।
Container में सामान्यतः **single process** होता है, लेकिन main process से subprocesses start करना भी संभव है, और इस तरह उसी container में **multiple processes** हो सकते हैं।
लेकिन **कम से कम एक running process** के बिना running container होना संभव नहीं है। यदि main process stop हो जाता है, तो container stop हो जाता है।
## FastAPI के लिए Docker Image बनाएँ { #build-a-docker-image-for-fastapi }
ठीक है, अब कुछ बनाते हैं! 🚀
मैं आपको दिखाऊँगा कि **official Python** image पर आधारित FastAPI के लिए **scratch से** **Docker image** कैसे बनाएँ।
यह वही है जो आप **अधिकतर मामलों** में करना चाहेंगे, उदाहरण के लिए:
* **Kubernetes** या समान tools का उपयोग करते समय
* **Raspberry Pi** पर चलाते समय
* ऐसा cloud service उपयोग करते समय जो आपके लिए container image run करेगा, आदि।
### Package Requirements { #package-requirements }
आपकी application के लिए **package requirements** सामान्यतः किसी file में होंगे।
यह मुख्य रूप से उस tool पर निर्भर करेगा जिसका उपयोग आप उन requirements को **install** करने के लिए करते हैं।
इसे करने का सबसे आम तरीका है `requirements.txt` file रखना, जिसमें package names और उनके versions हों, प्रति line एक।
आप versions की ranges set करने के लिए निश्चित रूप से वही ideas उपयोग करेंगे जो आपने [FastAPI versions के बारे में](versions.md) में पढ़े हैं।
उदाहरण के लिए, आपका `requirements.txt` ऐसा दिख सकता है:
```
fastapi[standard]>=0.113.0,<0.114.0
pydantic>=2.7.0,<3.0.0
```
और आप सामान्यतः उन package dependencies को `pip` से install करेंगे, उदाहरण के लिए:
<div class="termy">
```console
$ pip install -r requirements.txt
---> 100%
Successfully installed fastapi pydantic
```
</div>
/// note | नोट
Package dependencies define और install करने के लिए अन्य formats और tools भी हैं।
///
### **FastAPI** Code बनाएँ { #create-the-fastapi-code }
* एक `app` directory बनाएँ और उसमें enter करें।
* एक खाली file `__init__.py` बनाएँ।
* एक `main.py` file बनाएँ जिसमें हो:
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
```
### Dockerfile { #dockerfile }
अब उसी project directory में एक file `Dockerfile` बनाएँ जिसमें हो:
```{ .dockerfile .annotate }
# (1)!
FROM python:3.14
# (2)!
WORKDIR /code
# (3)!
COPY ./requirements.txt /code/requirements.txt
# (4)!
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
# (5)!
COPY ./app /code/app
# (6)!
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
```
1. Official Python base image से start करें।
2. Current working directory को `/code` पर set करें।
यही वह जगह है जहाँ हम `requirements.txt` file और `app` directory रखेंगे।
3. Requirements वाली file को `/code` directory में copy करें।
पहले **केवल** requirements वाली file copy करें, बाकी code नहीं।
क्योंकि यह file **अक्सर change नहीं होती**, Docker इसे detect करेगा और इस step के लिए **cache** का उपयोग करेगा, जिससे अगले step के लिए भी cache enable हो जाएगा।
4. Requirements file में package dependencies install करें।
`--no-cache-dir` option `pip` को बताता है कि downloaded packages को locally save न करे, क्योंकि यह केवल तब उपयोगी होता जब `pip` को उन्हीं packages को install करने के लिए फिर से run किया जाना हो, लेकिन containers के साथ काम करते समय ऐसा मामला नहीं है।
/// note | नोट
`--no-cache-dir` केवल `pip` से संबंधित है, इसका Docker या containers से कोई संबंध नहीं है।
///
`--upgrade` option `pip` को बताता है कि यदि packages पहले से installed हैं तो उन्हें upgrade करे।
क्योंकि पिछला step जिसमें file copy की गई थी **Docker cache** द्वारा detect किया जा सकता है, इसलिए यह step भी available होने पर **Docker cache का उपयोग** करेगा।
इस step में cache का उपयोग development के दौरान image बार-बार build करते समय आपका बहुत **समय** **बचाएगा**, हर बार सभी dependencies को **download और install** करने के बजाय।
5. `./app` directory को `/code` directory के अंदर copy करें।
क्योंकि इसमें सारा code है, और यही वह चीज़ है जो **सबसे अधिक बार change होती** है, Docker **cache** इस या किसी भी **आगे के steps** के लिए आसानी से उपयोग नहीं होगा।
इसलिए, container image build times optimize करने के लिए इसे `Dockerfile` के **end के पास** रखना महत्वपूर्ण है।
6. **command** set करें ताकि `fastapi run` उपयोग हो, जो अंदर से Uvicorn का उपयोग करता है।
`CMD` strings की list लेता है, इन strings में से प्रत्येक वही है जिसे आप command line में spaces से अलग करके type करेंगे।
यह command **current working directory** से run होगा, वही `/code` directory जिसे आपने ऊपर `WORKDIR /code` से set किया है।
/// tip | टिप
Code में प्रत्येक number bubble पर click करके review करें कि हर line क्या करती है। 👆
///
/// warning | चेतावनी
नीचे समझाए अनुसार, `CMD` instruction का **exec form** **हमेशा** use करना सुनिश्चित करें।
///
#### `CMD` उपयोग करें - Exec Form { #use-cmd-exec-form }
[`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) Docker instruction दो forms में लिखा जा सकता है:
**Exec** form:
```Dockerfile
# ✅ यह करें
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
```
⛔️ **Shell** form:
```Dockerfile
# ⛔️ यह न करें
CMD fastapi run app/main.py --port 80
```
यह सुनिश्चित करने के लिए कि FastAPI gracefully shutdown कर सके और [lifespan events](../advanced/events.md) trigger हों, हमेशा **exec** form use करें।
आप इसके बारे में [shell और exec form के लिए Docker docs](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form) में और पढ़ सकते हैं।
`docker compose` का उपयोग करते समय यह काफी noticeable हो सकता है। अधिक technical details के लिए यह Docker Compose FAQ section देखें: [मेरी services को recreate या stop होने में 10 seconds क्यों लगते हैं?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop).
#### Directory Structure { #directory-structure }
अब आपके पास ऐसी directory structure होनी चाहिए:
```
.
├── app
│   ├── __init__.py
│ └── main.py
├── Dockerfile
└── requirements.txt
```
#### TLS Termination Proxy के पीछे { #behind-a-tls-termination-proxy }
यदि आप अपना container Nginx या Traefik जैसे TLS Termination Proxy (load balancer) के पीछे चला रहे हैं, तो option `--proxy-headers` जोड़ें, यह Uvicorn (FastAPI CLI के माध्यम से) को बताएगा कि उस proxy द्वारा भेजे गए headers पर trust करे, जो उसे बताता है कि application HTTPS के पीछे चल रही है, आदि।
```Dockerfile
CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
```
#### Docker Cache { #docker-cache }
इस `Dockerfile` में एक महत्वपूर्ण trick है, हम पहले **केवल dependencies वाली file** copy करते हैं, बाकी code नहीं। मैं आपको बताता हूँ क्यों।
```Dockerfile
COPY ./requirements.txt /code/requirements.txt
```
Docker और अन्य tools इन container images को **incrementally build** करते हैं, **एक layer के ऊपर दूसरी layer** जोड़ते हुए, `Dockerfile` के top से शुरू करके और `Dockerfile` के प्रत्येक instruction द्वारा बनाई गई कोई भी files जोड़ते हुए।
Docker और समान tools image build करते समय **internal cache** भी use करते हैं, यदि कोई file पिछली बार container image build करने के बाद से change नहीं हुई है, तो वह file को फिर से copy करने और scratch से नई layer बनाने के बजाय पिछली बार बनाई गई **उसी layer को reuse** करेगा।
सिर्फ files copy करने से बचना जरूरी नहीं कि चीज़ों को बहुत बेहतर कर दे, लेकिन क्योंकि उसने उस step के लिए cache use किया, वह **अगले step के लिए cache use** कर सकता है। उदाहरण के लिए, वह उस instruction के लिए cache use कर सकता है जो dependencies install करता है:
```Dockerfile
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
```
Package requirements वाली file **अक्सर change नहीं होगी**। इसलिए, केवल उस file को copy करके, Docker उस step के लिए **cache use** कर पाएगा।
और फिर, Docker उन dependencies को download और install करने वाले **अगले step के लिए cache use** कर पाएगा। और यहीं हम **बहुत समय बचाते हैं**। ✨ ...और इंतज़ार की बोरियत से बचते हैं। 😪😆
Package dependencies को download और install करने में **minutes लग सकते हैं**, लेकिन **cache** का उपयोग करने में अधिकतम **seconds** लगेंगे।
और क्योंकि development के दौरान आप अपने code changes काम कर रहे हैं या नहीं यह check करने के लिए container image बार-बार build करेंगे, इससे बहुत सारा जमा हुआ समय बचेगा।
फिर, `Dockerfile` के end के पास, हम सारा code copy करते हैं। क्योंकि यही वह चीज़ है जो **सबसे अधिक बार change होती** है, हम इसे end के पास रखते हैं, क्योंकि लगभग हमेशा इस step के बाद कुछ भी cache use नहीं कर पाएगा।
```Dockerfile
COPY ./app /code/app
```
### Docker Image Build करें { #build-the-docker-image }
अब जब सभी files अपनी जगह पर हैं, चलिए container image build करते हैं।
* Project directory में जाएँ (जहाँ आपका `Dockerfile` है, जिसमें आपकी `app` directory है)।
* अपनी FastAPI image build करें:
<div class="termy">
```console
$ docker build -t myimage .
---> 100%
```
</div>
/// tip | टिप
अंत में `.` पर ध्यान दें, यह `./` के equivalent है, यह Docker को container image build करने के लिए use की जाने वाली directory बताता है।
इस मामले में, यह वही current directory (`.`) है।
///
### Docker Container Start करें { #start-the-docker-container }
* अपनी image पर आधारित container run करें:
<div class="termy">
```console
$ docker run -d --name mycontainer -p 80:80 myimage
```
</div>
## इसे Check करें { #check-it }
आप इसे अपने Docker container के URL में check कर पाएँगे, उदाहरण के लिए: [http://192.168.99.100/items/5?q=somequery](http://192.168.99.100/items/5?q=somequery) या [http://127.0.0.1/items/5?q=somequery](http://127.0.0.1/items/5?q=somequery) (या equivalent, अपने Docker host का उपयोग करके)।
आपको कुछ ऐसा दिखेगा:
```JSON
{"item_id": 5, "q": "somequery"}
```
## Interactive API docs { #interactive-api-docs }
अब आप [http://192.168.99.100/docs](http://192.168.99.100/docs) या [http://127.0.0.1/docs](http://127.0.0.1/docs) (या equivalent, अपने Docker host का उपयोग करके) पर जा सकते हैं।
आप automatic interactive API documentation देखेंगे ([Swagger UI](https://github.com/swagger-api/swagger-ui) द्वारा provided):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
## Alternative API docs { #alternative-api-docs }
और आप [http://192.168.99.100/redoc](http://192.168.99.100/redoc) या [http://127.0.0.1/redoc](http://127.0.0.1/redoc) (या equivalent, अपने Docker host का उपयोग करके) पर भी जा सकते हैं।
आप alternative automatic documentation देखेंगे ([ReDoc](https://github.com/Rebilly/ReDoc) द्वारा provided):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Single-File FastAPI के साथ Docker Image बनाएँ { #build-a-docker-image-with-a-single-file-fastapi }
यदि आपकी FastAPI एक single file है, उदाहरण के लिए, `./app` directory के बिना `main.py`, तो आपकी file structure ऐसी दिख सकती है:
```
.
├── Dockerfile
├── main.py
└── requirements.txt
```
फिर आपको बस `Dockerfile` के अंदर file copy करने के लिए संबंधित paths बदलने होंगे:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.14
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
# (1)!
COPY ./main.py /code/
# (2)!
CMD ["fastapi", "run", "main.py", "--port", "80"]
```
1. `main.py` file को सीधे `/code` directory में copy करें (बिना किसी `./app` directory के)।
2. Single file `main.py` में अपनी application serve करने के लिए `fastapi run` use करें।
जब आप file को `fastapi run` में pass करते हैं, तो यह automatically detect करेगा कि यह single file है और किसी package का हिस्सा नहीं है, और यह जान जाएगा कि इसे कैसे import करना है और आपकी FastAPI app को serve करना है। 😎
## Deployment Concepts { #deployment-concepts }
आइए containers के संदर्भ में फिर से उन्हीं कुछ [Deployment Concepts](concepts.md) के बारे में बात करें।
Containers मुख्य रूप से application को **build और deploy** करने की process को सरल बनाने का tool हैं, लेकिन वे इन **deployment concepts** को handle करने के लिए कोई particular approach enforce नहीं करते, और कई संभावित strategies हैं।
**अच्छी खबर** यह है कि हर अलग strategy के साथ सभी deployment concepts को cover करने का एक तरीका है। 🎉
आइए इन **deployment concepts** को containers के संदर्भ में review करें:
* HTTPS
* startup पर Running
* Restarts
* Replication (running processes की संख्या)
* Memory
* Start करने से पहले previous steps
## HTTPS { #https }
यदि हम FastAPI application के लिए सिर्फ **container image** (और बाद में running **container**) पर focus करें, तो HTTPS सामान्यतः किसी अन्य tool द्वारा **externally** handle किया जाएगा।
यह कोई दूसरा container हो सकता है, उदाहरण के लिए [Traefik](https://traefik.io/) के साथ, जो **HTTPS** और **certificates** की **automatic** acquisition handle करता है।
/// tip | टिप
Traefik के Docker, Kubernetes, और अन्य के साथ integrations हैं, इसलिए इसके साथ अपने containers के लिए HTTPS set up और configure करना बहुत आसान है।
///
वैकल्पिक रूप से, HTTPS को किसी cloud provider द्वारा उनकी services में से एक के रूप में handle किया जा सकता है (application अभी भी container में चल रही हो)।
## Startup पर Running और Restarts { #running-on-startup-and-restarts }
सामान्यतः कोई दूसरा tool आपके container को **start और run** करने के लिए charge में होता है।
यह सीधे **Docker**, **Docker Compose**, **Kubernetes**, कोई **cloud service**, आदि हो सकता है।
अधिकतर (या सभी) मामलों में, startup पर container run करने और failures पर restarts enable करने के लिए एक simple option होता है। उदाहरण के लिए, Docker में यह command line option `--restart` है।
Containers का उपयोग किए बिना, applications को startup पर और restarts के साथ run कराना cumbersome और difficult हो सकता है। लेकिन **containers के साथ काम करते समय** अधिकतर मामलों में यह functionality default रूप से शामिल होती है। ✨
## Replication - Processes की संख्या { #replication-number-of-processes }
यदि आपके पास machines का <dfn title="मशीनों का एक समूह जो किसी तरह से connect होने और साथ काम करने के लिए configured हैं।">cluster</dfn> है जिसमें **Kubernetes**, Docker Swarm Mode, Nomad, या multiple machines पर distributed containers manage करने के लिए कोई अन्य similar complex system है, तो आप शायद प्रत्येक container में **process manager** (जैसे workers के साथ Uvicorn) उपयोग करने के बजाय **cluster level** पर **replication handle** करना चाहेंगे।
Kubernetes जैसे distributed container management systems में incoming requests के लिए **load balancing** support करते हुए **containers की replication** handle करने का कोई integrated तरीका सामान्यतः होता है। सब **cluster level** पर।
उन मामलों में, आप शायद ऊपर [समझाए अनुसार](#dockerfile) **scratch से Docker image** build करना चाहेंगे, अपनी dependencies install करके, और multiple Uvicorn workers उपयोग करने के बजाय **single Uvicorn process** run करना चाहेंगे।
### Load Balancer { #load-balancer }
Containers का उपयोग करते समय, आपके पास सामान्यतः कोई component होगा जो **main port पर listening** कर रहा होगा। संभवतः यह कोई दूसरा container हो सकता है जो **HTTPS** handle करने के लिए **TLS Termination Proxy** भी हो, या कोई similar tool।
क्योंकि यह component requests का **load** लेगा और उसे workers में (उम्मीद है) **balanced** तरीके से distribute करेगा, इसे सामान्यतः **Load Balancer** भी कहा जाता है।
/// tip | टिप
HTTPS के लिए उपयोग किया गया वही **TLS Termination Proxy** component शायद **Load Balancer** भी होगा।
///
और containers के साथ काम करते समय, उन्हें start और manage करने के लिए आप जो system use करते हैं, उसमें उस **load balancer** (जो **TLS Termination Proxy** भी हो सकता है) से आपकी app वाले container(s) तक **network communication** (जैसे HTTP requests) transmit करने के internal tools पहले से होंगे।
### One Load Balancer - Multiple Worker Containers { #one-load-balancer-multiple-worker-containers }
**Kubernetes** या similar distributed container management systems के साथ काम करते समय, उनके internal networking mechanisms का उपयोग main **port** पर listening करने वाले single **load balancer** को communication (requests) आपकी app चला रहे संभवतः **multiple containers** तक transmit करने देगा।
आपकी app चला रहे इन containers में से प्रत्येक में सामान्यतः **सिर्फ एक process** होगा (जैसे आपकी FastAPI application चलाने वाला Uvicorn process)। वे सभी **identical containers** होंगे, वही चीज़ चला रहे होंगे, लेकिन प्रत्येक का अपना process, memory, आदि होगा। इस तरह आप CPU के **different cores** में, या यहाँ तक कि **different machines** में **parallelization** का लाभ उठाएँगे।
और **load balancer** वाला distributed container system requests को आपकी app वाले प्रत्येक container तक **बारी-बारी से distribute** करेगा। इसलिए, प्रत्येक request आपकी app चला रहे multiple **replicated containers** में से किसी एक द्वारा handle की जा सकती है।
और सामान्यतः यह **load balancer** आपके cluster में *other* apps पर जाने वाली requests handle कर पाएगा (जैसे अलग domain पर, या अलग URL path prefix के तहत), और उस communication को आपके cluster में चल रही *उस other* application के सही containers तक transmit करेगा।
### प्रति Container एक Process { #one-process-per-container }
इस तरह के scenario में, आप शायद **प्रति container एक single (Uvicorn) process** रखना चाहेंगे, क्योंकि आप पहले से ही cluster level पर replication handle कर रहे होंगे।
तो, इस मामले में, आप container में multiple workers **नहीं** रखना चाहेंगे, उदाहरण के लिए `--workers` command line option के साथ। आप प्रति container बस **single Uvicorn process** रखना चाहेंगे (लेकिन शायद multiple containers)।
Container के अंदर एक और process manager रखना (जैसा multiple workers के साथ होगा) केवल **unnecessary complexity** जोड़ेगा, जिसे आप बहुत संभव है कि अपने cluster system के साथ पहले से संभाल रहे हैं।
### Multiple Processes वाले Containers और Special Cases { #containers-with-multiple-processes-and-special-cases }
बेशक, ऐसे **special cases** हैं जहाँ आप अंदर कई **Uvicorn worker processes** वाला **container** रखना चाह सकते हैं।
उन मामलों में, आप run किए जाने वाले workers की संख्या set करने के लिए `--workers` command line option उपयोग कर सकते हैं:
```{ .dockerfile .annotate }
FROM python:3.14
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
# (1)!
CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
```
1. यहाँ हम workers की संख्या 4 पर set करने के लिए `--workers` command line option उपयोग करते हैं।
यहाँ कुछ examples हैं कि यह कब meaningful हो सकता है:
#### एक Simple App { #a-simple-app }
यदि आपकी application **इतनी simple** है कि आप इसे **single server** पर run कर सकते हैं, cluster पर नहीं, तो आप container में process manager चाह सकते हैं।
#### Docker Compose { #docker-compose }
आप **Docker Compose** के साथ **single server** (cluster नहीं) पर deploy कर रहे हो सकते हैं, इसलिए shared network और **load balancing** preserve करते हुए containers की replication (Docker Compose के साथ) manage करने का आसान तरीका आपके पास नहीं होगा।
फिर आप **single container** रखना चाह सकते हैं जिसमें **process manager** अंदर **कई worker processes** start करे।
---
मुख्य बात यह है कि इनमें से **कोई भी** ऐसी **पत्थर पर लिखी rules** नहीं हैं जिन्हें आपको आँख बंद करके follow करना हो। आप इन ideas का उपयोग **अपने use case का evaluate** करने और अपने system के लिए best approach तय करने के लिए कर सकते हैं, यह check करते हुए कि इन concepts को कैसे manage करना है:
* Security - HTTPS
* startup पर Running
* Restarts
* Replication (running processes की संख्या)
* Memory
* Start करने से पहले previous steps
## Memory { #memory }
यदि आप **प्रति container single process** run करते हैं, तो उन containers में से प्रत्येक (यदि replicated हैं तो एक से अधिक) द्वारा consumed memory की quantity कमोबेश well-defined, stable, और limited होगी।
और फिर आप अपने container management system (उदाहरण के लिए **Kubernetes** में) की configurations में वही memory limits और requirements set कर सकते हैं। इस तरह वह उन containers द्वारा आवश्यक memory की मात्रा, और cluster में machines में available मात्रा को ध्यान में रखते हुए **available machines** में **containers replicate** कर पाएगा।
यदि आपकी application **simple** है, तो यह शायद **problem नहीं होगी**, और आपको hard memory limits specify करने की आवश्यकता नहीं हो सकती। लेकिन यदि आप **बहुत memory use** कर रहे हैं (उदाहरण के लिए **machine learning** models के साथ), तो आपको check करना चाहिए कि आप कितनी memory consume कर रहे हैं और **प्रत्येक machine** पर run होने वाले **containers की संख्या** adjust करनी चाहिए (और शायद अपने cluster में और machines add करनी चाहिए)।
यदि आप **प्रति container multiple processes** run करते हैं, तो आपको सुनिश्चित करना होगा कि start किए गए processes की संख्या available memory से **अधिक memory consume** न करे।
## Start करने से पहले Previous Steps और Containers { #previous-steps-before-starting-and-containers }
यदि आप containers (जैसे Docker, Kubernetes) उपयोग कर रहे हैं, तो दो मुख्य approaches हैं जिनका आप उपयोग कर सकते हैं।
### Multiple Containers { #multiple-containers }
यदि आपके पास **multiple containers** हैं, शायद प्रत्येक **single process** run कर रहा है (उदाहरण के लिए, **Kubernetes** cluster में), तो आप replicated worker containers run करने से **पहले**, single container में, single process चलाते हुए, **previous steps** का काम करने वाला **separate container** रखना चाहेंगे।
/// note | नोट
यदि आप Kubernetes उपयोग कर रहे हैं, तो यह शायद [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) होगा।
///
यदि आपके use case में उन previous steps को **parallel में multiple times** run करने में कोई problem नहीं है (उदाहरण के लिए यदि आप database migrations नहीं चला रहे, बल्कि बस check कर रहे हैं कि database अभी ready है या नहीं), तो आप उन्हें हर container में main process start करने से ठीक पहले भी रख सकते हैं।
### Single Container { #single-container }
यदि आपका setup simple है, जिसमें **single container** है जो फिर multiple **worker processes** start करता है (या सिर्फ एक process), तो आप app के साथ process start करने से ठीक पहले, उन previous steps को उसी container में run कर सकते हैं।
### Base Docker Image { #base-docker-image }
एक official FastAPI Docker image हुआ करती थी: [tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker)। लेकिन अब यह deprecated है। ⛔️
आपको शायद इस base Docker image (या किसी अन्य similar one) का उपयोग **नहीं** करना चाहिए।
यदि आप **Kubernetes** (या अन्य) उपयोग कर रहे हैं और पहले से ही cluster level पर, multiple **containers** के साथ **replication** set कर रहे हैं। उन मामलों में, ऊपर बताए अनुसार **scratch से image build** करना बेहतर है: [FastAPI के लिए Docker Image बनाएँ](#build-a-docker-image-for-fastapi).
और यदि आपको multiple workers की आवश्यकता है, तो आप बस `--workers` command line option उपयोग कर सकते हैं।
/// note | Technical Details
Docker image तब बनाई गई थी जब Uvicorn dead workers को manage और restart करने का support नहीं करता था, इसलिए Uvicorn के साथ Gunicorn का उपयोग करना required था, जिससे काफी complexity जुड़ती थी, सिर्फ इसलिए कि Gunicorn Uvicorn worker processes को manage और restart कर सके।
लेकिन अब जब Uvicorn (और `fastapi` command) `--workers` use करने का support करते हैं, तो अपनी खुद की build करने के बजाय base Docker image उपयोग करने का कोई कारण नहीं है (यह लगभग उतनी ही code की मात्रा है 😅).
///
## Container Image Deploy करें { #deploy-the-container-image }
Container (Docker) Image होने के बाद इसे deploy करने के कई तरीके हैं।
उदाहरण के लिए:
* Single server में **Docker Compose** के साथ
* **Kubernetes** cluster के साथ
* Docker Swarm Mode cluster के साथ
* Nomad जैसे किसी अन्य tool के साथ
* किसी cloud service के साथ जो आपकी container image लेता है और उसे deploy करता है
## `uv` के साथ Docker Image { #docker-image-with-uv }
यदि आप अपने project को install और manage करने के लिए [uv](https://github.com/astral-sh/uv) उपयोग कर रहे हैं, तो आप उनकी [uv Docker guide](https://docs.astral.sh/uv/guides/integration/docker/) follow कर सकते हैं।
## Recap { #recap }
Container systems (जैसे **Docker** और **Kubernetes** के साथ) का उपयोग करने पर सभी **deployment concepts** handle करना काफी straightforward हो जाता है:
* HTTPS
* startup पर Running
* Restarts
* Replication (running processes की संख्या)
* Memory
* Start करने से पहले previous steps
अधिकतर मामलों में, आप शायद कोई base image use नहीं करना चाहेंगे, और इसके बजाय official Python Docker image पर आधारित **scratch से container image build** करेंगे।
`Dockerfile` में instructions के **order** और **Docker cache** का ध्यान रखकर आप **build times minimize** कर सकते हैं, ताकि आपकी productivity maximize हो (और बोरियत से बचें)। 😎

47
docs/hi/docs/deployment/fastapicloud.md

@ -0,0 +1,47 @@
# FastAPI Cloud { #fastapi-cloud }
आप अपनी FastAPI app को सिर्फ **एक command** से [FastAPI Cloud](https://fastapicloud.com) पर deploy कर सकते हैं। 🚀
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
CLI अपने-आप आपकी FastAPI application का पता लगा लेगा और उसे cloud पर deploy कर देगा। अगर आप logged in नहीं हैं, तो authentication प्रक्रिया पूरी करने के लिए आपका browser खुलेगा।
बस इतना ही! अब आप उस URL पर अपनी app access कर सकते हैं। ✨
## FastAPI Cloud के बारे में { #about-fastapi-cloud }
**[FastAPI Cloud](https://fastapicloud.com)** उसी author और team द्वारा बनाया गया है जो **FastAPI** के पीछे हैं।
यह कम से कम प्रयास में API को **build** करने, **deploy** करने, और **access** करने की प्रक्रिया को सरल बनाता है।
यह FastAPI के साथ apps बनाने वाले उसी **developer experience** को उन्हें cloud पर **deploy** करने में भी लाता है। 🎉
यह app deploy करते समय ज़रूरी अधिकांश चीज़ों का भी ध्यान रखेगा, जैसे:
* HTTPS
* Replication, requests के आधार पर autoscaling के साथ
* आदि।
FastAPI Cloud, *FastAPI and friends* open source projects का मुख्य sponsor और funding provider है। ✨
## दूसरे cloud providers पर deploy करें { #deploy-to-other-cloud-providers }
FastAPI open source है और standards पर आधारित है। आप FastAPI apps को अपने चुने हुए किसी भी cloud provider पर deploy कर सकते हैं।
उनके साथ FastAPI apps deploy करने के लिए अपने cloud provider की guides follow करें। 🤓
## अपने खुद के server पर deploy करें { #deploy-your-own-server }
मैं आपको इस **Deployment** guide में आगे सभी details भी सिखाऊँगा, ताकि आप समझ सकें कि क्या हो रहा है, क्या होना चाहिए, या FastAPI apps को अपने-आप, अपने खुद के servers के साथ भी कैसे deploy करना है। 🤓

231
docs/hi/docs/deployment/https.md

@ -0,0 +1,231 @@
# HTTPS के बारे में { #about-https }
यह मान लेना आसान है कि HTTPS कोई ऐसी चीज़ है जिसे बस "enabled" किया जाता है या नहीं।
लेकिन यह उससे कहीं ज़्यादा जटिल है।
/// tip | सुझाव
अगर आप जल्दी में हैं या आपको परवाह नहीं है, तो अलग-अलग तकनीकों के साथ सब कुछ setup करने के लिए step by step निर्देशों हेतु अगले sections पर जाएँ।
///
**HTTPS की मूल बातें सीखने** के लिए, एक उपभोक्ता के दृष्टिकोण से, देखें [https://howhttps.works/](https://howhttps.works/)।
अब, एक **developer के दृष्टिकोण** से, HTTPS के बारे में सोचते समय ध्यान रखने योग्य कई बातें यहाँ हैं:
* HTTPS के लिए, **server** के पास **तीसरे पक्ष** द्वारा बनाए गए "certificates" होने चाहिए।
* वे certificates वास्तव में तीसरे पक्ष से **प्राप्त** किए जाते हैं, "generated" नहीं।
* Certificates की एक **lifespan** होती है।
* वे **expire** हो जाते हैं।
* और फिर उन्हें **renew** करना पड़ता है, तीसरे पक्ष से **फिर से प्राप्त** करना पड़ता है।
* connection का encryption **TCP level** पर होता है।
* यह **HTTP से एक layer नीचे** है।
* इसलिए, **certificate और encryption** handling **HTTP से पहले** की जाती है।
* **TCP को "domains" के बारे में पता नहीं होता**। केवल IP addresses के बारे में।
* जिस **विशिष्ट domain** का request किया गया है, उसकी जानकारी **HTTP data** में जाती है।
* **HTTPS certificates** किसी **विशिष्ट domain** को "certify" करते हैं, लेकिन protocol और encryption TCP level पर होते हैं, इस domain को जानने से **पहले** कि किस domain से निपटा जा रहा है।
* **By default**, इसका मतलब होगा कि आपके पास **प्रति IP address केवल एक HTTPS certificate** हो सकता है।
* इससे कोई फर्क नहीं पड़ता कि आपका server कितना बड़ा है या उस पर मौजूद हर application कितनी छोटी हो सकती है।
* हालांकि, इसका एक **समाधान** है।
* **TLS** protocol (जो HTTP से पहले, TCP level पर encryption संभालता है) के लिए एक **extension** है जिसे **[<abbr title="Server Name Indication - सर्वर नाम संकेत">SNI</abbr>](https://en.wikipedia.org/wiki/Server_Name_Indication)** कहा जाता है।
* यह SNI extension एक ही server (एक **single IP address** के साथ) को **कई HTTPS certificates** रखने और **कई HTTPS domains/applications** serve करने की अनुमति देता है।
* इसे काम करने के लिए, server पर चल रहे, **public IP address** पर listen कर रहे, एक **single** component (program) के पास server में **सभी HTTPS certificates** होने चाहिए।
* सुरक्षित connection प्राप्त करने के **बाद**, communication protocol **अभी भी HTTP** रहता है।
* contents **encrypted** होते हैं, भले ही उन्हें **HTTP protocol** के साथ भेजा जा रहा हो।
Server (machine, host, आदि) पर **एक program/HTTP server** चलाना और **HTTPS के सभी हिस्सों को manage** करना एक सामान्य practice है: **encrypted HTTPS requests** प्राप्त करना, उसी server में चल रही वास्तविक HTTP application (इस मामले में **FastAPI** application) को **decrypted HTTP requests** भेजना, application से **HTTP response** लेना, उपयुक्त **HTTPS certificate** का उपयोग करके उसे **encrypt** करना और **HTTPS** का उपयोग करके client को वापस भेजना। इस server को अक्सर **[TLS Termination Proxy](https://en.wikipedia.org/wiki/TLS_termination_proxy)** कहा जाता है।
TLS Termination Proxy के रूप में आप जिन options का उपयोग कर सकते हैं, उनमें से कुछ हैं:
* Traefik (जो certificate renewals भी handle कर सकता है)
* Caddy (जो certificate renewals भी handle कर सकता है)
* Nginx
* HAProxy
## Let's Encrypt { #lets-encrypt }
Let's Encrypt से पहले, ये **HTTPS certificates** trusted तीसरे पक्षों द्वारा बेचे जाते थे।
इनमें से किसी certificate को प्राप्त करने की प्रक्रिया कठिन होती थी, काफी paperwork की जरूरत होती थी और certificates काफी महंगे होते थे।
लेकिन फिर **[Let's Encrypt](https://letsencrypt.org/)** बनाया गया।
यह Linux Foundation का एक project है। यह automated तरीके से **मुफ्त में HTTPS certificates** प्रदान करता है। ये certificates सभी standard cryptographic security का उपयोग करते हैं, और short-lived होते हैं (लगभग 3 महीने), इसलिए उनकी कम lifespan के कारण **security वास्तव में बेहतर** होती है।
Domains को सुरक्षित रूप से verify किया जाता है और certificates automatically generate किए जाते हैं। इससे इन certificates के renewal को automate करना भी संभव होता है।
विचार यह है कि इन certificates की acquisition और renewal को automate किया जाए ताकि आपके पास **secure HTTPS, मुफ्त में, हमेशा के लिए** हो सके।
## Developers के लिए HTTPS { #https-for-developers }
यहाँ step by step एक उदाहरण है कि HTTPS API कैसी दिख सकती है, मुख्य रूप से developers के लिए महत्वपूर्ण विचारों पर ध्यान देते हुए।
### Domain Name { #domain-name }
सब कुछ शायद आपके द्वारा कोई **domain name** **प्राप्त** करने से शुरू होगा। फिर, आप इसे DNS server में configure करेंगे (संभवतः आपके उसी cloud provider में)।
आप शायद एक cloud server (एक virtual machine) या कुछ समान प्राप्त करेंगे, और उसके पास एक <dfn title="समय के साथ नहीं बदलता। dynamic नहीं।">स्थिर</dfn> **public IP address** होगा।
DNS server(s) में आप एक record (एक "`A record`") configure करेंगे ताकि **आपका domain** आपके server के public **IP address** की ओर point करे।
आप शायद यह सिर्फ एक बार करेंगे, पहली बार, जब सब कुछ setup कर रहे होंगे।
/// tip | सुझाव
यह Domain Name वाला हिस्सा HTTPS से बहुत पहले का है, लेकिन चूँकि सब कुछ domain और IP address पर निर्भर करता है, इसलिए इसे यहाँ mention करना उचित है।
///
### DNS { #dns }
अब आइए वास्तविक HTTPS parts पर focus करें।
सबसे पहले, browser **DNS servers** से check करेगा कि **domain के लिए IP** क्या है, इस मामले में, `someapp.example.com`
DNS servers browser को किसी विशिष्ट **IP address** का उपयोग करने के लिए कहेंगे। यह आपके server द्वारा उपयोग किया जाने वाला public IP address होगा, जिसे आपने DNS servers में configure किया है।
<img src="/img/deployment/https/https01.drawio.svg">
### TLS Handshake Start { #tls-handshake-start }
Browser फिर उस IP address से **port 443** (HTTPS port) पर communicate करेगा।
Communication का पहला हिस्सा केवल client और server के बीच connection establish करना और वे कौन-सी cryptographic keys उपयोग करेंगे आदि तय करना है।
<img src="/img/deployment/https/https02.drawio.svg">
TLS connection establish करने के लिए client और server के बीच इस interaction को **TLS handshake** कहा जाता है।
### SNI Extension के साथ TLS { #tls-with-sni-extension }
Server में **केवल एक process** किसी विशिष्ट **IP address** में किसी विशिष्ट **port** पर listen कर सकता है। उसी IP address में दूसरे ports पर अन्य processes listen कर सकते हैं, लेकिन IP address और port के हर combination के लिए केवल एक।
TLS (HTTPS) by default विशिष्ट port `443` का उपयोग करता है। इसलिए हमें इसी port की जरूरत होगी।
क्योंकि इस port पर केवल एक process listen कर सकता है, जो process यह करेगा वह **TLS Termination Proxy** होगा।
TLS Termination Proxy के पास एक या अधिक **TLS certificates** (HTTPS certificates) तक access होगा।
ऊपर चर्चा किए गए **SNI extension** का उपयोग करके, TLS Termination Proxy check करेगा कि इस connection के लिए उपलब्ध TLS (HTTPS) certificates में से किसका उपयोग करना चाहिए, client द्वारा expected domain से match करने वाले certificate का उपयोग करते हुए।
इस मामले में, यह `someapp.example.com` के लिए certificate का उपयोग करेगा।
<img src="/img/deployment/https/https03.drawio.svg">
Client पहले से ही उस entity पर **trust** करता है जिसने वह TLS certificate generate किया है (इस मामले में Let's Encrypt, लेकिन हम इसके बारे में बाद में देखेंगे), इसलिए यह **verify** कर सकता है कि certificate valid है।
फिर, certificate का उपयोग करके, client और TLS Termination Proxy **तय करते हैं कि बाकी TCP communication को कैसे encrypt करना है**। इससे **TLS Handshake** वाला हिस्सा पूरा होता है।
इसके बाद, client और server के पास एक **encrypted TCP connection** होता है, यही TLS प्रदान करता है। और फिर वे उस connection का उपयोग वास्तविक **HTTP communication** शुरू करने के लिए कर सकते हैं।
और **HTTPS** यही है, यह pure (unencrypted) TCP connection के बजाय एक **secure TLS connection** के अंदर साधारण **HTTP** ही है।
/// tip | सुझाव
ध्यान दें कि communication का encryption **TCP level** पर होता है, HTTP level पर नहीं।
///
### HTTPS Request { #https-request }
अब जबकि client और server (विशेष रूप से browser और TLS Termination Proxy) के पास एक **encrypted TCP connection** है, वे **HTTP communication** शुरू कर सकते हैं।
तो, client एक **HTTPS request** भेजता है। यह encrypted TLS connection के माध्यम से बस एक HTTP request है।
<img src="/img/deployment/https/https04.drawio.svg">
### Request को Decrypt करें { #decrypt-the-request }
TLS Termination Proxy सहमत किए गए encryption का उपयोग **request को decrypt** करने के लिए करेगा, और **साधारण (decrypted) HTTP request** को application चलाने वाले process तक transmit करेगा (उदाहरण के लिए FastAPI application चलाने वाले Uvicorn के साथ एक process)।
<img src="/img/deployment/https/https05.drawio.svg">
### HTTP Response { #http-response }
Application request को process करेगी और TLS Termination Proxy को एक **साधारण (unencrypted) HTTP response** भेजेगी।
<img src="/img/deployment/https/https06.drawio.svg">
### HTTPS Response { #https-response }
TLS Termination Proxy फिर पहले सहमत cryptography (जो `someapp.example.com` के लिए certificate से शुरू हुई थी) का उपयोग करके **response को encrypt** करेगा, और इसे browser को वापस भेजेगा।
इसके बाद, browser verify करेगा कि response valid है और सही cryptographic key आदि से encrypted है। फिर वह **response को decrypt** करेगा और process करेगा।
<img src="/img/deployment/https/https07.drawio.svg">
Client (browser) को पता होगा कि response सही server से आया है क्योंकि यह उस cryptography का उपयोग कर रहा है जिस पर उन्होंने पहले **HTTPS certificate** का उपयोग करके सहमति की थी।
### Multiple Applications { #multiple-applications }
उसी server (या servers) में, **multiple applications** हो सकती हैं, उदाहरण के लिए, अन्य API programs या database।
केवल एक process विशिष्ट IP और port handle कर सकता है (हमारे उदाहरण में TLS Termination Proxy) लेकिन अन्य applications/processes भी server(s) पर चल सकते हैं, जब तक वे **public IP और port के उसी combination** का उपयोग करने की कोशिश नहीं करते।
<img src="/img/deployment/https/https08.drawio.svg">
इस तरह, TLS Termination Proxy **multiple domains** के लिए, multiple applications के लिए HTTPS और certificates handle कर सकता है, और फिर हर मामले में requests को सही application तक transmit कर सकता है।
### Certificate Renewal { #certificate-renewal }
भविष्य में किसी समय, प्रत्येक certificate **expire** हो जाएगा (इसे प्राप्त करने के लगभग 3 महीने बाद)।
और फिर, कोई दूसरा program होगा (कुछ मामलों में यह दूसरा program होता है, कुछ मामलों में यह वही TLS Termination Proxy हो सकता है) जो Let's Encrypt से बात करेगा, और certificate(s) को renew करेगा।
<img src="/img/deployment/https/https.drawio.svg">
**TLS certificates** किसी **domain name** से **associated** होते हैं, IP address से नहीं।
इसलिए, certificates renew करने के लिए, renewal program को authority (Let's Encrypt) को **prove** करना होगा कि वह वास्तव में उस domain को **"own" और control** करता है।
ऐसा करने के लिए, और अलग-अलग application needs को accommodate करने के लिए, इसे करने के कई तरीके हैं। कुछ लोकप्रिय तरीके हैं:
* **कुछ DNS records modify करें**
* इसके लिए, renewal program को DNS provider की APIs support करनी होंगी, इसलिए, आप जिस DNS provider का उपयोग कर रहे हैं, उसके आधार पर यह option हो भी सकता है या नहीं भी।
* Domain से associated public IP address पर (कम से कम certificate acquisition process के दौरान) **server के रूप में चलें**
* जैसा कि हमने ऊपर कहा, केवल एक process किसी विशिष्ट IP और port पर listen कर सकता है।
* यह उन कारणों में से एक है कि जब वही TLS Termination Proxy certificate renewal process का भी ध्यान रखता है तो यह बहुत उपयोगी होता है।
* अन्यथा, आपको TLS Termination Proxy को momentarily stop करना पड़ सकता है, certificates प्राप्त करने के लिए renewal program start करना पड़ सकता है, फिर उन्हें TLS Termination Proxy के साथ configure करना पड़ सकता है, और फिर TLS Termination Proxy को restart करना पड़ सकता है। यह ideal नहीं है, क्योंकि जिस समय TLS Termination Proxy off होगा, उस दौरान आपकी app(s) available नहीं होंगी।
App को serve करते हुए भी यह पूरा renewal process, उन मुख्य कारणों में से एक है कि आप application server के साथ सीधे TLS certificates (जैसे Uvicorn) का उपयोग करने के बजाय TLS Termination Proxy के साथ **HTTPS handle करने के लिए एक अलग system** रखना चाहेंगे।
## Proxy Forwarded Headers { #proxy-forwarded-headers }
HTTPS handle करने के लिए proxy का उपयोग करते समय, आपका **application server** (उदाहरण के लिए FastAPI CLI के माध्यम से Uvicorn) HTTPS process के बारे में कुछ नहीं जानता, यह **TLS Termination Proxy** के साथ plain HTTP में communicate करता है।
यह **proxy** सामान्यतः request को **application server** तक transmit करने से पहले कुछ HTTP headers on the fly set करेगा, ताकि application server को पता चल सके कि request proxy द्वारा **forwarded** की जा रही है।
/// note | तकनीकी विवरण
Proxy headers हैं:
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
///
फिर भी, क्योंकि **application server** नहीं जानता कि वह trusted **proxy** के पीछे है, by default, वह उन headers पर trust नहीं करेगा।
लेकिन आप **application server** को **proxy** द्वारा भेजे गए *forwarded* headers पर trust करने के लिए configure कर सकते हैं। अगर आप FastAPI CLI का उपयोग कर रहे हैं, तो आप *CLI Option* `--forwarded-allow-ips` का उपयोग करके उसे बता सकते हैं कि उसे किन IPs से आने वाले उन *forwarded* headers पर trust करना चाहिए।
उदाहरण के लिए, अगर **application server** केवल trusted **proxy** से communication receive कर रहा है, तो आप इसे `--forwarded-allow-ips="*"` पर set कर सकते हैं ताकि यह सभी incoming IPs पर trust करे, क्योंकि यह केवल उसी IP से requests receive करेगा जिसका उपयोग **proxy** कर रहा है।
इस तरह application यह जान पाएगी कि उसका अपना public URL क्या है, क्या वह HTTPS का उपयोग कर रही है, domain, आदि।
यह उदाहरण के लिए redirects को ठीक से handle करने में उपयोगी होगा।
/// tip | सुझाव
आप इसके बारे में documentation में और सीख सकते हैं: [Proxy के पीछे - Proxy Forwarded Headers सक्षम करें](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers)
///
## Recap { #recap }
**HTTPS** होना बहुत महत्वपूर्ण है, और अधिकांश मामलों में काफी **critical** है। HTTPS के आसपास एक developer के रूप में आपको जो ज़्यादातर effort लगाना होता है, वह बस **इन concepts को समझने** और वे कैसे काम करते हैं, इसे समझने के बारे में है।
लेकिन एक बार जब आप **developers के लिए HTTPS** की मूल जानकारी जान लेते हैं, तो आप सब कुछ सरल तरीके से manage करने में मदद के लिए अलग-अलग tools को आसानी से combine और configure कर सकते हैं।
अगले कुछ chapters में, मैं आपको **FastAPI** applications के लिए **HTTPS** setup करने के कई ठोस उदाहरण दिखाऊँगा। 🔒

23
docs/hi/docs/deployment/index.md

@ -0,0 +1,23 @@
# Deployment { #deployment }
**FastAPI** application को deploy करना अपेक्षाकृत आसान है।
## Deployment का क्या अर्थ है { #what-does-deployment-mean }
किसी application को **deploy** करने का अर्थ है उसे **users के लिए उपलब्ध** कराने के लिए आवश्यक चरण पूरे करना।
किसी **web API** के लिए, इसमें सामान्यतः उसे एक **remote machine** में रखना शामिल होता है, एक **server program** के साथ जो अच्छा performance, stability आदि प्रदान करता है, ताकि आपके **users** application को कुशलता से और बिना रुकावटों या समस्याओं के **access** कर सकें।
यह **development** चरणों के विपरीत है, जहाँ आप लगातार code बदल रहे होते हैं, उसे तोड़ते और ठीक करते हैं, development server को रोकते और फिर से शुरू करते हैं, आदि।
## Deployment Strategies { #deployment-strategies }
इसे करने के कई तरीके हैं, जो आपके विशिष्ट use case और आपके द्वारा उपयोग किए जाने वाले tools पर निर्भर करते हैं।
आप tools के संयोजन का उपयोग करके स्वयं **server deploy** कर सकते हैं, आप कोई **cloud service** उपयोग कर सकते हैं जो आपके लिए काम का कुछ हिस्सा करती है, या अन्य संभावित विकल्प चुन सकते हैं।
उदाहरण के लिए, हमने, FastAPI के पीछे की team ने, [**FastAPI Cloud**](https://fastapicloud.com) बनाया, ताकि FastAPI apps को cloud पर deploy करना जितना संभव हो उतना streamlined हो, FastAPI के साथ काम करने के समान developer experience के साथ।
मैं आपको कुछ मुख्य concepts दिखाऊँगा जिन्हें **FastAPI** application deploy करते समय शायद ध्यान में रखना चाहिए (हालाँकि इनमें से अधिकतर किसी भी अन्य प्रकार की web application पर लागू होता है)।
अगले sections में आपको ध्यान में रखने के लिए अधिक details और इसे करने की कुछ techniques दिखेंगी। ✨

156
docs/hi/docs/deployment/manually.md

@ -0,0 +1,156 @@
# Server को मैन्युअली चलाएँ { #run-a-server-manually }
## `fastapi run` Command का उपयोग करें { #use-the-fastapi-run-command }
संक्षेप में, अपनी FastAPI application serve करने के लिए `fastapi run` का उपयोग करें:
<div class="termy">
```console
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
Searching for package file structure from directories
with <font color="#3465A4">__init__.py</font> files
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
the following code:
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
Logs:
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>2306215</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C
to quit<b>)</b>
```
</div>
यह ज़्यादातर मामलों में काम करेगा। 😎
आप उस command का उपयोग, उदाहरण के लिए, अपनी **FastAPI** app को किसी container में, किसी server में, आदि शुरू करने के लिए कर सकते हैं।
## ASGI Servers { #asgi-servers }
आइए details में थोड़ा और गहराई से देखें।
FastAPI Python web frameworks और servers बनाने के लिए एक standard का उपयोग करता है जिसे <abbr title="Asynchronous Server Gateway Interface - asynchronous server gateway interface">ASGI</abbr> कहा जाता है। FastAPI एक ASGI web framework है।
किसी remote server machine में **FastAPI** application (या कोई भी दूसरी ASGI application) चलाने के लिए आपको मुख्य रूप से एक ASGI server program चाहिए, जैसे **Uvicorn**; यही `fastapi` command में default रूप से आता है।
कई विकल्प हैं, जिनमें शामिल हैं:
* [Uvicorn](https://www.uvicorn.dev/): एक high performance ASGI server।
* [Hypercorn](https://hypercorn.readthedocs.io/): एक ASGI server जो अन्य features के साथ HTTP/2 और Trio के साथ compatible है।
* [Daphne](https://github.com/django/daphne): Django Channels के लिए बनाया गया ASGI server।
* [Granian](https://github.com/emmett-framework/granian): Python applications के लिए एक Rust HTTP server।
## Server Machine और Server Program { #server-machine-and-server-program }
नामों के बारे में ध्यान रखने योग्य एक छोटा-सा detail है। 💡
शब्द "**server**" आमतौर पर remote/cloud computer (physical या virtual machine) और उस machine पर चल रहे program (जैसे Uvicorn), दोनों के लिए उपयोग किया जाता है।
बस ध्यान रखें कि जब आप सामान्य रूप से "server" पढ़ते हैं, तो यह उन दो चीज़ों में से किसी एक को संदर्भित कर सकता है।
Remote machine का संदर्भ देते समय, इसे **server** कहना आम है, लेकिन **machine**, **VM** (virtual machine), **node** भी कहा जाता है। ये सभी किसी प्रकार की remote machine को संदर्भित करते हैं, जो सामान्यतः Linux चला रही होती है, जहाँ आप programs चलाते हैं।
## Server Program Install करें { #install-the-server-program }
जब आप FastAPI install करते हैं, तो यह एक production server, Uvicorn, के साथ आता है, और आप इसे `fastapi run` command से शुरू कर सकते हैं।
लेकिन आप एक ASGI server को मैन्युअली भी install कर सकते हैं।
सुनिश्चित करें कि आप एक [virtual environment](../virtual-environments.md) बनाएँ, उसे activate करें, और फिर आप server application install कर सकते हैं।
उदाहरण के लिए, Uvicorn install करने के लिए:
<div class="termy">
```console
$ pip install "uvicorn[standard]"
---> 100%
```
</div>
किसी भी अन्य ASGI server program के लिए भी इसी तरह की प्रक्रिया लागू होगी।
/// tip | टिप
`standard` जोड़ने पर, Uvicorn कुछ recommended extra dependencies install और use करेगा।
इसमें `uvloop` शामिल है, जो `asyncio` के लिए high-performance drop-in replacement है, और बड़ा concurrency performance boost देता है।
जब आप `pip install "fastapi[standard]"` जैसी किसी command से FastAPI install करते हैं, तो आपको `uvicorn[standard]` भी मिल जाता है।
///
## Server Program चलाएँ { #run-the-server-program }
यदि आपने ASGI server मैन्युअली install किया है, तो आमतौर पर आपको अपनी FastAPI application import कराने के लिए एक खास format में import string पास करनी होगी:
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 80
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
</div>
/// note | नोट
Command `uvicorn main:app` इनका संदर्भ देती है:
* `main`: file `main.py` (Python "module")।
* `app`: `main.py` के अंदर `app = FastAPI()` line से बनाया गया object।
यह इसके equivalent है:
```Python
from main import app
```
///
हर alternative ASGI server program की command मिलती-जुलती होगी, आप उनके संबंधित documentation में और पढ़ सकते हैं।
/// warning | चेतावनी
Uvicorn और अन्य servers एक `--reload` option support करते हैं जो development के दौरान उपयोगी होता है।
`--reload` option बहुत अधिक resources consume करता है, अधिक unstable होता है, आदि।
यह **development** के दौरान बहुत मदद करता है, लेकिन आपको इसे **production** में use **नहीं** करना चाहिए।
///
## Deployment Concepts { #deployment-concepts }
ये examples server program (जैसे Uvicorn) चलाते हैं, **एक single process** शुरू करते हैं, जो predefined port (जैसे `80`) पर सभी IPs (`0.0.0.0`) को listen करता है।
यह basic idea है। लेकिन आप शायद कुछ अतिरिक्त चीज़ों का ध्यान रखना चाहेंगे, जैसे:
* Security - HTTPS
* startup पर चलना
* Restarts
* Replication (चल रहे processes की संख्या)
* Memory
* शुरू करने से पहले के previous steps
अगले chapters में मैं आपको इन concepts में से हर एक के बारे में, उनके बारे में कैसे सोचें, और उन्हें handle करने की strategies के साथ कुछ concrete examples के बारे में और बताऊँगा। 🚀

139
docs/hi/docs/deployment/server-workers.md

@ -0,0 +1,139 @@
# Server Workers - Workers के साथ Uvicorn { #server-workers-uvicorn-with-workers }
आइए पहले वाले deployment concepts को फिर से देखें:
* Security - HTTPS
* startup पर चलना
* Restarts
* **Replication (चल रहे processes की संख्या)**
* Memory
* शुरू करने से पहले के पिछले steps
इस बिंदु तक, docs के सभी tutorials में, आपने शायद एक **server program** चलाया होगा, उदाहरण के लिए, `fastapi` command का उपयोग करके, जो Uvicorn चलाता है, और एक **single process** चलाता है।
Applications deploy करते समय आप शायद **processes की कुछ replication** रखना चाहेंगे ताकि **multiple cores** का लाभ लिया जा सके और अधिक requests handle की जा सकें।
जैसा कि आपने पिछले chapter में [Deployment Concepts](concepts.md) के बारे में देखा, कई strategies हैं जिनका आप उपयोग कर सकते हैं।
यहाँ मैं आपको दिखाऊँगा कि `fastapi` command या सीधे `uvicorn` command का उपयोग करके **worker processes** के साथ **Uvicorn** कैसे उपयोग करें।
/// note | नोट
यदि आप containers का उपयोग कर रहे हैं, उदाहरण के लिए Docker या Kubernetes के साथ, तो मैं आपको इसके बारे में अगले chapter में और बताऊँगा: [Containers में FastAPI - Docker](docker.md)।
विशेष रूप से, **Kubernetes** पर चलते समय आप शायद workers का उपयोग **नहीं** करना चाहेंगे और इसके बजाय **प्रति container एक single Uvicorn process** चलाना चाहेंगे, लेकिन मैं आपको इसके बारे में उस chapter में बाद में बताऊँगा।
///
## Multiple Workers { #multiple-workers }
आप `--workers` command line option के साथ multiple workers शुरू कर सकते हैं:
//// tab | `fastapi`
यदि आप `fastapi` command का उपयोग करते हैं:
<div class="termy">
```console
$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
Searching for package file structure from directories with
<font color="#3465A4">__init__.py</font> files
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the
following code:
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
Logs:
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to
quit<b>)</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
```
</div>
////
//// tab | `uvicorn`
यदि आप सीधे `uvicorn` command का उपयोग करना पसंद करते हैं:
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
<font color="#A6E22E">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit)
<font color="#A6E22E">INFO</font>: Started parent process [<font color="#A1EFE4"><b>27365</b></font>]
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27368</font>]
<font color="#A6E22E">INFO</font>: Waiting for application startup.
<font color="#A6E22E">INFO</font>: Application startup complete.
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27369</font>]
<font color="#A6E22E">INFO</font>: Waiting for application startup.
<font color="#A6E22E">INFO</font>: Application startup complete.
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27370</font>]
<font color="#A6E22E">INFO</font>: Waiting for application startup.
<font color="#A6E22E">INFO</font>: Application startup complete.
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27367</font>]
<font color="#A6E22E">INFO</font>: Waiting for application startup.
<font color="#A6E22E">INFO</font>: Application startup complete.
```
</div>
////
यहाँ एकमात्र नया option `--workers` है, जो Uvicorn को 4 worker processes शुरू करने के लिए कहता है।
आप यह भी देख सकते हैं कि यह प्रत्येक process का **PID** दिखाता है, parent process के लिए `27365` (यह **process manager** है) और प्रत्येक worker process के लिए एक: `27368`, `27369`, `27370`, और `27367`
## Deployment Concepts { #deployment-concepts }
यहाँ आपने देखा कि application के execution को **parallelize** करने, CPU में **multiple cores** का लाभ लेने, और **अधिक requests** serve करने में सक्षम होने के लिए multiple **workers** का उपयोग कैसे किया जाता है।
ऊपर दी गई deployment concepts की सूची से, workers का उपयोग मुख्य रूप से **replication** वाले हिस्से में मदद करेगा, और थोड़ा बहुत **restarts** में भी, लेकिन आपको अभी भी बाकी चीज़ों का ध्यान रखना होगा:
* **Security - HTTPS**
* **startup पर चलना**
* ***Restarts***
* Replication (चल रहे processes की संख्या)
* **Memory**
* **शुरू करने से पहले के पिछले steps**
## Containers और Docker { #containers-and-docker }
अगले chapter में [Containers में FastAPI - Docker](docker.md) के बारे में मैं कुछ strategies समझाऊँगा जिनका उपयोग आप बाकी **deployment concepts** को handle करने के लिए कर सकते हैं।
मैं आपको दिखाऊँगा कि single Uvicorn process चलाने के लिए **शुरू से अपनी खुद की image कैसे build करें**। यह एक सरल process है और शायद यही आप तब करना चाहेंगे जब आप **Kubernetes** जैसे distributed container management system का उपयोग कर रहे हों।
## Recap { #recap }
आप `fastapi` या `uvicorn` commands के साथ `--workers` CLI option का उपयोग करके multiple worker processes का उपयोग कर सकते हैं, ताकि **multi-core CPUs** का लाभ लिया जा सके और **multiple processes parallel में** चलाए जा सकें।
यदि आप बाकी deployment concepts का खुद ध्यान रखते हुए **अपना खुद का deployment system** setup कर रहे हैं, तो आप इन tools और ideas का उपयोग कर सकते हैं।
Containers (जैसे Docker और Kubernetes) के साथ **FastAPI** के बारे में जानने के लिए अगला chapter देखें। आप देखेंगे कि उन tools में बाकी **deployment concepts** को भी हल करने के सरल तरीके हैं। ✨

93
docs/hi/docs/deployment/versions.md

@ -0,0 +1,93 @@
# FastAPI संस्करणों के बारे में { #about-fastapi-versions }
**FastAPI** पहले से ही कई applications और प्रणालियों में production में उपयोग किया जा रहा है। और test coverage 100% पर रखा जाता है। लेकिन इसका development अभी भी तेजी से आगे बढ़ रहा है।
नई features अक्सर जोड़ी जाती हैं, bugs नियमित रूप से ठीक किए जाते हैं, और code अभी भी लगातार बेहतर हो रहा है।
इसीलिए वर्तमान संस्करण अभी भी `0.x.x` हैं, यह दर्शाता है कि हर संस्करण में संभावित रूप से breaking changes हो सकते हैं। यह [Semantic Versioning](https://semver.org/) conventions का पालन करता है।
आप अभी **FastAPI** के साथ production applications बना सकते हैं (और संभव है कि आप कुछ समय से ऐसा कर भी रहे हों), आपको बस यह सुनिश्चित करना होगा कि आप ऐसा संस्करण उपयोग करें जो आपके बाकी code के साथ सही ढंग से काम करता हो।
## अपने `fastapi` संस्करण को pin करें { #pin-your-fastapi-version }
सबसे पहले आपको **FastAPI** के जिस संस्करण का उपयोग आप कर रहे हैं उसे उस विशिष्ट नवीनतम संस्करण पर "pin" करना चाहिए जिसके बारे में आपको पता है कि वह आपके application के लिए सही ढंग से काम करता है।
उदाहरण के लिए, मान लें कि आप अपने app में संस्करण `0.112.0` उपयोग कर रहे हैं।
यदि आप `requirements.txt` file उपयोग करते हैं, तो आप संस्करण को इस तरह निर्दिष्ट कर सकते हैं:
```txt
fastapi[standard]==0.112.0
```
इसका मतलब होगा कि आप ठीक संस्करण `0.112.0` का उपयोग करेंगे।
या आप इसे इस तरह भी pin कर सकते हैं:
```txt
fastapi[standard]>=0.112.0,<0.113.0
```
इसका मतलब होगा कि आप संस्करण `0.112.0` या उससे ऊपर, लेकिन `0.113.0` से कम उपयोग करेंगे, उदाहरण के लिए, संस्करण `0.112.2` अभी भी स्वीकार किया जाएगा।
यदि आप अपनी installations प्रबंधित करने के लिए कोई अन्य tool उपयोग करते हैं, जैसे `uv`, Poetry, Pipenv, या अन्य, तो उन सभी में ऐसा तरीका होता है जिसका उपयोग करके आप अपने packages के लिए विशिष्ट संस्करण परिभाषित कर सकते हैं।
## उपलब्ध संस्करण { #available-versions }
आप उपलब्ध संस्करणों को (जैसे वर्तमान नवीनतम क्या है यह जांचने के लिए) [Release Notes](../release-notes.md) में देख सकते हैं।
## संस्करणों के बारे में { #about-versions }
Semantic Versioning conventions के अनुसार, `1.0.0` से नीचे का कोई भी संस्करण संभावित रूप से breaking changes जोड़ सकता है।
FastAPI इस convention का भी पालन करता है कि कोई भी "PATCH" संस्करण परिवर्तन bug fixes और non-breaking changes के लिए होता है।
/// tip | सुझाव
"PATCH" आखिरी संख्या होती है, उदाहरण के लिए, `0.2.3` में, PATCH संस्करण `3` है।
///
तो, आपको इस तरह के संस्करण पर pin करने में सक्षम होना चाहिए:
```txt
fastapi>=0.45.0,<0.46.0
```
Breaking changes और नई features "MINOR" संस्करणों में जोड़ी जाती हैं।
/// tip | सुझाव
"MINOR" बीच की संख्या होती है, उदाहरण के लिए, `0.2.3` में, MINOR संस्करण `2` है।
///
## FastAPI संस्करणों को upgrade करना { #upgrading-the-fastapi-versions }
आपको अपने app के लिए tests जोड़ने चाहिए।
**FastAPI** के साथ यह बहुत आसान है (Starlette के लिए धन्यवाद), docs देखें: [Testing](../tutorial/testing.md)
Tests होने के बाद, आप **FastAPI** संस्करण को अधिक हाल के संस्करण में upgrade कर सकते हैं, और अपने tests चलाकर सुनिश्चित कर सकते हैं कि आपका पूरा code सही ढंग से काम कर रहा है।
यदि सब कुछ काम कर रहा है, या आवश्यक बदलाव करने के बाद, और आपके सभी tests pass हो रहे हैं, तो आप अपने `fastapi` को उस नए हालिया संस्करण पर pin कर सकते हैं।
## Starlette के बारे में { #about-starlette }
आपको `starlette` के संस्करण को pin नहीं करना चाहिए।
**FastAPI** के अलग-अलग संस्करण Starlette के किसी विशिष्ट नए संस्करण का उपयोग करेंगे।
इसलिए, आप बस **FastAPI** को सही Starlette संस्करण उपयोग करने दे सकते हैं।
## Pydantic के बारे में { #about-pydantic }
Pydantic अपने tests में **FastAPI** के tests शामिल करता है, इसलिए Pydantic के नए संस्करण (`1.0.0` से ऊपर) हमेशा FastAPI के साथ compatible होते हैं।
आप Pydantic को `1.0.0` से ऊपर किसी भी ऐसे संस्करण पर pin कर सकते हैं जो आपके लिए काम करता हो।
उदाहरण के लिए:
```txt
pydantic>=2.7.0,<3.0.0
```

298
docs/hi/docs/environment-variables.md

@ -0,0 +1,298 @@
# Environment Variables { #environment-variables }
/// tip | टिप
अगर आप पहले से जानते हैं कि "environment variables" क्या होते हैं और उनका उपयोग कैसे करना है, तो आप इसे छोड़ सकते हैं।
///
एक environment variable (जिसे "**env var**" भी कहा जाता है) एक variable है जो Python code के **बाहर**, **ऑपरेटिंग सिस्टम** में रहता है, और जिसे आपका Python code (या दूसरे programs भी) पढ़ सकते हैं।
Environment variables application **settings** संभालने, Python की **installation** के हिस्से के रूप में, आदि में उपयोगी हो सकते हैं।
## Env Vars बनाएं और उपयोग करें { #create-and-use-env-vars }
आप Python की ज़रूरत के बिना, **shell (terminal)** में environment variables **बना** और उपयोग कर सकते हैं:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
// आप MY_NAME नाम का env var ऐसे बना सकते हैं
$ export MY_NAME="Wade Wilson"
// फिर आप इसे दूसरे programs के साथ उपयोग कर सकते हैं, जैसे
$ echo "Hello $MY_NAME"
Hello Wade Wilson
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
// MY_NAME नाम का env var बनाएं
$ $Env:MY_NAME = "Wade Wilson"
// इसे दूसरे programs के साथ उपयोग करें, जैसे
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
```
</div>
////
## Python में env vars पढ़ें { #read-env-vars-in-python }
आप Python के **बाहर**, terminal में (या किसी भी दूसरे तरीके से) environment variables बना सकते हैं, और फिर **उन्हें Python में पढ़** सकते हैं।
उदाहरण के लिए, आपके पास `main.py` नाम की file हो सकती है जिसमें:
```Python hl_lines="3"
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
/// tip | टिप
[`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) का दूसरा argument लौटाने के लिए default value है।
अगर यह दिया नहीं गया है, तो default रूप से यह `None` होता है, यहाँ हम उपयोग करने के लिए default value के रूप में `"World"` देते हैं।
///
फिर आप उस Python program को call कर सकते हैं:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
// यहाँ हमने अभी env var set नहीं किया है
$ python main.py
// क्योंकि हमने env var set नहीं किया, हमें default value मिलती है
Hello World from Python
// लेकिन अगर हम पहले एक environment variable बनाते हैं
$ export MY_NAME="Wade Wilson"
// और फिर program को फिर से call करते हैं
$ python main.py
// अब यह environment variable पढ़ सकता है
Hello Wade Wilson from Python
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
// यहाँ हमने अभी env var set नहीं किया है
$ python main.py
// क्योंकि हमने env var set नहीं किया, हमें default value मिलती है
Hello World from Python
// लेकिन अगर हम पहले एक environment variable बनाते हैं
$ $Env:MY_NAME = "Wade Wilson"
// और फिर program को फिर से call करते हैं
$ python main.py
// अब यह environment variable पढ़ सकता है
Hello Wade Wilson from Python
```
</div>
////
क्योंकि environment variables code के बाहर set किए जा सकते हैं, लेकिन code द्वारा पढ़े जा सकते हैं, और उन्हें बाकी files के साथ store (`git` में commit) करने की ज़रूरत नहीं होती, इसलिए configurations या **settings** के लिए उनका उपयोग करना आम है।
आप किसी **specific program invocation** के लिए भी एक environment variable बना सकते हैं, जो केवल उसी program के लिए उपलब्ध होता है, और केवल उसकी अवधि तक।
ऐसा करने के लिए, program से ठीक पहले, उसी line पर इसे बनाएं:
<div class="termy">
```console
// इस program call के लिए line में MY_NAME नाम का env var बनाएं
$ MY_NAME="Wade Wilson" python main.py
// अब यह environment variable पढ़ सकता है
Hello Wade Wilson from Python
// इसके बाद env var मौजूद नहीं रहता
$ python main.py
Hello World from Python
```
</div>
/// tip | टिप
आप इसके बारे में [The Twelve-Factor App: Config](https://12factor.net/config) पर और पढ़ सकते हैं।
///
## Types और Validation { #types-and-validation }
ये environment variables केवल **text strings** को ही संभाल सकते हैं, क्योंकि ये Python से बाहरी होते हैं और इन्हें दूसरे programs तथा बाकी system (और अलग-अलग ऑपरेटिंग सिस्टम, जैसे Linux, Windows, और macOS) के साथ compatible होना होता है।
इसका मतलब है कि Python में environment variable से पढ़ा गया **कोई भी value** **`str` होगा**, और किसी अलग type में कोई भी conversion या कोई भी validation code में करना होगा।
आप [Advanced User Guide - Settings and Environment Variables](./advanced/settings.md) में **application settings** संभालने के लिए environment variables के उपयोग के बारे में और सीखेंगे।
## `PATH` Environment Variable { #path-environment-variable }
**`PATH`** नाम का एक **special** environment variable होता है जिसका उपयोग ऑपरेटिंग सिस्टम (Linux, macOS, Windows) चलाने के लिए programs खोजने में करते हैं।
`PATH` variable का value एक लंबी string होती है जो Linux और macOS पर colon `:` से, और Windows पर semicolon `;` से अलग की गई directories से बनी होती है।
उदाहरण के लिए, `PATH` environment variable ऐसा दिख सकता है:
//// tab | Linux, macOS
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
इसका मतलब है कि system को इन directories में programs ढूंढने चाहिए:
* `/usr/local/bin`
* `/usr/bin`
* `/bin`
* `/usr/sbin`
* `/sbin`
////
//// tab | Windows
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
```
इसका मतलब है कि system को इन directories में programs ढूंढने चाहिए:
* `C:\Program Files\Python312\Scripts`
* `C:\Program Files\Python312`
* `C:\Windows\System32`
////
जब आप terminal में कोई **command** type करते हैं, तो ऑपरेटिंग सिस्टम `PATH` environment variable में listed **उनमें से प्रत्येक directory** में program को **ढूंढता है**
उदाहरण के लिए, जब आप terminal में `python` type करते हैं, तो ऑपरेटिंग सिस्टम उस list की **पहली directory** में `python` नाम का program ढूंढता है।
अगर उसे यह मिल जाता है, तो वह **इसे उपयोग** करेगा। नहीं तो वह **दूसरी directories** में ढूंढना जारी रखता है।
### Python install करना और `PATH` update करना { #installing-python-and-updating-the-path }
जब आप Python install करते हैं, तो आपसे पूछा जा सकता है कि क्या आप `PATH` environment variable को update करना चाहते हैं।
//// tab | Linux, macOS
मान लें कि आप Python install करते हैं और वह `/opt/custompython/bin` directory में जाता है।
अगर आप `PATH` environment variable को update करने के लिए yes कहते हैं, तो installer `/opt/custompython/bin` को `PATH` environment variable में जोड़ देगा।
यह ऐसा दिख सकता है:
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
```
इस तरह, जब आप terminal में `python` type करते हैं, तो system Python program को `/opt/custompython/bin` (आखिरी directory) में ढूंढेगा और उसी का उपयोग करेगा।
////
//// tab | Windows
मान लें कि आप Python install करते हैं और वह `C:\opt\custompython\bin` directory में जाता है।
अगर आप `PATH` environment variable को update करने के लिए yes कहते हैं, तो installer `C:\opt\custompython\bin` को `PATH` environment variable में जोड़ देगा।
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
```
इस तरह, जब आप terminal में `python` type करते हैं, तो system Python program को `C:\opt\custompython\bin` (आखिरी directory) में ढूंढेगा और उसी का उपयोग करेगा।
////
तो, अगर आप type करते हैं:
<div class="termy">
```console
$ python
```
</div>
//// tab | Linux, macOS
System `/opt/custompython/bin` में `python` program को **ढूंढेगा** और उसे चलाएगा।
यह लगभग ऐसा type करने के बराबर होगा:
<div class="termy">
```console
$ /opt/custompython/bin/python
```
</div>
////
//// tab | Windows
System `C:\opt\custompython\bin\python` में `python` program को **ढूंढेगा** और उसे चलाएगा।
यह लगभग ऐसा type करने के बराबर होगा:
<div class="termy">
```console
$ C:\opt\custompython\bin\python
```
</div>
////
यह जानकारी [Virtual Environments](virtual-environments.md) के बारे में सीखते समय उपयोगी होगी।
## निष्कर्ष { #conclusion }
इससे आपको यह basic समझ मिल जानी चाहिए कि **environment variables** क्या होते हैं और Python में उनका उपयोग कैसे करना है।
आप इनके बारे में [Wikipedia for Environment Variable](https://en.wikipedia.org/wiki/Environment_variable) में भी और पढ़ सकते हैं।
कई मामलों में तुरंत यह बहुत स्पष्ट नहीं होता कि environment variables कैसे उपयोगी और applicable होंगे। लेकिन जब आप developing कर रहे होते हैं, तो ये कई अलग-अलग scenarios में बार-बार सामने आते हैं, इसलिए इनके बारे में जानना अच्छा है।
उदाहरण के लिए, अगले section में, [Virtual Environments](virtual-environments.md) के बारे में, आपको इस जानकारी की ज़रूरत होगी।

87
docs/hi/docs/help-fastapi.md

@ -0,0 +1,87 @@
# मदद { #help }
क्या आप FastAPI की मदद करना चाहते हैं या FastAPI के बारे में मदद पाना चाहते हैं?
मदद करने और मदद पाने के बहुत सरल तरीके हैं।
## newsletter की सदस्यता लें { #subscribe-to-the-newsletter }
आप (कभी-कभार आने वाले) [**FastAPI and friends** newsletter](newsletter.md) की सदस्यता ले सकते हैं ताकि आप इन चीज़ों से अपडेट रहें:
* FastAPI और friends के बारे में खबरें 🚀
* गाइड्स 📝
* Features ✨
* Breaking changes 🚨
* टिप्स और ट्रिक्स ✅
## FastAPI को ऑनलाइन फ़ॉलो करें { #follow-fastapi-online }
आप **FastAPI** को कई जगहों पर ऑनलाइन फ़ॉलो कर सकते हैं:
* [**X / Twitter** पर @fastapi](https://x.com/fastapi)
* [**Bluesky** पर @fastapi.tiangolo.com](https://bsky.app/profile/fastapi.tiangolo.com)
* [**LinkedIn** पर FastAPI](https://www.linkedin.com/company/fastapi/)
## GitHub में **FastAPI** को Star करें { #star-fastapi-in-github }
आप GitHub में FastAPI को "star" कर सकते हैं (ऊपर दाईं ओर star बटन पर क्लिक करके): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). ⭐️
Star जोड़ने से, अन्य users इसे अधिक आसानी से ढूंढ पाएंगे और देख पाएंगे कि यह दूसरों के लिए पहले से उपयोगी रहा है।
## Releases के लिए GitHub repository को Watch करें { #watch-the-github-repository-for-releases }
आप GitHub में FastAPI को "watch" कर सकते हैं (ऊपर दाईं ओर "watch" बटन पर क्लिक करके): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). 👀
वहाँ आप "Releases only" चुन सकते हैं।
ऐसा करने पर, जब भी bug fixes और नए features के साथ **FastAPI** की कोई नई release (एक नया version) आएगी, आपको notifications (आपके email में) मिलेंगे।
## लेखक को फ़ॉलो करें { #follow-the-author }
आप [मुझे (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com), लेखक को कुछ जगहों पर फ़ॉलो कर सकते हैं, ताकि जब मेरे पास FastAPI और friends के बारे में साझा करने के लिए खबरें हों तो आपको पता चले:
* [**GitHub** पर @tiangolo](https://github.com/tiangolo).
* [**X (Twitter)** पर @tiangolo](https://x.com/tiangolo)
* [**Bluesky** पर @tiangolo.com](https://bsky.app/profile/tiangolo.com)
* [**LinkedIn** पर @tiangolo](https://www.linkedin.com/in/tiangolo/).
## GitHub में प्रश्नों के साथ दूसरों की मदद करें { #help-others-with-questions-in-github }
आप [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered) में दूसरों के प्रश्नों में मदद करने की कोशिश कर सकते हैं।
कई मामलों में आपको उन प्रश्नों का उत्तर पहले से पता हो सकता है। 🤓
यदि आप बहुत से लोगों के प्रश्नों में उनकी मदद कर रहे हैं, तो आप आधिकारिक [FastAPI Expert](fastapi-people.md#fastapi-experts) बन जाएंगे। 🎉
बस याद रखें, सबसे महत्वपूर्ण बात है: विनम्र रहने की कोशिश करें। 🤗
### मदद कैसे करें { #how-to-help }
यहाँ [मदद कैसे करें वाली गाइड](https://tiangolo.com/open-source/help/#help-others-with-questions-in-github) का पालन करें।
## प्रश्न पूछें { #ask-questions }
आप GitHub repository में [एक नया प्रश्न बना सकते हैं](https://github.com/fastapi/fastapi/discussions/new?category=questions), उदाहरण के लिए:
* कोई **प्रश्न** पूछें या किसी **समस्या** के बारे में पूछें।
* कोई नया **feature** सुझाएँ।
## Chat से जुड़ें { #join-the-chat }
👥 [Discord chat server](https://discord.gg/VQjSZaeJmf) 👥 से जुड़ें और FastAPI community में दूसरों के साथ बातचीत करें।
/// tip | सुझाव
प्रश्नों के लिए, उन्हें GitHub Discussions में पूछें, वहाँ आपको मदद मिलने की संभावना कहीं बेहतर है।
Chat का उपयोग केवल अन्य सामान्य बातचीत के लिए करें।
///
### प्रश्नों के लिए Chat का उपयोग न करें { #dont-use-the-chat-for-questions }
ध्यान रखें कि chats अधिक "मुक्त बातचीत" की अनुमति देते हैं, इसलिए बहुत सामान्य और उत्तर देने में अधिक कठिन प्रश्न पूछना आसान हो जाता है, इसलिए हो सकता है आपको उत्तर न मिलें।
GitHub में, template आपको सही प्रश्न लिखने में मार्गदर्शन करेगा ताकि आप अधिक आसानी से अच्छा उत्तर पा सकें, या पूछने से पहले ही समस्या को स्वयं भी हल कर सकें।
Chat systems में बातचीत GitHub जितनी आसानी से searchable भी नहीं होती, वे खो जाती हैं।

17
docs/hi/docs/how-to/authentication-error-status-code.md

@ -0,0 +1,17 @@
# पुराने 403 Authentication Error Status Codes का उपयोग करें { #use-old-403-authentication-error-status-codes }
FastAPI version `0.122.0` से पहले, जब integrated security utilities failed authentication के बाद client को error लौटाती थीं, तो वे HTTP status code `403 Forbidden` का उपयोग करती थीं।
FastAPI version `0.122.0` से शुरू होकर, वे अधिक उपयुक्त HTTP status code `401 Unauthorized` का उपयोग करती हैं, और HTTP specifications, [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1), [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized) का पालन करते हुए response में एक उचित `WWW-Authenticate` header लौटाती हैं।
लेकिन अगर किसी कारण से आपके clients पुराने behavior पर निर्भर हैं, तो आप अपनी security classes में method `make_not_authenticated_error` को override करके उस पर वापस जा सकते हैं।
उदाहरण के लिए, आप `HTTPBearer` का एक subclass बना सकते हैं जो default `401 Unauthorized` error के बजाय `403 Forbidden` error लौटाता है:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
/// tip | टिप
ध्यान दें कि function exception instance लौटाता है, उसे raise नहीं करता। raising बाकी internal code में किया जाता है।
///

56
docs/hi/docs/how-to/conditional-openapi.md

@ -0,0 +1,56 @@
# सशर्त OpenAPI { #conditional-openapi }
अगर आपको ज़रूरत हो, तो आप environment के आधार पर OpenAPI को सशर्त रूप से configure करने के लिए settings और environment variables का उपयोग कर सकते हैं, और इसे पूरी तरह disable भी कर सकते हैं।
## security, APIs, और docs के बारे में { #about-security-apis-and-docs }
production में अपनी documentation user interfaces को छिपाना आपकी API को सुरक्षित करने का तरीका *नहीं होना चाहिए*
इससे आपकी API में कोई अतिरिक्त security नहीं जुड़ती, *path operations* अभी भी वहीं उपलब्ध रहेंगी जहाँ वे हैं।
अगर आपके code में कोई security flaw है, तो वह अभी भी मौजूद रहेगा।
documentation को छिपाना बस यह समझना अधिक कठिन बना देता है कि आपकी API के साथ कैसे interact किया जाए, और production में इसे debug करना आपके लिए अधिक कठिन बना सकता है। इसे बस [Security through obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity) का एक रूप माना जा सकता है।
अगर आप अपनी API को secure करना चाहते हैं, तो कई बेहतर चीज़ें हैं जो आप कर सकते हैं, उदाहरण के लिए:
* सुनिश्चित करें कि आपके request bodies और responses के लिए अच्छी तरह defined Pydantic models हैं।
* dependencies का उपयोग करके कोई भी required permissions और roles configure करें।
* plaintext passwords कभी store न करें, केवल password hashes store करें।
* pwdlib और JWT tokens आदि जैसे जाने-माने cryptographic tools implement और use करें।
* जहाँ ज़रूरत हो, OAuth2 scopes के साथ अधिक granular permission controls जोड़ें।
* ...आदि।
फिर भी, आपके पास कोई बहुत विशिष्ट use case हो सकता है जहाँ आपको सच में किसी environment (जैसे production) के लिए या environment variables से मिली configurations के आधार पर API docs को disable करने की ज़रूरत हो।
## settings और env vars से सशर्त OpenAPI { #conditional-openapi-from-settings-and-env-vars }
आप अपनी generated OpenAPI और docs UIs को configure करने के लिए आसानी से वही Pydantic settings use कर सकते हैं।
उदाहरण के लिए:
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
यहाँ हम setting `openapi_url` को उसी default `"/openapi.json"` के साथ declare करते हैं।
और फिर `FastAPI` app बनाते समय हम इसका उपयोग करते हैं।
फिर आप environment variable `OPENAPI_URL` को empty string पर set करके OpenAPI (UI docs सहित) को disable कर सकते हैं, जैसे:
<div class="termy">
```console
$ OPENAPI_URL= uvicorn main:app
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
फिर अगर आप `/openapi.json`, `/docs`, या `/redoc` URLs पर जाते हैं, तो आपको बस इस तरह का `404 Not Found` error मिलेगा:
```JSON
{
"detail": "Not Found"
}
```

70
docs/hi/docs/how-to/configure-swagger-ui.md

@ -0,0 +1,70 @@
# Swagger UI configure करें { #configure-swagger-ui }
आप कुछ अतिरिक्त [Swagger UI parameters](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/) configure कर सकते हैं।
इन्हें configure करने के लिए, `FastAPI()` app object बनाते समय या `get_swagger_ui_html()` function में `swagger_ui_parameters` argument pass करें।
`swagger_ui_parameters` एक dictionary प्राप्त करता है जिसमें configurations सीधे Swagger UI को pass की जाती हैं।
FastAPI configurations को **JSON** में बदलता है ताकि वे JavaScript के साथ compatible हों, क्योंकि Swagger UI को यही चाहिए।
## Syntax Highlighting disable करें { #disable-syntax-highlighting }
उदाहरण के लिए, आप Swagger UI में syntax highlighting disable कर सकते हैं।
Settings बदले बिना, syntax highlighting default रूप से enabled रहती है:
<img src="/img/tutorial/extending-openapi/image02.png">
लेकिन आप `syntaxHighlight` को `False` पर set करके इसे disable कर सकते हैं:
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
...और फिर Swagger UI अब syntax highlighting नहीं दिखाएगा:
<img src="/img/tutorial/extending-openapi/image03.png">
## Theme बदलें { #change-the-theme }
इसी तरह आप key `"syntaxHighlight.theme"` के साथ syntax highlighting theme set कर सकते हैं (ध्यान दें कि इसके बीच में एक dot है):
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
वह configuration syntax highlighting color theme बदल देगी:
<img src="/img/tutorial/extending-openapi/image04.png">
## Default Swagger UI Parameters बदलें { #change-default-swagger-ui-parameters }
FastAPI में ज़्यादातर use cases के लिए उपयुक्त कुछ default configuration parameters शामिल हैं।
इसमें ये default configurations शामिल हैं:
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
आप `swagger_ui_parameters` argument में अलग value set करके इनमें से किसी को भी override कर सकते हैं।
उदाहरण के लिए, `deepLinking` disable करने के लिए आप ये settings `swagger_ui_parameters` में pass कर सकते हैं:
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
## अन्य Swagger UI Parameters { #other-swagger-ui-parameters }
आप जिन अन्य सभी संभावित configurations का उपयोग कर सकते हैं, उन्हें देखने के लिए आधिकारिक [Swagger UI parameters के docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/) पढ़ें।
## केवल JavaScript settings { #javascript-only-settings }
Swagger UI अन्य configurations को **केवल JavaScript** objects (उदाहरण के लिए, JavaScript functions) होने की भी अनुमति देता है।
FastAPI में ये केवल JavaScript `presets` settings भी शामिल हैं:
```JavaScript
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
]
```
ये **JavaScript** objects हैं, strings नहीं, इसलिए आप इन्हें सीधे Python code से pass नहीं कर सकते।
अगर आपको ऐसी केवल JavaScript configurations का उपयोग करना है, तो आप ऊपर दिए गए methods में से किसी एक का उपयोग कर सकते हैं। पूरी Swagger UI *path operation* को override करें और आपको जो भी JavaScript चाहिए उसे manually लिखें।

185
docs/hi/docs/how-to/custom-docs-ui-assets.md

@ -0,0 +1,185 @@
# कस्टम Docs UI Static Assets (Self-Hosting) { #custom-docs-ui-static-assets-self-hosting }
API docs **Swagger UI** और **ReDoc** का उपयोग करते हैं, और उनमें से प्रत्येक को कुछ JavaScript और CSS files की जरूरत होती है।
Default रूप से, वे files एक <abbr title="Content Delivery Network - सामग्री वितरण नेटवर्क: एक सेवा, जो सामान्यतः कई servers से बनी होती है, जो JavaScript और CSS जैसी static files प्रदान करती है। इसका सामान्य उपयोग उन files को client के करीब वाले server से serve करने के लिए किया जाता है, जिससे performance बेहतर होती है।">CDN</abbr> से serve की जाती हैं।
लेकिन इसे customize करना संभव है, आप कोई विशिष्ट CDN set कर सकते हैं, या files को स्वयं serve कर सकते हैं।
## JavaScript और CSS के लिए कस्टम CDN { #custom-cdn-for-javascript-and-css }
मान लें कि आप कोई अलग <abbr title="Content Delivery Network - सामग्री वितरण नेटवर्क">CDN</abbr> उपयोग करना चाहते हैं, उदाहरण के लिए आप `https://unpkg.com/` उपयोग करना चाहते हैं।
यह उपयोगी हो सकता है अगर, उदाहरण के लिए, आप ऐसे देश में रहते हैं जो कुछ URLs को restrict करता है।
### Automatic docs को disable करें { #disable-the-automatic-docs }
पहला step automatic docs को disable करना है, क्योंकि default रूप से, वे default CDN का उपयोग करते हैं।
उन्हें disable करने के लिए, अपना `FastAPI` app बनाते समय उनके URLs को `None` पर set करें:
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
### कस्टम docs शामिल करें { #include-the-custom-docs }
अब आप कस्टम docs के लिए *path operations* बना सकते हैं।
आप docs के लिए HTML pages बनाने हेतु FastAPI के internal functions को reuse कर सकते हैं, और उन्हें जरूरी arguments pass कर सकते हैं:
* `openapi_url`: वह URL जहां docs के लिए HTML page आपके API के लिए OpenAPI schema प्राप्त कर सकता है। आप यहां attribute `app.openapi_url` का उपयोग कर सकते हैं।
* `title`: आपके API का title।
* `oauth2_redirect_url`: default उपयोग करने के लिए आप यहां `app.swagger_ui_oauth2_redirect_url` का उपयोग कर सकते हैं।
* `swagger_js_url`: वह URL जहां आपके Swagger UI docs के लिए HTML **JavaScript** file प्राप्त कर सकता है। यह कस्टम CDN URL है।
* `swagger_css_url`: वह URL जहां आपके Swagger UI docs के लिए HTML **CSS** file प्राप्त कर सकता है। यह कस्टम CDN URL है।
और ReDoc के लिए भी इसी तरह...
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
/// tip | सुझाव
`swagger_ui_redirect` के लिए *path operation* तब एक helper है जब आप OAuth2 का उपयोग करते हैं।
यदि आप अपने API को किसी OAuth2 provider के साथ integrate करते हैं, तो आप authenticate कर पाएंगे और प्राप्त credentials के साथ API docs पर वापस आ पाएंगे। और वास्तविक OAuth2 authentication का उपयोग करके उससे interact कर पाएंगे।
Swagger UI आपके लिए इसे behind the scenes handle करेगा, लेकिन इसके लिए इस "redirect" helper की जरूरत होती है।
///
### इसे test करने के लिए एक *path operation* बनाएं { #create-a-path-operation-to-test-it }
अब, यह test करने के लिए कि सब कुछ काम करता है, एक *path operation* बनाएं:
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
### इसे test करें { #test-it }
अब, आप अपने docs पर [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) जा सकेंगे, और page reload करने पर, यह उन assets को नए CDN से load करेगा।
## Docs के लिए JavaScript और CSS की Self-hosting { #self-hosting-javascript-and-css-for-docs }
JavaScript और CSS की self-hosting उपयोगी हो सकती है अगर, उदाहरण के लिए, आपको चाहिए कि आपका app offline रहने पर भी, खुले Internet access के बिना, या local network में काम करता रहे।
यहां आप देखेंगे कि उन files को स्वयं, उसी FastAPI app में कैसे serve किया जाए, और docs को उनका उपयोग करने के लिए कैसे configure किया जाए।
### Project file structure { #project-file-structure }
मान लें आपके project की file structure ऐसी दिखती है:
```
.
├── app
│ ├── __init__.py
│ ├── main.py
```
अब उन static files को store करने के लिए एक directory बनाएं।
आपकी नई file structure ऐसी दिख सकती है:
```
.
├── app
│   ├── __init__.py
│   ├── main.py
└── static/
```
### Files download करें { #download-the-files }
Docs के लिए जरूरी static files download करें और उन्हें उस `static/` directory में रखें।
आप शायद प्रत्येक link पर right-click करके "Save link as..." जैसा कोई option select कर सकते हैं।
**Swagger UI** files का उपयोग करता है:
* [`swagger-ui-bundle.js`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js)
* [`swagger-ui.css`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css)
और **ReDoc** file का उपयोग करता है:
* [`redoc.standalone.js`](https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js)
उसके बाद, आपकी file structure ऐसी दिख सकती है:
```
.
├── app
│   ├── __init__.py
│   ├── main.py
└── static
├── redoc.standalone.js
├── swagger-ui-bundle.js
└── swagger-ui.css
```
### Static files serve करें { #serve-the-static-files }
* `StaticFiles` import करें।
* किसी विशिष्ट path में `StaticFiles()` instance को "Mount" करें।
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
### Static files को test करें { #test-the-static-files }
अपना application start करें और [http://127.0.0.1:8000/static/redoc.standalone.js](http://127.0.0.1:8000/static/redoc.standalone.js) पर जाएं।
आपको **ReDoc** के लिए एक बहुत लंबी JavaScript file दिखनी चाहिए।
यह कुछ इस तरह से शुरू हो सकती है:
```JavaScript
/*! For license information please see redoc.standalone.js.LICENSE.txt */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):
...
```
यह confirm करता है कि आप अपने app से static files serve कर पा रहे हैं, और आपने docs के लिए static files को सही जगह पर रखा है।
अब हम app को docs के लिए उन static files का उपयोग करने के लिए configure कर सकते हैं।
### Static files के लिए automatic docs को disable करें { #disable-the-automatic-docs-for-static-files }
कस्टम CDN का उपयोग करने जैसा ही, पहला step automatic docs को disable करना है, क्योंकि वे default रूप से CDN का उपयोग करते हैं।
उन्हें disable करने के लिए, अपना `FastAPI` app बनाते समय उनके URLs को `None` पर set करें:
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
### Static files के लिए कस्टम docs शामिल करें { #include-the-custom-docs-for-static-files }
और कस्टम CDN की तरह ही, अब आप कस्टम docs के लिए *path operations* बना सकते हैं।
फिर से, आप docs के लिए HTML pages बनाने हेतु FastAPI के internal functions को reuse कर सकते हैं, और उन्हें जरूरी arguments pass कर सकते हैं:
* `openapi_url`: वह URL जहां docs के लिए HTML page आपके API के लिए OpenAPI schema प्राप्त कर सकता है। आप यहां attribute `app.openapi_url` का उपयोग कर सकते हैं।
* `title`: आपके API का title।
* `oauth2_redirect_url`: default उपयोग करने के लिए आप यहां `app.swagger_ui_oauth2_redirect_url` का उपयोग कर सकते हैं।
* `swagger_js_url`: वह URL जहां आपके Swagger UI docs के लिए HTML **JavaScript** file प्राप्त कर सकता है। **यह वही है जिसे अब आपका अपना app serve कर रहा है**
* `swagger_css_url`: वह URL जहां आपके Swagger UI docs के लिए HTML **CSS** file प्राप्त कर सकता है। **यह वही है जिसे अब आपका अपना app serve कर रहा है**
और ReDoc के लिए भी इसी तरह...
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
/// tip | सुझाव
`swagger_ui_redirect` के लिए *path operation* तब एक helper है जब आप OAuth2 का उपयोग करते हैं।
यदि आप अपने API को किसी OAuth2 provider के साथ integrate करते हैं, तो आप authenticate कर पाएंगे और प्राप्त credentials के साथ API docs पर वापस आ पाएंगे। और वास्तविक OAuth2 authentication का उपयोग करके उससे interact कर पाएंगे।
Swagger UI आपके लिए इसे behind the scenes handle करेगा, लेकिन इसके लिए इस "redirect" helper की जरूरत होती है।
///
### Static files को test करने के लिए एक *path operation* बनाएं { #create-a-path-operation-to-test-static-files }
अब, यह test करने के लिए कि सब कुछ काम करता है, एक *path operation* बनाएं:
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
### Static Files UI को test करें { #test-static-files-ui }
अब, आप अपना WiFi disconnect कर सकेंगे, अपने docs पर [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) जा सकेंगे, और page reload कर सकेंगे।
और Internet के बिना भी, आप अपने API के docs देख पाएंगे और उससे interact कर पाएंगे।

109
docs/hi/docs/how-to/custom-request-and-route.md

@ -0,0 +1,109 @@
# Custom Request और APIRoute class { #custom-request-and-apiroute-class }
कुछ मामलों में, आप `Request` और `APIRoute` classes द्वारा उपयोग किए जाने वाले logic को override करना चाह सकते हैं।
विशेष रूप से, यह middleware में logic का एक अच्छा विकल्प हो सकता है।
उदाहरण के लिए, अगर आप request body को आपके application द्वारा process किए जाने से पहले पढ़ना या manipulate करना चाहते हैं।
/// danger | खतरा
यह एक "advanced" feature है।
अगर आप अभी-अभी **FastAPI** के साथ शुरुआत कर रहे हैं, तो शायद आप इस section को छोड़ना चाहेंगे।
///
## Use cases { #use-cases }
कुछ use cases में शामिल हैं:
* non-JSON request bodies को JSON में convert करना (जैसे [`msgpack`](https://msgpack.org/index.html)).
* gzip-compressed request bodies को decompress करना।
* सभी request bodies को automatically log करना।
## Custom request body encodings को संभालना { #handling-custom-request-body-encodings }
आइए देखें कि gzip requests को decompress करने के लिए custom `Request` subclass का उपयोग कैसे करें।
और उस custom request class का उपयोग करने के लिए एक `APIRoute` subclass।
### Custom `GzipRequest` class बनाएँ { #create-a-custom-gziprequest-class }
/// tip | सुझाव
यह दिखाने के लिए एक सरल उदाहरण है कि यह कैसे काम करता है, अगर आपको Gzip support चाहिए, तो आप दिए गए [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware) का उपयोग कर सकते हैं।
///
सबसे पहले, हम एक `GzipRequest` class बनाते हैं, जो उपयुक्त header की मौजूदगी में body को decompress करने के लिए `Request.body()` method को overwrite करेगी।
अगर header में `gzip` नहीं है, तो यह body को decompress करने की कोशिश नहीं करेगी।
इस तरह, वही route class gzip compressed या uncompressed requests को संभाल सकती है।
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
### Custom `GzipRoute` class बनाएँ { #create-a-custom-gziproute-class }
इसके बाद, हम `fastapi.routing.APIRoute` की एक custom subclass बनाते हैं जो `GzipRequest` का उपयोग करेगी।
इस बार, यह `APIRoute.get_route_handler()` method को overwrite करेगी।
यह method एक function return करता है। और वही function एक request प्राप्त करेगा और response return करेगा।
यहाँ हम इसका उपयोग original request से `GzipRequest` बनाने के लिए करते हैं।
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
/// note | तकनीकी विवरण
एक `Request` में `request.scope` attribute होता है, जो बस एक Python `dict` है जिसमें request से संबंधित metadata होता है।
एक `Request` में `request.receive` भी होता है, जो request की body को "receive" करने के लिए एक function है।
`scope` `dict` और `receive` function दोनों ASGI specification का हिस्सा हैं।
और ये दो चीजें, `scope` और `receive`, नई `Request` instance बनाने के लिए आवश्यक हैं।
`Request` के बारे में अधिक जानने के लिए [Requests के बारे में Starlette के docs](https://www.starlette.dev/requests/) देखें।
///
`GzipRequest.get_route_handler` द्वारा return किए गए function का केवल एक अलग काम है: `Request` को `GzipRequest` में convert करना।
ऐसा करने से, हमारा `GzipRequest` data को हमारे *path operations* तक पास करने से पहले decompress करने का ध्यान रखेगा (अगर आवश्यक हो)।
उसके बाद, processing logic सब वही रहता है।
लेकिन `GzipRequest.body` में हमारे बदलावों की वजह से, request body जरूरत पड़ने पर **FastAPI** द्वारा load किए जाने पर automatically decompress हो जाएगी।
## Exception handler में request body तक पहुँचना { #accessing-the-request-body-in-an-exception-handler }
/// tip | सुझाव
इसी समस्या को हल करने के लिए, `RequestValidationError` के custom handler में `body` का उपयोग करना शायद बहुत आसान है ([Errors संभालना](../tutorial/handling-errors.md#use-the-requestvalidationerror-body))।
लेकिन यह उदाहरण अभी भी valid है और यह दिखाता है कि internal components के साथ कैसे interact करें।
///
हम इसी approach का उपयोग exception handler में request body तक पहुँचने के लिए भी कर सकते हैं।
हमें बस request को `try`/`except` block के अंदर संभालना है:
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
अगर कोई exception होता है, तो `Request` instance अभी भी scope में होगी, इसलिए error संभालते समय हम request body को पढ़ सकते हैं और उसका उपयोग कर सकते हैं:
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
## Router में custom `APIRoute` class { #custom-apiroute-class-in-a-router }
आप `APIRouter` का `route_class` parameter भी set कर सकते हैं:
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
इस उदाहरण में, `router` के अंतर्गत *path operations* custom `TimedRoute` class का उपयोग करेंगे, और response में एक अतिरिक्त `X-Response-Time` header होगा जिसमें response generate करने में लगा समय होगा:
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}

88
docs/hi/docs/how-to/extending-openapi.md

@ -0,0 +1,88 @@
# OpenAPI को विस्तारित करना { #extending-openapi }
कुछ मामलों में आपको generated OpenAPI schema को संशोधित करने की ज़रूरत हो सकती है।
इस section में आप देखेंगे कि कैसे।
## सामान्य process { #the-normal-process }
सामान्य (default) process इस प्रकार है।
एक `FastAPI` application (instance) में एक `.openapi()` method होता है, जिससे OpenAPI schema return करने की अपेक्षा की जाती है।
application object बनाने के हिस्से के रूप में, `/openapi.json` के लिए (या आपने अपने `openapi_url` में जो भी set किया है उसके लिए) एक *path operation* registered होता है।
यह बस application के `.openapi()` method के result के साथ एक JSON response return करता है।
Default रूप से, method `.openapi()` जो करता है वह यह है कि property `.openapi_schema` को check करता है कि उसमें contents हैं या नहीं, और उन्हें return करता है।
अगर नहीं हैं, तो यह उन्हें `fastapi.openapi.utils.get_openapi` में utility function का उपयोग करके generate करता है।
और वह function `get_openapi()` parameters के रूप में ये प्राप्त करता है:
* `title`: OpenAPI title, जो docs में दिखाया जाता है।
* `version`: आपके API का version, जैसे `2.5.0`
* `openapi_version`: उपयोग की गई OpenAPI specification का version। Default रूप से, latest: `3.1.0`
* `summary`: API का एक छोटा summary।
* `description`: आपके API का description, इसमें markdown शामिल हो सकता है और यह docs में दिखाया जाएगा।
* `routes`: application से routes, जो `app.routes` से लिए जाते हैं। FastAPI इन्हें registered *path operations* collect करने के लिए उपयोग करता है, जिनमें included routers से आने वाले भी शामिल हैं।
/// tip | तकनीकी विवरण
`app.routes` एक lower-level route tree है। इसमें route candidates शामिल हो सकते हैं जिन्हें FastAPI internally included routers के लिए उपयोग करता है, केवल final `APIRoute` objects ही नहीं।
आप फिर भी `app.routes` को `get_openapi()` में pass कर सकते हैं। FastAPI effective path operations collect करने के लिए उस route tree को traverse करेगा।
///
/// note | नोट
parameter `summary` OpenAPI 3.1.0 और उससे ऊपर में उपलब्ध है, जिसे FastAPI 0.99.0 और उससे ऊपर support करता है।
///
## Defaults को override करना { #overriding-the-defaults }
ऊपर दी गई जानकारी का उपयोग करके, आप OpenAPI schema generate करने और अपनी ज़रूरत के अनुसार प्रत्येक हिस्से को override करने के लिए उसी utility function का उपयोग कर सकते हैं।
उदाहरण के लिए, आइए [custom logo शामिल करने के लिए ReDoc का OpenAPI extension](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo) जोड़ें।
### सामान्य **FastAPI** { #normal-fastapi }
सबसे पहले, अपनी पूरी **FastAPI** application सामान्य रूप से लिखें:
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
### OpenAPI schema generate करें { #generate-the-openapi-schema }
फिर, `custom_openapi()` function के अंदर, OpenAPI schema generate करने के लिए उसी utility function का उपयोग करें:
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
### OpenAPI schema को संशोधित करें { #modify-the-openapi-schema }
अब आप OpenAPI schema में `info` "object" में custom `x-logo` जोड़कर ReDoc extension जोड़ सकते हैं:
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
### OpenAPI schema को cache करें { #cache-the-openapi-schema }
आप अपनी generated schema store करने के लिए property `.openapi_schema` को "cache" के रूप में उपयोग कर सकते हैं।
इस तरह, जब भी कोई user आपके API docs खोलेगा, आपकी application को हर बार schema generate नहीं करना पड़ेगा।
यह केवल एक बार generate होगा, और फिर अगली requests के लिए वही cached schema उपयोग किया जाएगा।
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
### Method को override करें { #override-the-method }
अब आप `.openapi()` method को अपने नए function से replace कर सकते हैं।
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
### इसे check करें { #check-it }
जब आप [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) पर जाएंगे, तो आप देखेंगे कि आप अपना custom logo उपयोग कर रहे हैं (इस उदाहरण में, **FastAPI** का logo):
<img src="/img/tutorial/extending-openapi/image01.png">

43
docs/hi/docs/how-to/general.md

@ -0,0 +1,43 @@
# सामान्य - How To - Recipes { #general-how-to-recipes }
सामान्य या अक्सर पूछे जाने वाले प्रश्नों के लिए, docs में अन्य जगहों के कई pointers यहाँ दिए गए हैं।
## Data फ़िल्टर करें - सुरक्षा { #filter-data-security }
यह सुनिश्चित करने के लिए कि आप जितना data लौटाना चाहिए उससे अधिक न लौटाएँ, [Tutorial - Response Model - Return Type](../tutorial/response-model.md) के docs पढ़ें।
## Response Performance को optimize करें - Response Model - Return Type { #optimize-response-performance-response-model-return-type }
JSON data लौटाते समय performance को optimize करने के लिए, return type या response model का उपयोग करें, इस तरह Pydantic JSON में serialization को Rust side पर संभालेगा, Python से गुज़रे बिना। अधिक पढ़ें [Tutorial - Response Model - Return Type](../tutorial/response-model.md) के docs में।
## Documentation Tags - OpenAPI { #documentation-tags-openapi }
अपने *path operations* में tags जोड़ने और उन्हें docs UI में group करने के लिए, [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags) के docs पढ़ें।
## Documentation Summary और Description - OpenAPI { #documentation-summary-and-description-openapi }
अपने *path operations* में summary और description जोड़ने, और उन्हें docs UI में दिखाने के लिए, [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description) के docs पढ़ें।
## Documentation Response description - OpenAPI { #documentation-response-description-openapi }
response का description define करने के लिए, जो docs UI में दिखाया जाता है, [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description) के docs पढ़ें।
## Documentation में *Path Operation* को Deprecate करें - OpenAPI { #documentation-deprecate-a-path-operation-openapi }
किसी *path operation* को deprecate करने और उसे docs UI में दिखाने के लिए, [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation) के docs पढ़ें।
## किसी भी Data को JSON-compatible में convert करें { #convert-any-data-to-json-compatible }
किसी भी data को JSON-compatible में convert करने के लिए, [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md) के docs पढ़ें।
## OpenAPI Metadata - Docs { #openapi-metadata-docs }
अपने OpenAPI schema में metadata जोड़ने के लिए, जिसमें license, version, contact, आदि शामिल हैं, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md) के docs पढ़ें।
## OpenAPI Custom URL { #openapi-custom-url }
OpenAPI URL को customize करने (या हटाने) के लिए, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url) के docs पढ़ें।
## OpenAPI Docs URLs { #openapi-docs-urls }
अपने-आप generate किए गए docs user interfaces के लिए उपयोग किए जाने वाले URLs को update करने के लिए, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls) के docs पढ़ें।

60
docs/hi/docs/how-to/graphql.md

@ -0,0 +1,60 @@
# GraphQL { #graphql }
क्योंकि **FastAPI** **ASGI** standard पर आधारित है, इसलिए ASGI के साथ compatible किसी भी **GraphQL** library को integrate करना बहुत आसान है।
आप उसी application में सामान्य FastAPI *path operations* को GraphQL के साथ combine कर सकते हैं।
/// tip | सुझाव
**GraphQL** कुछ बहुत specific use cases को solve करता है।
Common **web APIs** की तुलना में इसके **advantages** और **disadvantages** हैं।
सुनिश्चित करें कि आप evaluate करें कि आपके use case के लिए **benefits**, **drawbacks** की भरपाई करते हैं या नहीं। 🤓
///
## GraphQL Libraries { #graphql-libraries }
यहाँ कुछ **GraphQL** libraries हैं जिनमें **ASGI** support है। आप उन्हें **FastAPI** के साथ उपयोग कर सकते हैं:
* [Strawberry](https://strawberry.rocks/) 🍓
* [FastAPI के लिए docs](https://strawberry.rocks/docs/integrations/fastapi) के साथ
* [Ariadne](https://ariadnegraphql.org/)
* [FastAPI के लिए docs](https://ariadnegraphql.org/docs/fastapi-integration) के साथ
* [Tartiflette](https://tartiflette.io/)
* ASGI integration प्रदान करने के लिए [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) के साथ
* [Graphene](https://graphene-python.org/)
* [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3) के साथ
## Strawberry के साथ GraphQL { #graphql-with-strawberry }
यदि आपको **GraphQL** के साथ काम करने की ज़रूरत है या आप करना चाहते हैं, तो [**Strawberry**](https://strawberry.rocks/) **recommended** library है क्योंकि इसका design **FastAPI** के design के सबसे करीब है, यह पूरी तरह **type annotations** पर आधारित है।
आपके use case के आधार पर, आप कोई अलग library उपयोग करना पसंद कर सकते हैं, लेकिन अगर आप मुझसे पूछें, तो मैं शायद सुझाव दूँगा कि आप **Strawberry** आज़माएँ।
यहाँ एक छोटा preview है कि आप Strawberry को FastAPI के साथ कैसे integrate कर सकते हैं:
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
आप [Strawberry documentation](https://strawberry.rocks/) में Strawberry के बारे में और जान सकते हैं।
और [FastAPI के साथ Strawberry](https://strawberry.rocks/docs/integrations/fastapi) के बारे में docs भी।
## Starlette से पुराना `GraphQLApp` { #older-graphqlapp-from-starlette }
Starlette के पिछले versions में [Graphene](https://graphene-python.org/) के साथ integrate करने के लिए एक `GraphQLApp` class शामिल थी।
इसे Starlette से deprecated कर दिया गया था, लेकिन यदि आपके पास ऐसा code है जो इसका उपयोग करता था, तो आप आसानी से [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3) पर **migrate** कर सकते हैं, जो वही use case cover करता है और जिसका **लगभग identical interface** है।
/// tip | सुझाव
यदि आपको GraphQL की ज़रूरत है, तो मैं फिर भी recommend करूँगा कि आप [Strawberry](https://strawberry.rocks/) देखें, क्योंकि यह custom classes और types की बजाय type annotations पर आधारित है।
///
## और जानें { #learn-more }
आप [official GraphQL documentation](https://graphql.org/) में **GraphQL** के बारे में और जान सकते हैं।
आप ऊपर वर्णित उन libraries में से प्रत्येक के बारे में उनके links में और भी पढ़ सकते हैं।

13
docs/hi/docs/how-to/index.md

@ -0,0 +1,13 @@
# कैसे करें - रेसिपी { #how-to-recipes }
यहाँ आप **कई topics** के लिए अलग-अलग recipes या "how to" guides देखेंगे।
इनमें से ज़्यादातर ideas कमोबेश **स्वतंत्र** होंगे, और ज़्यादातर मामलों में आपको इन्हें केवल तभी पढ़ने की ज़रूरत होगी जब वे सीधे **आपके project** पर लागू होते हों।
अगर कुछ आपके project के लिए रोचक और उपयोगी लगता है, तो आगे बढ़कर उसे देखें, लेकिन नहीं तो आप शायद उन्हें छोड़ सकते हैं।
/// tip | सुझाव
अगर आप **FastAPI सीखना** structured तरीके से चाहते हैं (recommended), तो इसके बजाय [ट्यूटोरियल - यूज़र गाइड](../tutorial/index.md) को अध्याय-दर-अध्याय पढ़ें।
///

153
docs/hi/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md

@ -0,0 +1,153 @@
# Pydantic v1 से Pydantic v2 में माइग्रेट करें { #migrate-from-pydantic-v1-to-pydantic-v2 }
अगर आपके पास कोई पुराना FastAPI app है, तो हो सकता है कि आप Pydantic version 1 का उपयोग कर रहे हों।
FastAPI version 0.100.0 में Pydantic v1 या v2, दोनों में से किसी के लिए support था। यह वही उपयोग करता था जो आपने install किया हुआ था।
FastAPI version 0.119.0 ने Pydantic v2 के अंदर से Pydantic v1 के लिए आंशिक support पेश किया (`pydantic.v1` के रूप में), ताकि v2 में migration आसान हो सके।
FastAPI 0.126.0 ने Pydantic v1 के लिए support हटा दिया, लेकिन थोड़े समय के लिए `pydantic.v1` को support करना जारी रखा।
FastAPI 0.128.0 ने `pydantic.v1` के लिए support भी हटा दिया, इसलिए FastAPI के नवीनतम versions के लिए Pydantic v2 required है।
/// warning | चेतावनी
Pydantic team ने **Python 3.14** से शुरू करते हुए, Python के नवीनतम versions के लिए Pydantic v1 का support बंद कर दिया।
इसमें `pydantic.v1` भी शामिल है, जो अब Python 3.14 और उससे ऊपर में supported नहीं है।
अगर आप Python की नवीनतम features का उपयोग करना चाहते हैं, तो आपको यह सुनिश्चित करना होगा कि आप Pydantic v2 का उपयोग करें।
///
अगर आपके पास Pydantic v1 वाला कोई पुराना FastAPI app है, तो यहाँ मैं आपको दिखाऊँगा कि उसे Pydantic v2 में कैसे migrate करें, और gradual migration में मदद के लिए **FastAPI 0.119.0 की features** भी दिखाऊँगा।
## आधिकारिक गाइड { #official-guide }
Pydantic के पास v1 से v2 के लिए एक आधिकारिक [Migration Guide](https://docs.pydantic.dev/latest/migration/) है।
इसमें यह भी शामिल है कि क्या बदला है, validations अब कैसे अधिक सही और strict हैं, संभावित caveats आदि।
क्या बदला है इसे बेहतर समझने के लिए आप इसे पढ़ सकते हैं।
## Tests { #tests }
सुनिश्चित करें कि आपके app के लिए [tests](../tutorial/testing.md) हैं और आप उन्हें continuous integration (CI) पर चलाते हैं।
इस तरह, आप upgrade कर सकते हैं और सुनिश्चित कर सकते हैं कि सब कुछ अभी भी अपेक्षा के अनुसार काम कर रहा है।
## `bump-pydantic` { #bump-pydantic }
कई मामलों में, जब आप customizations के बिना regular Pydantic models का उपयोग करते हैं, तो आप Pydantic v1 से Pydantic v2 में migration की अधिकांश प्रक्रिया automate कर पाएँगे।
आप उसी Pydantic team का [`bump-pydantic`](https://github.com/pydantic/bump-pydantic) उपयोग कर सकते हैं।
यह tool आपको उस अधिकांश code को अपने आप बदलने में मदद करेगा जिसे बदलने की ज़रूरत है।
इसके बाद, आप tests चला सकते हैं और जाँच सकते हैं कि सब कुछ काम करता है या नहीं। अगर करता है, तो आपका काम हो गया। 😎
## v2 में Pydantic v1 { #pydantic-v1-in-v2 }
Pydantic v2 में Pydantic v1 की सभी चीज़ें `pydantic.v1` submodule के रूप में शामिल हैं। लेकिन यह Python 3.13 से ऊपर के versions में अब supported नहीं है।
इसका मतलब है कि आप Pydantic v2 का नवीनतम version install कर सकते हैं और इस submodule से पुराने Pydantic v1 components को import और उपयोग कर सकते हैं, जैसे कि आपके पास पुराना Pydantic v1 install हो।
{* ../../docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py hl[1,4] *}
### v2 में Pydantic v1 के लिए FastAPI support { #fastapi-support-for-pydantic-v1-in-v2 }
/// warning | चेतावनी
`pydantic.v1` models के लिए यह FastAPI support **FastAPI 0.119.0** में जोड़ा गया था और **FastAPI 0.128.0** में हटा दिया गया। इसका उद्देश्य Pydantic v2 में migration के लिए अस्थायी सहायता होना था।
FastAPI के वर्तमान versions में, अपने app में `pydantic.v1` model का उपयोग करने पर error आएगा।
इस section का बाकी हिस्सा केवल उन पुराने versions में उपलब्ध अस्थायी support का वर्णन करता है।
///
FastAPI 0.119.0 से, Pydantic v2 के अंदर से Pydantic v1 के लिए आंशिक support भी है, ताकि v2 में migration आसान हो सके।
इसलिए, आप Pydantic को नवीनतम version 2 में upgrade कर सकते थे, और imports को `pydantic.v1` submodule का उपयोग करने के लिए बदल सकते थे, और कई मामलों में यह बस काम कर जाता।
{* ../../docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py hl[2,5,15] *}
/// warning | चेतावनी
ध्यान रखें कि Pydantic team अब Python के हाल के versions में Pydantic v1 को support नहीं करती, Python 3.14 से शुरू करते हुए, इसलिए `pydantic.v1` का उपयोग भी Python 3.14 और उससे ऊपर में supported नहीं है।
///
### एक ही app में Pydantic v1 और v2 { #pydantic-v1-and-v2-on-the-same-app }
Pydantic द्वारा यह **supported नहीं है** कि Pydantic v2 का कोई model हो जिसके अपने fields Pydantic v1 models के रूप में defined हों, या इसका उल्टा।
```mermaid
graph TB
subgraph "❌ Not Supported"
direction TB
subgraph V2["Pydantic v2 Model"]
V1Field["Pydantic v1 Model"]
end
subgraph V1["Pydantic v1 Model"]
V2Field["Pydantic v2 Model"]
end
end
style V2 fill:#f9fff3
style V1 fill:#fff6f0
style V1Field fill:#fff6f0
style V2Field fill:#f9fff3
```
...लेकिन आपके पास एक ही app में अलग-अलग models हो सकते हैं, कुछ Pydantic v1 का उपयोग करते हुए और कुछ Pydantic v2 का उपयोग करते हुए।
```mermaid
graph TB
subgraph "✅ Supported"
direction TB
subgraph V2["Pydantic v2 Model"]
V2Field["Pydantic v2 Model"]
end
subgraph V1["Pydantic v1 Model"]
V1Field["Pydantic v1 Model"]
end
end
style V2 fill:#f9fff3
style V1 fill:#fff6f0
style V1Field fill:#fff6f0
style V2Field fill:#f9fff3
```
कुछ मामलों में, आपके FastAPI app में एक ही **path operation** में Pydantic v1 और v2 दोनों models होना भी संभव है:
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
ऊपर दिए गए इस उदाहरण में, input model एक Pydantic v1 model है, और output model (`response_model=ItemV2` में defined) एक Pydantic v2 model है।
### Pydantic v1 parameters { #pydantic-v1-parameters }
अगर आपको Pydantic v1 models के साथ parameters के लिए FastAPI-specific tools जैसे `Body`, `Query`, `Form` आदि का उपयोग करना है, तो Pydantic v2 में migration पूरा करते समय आप उन्हें `fastapi.temp_pydantic_v1_params` से import कर सकते हैं:
{* ../../docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py hl[4,18] *}
### चरणों में माइग्रेट करें { #migrate-in-steps }
/// warning | चेतावनी
नीचे वर्णित, एक ही app में Pydantic v1 और v2 दोनों models का उपयोग करके gradual migration केवल **FastAPI 0.119.0 से 0.127.x** में काम करता है। इसे **FastAPI 0.128.0** में हटा दिया गया, नवीनतम versions के लिए **Pydantic v2** models required हैं।
///
/// tip | सुझाव
पहले `bump-pydantic` के साथ कोशिश करें, अगर आपके tests pass हो जाते हैं और वह काम करता है, तो आपका काम एक command में हो गया। ✨
///
अगर `bump-pydantic` आपके use case के लिए काम नहीं करता, तो आप Pydantic v2 में gradual migration करने के लिए एक ही app में Pydantic v1 और v2 दोनों models के support का उपयोग कर सकते हैं।
आप पहले Pydantic को नवीनतम version 2 का उपयोग करने के लिए upgrade कर सकते हैं, और अपने सभी models के लिए `pydantic.v1` का उपयोग करने के लिए imports बदल सकते हैं।
फिर, आप gradual steps में, groups के रूप में अपने models को Pydantic v1 से v2 में migrate करना शुरू कर सकते हैं। 🚶

102
docs/hi/docs/how-to/separate-openapi-schemas.md

@ -0,0 +1,102 @@
# Input और Output के लिए अलग OpenAPI Schemas या नहीं { #separate-openapi-schemas-for-input-and-output-or-not }
जबसे **Pydantic v2** रिलीज़ हुआ है, generated OpenAPI पहले की तुलना में थोड़ा अधिक सटीक और **सही** है। 😎
वास्तव में, कुछ मामलों में, एक ही Pydantic model के लिए OpenAPI में **दो JSON Schemas** भी होंगे, input और output के लिए, इस पर निर्भर करते हुए कि उनमें **default values** हैं या नहीं।
आइए देखते हैं कि यह कैसे काम करता है और अगर आपको ज़रूरत हो तो इसे कैसे बदलना है।
## Input और Output के लिए Pydantic Models { #pydantic-models-for-input-and-output }
मान लीजिए आपके पास default values वाला एक Pydantic model है, जैसे यह:
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *}
### Input के लिए Model { #model-for-input }
अगर आप इस model को यहाँ की तरह input के रूप में उपयोग करते हैं:
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *}
...तो `description` field **required नहीं होगा**। क्योंकि इसका default value `None` है।
### Docs में Input Model { #input-model-in-docs }
आप docs में इसकी पुष्टि कर सकते हैं, `description` field के पास **लाल asterisk** नहीं है, इसे required के रूप में mark नहीं किया गया है:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image01.png">
</div>
### Output के लिए Model { #model-for-output }
लेकिन अगर आप उसी model को output के रूप में उपयोग करते हैं, जैसे यहाँ:
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
...तो क्योंकि `description` का default value है, अगर आप उस field के लिए **कुछ भी return नहीं करते**, तब भी इसका वही **default value** रहेगा।
### Output Response Data के लिए Model { #model-for-output-response-data }
अगर आप docs के साथ interact करते हैं और response जाँचते हैं, तो भले ही code ने `description` fields में से किसी एक में कुछ भी add नहीं किया, JSON response में default value (`null`) शामिल होता है:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image02.png">
</div>
इसका मतलब है कि इसमें **हमेशा एक value होगा**, बस कभी-कभी value `None` हो सकता है (या JSON में `null`)।
इसका मतलब है कि आपकी API का उपयोग करने वाले clients को यह जाँचने की ज़रूरत नहीं है कि value मौजूद है या नहीं, वे **मान सकते हैं कि field हमेशा मौजूद रहेगा**, बस कुछ मामलों में इसका default value `None` होगा।
OpenAPI में इसे describe करने का तरीका है कि उस field को **required** के रूप में mark किया जाए, क्योंकि वह हमेशा मौजूद रहेगा।
इस वजह से, किसी model के लिए JSON Schema अलग हो सकता है, यह इस पर निर्भर करता है कि उसे **input या output** के लिए उपयोग किया गया है:
* **input** के लिए `description` **required नहीं होगा**
* **output** के लिए यह **required** होगा (और संभवतः `None`, या JSON terms में, `null`)
### Docs में Output के लिए Model { #model-for-output-in-docs }
आप docs में output model भी देख सकते हैं, **दोनों** `name` और `description` को **लाल asterisk** के साथ **required** के रूप में mark किया गया है:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image03.png">
</div>
### Docs में Input और Output के लिए Model { #model-for-input-and-output-in-docs }
और अगर आप OpenAPI में उपलब्ध सभी Schemas (JSON Schemas) जाँचते हैं, तो आप देखेंगे कि दो हैं, एक `Item-Input` और एक `Item-Output`
`Item-Input` के लिए, `description` **required नहीं है**, इसमें लाल asterisk नहीं है।
लेकिन `Item-Output` के लिए, `description` **required** है, इसमें लाल asterisk है।
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image04.png">
</div>
**Pydantic v2** की इस feature के साथ, आपकी API documentation अधिक **precise** होती है, और अगर आपके पास autogenerated clients और SDKs हैं, तो वे भी अधिक precise होंगे, बेहतर **developer experience** और consistency के साथ। 🎉
## Schemas को अलग न करें { #do-not-separate-schemas }
अब, कुछ मामले ऐसे हैं जहाँ आप **input और output के लिए same schema** रखना चाह सकते हैं।
शायद इसका मुख्य use case यह है कि अगर आपके पास पहले से कुछ autogenerated client code/SDKs हैं और आप अभी सभी autogenerated client code/SDKs को update नहीं करना चाहते, तो शायद आप इसे किसी समय करना चाहेंगे, लेकिन शायद अभी नहीं।
उस स्थिति में, आप **FastAPI** में इस feature को parameter `separate_input_output_schemas=False` के साथ disable कर सकते हैं।
/// note | नोट
`separate_input_output_schemas` के लिए support FastAPI `0.102.0` में add किया गया था। 🤓
///
{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *}
### Docs में Input और Output Models के लिए Same Schema { #same-schema-for-input-and-output-models-in-docs }
और अब model के लिए input और output के लिए केवल एक single schema होगा, सिर्फ `Item`, और इसमें `description` **required नहीं** होगा:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
</div>

7
docs/hi/docs/how-to/testing-database.md

@ -0,0 +1,7 @@
# Database की Testing { #testing-a-database }
आप databases, SQL, और SQLModel के बारे में [SQLModel docs](https://sqlmodel.tiangolo.com/) में पढ़ सकते हैं। 🤓
[FastAPI के साथ SQLModel इस्तेमाल करने पर एक छोटा tutorial](https://sqlmodel.tiangolo.com/tutorial/fastapi/) है। ✨
उस tutorial में [SQL databases की testing](https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/) के बारे में एक section शामिल है। 😎

5
docs/hi/docs/learn/index.md

@ -0,0 +1,5 @@
# सीखें { #learn }
यहाँ **FastAPI** सीखने के लिए परिचयात्मक section और ट्यूटोरियल हैं।
आप इसे FastAPI सीखने का एक **book**, एक **course**, **आधिकारिक** और अनुशंसित तरीका मान सकते हैं। 😎

3
docs/hi/docs/resources/index.md

@ -0,0 +1,3 @@
# संसाधन { #resources }
अतिरिक्त संसाधन, external links, और भी बहुत कुछ। ✈️

86
docs/hi/docs/tutorial/background-tasks.md

@ -0,0 +1,86 @@
# Background Tasks { #background-tasks }
आप background tasks define कर सकते हैं जिन्हें response लौटाने के *बाद* चलाया जाए।
यह उन operations के लिए उपयोगी है जिन्हें request के बाद होना होता है, लेकिन client को response पाने से पहले operation के पूरा होने का इंतज़ार करने की वास्तव में ज़रूरत नहीं होती।
इसमें, उदाहरण के लिए, ये शामिल हैं:
* कोई action करने के बाद भेजे गए email notifications:
* क्योंकि email server से connect करना और email भेजना आम तौर पर "slow" (कई seconds) होता है, आप response तुरंत लौटा सकते हैं और email notification को background में भेज सकते हैं।
* data process करना:
* उदाहरण के लिए, मान लीजिए आपको एक file मिलती है जिसे किसी slow process से गुजरना है, आप "Accepted" (HTTP 202) का response लौटा सकते हैं और file को background में process कर सकते हैं।
## `BackgroundTasks` का उपयोग करना { #using-backgroundtasks }
सबसे पहले, `BackgroundTasks` import करें और अपनी *path operation function* में `BackgroundTasks` की type declaration के साथ एक parameter define करें:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
**FastAPI** आपके लिए `BackgroundTasks` type का object बनाएगा और उसे उस parameter के रूप में pass करेगा।
## task function बनाएँ { #create-a-task-function }
background task के रूप में चलाने के लिए एक function बनाएँ।
यह बस एक standard function है जो parameters receive कर सकता है।
यह `async def` या normal `def` function हो सकता है, **FastAPI** जानता होगा कि इसे सही तरीके से कैसे handle करना है।
इस case में, task function एक file में लिखेगा (email भेजने का simulation करते हुए)।
और क्योंकि write operation `async` और `await` का उपयोग नहीं करता, हम function को normal `def` के साथ define करते हैं:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## background task जोड़ें { #add-the-background-task }
अपनी *path operation function* के अंदर, अपनी task function को *background tasks* object में method `.add_task()` के साथ pass करें:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
`.add_task()` arguments के रूप में receive करता है:
* background में चलाने के लिए एक task function (`write_notification`)।
* arguments की कोई भी sequence जो order में task function को pass की जानी चाहिए (`email`)।
* कोई भी keyword arguments जो task function को pass किए जाने चाहिए (`message="some notification"`)।
## Dependency Injection { #dependency-injection }
`BackgroundTasks` का उपयोग dependency injection system के साथ भी काम करता है, आप कई levels पर `BackgroundTasks` type का parameter declare कर सकते हैं: किसी *path operation function* में, dependency (dependable) में, sub-dependency में, आदि।
**FastAPI** जानता है कि हर case में क्या करना है और same object को कैसे reuse करना है, ताकि सभी background tasks merge हो जाएँ और बाद में background में run हों:
{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
इस example में, response भेजे जाने के *बाद* messages `log.txt` file में लिखे जाएँगे।
अगर request में कोई query थी, तो उसे एक background task में log में लिखा जाएगा।
और फिर *path operation function* पर generate हुआ एक और background task `email` path parameter का उपयोग करके एक message लिखेगा।
## Technical Details { #technical-details }
class `BackgroundTasks` सीधे [`starlette.background`](https://www.starlette.dev/background/) से आती है।
इसे सीधे FastAPI में import/include किया गया है ताकि आप इसे `fastapi` से import कर सकें और गलती से `starlette.background` से alternative `BackgroundTask` (अंत में `s` के बिना) import करने से बच सकें।
सिर्फ `BackgroundTasks` (और `BackgroundTask` नहीं) का उपयोग करने से, इसे *path operation function* parameter के रूप में use करना संभव होता है और **FastAPI** आपके लिए बाकी चीज़ें handle करता है, ठीक वैसे ही जैसे `Request` object को सीधे use करते समय होता है।
FastAPI में अकेले `BackgroundTask` का उपयोग करना अभी भी संभव है, लेकिन आपको अपने code में object बनाना होगा और उसे शामिल करते हुए Starlette `Response` return करना होगा।
आप [Background Tasks के लिए Starlette के official docs](https://www.starlette.dev/background/) में अधिक details देख सकते हैं।
## सावधानी { #caveat }
अगर आपको heavy background computation perform करनी है और यह ज़रूरी नहीं है कि वह same process द्वारा run हो (उदाहरण के लिए, आपको memory, variables, आदि share करने की ज़रूरत नहीं है), तो आपको [Celery](https://docs.celeryq.dev) जैसे दूसरे बड़े tools का उपयोग करने से लाभ हो सकता है।
उन्हें आम तौर पर अधिक complex configurations, RabbitMQ या Redis जैसे message/job queue manager की ज़रूरत होती है, लेकिन वे आपको multiple processes में, और खासकर multiple servers में, background tasks run करने देते हैं।
लेकिन अगर आपको उसी **FastAPI** app से variables और objects access करने हैं, या आपको छोटे background tasks perform करने हैं (जैसे email notification भेजना), तो आप आसानी से `BackgroundTasks` का उपयोग कर सकते हैं।
## Recap { #recap }
background tasks जोड़ने के लिए *path operation functions* और dependencies में parameters के साथ `BackgroundTasks` import और use करें।

547
docs/hi/docs/tutorial/bigger-applications.md

@ -0,0 +1,547 @@
# बड़े Applications - Multiple Files { #bigger-applications-multiple-files }
अगर आप कोई application या web API बना रहे हैं, तो ऐसा कम ही होता है कि आप सब कुछ एक ही file में रख सकें।
**FastAPI** आपके application को structure करने के लिए एक सुविधाजनक tool देता है, और साथ ही पूरी flexibility भी बनाए रखता है।
/// note | नोट
अगर आप Flask से आए हैं, तो यह Flask के Blueprints के बराबर होगा।
///
## एक उदाहरण file structure { #an-example-file-structure }
मान लीजिए आपके पास ऐसा file structure है:
```
.
├── app
│ ├── __init__.py
│ ├── main.py
│ ├── dependencies.py
│ └── routers
│ │ ├── __init__.py
│ │ ├── items.py
│ │ └── users.py
│ └── internal
│ ├── __init__.py
│ └── admin.py
```
/// tip | टिप
कई `__init__.py` files हैं: हर directory या subdirectory में एक।
यही एक file से दूसरी file में code import करने की अनुमति देता है।
उदाहरण के लिए, `app/main.py` में आपके पास ऐसी line हो सकती है:
```
from app.routers import items
```
///
* `app` directory में सब कुछ है। और इसमें एक खाली file `app/__init__.py` है, इसलिए यह एक "Python package" है ("Python modules" का संग्रह): `app`.
* इसमें एक `app/main.py` file है। क्योंकि यह एक Python package (एक ऐसी directory जिसमें `__init__.py` file है) के अंदर है, यह उस package का एक "module" है: `app.main`.
* एक `app/dependencies.py` file भी है, `app/main.py` की तरह, यह एक "module" है: `app.dependencies`.
* एक subdirectory `app/routers/` है जिसमें एक और file `__init__.py` है, इसलिए यह एक "Python subpackage" है: `app.routers`.
* file `app/routers/items.py` एक package, `app/routers/`, के अंदर है, इसलिए यह एक submodule है: `app.routers.items`.
* `app/routers/users.py` के साथ भी वही है, यह एक और submodule है: `app.routers.users`.
* एक subdirectory `app/internal/` भी है जिसमें एक और file `__init__.py` है, इसलिए यह एक और "Python subpackage" है: `app.internal`.
* और file `app/internal/admin.py` एक और submodule है: `app.internal.admin`.
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
वही file structure comments के साथ:
```bash
.
├── app # "app" एक Python package है
│   ├── __init__.py # यह file "app" को "Python package" बनाती है
│   ├── main.py # "main" module, जैसे import app.main
│   ├── dependencies.py # "dependencies" module, जैसे import app.dependencies
│   └── routers # "routers" एक "Python subpackage" है
│   │ ├── __init__.py # "routers" को "Python subpackage" बनाता है
│   │ ├── items.py # "items" submodule, जैसे import app.routers.items
│   │ └── users.py # "users" submodule, जैसे import app.routers.users
│   └── internal # "internal" एक "Python subpackage" है
│   ├── __init__.py # "internal" को "Python subpackage" बनाता है
│   └── admin.py # "admin" submodule, जैसे import app.internal.admin
```
## `APIRouter` { #apirouter }
मान लीजिए सिर्फ users को handle करने के लिए dedicated file `/app/routers/users.py` पर submodule है।
आप अपने users से संबंधित *path operations* को बाकी code से अलग रखना चाहते हैं, ताकि यह व्यवस्थित रहे।
लेकिन यह अभी भी उसी **FastAPI** application/web API का हिस्सा है (यह उसी "Python Package" का हिस्सा है)।
आप उस module के लिए *path operations* `APIRouter` का उपयोग करके बना सकते हैं।
### `APIRouter` import करें { #import-apirouter }
आप इसे import करते हैं और उसी तरह एक "instance" बनाते हैं जैसे आप `FastAPI` class के साथ करते:
{* ../../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 }
और फिर आप इसका उपयोग अपने *path operations* declare करने के लिए करते हैं।
इसे उसी तरह उपयोग करें जैसे आप `FastAPI` class का उपयोग करते:
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
आप `APIRouter` को एक "mini `FastAPI`" class की तरह सोच सकते हैं।
सभी वही options समर्थित हैं।
सभी वही `parameters`, `responses`, `dependencies`, `tags`, आदि।
/// tip | टिप
इस उदाहरण में, variable को `router` कहा गया है, लेकिन आप इसे अपनी इच्छा अनुसार कोई भी नाम दे सकते हैं।
///
हम इस `APIRouter` को main `FastAPI` app में शामिल करने जा रहे हैं, लेकिन पहले, dependencies और एक और `APIRouter` देखें।
## Dependencies { #dependencies }
हम देखते हैं कि हमें application के कई स्थानों पर उपयोग होने वाली कुछ dependencies की ज़रूरत होगी।
इसलिए हम उन्हें उनके अपने `dependencies` module (`app/dependencies.py`) में रखते हैं।
अब हम एक custom `X-Token` header पढ़ने के लिए एक सरल dependency का उपयोग करेंगे:
{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | टिप
हम इस उदाहरण को सरल बनाने के लिए एक काल्पनिक header का उपयोग कर रहे हैं।
लेकिन वास्तविक मामलों में आपको integrated [Security utilities](security/index.md) का उपयोग करके बेहतर परिणाम मिलेंगे।
///
## `APIRouter` के साथ एक और module { #another-module-with-apirouter }
मान लीजिए आपके application से "items" को handle करने के लिए dedicated endpoints भी `app/routers/items.py` module में हैं।
आपके पास इनके लिए *path operations* हैं:
* `/items/`
* `/items/{item_id}`
यह सब `app/routers/users.py` जैसी ही structure है।
लेकिन हम थोड़े अधिक smart होना चाहते हैं और code को थोड़ा simplify करना चाहते हैं।
हम जानते हैं कि इस module के सभी *path operations* में वही हैं:
* Path `prefix`: `/items`.
* `tags`: (सिर्फ एक tag: `items`).
* अतिरिक्त `responses`.
* `dependencies`: उन सभी को वह `X-Token` dependency चाहिए जो हमने बनाई है।
इसलिए, यह सब प्रत्येक *path operation* में जोड़ने के बजाय, हम इसे `APIRouter` में जोड़ सकते हैं।
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
क्योंकि प्रत्येक *path operation* का path `/` से शुरू होना चाहिए, जैसे:
```Python hl_lines="1"
@router.get("/{item_id}")
async def read_item(item_id: str):
...
```
...prefix में अंत में `/` शामिल नहीं होना चाहिए।
इसलिए, इस मामले में prefix `/items` है।
हम `tags` की list और अतिरिक्त `responses` भी जोड़ सकते हैं जो इस router में शामिल सभी *path operations* पर लागू होंगे।
और हम `dependencies` की list जोड़ सकते हैं जो router के सभी *path operations* में जोड़ी जाएगी और उन पर किए गए हर request के लिए execute/solve की जाएगी।
/// tip | टिप
ध्यान दें कि, [*path operation decorators* में dependencies](dependencies/dependencies-in-path-operation-decorators.md) की तरह ही, आपके *path operation function* को कोई value pass नहीं की जाएगी।
///
अंतिम परिणाम यह है कि item paths अब ये हैं:
* `/items/`
* `/items/{item_id}`
...जैसा हमने चाहा था।
* उन्हें tags की list से mark किया जाएगा जिसमें एक ही string `"items"` होगी।
* ये "tags" automatic interactive documentation systems (OpenAPI का उपयोग करते हुए) के लिए विशेष रूप से उपयोगी हैं।
* उन सभी में predefined `responses` शामिल होंगे।
* इन सभी *path operations* से पहले `dependencies` की list evaluate/execute की जाएगी।
* अगर आप किसी specific *path operation* में भी dependencies declare करते हैं, **तो वे भी execute होंगी**
* router dependencies पहले execute होती हैं, फिर decorator में [`dependencies`](dependencies/dependencies-in-path-operation-decorators.md), और फिर normal parameter dependencies।
* आप [`Security` dependencies with `scopes`](../advanced/security/oauth2-scopes.md) भी जोड़ सकते हैं।
/// tip | टिप
`APIRouter` में `dependencies` होने का उपयोग, उदाहरण के लिए, *path operations* के पूरे group के लिए authentication require करने के लिए किया जा सकता है। भले ही dependencies उनमें से हर एक में individually न जोड़ी गई हों।
///
/// tip | टिप
`prefix`, `tags`, `responses`, और `dependencies` parameters (कई अन्य मामलों की तरह) **FastAPI** की एक feature हैं जो आपको code duplication से बचने में मदद करती है।
///
### dependencies import करें { #import-the-dependencies }
यह code `app.routers.items` module, file `app/routers/items.py` में रहता है।
और हमें dependency function `app.dependencies` module, file `app/dependencies.py` से लेनी है।
इसलिए हम dependencies के लिए `..` के साथ relative import का उपयोग करते हैं:
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
#### Relative imports कैसे काम करते हैं { #how-relative-imports-work }
/// tip | टिप
अगर आप पूरी तरह जानते हैं कि imports कैसे काम करते हैं, तो नीचे वाले अगले section पर जाएँ।
///
एक single dot `.`, जैसे:
```Python
from .dependencies import get_token_header
```
का मतलब होगा:
* उसी package से शुरू करना जिसमें यह module (file `app/routers/items.py`) रहता है (directory `app/routers/`)...
* module `dependencies` ढूँढना (`app/routers/dependencies.py` पर एक काल्पनिक file)...
* और उससे, function `get_token_header` import करना।
लेकिन वह file मौजूद नहीं है, हमारी dependencies `app/dependencies.py` पर एक file में हैं।
याद रखें कि हमारी app/file structure कैसी दिखती है:
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
---
दो dots `..`, जैसे:
```Python
from ..dependencies import get_token_header
```
का मतलब है:
* उसी package से शुरू करना जिसमें यह module (file `app/routers/items.py`) रहता है (directory `app/routers/`)...
* parent package (directory `app/`) पर जाना...
* और वहाँ, module `dependencies` ढूँढना (file `app/dependencies.py` पर)...
* और उससे, function `get_token_header` import करना।
यह सही तरीके से काम करता है! 🎉
---
उसी तरह, अगर हमने तीन dots `...` का उपयोग किया होता, जैसे:
```Python
from ...dependencies import get_token_header
```
तो उसका मतलब होगा:
* उसी package से शुरू करना जिसमें यह module (file `app/routers/items.py`) रहता है (directory `app/routers/`)...
* parent package (directory `app/`) पर जाना...
* फिर उस package के parent पर जाना (कोई parent package नहीं है, `app` top level है 😱)...
* और वहाँ, module `dependencies` ढूँढना (file `app/dependencies.py` पर)...
* और उससे, function `get_token_header` import करना।
यह `app/` के ऊपर किसी package को refer करेगा, जिसकी अपनी file `__init__.py` आदि होगी। लेकिन हमारे पास वह नहीं है। इसलिए, हमारे उदाहरण में इससे error आएगा। 🚨
लेकिन अब आप जानते हैं कि यह कैसे काम करता है, इसलिए आप अपने apps में relative imports का उपयोग कर सकते हैं, चाहे वे कितने भी complex हों। 🤓
### कुछ custom `tags`, `responses`, और `dependencies` जोड़ें { #add-some-custom-tags-responses-and-dependencies }
हम प्रत्येक *path operation* में prefix `/items` या `tags=["items"]` नहीं जोड़ रहे हैं क्योंकि हमने उन्हें `APIRouter` में जोड़ दिया है।
लेकिन हम अभी भी _अधिक_ `tags` जोड़ सकते हैं जो किसी specific *path operation* पर लागू होंगे, और उस *path operation* के लिए specific कुछ अतिरिक्त `responses` भी:
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | टिप
इस आखिरी path operation में tags का combination होगा: `["items", "custom"]`
और documentation में इसके दोनों responses भी होंगे, एक `404` के लिए और एक `403` के लिए।
///
## मुख्य `FastAPI` { #the-main-fastapi }
अब, `app/main.py` पर module देखें।
यहीं आप `FastAPI` class import और use करते हैं।
यह आपके application की main file होगी जो सब कुछ एक साथ जोड़ती है।
और क्योंकि आपका अधिकतर logic अब अपने-अपने specific module में रहेगा, main file काफी सरल होगी।
### `FastAPI` import करें { #import-fastapi }
आप सामान्य रूप से `FastAPI` class import और create करते हैं।
और हम [global dependencies](dependencies/global-dependencies.md) भी declare कर सकते हैं जिन्हें प्रत्येक `APIRouter` के लिए dependencies के साथ combine किया जाएगा:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
### `APIRouter` import करें { #import-the-apirouter }
अब हम उन अन्य submodules को import करते हैं जिनके पास `APIRouter`s हैं:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
क्योंकि files `app/routers/users.py` और `app/routers/items.py` ऐसे submodules हैं जो उसी Python package `app` का हिस्सा हैं, हम "relative imports" का उपयोग करके उन्हें import करने के लिए single dot `.` का उपयोग कर सकते हैं।
### importing कैसे काम करता है { #how-the-importing-works }
section:
```Python
from .routers import items, users
```
का मतलब है:
* उसी package से शुरू करना जिसमें यह module (file `app/main.py`) रहता है (directory `app/`)...
* subpackage `routers` ढूँढना (directory `app/routers/` पर)...
* और उससे, submodule `items` (file `app/routers/items.py` पर) और `users` (file `app/routers/users.py` पर) import करना...
module `items` में एक variable `router` (`items.router`) होगा। यह वही है जो हमने file `app/routers/items.py` में बनाया था, यह एक `APIRouter` object है।
और फिर हम module `users` के लिए भी वही करते हैं।
हम उन्हें इस तरह भी import कर सकते थे:
```Python
from app.routers import items, users
```
/// note | नोट
पहला version एक "relative import" है:
```Python
from .routers import items, users
```
दूसरा version एक "absolute import" है:
```Python
from app.routers import items, users
```
Python Packages और Modules के बारे में अधिक जानने के लिए, [Modules के बारे में official Python documentation](https://docs.python.org/3/tutorial/modules.html) पढ़ें।
///
### नामों के collisions से बचें { #avoid-name-collisions }
हम submodule `items` को directly import कर रहे हैं, केवल उसके variable `router` को import करने के बजाय।
ऐसा इसलिए है क्योंकि हमारे पास submodule `users` में भी `router` नाम का एक और variable है।
अगर हमने एक के बाद एक import किया होता, जैसे:
```Python
from .routers.items import router
from .routers.users import router
```
तो `users` का `router`, `items` वाले को overwrite कर देता और हम उन्हें एक ही समय में use नहीं कर पाते।
इसलिए, उन्हें एक ही file में दोनों को use करने में सक्षम होने के लिए, हम submodules को directly import करते हैं:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
### `users` और `items` के लिए `APIRouter`s include करें { #include-the-apirouters-for-users-and-items }
अब, submodules `users` और `items` से `router`s include करें:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
/// note | नोट
`users.router` file `app/routers/users.py` के अंदर मौजूद `APIRouter` को contain करता है।
और `items.router` file `app/routers/items.py` के अंदर मौजूद `APIRouter` को contain करता है।
///
`app.include_router()` के साथ हम प्रत्येक `APIRouter` को main `FastAPI` application में जोड़ सकते हैं।
यह उस router के सभी routes को उसका हिस्सा बनाकर include करेगा।
/// note | तकनीकी विवरण
FastAPI मूल `APIRouter` और उसके `APIRoute`s को active रखता है जब router main application में include किया जाता है।
इसका मतलब है कि custom `APIRouter` और `APIRoute` subclasses router include होने के बाद भी participate कर सकते हैं।
///
/// tip | टिप
routers include करते समय आपको performance के बारे में चिंता करने की ज़रूरत नहीं है।
इसे lightweight होने और हर request में overhead जोड़ने से बचने के लिए design किया गया है।
इसलिए यह performance को affect नहीं करेगा। ⚡
///
### custom `prefix`, `tags`, `responses`, और `dependencies` के साथ `APIRouter` include करें { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies }
अब, कल्पना करें कि आपकी organization ने आपको `app/internal/admin.py` file दी है।
इसमें कुछ admin *path operations* वाला `APIRouter` है जिसे आपकी organization कई projects के बीच share करती है।
इस उदाहरण के लिए यह बहुत सरल होगा। लेकिन मान लीजिए कि क्योंकि यह organization में अन्य projects के साथ shared है, हम इसे modify नहीं कर सकते और `prefix`, `dependencies`, `tags`, आदि directly `APIRouter` में नहीं जोड़ सकते:
{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
लेकिन हम फिर भी `APIRouter` include करते समय एक custom `prefix` set करना चाहते हैं ताकि इसके सभी *path operations* `/admin` से शुरू हों, हम इसे इस project के लिए पहले से मौजूद `dependencies` के साथ secure करना चाहते हैं, और हम `tags` और `responses` include करना चाहते हैं।
हम original `APIRouter` को modify किए बिना यह सब declare कर सकते हैं, उन parameters को `app.include_router()` में pass करके:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
इस तरह, original `APIRouter` unmodified रहेगा, इसलिए हम वही `app/internal/admin.py` file organization में अन्य projects के साथ अब भी share कर सकते हैं।
परिणाम यह है कि हमारी app में, `admin` module से प्रत्येक *path operation* में होगा:
* prefix `/admin`.
* tag `admin`.
* dependency `get_token_header`.
* response `418`. 🍵
लेकिन यह केवल हमारी app में उस `APIRouter` को affect करेगा, उसे use करने वाले किसी अन्य code को नहीं।
इसलिए, उदाहरण के लिए, अन्य projects उसी `APIRouter` को किसी अलग authentication method के साथ use कर सकते हैं।
### एक *path operation* include करें { #include-a-path-operation }
हम सीधे `FastAPI` app में भी *path operations* जोड़ सकते हैं।
यहाँ हम ऐसा करते हैं... बस यह दिखाने के लिए कि हम कर सकते हैं 🤷:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
और यह `app.include_router()` के साथ जोड़े गए सभी अन्य *path operations* के साथ सही तरीके से काम करेगा।
/// note | बहुत तकनीकी विवरण
**नोट**: यह बहुत technical detail है जिसे आप शायद **बस skip** कर सकते हैं।
---
`APIRouter`s "mounted" नहीं होते, वे बाकी application से isolated नहीं होते।
ऐसा इसलिए है क्योंकि हम उनके *path operations* को OpenAPI schema और user interfaces में include करना चाहते हैं।
FastAPI original routers और path operations को active रखता है, और requests handle करते समय और OpenAPI generate करते समय router prefixes, dependencies, tags, responses, और अन्य metadata को combine करता है।
///
## `pyproject.toml` में `entrypoint` configure करें { #configure-the-entrypoint-in-pyproject-toml }
क्योंकि आपका FastAPI `app` object `app/main.py` में रहता है, आप अपने `pyproject.toml` file में `entrypoint` को इस तरह configure कर सकते हैं:
```toml
[tool.fastapi]
entrypoint = "app.main:app"
```
यह इस तरह import करने के बराबर है:
```python
from app.main import app
```
इस तरह `fastapi` command जान जाएगा कि आपकी app कहाँ मिलेगी।
/// Note | नोट
आप command को path भी pass कर सकते हैं, जैसे:
```console
$ fastapi dev app/main.py
```
लेकिन हर बार `fastapi` command call करते समय आपको सही path pass करना याद रखना होगा।
इसके अलावा, अन्य tools शायद इसे ढूँढ न पाएँ, उदाहरण के लिए [VS Code Extension](../editor-support.md) या [FastAPI Cloud](https://fastapicloud.com), इसलिए `pyproject.toml` में `entrypoint` का उपयोग करने की सलाह दी जाती है।
///
## automatic API docs जाँचें { #check-the-automatic-api-docs }
अब, अपनी app चलाएँ:
<div class="termy">
```console
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
और docs को [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) पर खोलें।
आप automatic API docs देखेंगे, जिसमें सभी submodules से paths शामिल होंगे, सही paths (और prefixes) और सही tags का उपयोग करते हुए:
<img src="/img/tutorial/bigger-applications/image01.png">
## अलग-अलग `prefix` के साथ उसी router को multiple times include करें { #include-the-same-router-multiple-times-with-different-prefix }
आप अलग-अलग prefixes का उपयोग करके *same* router के साथ `.include_router()` को multiple times भी use कर सकते हैं।
यह उपयोगी हो सकता है, उदाहरण के लिए, उसी API को अलग-अलग prefixes के तहत expose करने के लिए, जैसे `/api/v1` और `/api/latest`
यह एक advanced usage है जिसकी आपको शायद सच में ज़रूरत न हो, लेकिन अगर हो तो यह मौजूद है।
## एक `APIRouter` को दूसरे में include करें { #include-an-apirouter-in-another }
जिस तरह आप `FastAPI` application में `APIRouter` include कर सकते हैं, उसी तरह आप एक `APIRouter` को दूसरे `APIRouter` में include कर सकते हैं:
```Python
router.include_router(other_router)
```
आप यह `FastAPI` app में `router` include करने से पहले या बाद में कर सकते हैं। FastAPI फिर भी `other_router` से *path operations* को routing और OpenAPI में include करेगा।
बाद में routers में जोड़े गए *path operations* पर भी यही लागू होता है। वे पहले वाली inclusion के माध्यम से भी visible होंगे।
/// warning | तकनीकी विवरण
router include करने के बाद `router.routes` को directly mutate करने से बचें। FastAPI router inclusion को live मानता है, इसलिए original router और उसके routes routing और OpenAPI generation का हिस्सा बने रहते हैं।
routes और routers जोड़ने के लिए documented APIs जैसे path operation decorators और `.include_router()` का उपयोग करें।
`router.routes` को एक lower-level route tree की तरह treat करें जिसमें route definitions और included routers हो सकते हैं, और इस पर final path operations की flat list की तरह rely करने से बचें।
///

61
docs/hi/docs/tutorial/body-fields.md

@ -0,0 +1,61 @@
# Body - Fields { #body-fields }
जिस तरह आप *path operation function* के parameters में `Query`, `Path` और `Body` के साथ अतिरिक्त validation और metadata घोषित कर सकते हैं, उसी तरह आप Pydantic के `Field` का उपयोग करके Pydantic models के अंदर validation और metadata घोषित कर सकते हैं।
## `Field` import करें { #import-field }
सबसे पहले, आपको इसे import करना होगा:
{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
/// warning | चेतावनी
ध्यान दें कि `Field` को सीधे `pydantic` से import किया जाता है, `fastapi` से नहीं, जैसे बाकी सभी (`Query`, `Path`, `Body`, आदि) किए जाते हैं।
///
## model attributes घोषित करें { #declare-model-attributes }
फिर आप model attributes के साथ `Field` का उपयोग कर सकते हैं:
{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[11:14] *}
`Field` उसी तरह काम करता है जैसे `Query`, `Path` और `Body`, इसमें वही सभी parameters आदि होते हैं।
/// note | तकनीकी विवरण
वास्तव में, `Query`, `Path` और अन्य जिन्हें आप आगे देखेंगे, एक सामान्य `Param` class के subclasses के objects बनाते हैं, जो स्वयं Pydantic की `FieldInfo` class का subclass है।
और Pydantic का `Field` भी `FieldInfo` का एक instance लौटाता है।
`Body` भी सीधे `FieldInfo` के subclass के objects लौटाता है। और कुछ अन्य भी हैं जिन्हें आप बाद में देखेंगे, जो `Body` class के subclasses हैं।
याद रखें कि जब आप `fastapi` से `Query`, `Path` और अन्य import करते हैं, तो वे वास्तव में functions होते हैं जो विशेष classes लौटाते हैं।
///
/// tip | सुझाव
ध्यान दें कि type, default value और `Field` वाले हर model के attribute की संरचना *path operation function* के parameter जैसी ही होती है, बस `Path`, `Query` और `Body` की जगह `Field` होता है।
///
## अतिरिक्त जानकारी जोड़ें { #add-extra-information }
आप `Field`, `Query`, `Body` आदि में अतिरिक्त जानकारी घोषित कर सकते हैं। और यह जनरेट किए गए JSON Schema में शामिल होगी।
आप docs में आगे examples घोषित करना सीखते समय अतिरिक्त जानकारी जोड़ने के बारे में और जानेंगे।
/// warning | चेतावनी
`Field` को दिए गए अतिरिक्त keys आपके application के परिणामी OpenAPI schema में भी मौजूद होंगे।
क्योंकि ये keys जरूरी नहीं कि OpenAPI specification का हिस्सा हों, इसलिए कुछ OpenAPI tools, उदाहरण के लिए [OpenAPI validator](https://validator.swagger.io/), आपके जनरेट किए गए schema के साथ काम नहीं कर सकते।
///
## Recap { #recap }
आप model attributes के लिए अतिरिक्त validations और metadata घोषित करने के लिए Pydantic के `Field` का उपयोग कर सकते हैं।
आप अतिरिक्त JSON Schema metadata पास करने के लिए extra keyword arguments का भी उपयोग कर सकते हैं।

169
docs/hi/docs/tutorial/body-multiple-params.md

@ -0,0 +1,169 @@
# Body - कई Parameters { #body-multiple-parameters }
अब जबकि हमने देख लिया है कि `Path` और `Query` का उपयोग कैसे करना है, आइए request body declarations के और उन्नत उपयोग देखें।
## `Path`, `Query` और body parameters को मिलाएँ { #mix-path-query-and-body-parameters }
सबसे पहले, बेशक, आप `Path`, `Query` और request body parameter declarations को स्वतंत्र रूप से मिला सकते हैं और **FastAPI** जान जाएगा कि क्या करना है।
और आप body parameters को optional भी declare कर सकते हैं, default को `None` पर सेट करके:
{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
/// note | नोट
ध्यान दें कि, इस मामले में, body से लिया जाने वाला `item` optional है। क्योंकि इसका default value `None` है।
///
## कई body parameters { #multiple-body-parameters }
पिछले उदाहरण में, *path operations* एक JSON body की अपेक्षा करेंगे जिसमें `Item` के attributes हों, जैसे:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
```
लेकिन आप कई body parameters भी declare कर सकते हैं, उदाहरण के लिए `item` और `user`:
{* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
इस मामले में, **FastAPI** ध्यान देगा कि function में एक से अधिक body parameter हैं (दो parameters हैं जो Pydantic models हैं)।
तो, फिर यह parameter names को body में keys (field names) के रूप में उपयोग करेगा, और ऐसी body की अपेक्षा करेगा:
```JSON
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
```
/// note | नोट
ध्यान दें कि भले ही `item` को पहले की तरह ही declare किया गया था, अब उससे अपेक्षा की जाती है कि वह body के अंदर key `item` के साथ हो।
///
**FastAPI** request से automatic conversion करेगा, ताकि parameter `item` को उसकी विशिष्ट content मिले और `user` के लिए भी यही हो।
यह compound data का validation करेगा, और इसे OpenAPI schema और automatic docs के लिए उसी तरह document करेगा।
## body में एकल values { #singular-values-in-body }
जिस तरह query और path parameters के लिए extra data define करने हेतु `Query` और `Path` हैं, **FastAPI** एक समान `Body` प्रदान करता है।
उदाहरण के लिए, पिछले model को extend करते हुए, आप तय कर सकते हैं कि आप उसी body में `item` और `user` के अलावा एक और key `importance` रखना चाहते हैं।
यदि आप इसे जैसे है वैसे declare करते हैं, क्योंकि यह एक single value है, **FastAPI** मान लेगा कि यह एक query parameter है।
लेकिन आप **FastAPI** को `Body` का उपयोग करके इसे एक और body key के रूप में treat करने का निर्देश दे सकते हैं:
{* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
इस मामले में, **FastAPI** ऐसी body की अपेक्षा करेगा:
```JSON
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
```
फिर से, यह data types को convert करेगा, validate करेगा, document करेगा, आदि।
## कई body params और query { #multiple-body-params-and-query }
बेशक, आप जब भी ज़रूरत हो, किसी भी body parameters के अतिरिक्त, extra query parameters भी declare कर सकते हैं।
क्योंकि default रूप से, single values को query parameters के रूप में interpret किया जाता है, आपको स्पष्ट रूप से `Query` जोड़ने की ज़रूरत नहीं है, आप बस ऐसा कर सकते हैं:
```Python
q: str | None = None
```
उदाहरण के लिए:
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
/// note | नोट
`Body` में भी वही सभी extra validation और metadata parameters हैं जो `Query`, `Path` और अन्य में हैं जिन्हें आप बाद में देखेंगे।
///
## एक single body parameter को embed करें { #embed-a-single-body-parameter }
मान लीजिए आपके पास Pydantic model `Item` से केवल एक single `item` body parameter है।
default रूप से, **FastAPI** फिर सीधे उसकी body की अपेक्षा करेगा।
लेकिन यदि आप चाहते हैं कि यह key `item` के साथ JSON की अपेक्षा करे और उसके अंदर model contents हों, जैसा कि यह तब करता है जब आप extra body parameters declare करते हैं, तो आप special `Body` parameter `embed` का उपयोग कर सकते हैं:
```Python
item: Annotated[Item, Body(embed=True)]
```
जैसे कि:
{* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
इस मामले में **FastAPI** ऐसी body की अपेक्षा करेगा:
```JSON hl_lines="2"
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
```
इसके बजाय:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
```
## Recap { #recap }
आप अपनी *path operation function* में कई body parameters जोड़ सकते हैं, भले ही एक request में केवल एक ही body हो सकती है।
लेकिन **FastAPI** इसे handle करेगा, आपको आपके function में सही data देगा, और *path operation* में सही schema को validate और document करेगा।
आप single values को body के हिस्से के रूप में receive करने के लिए भी declare कर सकते हैं।
और आप **FastAPI** को body को एक key में embed करने का निर्देश दे सकते हैं, भले ही केवल एक single parameter declare किया गया हो।

221
docs/hi/docs/tutorial/body-nested-models.md

@ -0,0 +1,221 @@
# Body - Nested Models { #body-nested-models }
**FastAPI** के साथ, आप arbitrarily deeply nested models को define, validate, document, और use कर सकते हैं (Pydantic की बदौलत)।
## List fields { #list-fields }
आप किसी attribute को subtype के रूप में define कर सकते हैं। उदाहरण के लिए, एक Python `list`:
{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
यह `tags` को एक list बना देगा, हालांकि यह list के elements का type declare नहीं करता।
## Type parameter के साथ List fields { #list-fields-with-type-parameter }
लेकिन Python में internal types, या "type parameters" के साथ lists declare करने का एक खास तरीका है:
### Type parameter के साथ `list` declare करें { #declare-a-list-with-a-type-parameter }
ऐसे types declare करने के लिए जिनमें type parameters (internal types) होते हैं, जैसे `list`, `dict`, `tuple`,
internal type(s) को square brackets: `[` और `]` का उपयोग करके "type parameters" के रूप में pass करें
```Python
my_list: list[str]
```
Type declarations के लिए यह सब standard Python syntax है।
Internal types वाले model attributes के लिए भी वही standard syntax उपयोग करें।
तो, हमारे उदाहरण में, हम `tags` को खास तौर पर "strings की list" बना सकते हैं:
{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
## Set types { #set-types }
लेकिन फिर हम इस पर सोचते हैं, और समझते हैं कि tags repeat नहीं होने चाहिए, वे शायद unique strings होंगे।
और Python में unique items के sets के लिए एक खास data type है, `set`
फिर हम `tags` को strings के set के रूप में declare कर सकते हैं:
{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
इसके साथ, भले ही आपको duplicate data वाला request मिले, वह unique items के set में convert हो जाएगा।
और जब भी आप उस data को output करेंगे, भले ही source में duplicates हों, वह unique items के set के रूप में output होगा।
और इसे उसी अनुसार annotate / document भी किया जाएगा।
## Nested Models { #nested-models }
Pydantic model के हर attribute का एक type होता है।
लेकिन वह type खुद भी कोई दूसरा Pydantic model हो सकता है।
इसलिए, आप खास attribute names, types और validations के साथ deeply nested JSON "objects" declare कर सकते हैं।
यह सब, मनचाही गहराई तक nested हो सकता है।
### Submodel define करें { #define-a-submodel }
उदाहरण के लिए, हम एक `Image` model define कर सकते हैं:
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
### Submodel को type के रूप में उपयोग करें { #use-the-submodel-as-a-type }
और फिर हम इसे किसी attribute के type के रूप में उपयोग कर सकते हैं:
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
इसका मतलब होगा कि **FastAPI** कुछ इस तरह के body की अपेक्षा करेगा:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": ["rock", "metal", "bar"],
"image": {
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
}
}
```
फिर से, सिर्फ वह declaration करने से, **FastAPI** के साथ आपको मिलता है:
* Editor support (completion, आदि), nested models के लिए भी
* Data conversion
* Data validation
* Automatic documentation
## Special types और validation { #special-types-and-validation }
`str`, `int`, `float`, आदि जैसे सामान्य singular types के अलावा, आप अधिक complex singular types उपयोग कर सकते हैं जो `str` से inherit करते हैं।
आपके पास मौजूद सभी options देखने के लिए, [Pydantic का Type Overview](https://docs.pydantic.dev/latest/concepts/types/) देखें। अगले chapter में आपको कुछ उदाहरण दिखेंगे।
उदाहरण के लिए, जैसा कि `Image` model में हमारे पास एक `url` field है, हम इसे `str` के बजाय Pydantic के `HttpUrl` का instance declare कर सकते हैं:
{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
String को valid URL होने के लिए check किया जाएगा, और JSON Schema / OpenAPI में उसी तरह document किया जाएगा।
## Submodels की lists वाले attributes { #attributes-with-lists-of-submodels }
आप Pydantic models को `list`, `set`, आदि के subtypes के रूप में भी उपयोग कर सकते हैं:
{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
यह इस तरह के JSON body की अपेक्षा करेगा (convert, validate, document, आदि):
```JSON hl_lines="11"
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": [
"rock",
"metal",
"bar"
],
"images": [
{
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
},
{
"url": "http://example.com/dave.jpg",
"name": "The Baz"
}
]
}
```
/// note | नोट
ध्यान दें कि `images` key में अब image objects की एक list है।
///
## Deeply nested models { #deeply-nested-models }
आप arbitrarily deeply nested models define कर सकते हैं:
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
/// note | नोट
ध्यान दें कि `Offer` में `Item`s की एक list है, जिनमें आगे `Image`s की एक optional list है
///
## Pure lists के bodies { #bodies-of-pure-lists }
अगर जिस JSON body की आप अपेक्षा करते हैं उसका top level value एक JSON `array` (एक Python `list`) है, तो आप function के parameter में type declare कर सकते हैं, बिल्कुल Pydantic models की तरह:
```Python
images: list[Image]
```
जैसे कि:
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
## हर जगह editor support { #editor-support-everywhere }
और आपको हर जगह editor support मिलता है।
Lists के अंदर के items के लिए भी:
<img src="/img/tutorial/body-nested-models/image01.png">
अगर आप Pydantic models के बजाय सीधे `dict` के साथ काम कर रहे होते, तो आपको इस तरह का editor support नहीं मिल सकता था।
लेकिन आपको उनकी चिंता भी करने की ज़रूरत नहीं है, आने वाले dicts अपने आप convert हो जाते हैं और आपका output भी अपने आप JSON में convert हो जाता है।
## Arbitrary `dict`s के bodies { #bodies-of-arbitrary-dicts }
आप body को एक `dict` के रूप में भी declare कर सकते हैं, जिसकी keys किसी type की हों और values किसी दूसरे type की।
इस तरह, आपको पहले से यह जानने की ज़रूरत नहीं होती कि valid field/attribute names क्या हैं (जैसा कि Pydantic models के साथ होता)।
यह तब उपयोगी होगा जब आप ऐसी keys receive करना चाहते हैं जिन्हें आप पहले से नहीं जानते।
---
एक और उपयोगी case वह है जब आप किसी दूसरे type (जैसे, `int`) की keys रखना चाहते हैं।
यही हम यहाँ देखने जा रहे हैं।
इस case में, आप कोई भी `dict` accept करेंगे, जब तक कि उसमें `float` values वाली `int` keys हों:
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
/// tip | टिप
ध्यान रखें कि JSON केवल `str` को keys के रूप में support करता है।
लेकिन Pydantic में automatic data conversion है।
इसका मतलब है कि, भले ही आपके API clients केवल strings को keys के रूप में भेज सकते हैं, जब तक उन strings में pure integers हैं, Pydantic उन्हें convert और validate कर देगा।
और `weights` के रूप में आपको जो `dict` receive होगा, उसमें वास्तव में `int` keys और `float` values होंगी।
///
## Recap { #recap }
**FastAPI** के साथ आपके पास Pydantic models द्वारा दी गई अधिकतम flexibility होती है, जबकि आपका code simple, short और elegant बना रहता है।
लेकिन सभी benefits के साथ:
* Editor support (हर जगह completion!)
* Data conversion (a.k.a. parsing / serialization)
* Data validation
* Schema documentation
* Automatic docs

100
docs/hi/docs/tutorial/body-updates.md

@ -0,0 +1,100 @@
# Body - अपडेट्स { #body-updates }
## `PUT` के साथ बदलकर अपडेट करना { #update-replacing-with-put }
किसी item को अपडेट करने के लिए आप [HTTP `PUT`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) operation का उपयोग कर सकते हैं।
आप input data को ऐसे data में बदलने के लिए `jsonable_encoder` का उपयोग कर सकते हैं जिसे JSON के रूप में संग्रहीत किया जा सके (जैसे NoSQL database के साथ)। उदाहरण के लिए, `datetime` को `str` में बदलना।
{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
`PUT` का उपयोग ऐसा data प्राप्त करने के लिए किया जाता है जो मौजूदा data को बदल दे।
### बदलने के बारे में चेतावनी { #warning-about-replacing }
इसका मतलब है कि अगर आप item `bar` को `PUT` का उपयोग करके ऐसे body के साथ अपडेट करना चाहते हैं जिसमें यह हो:
```Python
{
"name": "Barz",
"price": 3,
"description": None,
}
```
क्योंकि इसमें पहले से संग्रहीत attribute `"tax": 20.2` शामिल नहीं है, input model `"tax": 10.5` की default value लेगा।
और data उस "नए" `tax` `10.5` के साथ सहेजा जाएगा।
## `PATCH` के साथ आंशिक अपडेट्स { #partial-updates-with-patch }
आप data को *आंशिक रूप से* अपडेट करने के लिए [HTTP `PATCH`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) operation का भी उपयोग कर सकते हैं।
इसका मतलब है कि आप केवल वही data भेज सकते हैं जिसे आप अपडेट करना चाहते हैं, बाकी को वैसा ही छोड़ते हुए।
/// note | नोट
`PATCH`, `PUT` की तुलना में कम सामान्य रूप से उपयोग और जाना जाता है।
और कई teams आंशिक अपडेट्स के लिए भी केवल `PUT` का उपयोग करती हैं।
आप इन्हें जैसे चाहें वैसे उपयोग करने के लिए **स्वतंत्र** हैं, **FastAPI** कोई प्रतिबंध नहीं लगाता।
लेकिन यह गाइड आपको मोटे तौर पर दिखाती है कि इन्हें कैसे उपयोग करने का इरादा है।
///
### Pydantic के `exclude_unset` parameter का उपयोग करना { #using-pydantics-exclude-unset-parameter }
अगर आप आंशिक अपडेट्स प्राप्त करना चाहते हैं, तो Pydantic के model के `.model_dump()` में parameter `exclude_unset` का उपयोग करना बहुत उपयोगी है।
जैसे `item.model_dump(exclude_unset=True)`
इससे केवल उस data के साथ एक `dict` बनेगा जो `item` model बनाते समय सेट किया गया था, default values को छोड़कर।
फिर आप इसका उपयोग केवल उस data के साथ एक `dict` बनाने के लिए कर सकते हैं जो सेट किया गया था (request में भेजा गया), default values को छोड़ते हुए:
{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
### Pydantic के `update` parameter का उपयोग करना { #using-pydantics-update-parameter }
अब, आप `.model_copy()` का उपयोग करके मौजूदा model की एक copy बना सकते हैं, और अपडेट करने के लिए data वाले `dict` के साथ `update` parameter पास कर सकते हैं।
जैसे `stored_item_model.model_copy(update=update_data)`:
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
### आंशिक अपडेट्स Recap { #partial-updates-recap }
संक्षेप में, आंशिक अपडेट्स लागू करने के लिए आप:
* (वैकल्पिक रूप से) `PUT` के बजाय `PATCH` का उपयोग करें।
* संग्रहीत data प्राप्त करें।
* उस data को Pydantic model में रखें।
* input model से default values के बिना एक `dict` बनाएँ (`exclude_unset` का उपयोग करके)।
* इस तरह आप केवल उन values को अपडेट कर सकते हैं जिन्हें वास्तव में user ने सेट किया है, बजाय इसके कि आपके model में पहले से संग्रहीत values को default values से override कर दें।
* संग्रहीत model की एक copy बनाएँ, और प्राप्त आंशिक अपडेट्स के साथ उसके attributes को अपडेट करें (`update` parameter का उपयोग करके)।
* copied model को ऐसी चीज़ में बदलें जिसे आपकी DB में संग्रहीत किया जा सके (उदाहरण के लिए, `jsonable_encoder` का उपयोग करके)।
* यह model की `.model_dump()` method को फिर से उपयोग करने जैसा है, लेकिन यह सुनिश्चित करता है (और बदलता है) कि values ऐसे data types में हों जिन्हें JSON में बदला जा सके, उदाहरण के लिए, `datetime` को `str` में।
* data को अपनी DB में सहेजें।
* अपडेट किया गया model लौटाएँ।
{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
/// tip | टिप
आप वास्तव में इसी तकनीक का उपयोग HTTP `PUT` operation के साथ भी कर सकते हैं।
लेकिन यहाँ का उदाहरण `PATCH` का उपयोग करता है क्योंकि इसे इन्हीं use cases के लिए बनाया गया था।
///
/// note | नोट
ध्यान दें कि input model अभी भी validate किया जाता है।
इसलिए, अगर आप ऐसे आंशिक अपडेट्स प्राप्त करना चाहते हैं जो सभी attributes को छोड़ सकते हैं, तो आपको ऐसा model चाहिए जिसमें सभी attributes optional के रूप में चिह्नित हों (default values या `None` के साथ)।
**अपडेट्स** के लिए सभी optional values वाले models और **creation** के लिए required values वाले models में अंतर करने के लिए, आप [Extra Models](extra-models.md) में बताए गए विचारों का उपयोग कर सकते हैं।
///

166
docs/hi/docs/tutorial/body.md

@ -0,0 +1,166 @@
# Request Body { #request-body }
जब आपको किसी client (मान लें, एक browser) से अपनी API को data भेजना होता है, तो आप उसे **request body** के रूप में भेजते हैं।
**request** body वह data है जो client आपकी API को भेजता है। **response** body वह data है जो आपकी API client को भेजती है।
आपकी API को लगभग हमेशा **response** body भेजनी होती है। लेकिन clients को हर समय **request bodies** भेजने की ज़रूरत नहीं होती, कभी-कभी वे केवल एक path request करते हैं, शायद कुछ query parameters के साथ, लेकिन body नहीं भेजते।
**request** body घोषित करने के लिए, आप [Pydantic](https://docs.pydantic.dev/) models का उनकी पूरी शक्ति और लाभों के साथ उपयोग करते हैं।
/// note | नोट
Data भेजने के लिए, आपको इनमें से किसी एक का उपयोग करना चाहिए: `POST` (सबसे आम), `PUT`, `DELETE` या `PATCH`.
`GET` request के साथ body भेजने का व्यवहार specifications में undefined है, फिर भी, FastAPI इसे support करता है, केवल बहुत जटिल/चरम use cases के लिए।
क्योंकि इसे discouraged किया जाता है, Swagger UI वाले interactive docs `GET` का उपयोग करते समय body के लिए documentation नहीं दिखाएँगे, और बीच में मौजूद proxies इसे support नहीं कर सकते।
///
## Pydantic के `BaseModel` को import करें { #import-pydantics-basemodel }
सबसे पहले, आपको `pydantic` से `BaseModel` import करना होगा:
{* ../../docs_src/body/tutorial001_py310.py hl[2] *}
## अपना data model बनाएँ { #create-your-data-model }
फिर आप अपने data model को एक class के रूप में घोषित करते हैं जो `BaseModel` से inherit करती है।
सभी attributes के लिए standard Python types का उपयोग करें:
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
Query parameters घोषित करते समय की तरह, जब किसी model attribute का default value होता है, तो वह required नहीं होता। अन्यथा, वह required होता है। उसे केवल optional बनाने के लिए `None` का उपयोग करें।
उदाहरण के लिए, ऊपर दिया गया यह model इस तरह का JSON "`object`" (या Python `dict`) घोषित करता है:
```JSON
{
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
}
```
...क्योंकि `description` और `tax` optional हैं (`None` के default value के साथ), यह JSON "`object`" भी valid होगा:
```JSON
{
"name": "Foo",
"price": 45.2
}
```
## इसे एक parameter के रूप में घोषित करें { #declare-it-as-a-parameter }
इसे अपनी *path operation* में जोड़ने के लिए, इसे उसी तरह घोषित करें जैसे आपने path और query parameters घोषित किए थे:
{* ../../docs_src/body/tutorial001_py310.py hl[16] *}
...और इसके type को आपके बनाए हुए model, `Item`, के रूप में घोषित करें।
## परिणाम { #results }
सिर्फ उस Python type declaration के साथ, **FastAPI** यह करेगा:
* request के body को JSON के रूप में पढ़ेगा।
* संबंधित types को convert करेगा (यदि ज़रूरत हो)।
* data को validate करेगा।
* यदि data invalid है, तो यह एक अच्छा और स्पष्ट error return करेगा, जो ठीक-ठीक बताएगा कि गलत data कहाँ और क्या था।
* आपको प्राप्त data parameter `item` में देगा।
* क्योंकि आपने इसे function में `Item` type का घोषित किया है, आपको इसके सभी attributes और उनके types के लिए पूरा editor support (completion, आदि) भी मिलेगा।
* आपके model के लिए [JSON Schema](https://json-schema.org) definitions generate करेगा, यदि आपके project के लिए उचित हो तो आप उन्हें कहीं और भी उपयोग कर सकते हैं।
* वे schemas generated OpenAPI schema का हिस्सा होंगे, और automatic documentation <abbr title="User Interfaces - उपयोगकर्ता इंटरफ़ेस">UIs</abbr> द्वारा उपयोग किए जाएँगे।
## स्वचालित docs { #automatic-docs }
आपके models के JSON Schemas आपके OpenAPI generated schema का हिस्सा होंगे, और interactive API docs में दिखाए जाएँगे:
<img src="/img/tutorial/body/image01.png">
और वे API docs में हर उस *path operation* के अंदर भी उपयोग किए जाएँगे जिसे उनकी ज़रूरत है:
<img src="/img/tutorial/body/image02.png">
## Editor support { #editor-support }
अपने editor में, अपने function के अंदर आपको हर जगह type hints और completion मिलेंगे (यदि आपको Pydantic model के बजाय `dict` मिला होता, तो ऐसा नहीं होता):
<img src="/img/tutorial/body/image03.png">
आपको incorrect type operations के लिए error checks भी मिलते हैं:
<img src="/img/tutorial/body/image04.png">
यह संयोग से नहीं है, पूरा framework इसी design के इर्द-गिर्द बनाया गया था।
और किसी भी implementation से पहले, design phase में इसे पूरी तरह test किया गया था, ताकि सुनिश्चित किया जा सके कि यह सभी editors के साथ काम करेगा।
इसे support करने के लिए Pydantic में भी कुछ बदलाव किए गए थे।
पिछले screenshots [Visual Studio Code](https://code.visualstudio.com) के साथ लिए गए थे।
लेकिन आपको [PyCharm](https://www.jetbrains.com/pycharm/) और अधिकांश अन्य Python editors के साथ भी वही editor support मिलेगा:
<img src="/img/tutorial/body/image05.png">
/// tip | सुझाव
यदि आप [PyCharm](https://www.jetbrains.com/pycharm/) को अपने editor के रूप में उपयोग करते हैं, तो आप [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/) का उपयोग कर सकते हैं।
यह Pydantic models के लिए editor support को बेहतर बनाता है, इन चीज़ों के साथ:
* auto-completion
* type checks
* refactoring
* searching
* inspections
///
## model का उपयोग करें { #use-the-model }
Function के अंदर, आप model object के सभी attributes को सीधे access कर सकते हैं:
{* ../../docs_src/body/tutorial002_py310.py *}
## Request body + path parameters { #request-body-path-parameters }
आप path parameters और request body को एक ही समय में घोषित कर सकते हैं।
**FastAPI** पहचानेगा कि वे function parameters जो path parameters से match करते हैं, उन्हें **path से लिया जाना चाहिए**, और वे function parameters जो Pydantic models के रूप में घोषित हैं, उन्हें **request body से लिया जाना चाहिए**
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
## Request body + path + query parameters { #request-body-path-query-parameters }
आप **body**, **path** और **query** parameters को भी एक ही समय में घोषित कर सकते हैं।
**FastAPI** उनमें से प्रत्येक को पहचानेगा और data को सही जगह से लेगा।
{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
Function parameters को इस प्रकार पहचाना जाएगा:
* यदि parameter **path** में भी घोषित है, तो उसे path parameter के रूप में उपयोग किया जाएगा।
* यदि parameter **singular type** का है (जैसे `int`, `float`, `str`, `bool`, आदि), तो उसे **query** parameter के रूप में interpret किया जाएगा।
* यदि parameter को **Pydantic model** के type का घोषित किया गया है, तो उसे request **body** के रूप में interpret किया जाएगा।
/// note | नोट
FastAPI जान जाएगा कि `q` का value required नहीं है क्योंकि उसका default value `= None` है।
`str | None` का उपयोग FastAPI यह निर्धारित करने के लिए नहीं करता कि value required नहीं है, वह जान जाएगा कि यह required नहीं है क्योंकि इसका default value `= None` है।
लेकिन type annotations जोड़ने से आपका editor आपको बेहतर support दे सकेगा और errors detect कर सकेगा।
///
## Pydantic के बिना { #without-pydantic }
यदि आप Pydantic models का उपयोग नहीं करना चाहते, तो आप **Body** parameters का भी उपयोग कर सकते हैं। [Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body) के docs देखें।

76
docs/hi/docs/tutorial/cookie-param-models.md

@ -0,0 +1,76 @@
# Cookie Parameter Models { #cookie-parameter-models }
अगर आपके पास संबंधित **cookies** का एक समूह है, तो आप उन्हें declare करने के लिए एक **Pydantic model** बना सकते हैं। 🍪
यह आपको **model को फिर से उपयोग** करने की अनुमति देगा, **कई जगहों** पर, और साथ ही सभी parameters के लिए validations और metadata एक साथ declare करने की भी। 😎
/// note | नोट
यह FastAPI version `0.115.0` से supported है। 🤓
///
/// tip | सुझाव
यही तकनीक `Query`, `Cookie`, और `Header` पर लागू होती है। 😎
///
## Pydantic Model के साथ Cookies { #cookies-with-a-pydantic-model }
जिन **cookie** parameters की आपको ज़रूरत है, उन्हें एक **Pydantic model** में declare करें, और फिर parameter को `Cookie` के रूप में declare करें:
{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
**FastAPI** request में प्राप्त **cookies** से **हर field** के लिए data **extract** करेगा और आपको वह Pydantic model देगा जिसे आपने define किया है।
## Docs देखें { #check-the-docs }
आप `/docs` पर docs UI में defined cookies देख सकते हैं:
<div class="screenshot">
<img src="/img/tutorial/cookie-param-models/image01.png">
</div>
/// note | नोट
ध्यान रखें कि, क्योंकि **browsers cookies को** विशेष तरीकों से और पर्दे के पीछे handle करते हैं, वे **JavaScript** को आसानी से उन्हें छूने की अनुमति **नहीं** देते।
अगर आप `/docs` पर **API docs UI** पर जाते हैं, तो आप अपने *path operations* के लिए cookies की **documentation** देख पाएँगे।
लेकिन भले ही आप **data भरें** और "Execute" पर क्लिक करें, क्योंकि docs UI **JavaScript** के साथ काम करता है, cookies नहीं भेजे जाएँगे, और आपको एक **error** message दिखाई देगा जैसे कि आपने कोई values लिखी ही न हों।
///
## Extra Cookies को forbid करें { #forbid-extra-cookies }
कुछ विशेष use cases में (शायद बहुत आम नहीं), आप उन cookies को **restrict** करना चाह सकते हैं जिन्हें आप प्राप्त करना चाहते हैं।
आपकी API के पास अब अपनी खुद की <dfn title="यह एक मज़ाक है, बस स्पष्ट करने के लिए। इसका cookie सहमति से कोई लेना-देना नहीं है, लेकिन यह मज़ेदार है कि अब API भी बेचारे cookies को reject कर सकती है। एक cookie लीजिए। 🍪">cookie सहमति</dfn> को control करने की शक्ति है। 🤪🍪
आप Pydantic के model configuration का उपयोग करके किसी भी `extra` fields को `forbid` कर सकते हैं:
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
अगर कोई client कुछ **extra cookies** भेजने की कोशिश करता है, तो उन्हें एक **error** response मिलेगा।
बेचारे cookie banners, जो <dfn title="यह एक और मज़ाक है। मेरी बात पर ध्यान न दें। अपनी cookie के लिए कुछ coffee लीजिए। ☕">API द्वारा उसे reject किए जाने</dfn> के लिए आपकी सहमति पाने में इतनी मेहनत करते हैं। 🍪
उदाहरण के लिए, अगर client `good-list-please` value के साथ एक `santa_tracker` cookie भेजने की कोशिश करता है, तो client को एक **error** response मिलेगा जो बताएगा कि `santa_tracker` <dfn title="Santa cookies की कमी को पसंद नहीं करता। 🎅 ठीक है, अब और cookie jokes नहीं।">cookie की अनुमति नहीं है</dfn>:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["cookie", "santa_tracker"],
"msg": "Extra inputs are not permitted",
"input": "good-list-please",
}
]
}
```
## सारांश { #summary }
आप **FastAPI** में <dfn title="जाने से पहले एक आखिरी cookie लीजिए। 🍪">**cookies**</dfn> declare करने के लिए **Pydantic models** का उपयोग कर सकते हैं। 😎

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save