mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-24 14:48:35 -05:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c519614b45 | ||
|
|
9c794c9c0d | ||
|
|
c4f8143dea | ||
|
|
45822d31f2 | ||
|
|
4c1a1938bc | ||
|
|
5afa6d7066 | ||
|
|
f0b5f8adf7 | ||
|
|
b0761c2552 | ||
|
|
53d90074e5 | ||
|
|
7038bedc5d | ||
|
|
48849f8a11 | ||
|
|
b7fb8eb656 | ||
|
|
ac3c2dd965 | ||
|
|
febf6b6a52 | ||
|
|
71f2be2387 | ||
|
|
50639525bf | ||
|
|
80ba3fc5db | ||
|
|
d7942aea2d | ||
|
|
12c188b311 | ||
|
|
9b09974cfc | ||
|
|
0507458504 | ||
|
|
be03a7313e | ||
|
|
111ced53af | ||
|
|
d63f0d60ba | ||
|
|
4d8d092925 | ||
|
|
33cd8bbcc5 | ||
|
|
73546a68e6 | ||
|
|
c9f11c2b73 | ||
|
|
e58c185526 | ||
|
|
923d44de35 | ||
|
|
7148584ac4 | ||
|
|
38f65c033f | ||
|
|
5f998ee55a | ||
|
|
7358ed246e | ||
|
|
d4e183da3f | ||
|
|
0e4dc88bd7 | ||
|
|
b887d434db | ||
|
|
766a14ddff | ||
|
|
6384f730f7 | ||
|
|
84ef149f83 | ||
|
|
495d90161b | ||
|
|
ac6c08c71f | ||
|
|
a30eb6f517 | ||
|
|
3347f0dde5 | ||
|
|
91672fb9ed | ||
|
|
07684aea79 | ||
|
|
63c428fbf9 | ||
|
|
b77f2351d1 |
40
.github/workflows/build-docs.yml
vendored
40
.github/workflows/build-docs.yml
vendored
@@ -7,6 +7,10 @@ on:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -48,18 +52,20 @@ jobs:
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- uses: actions/cache@v4
|
||||
id: cache
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt', 'requirements-docs-insiders.txt', 'requirements-docs-tests.txt') }}-v08
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install docs extras
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-docs.txt
|
||||
run: uv pip install -r requirements-docs.txt
|
||||
# Install MkDocs Material Insiders here just to put it in the cache for the rest of the steps
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-docs-insiders.txt
|
||||
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
|
||||
run: uv pip install -r requirements-docs-insiders.txt
|
||||
env:
|
||||
TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
|
||||
- name: Verify Docs
|
||||
@@ -88,17 +94,19 @@ jobs:
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- uses: actions/cache@v4
|
||||
id: cache
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt', 'requirements-docs-insiders.txt', 'requirements-docs-tests.txt') }}-v08
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install docs extras
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-docs.txt
|
||||
run: uv pip install -r requirements-docs.txt
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-docs-insiders.txt
|
||||
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
|
||||
run: uv pip install -r requirements-docs-insiders.txt
|
||||
env:
|
||||
TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
|
||||
- name: Update Languages
|
||||
|
||||
18
.github/workflows/deploy-docs.yml
vendored
18
.github/workflows/deploy-docs.yml
vendored
@@ -12,6 +12,9 @@ permissions:
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
deploy-docs:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -25,21 +28,22 @@ jobs:
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- uses: actions/cache@v4
|
||||
id: cache
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-github-actions-${{ env.pythonLocation }}-${{ hashFiles('requirements-github-actions.txt') }}-v01
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install GitHub Actions dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-github-actions.txt
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
- name: Deploy Docs Status Pending
|
||||
run: python ./scripts/deploy_docs_status.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
RUN_ID: ${{ github.run_id }}
|
||||
|
||||
- name: Clean site
|
||||
run: |
|
||||
rm -rf ./site
|
||||
|
||||
4
.github/workflows/issue-manager.yml
vendored
4
.github/workflows/issue-manager.yml
vendored
@@ -39,5 +39,9 @@ jobs:
|
||||
"waiting": {
|
||||
"delay": 2628000,
|
||||
"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
|
||||
},
|
||||
"invalid": {
|
||||
"delay": 0,
|
||||
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
|
||||
}
|
||||
}
|
||||
|
||||
25
.github/workflows/label-approved.yml
vendored
25
.github/workflows/label-approved.yml
vendored
@@ -8,6 +8,9 @@ on:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
label-approved:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
@@ -17,10 +20,26 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: docker://tiangolo/label-approved:0.0.4
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
config: >
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install GitHub Actions dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
- name: Label Approved
|
||||
run: python ./scripts/label_approved.py
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CONFIG: >
|
||||
{
|
||||
"approved-1":
|
||||
{
|
||||
|
||||
16
.github/workflows/notify-translations.yml
vendored
16
.github/workflows/notify-translations.yml
vendored
@@ -18,6 +18,9 @@ on:
|
||||
permissions:
|
||||
discussions: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
notify-translations:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -27,6 +30,19 @@ jobs:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
|
||||
17
.github/workflows/smokeshow.yml
vendored
17
.github/workflows/smokeshow.yml
vendored
@@ -8,6 +8,9 @@ on:
|
||||
permissions:
|
||||
statuses: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
smokeshow:
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
@@ -18,19 +21,25 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- run: pip install smokeshow
|
||||
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- run: uv pip install -r requirements-github-actions.txt
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: coverage-html
|
||||
path: htmlcov
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
|
||||
- run: smokeshow upload htmlcov
|
||||
env:
|
||||
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
|
||||
|
||||
57
.github/workflows/test.yml
vendored
57
.github/workflows/test.yml
vendored
@@ -12,6 +12,9 @@ on:
|
||||
# cron every week on monday
|
||||
- cron: "0 0 * * 1"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -25,19 +28,18 @@ jobs:
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v4
|
||||
id: cache
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt', 'requirements-docs-tests.txt') }}-test-v08
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-tests.txt
|
||||
run: uv pip install -r requirements-tests.txt
|
||||
- name: Install Pydantic v2
|
||||
run: pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
||||
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
||||
- name: Lint
|
||||
run: bash scripts/lint.sh
|
||||
|
||||
@@ -63,23 +65,22 @@ jobs:
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v4
|
||||
id: cache
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt', 'requirements-docs-tests.txt') }}-test-v08
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-tests.txt
|
||||
run: uv pip install -r requirements-tests.txt
|
||||
- name: Install Pydantic v1
|
||||
if: matrix.pydantic-version == 'pydantic-v1'
|
||||
run: pip install "pydantic>=1.10.0,<2.0.0"
|
||||
run: uv pip install "pydantic>=1.10.0,<2.0.0"
|
||||
- name: Install Pydantic v2
|
||||
if: matrix.pydantic-version == 'pydantic-v2'
|
||||
run: pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
||||
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
||||
- run: mkdir coverage
|
||||
- name: Test
|
||||
run: bash scripts/test.sh
|
||||
@@ -105,16 +106,22 @@ jobs:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.8'
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-tests.txt
|
||||
- name: Get coverage files
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: coverage-*
|
||||
path: coverage
|
||||
merge-multiple: true
|
||||
- run: pip install coverage[toml]
|
||||
- run: ls -la coverage
|
||||
- run: coverage combine coverage
|
||||
- run: coverage report
|
||||
|
||||
@@ -95,7 +95,7 @@ The key features are:
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ FastAPI Python ilə API yaratmaq üçün standart Python <abbr title="Tip Məsl
|
||||
|
||||
"_Düzünü desəm, sizin qurduğunuz şey həqiqətən möhkəm və peşəkar görünür. Bir çox cəhətdən **Hug**-un olmasını istədiyim kimdir - kiminsə belə bir şey qurduğunu görmək həqiqətən ruhlandırıcıdır._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ FastAPI একটি আধুনিক, দ্রুত ( বেশি ক্
|
||||
|
||||
"\_সত্যিই, আপনি যা তৈরি করেছেন তা খুব মজবুত এবং পরিপূর্ন৷ অনেক উপায়ে, আমি যা **Hug** এ করতে চেয়েছিলাম - তা কাউকে তৈরি করতে দেখে আমি সত্যিই অনুপ্রানিত৷\_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">টিমোথি ক্রসলে - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> স্রষ্টা</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">টিমোথি ক্রসলে - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> স্রষ্টা</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ Das hat tatsächlich dazu geführt, dass Teile von Pydantic aktualisiert wurden,
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug war eines der ersten Frameworks, welches die Deklaration von API-Parametertypen mithilfe von Python-Typhinweisen implementierte. Das war eine großartige Idee, die andere Tools dazu inspirierte, dasselbe zu tun.
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ Seine Schlüssel-Merkmale sind:
|
||||
|
||||
„_Ehrlich, was Du gebaut hast, sieht super solide und poliert aus. In vielerlei Hinsicht ist es so, wie ich **Hug** haben wollte – es ist wirklich inspirierend, jemanden so etwas bauen zu sehen._“
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>Autor von <a href="https://www.hug.rest/" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(Ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>Autor von <a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(Ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ APISpec ✍ 🎏 🍭 👩💻.
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">🤗</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">🤗</a>
|
||||
|
||||
🤗 🕐 🥇 🛠️ 🛠️ 📄 🛠️ 🔢 🆎 ⚙️ 🐍 🆎 🔑. 👉 👑 💭 👈 😮 🎏 🧰 🎏.
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ FastAPI 🏛, ⏩ (↕-🎭), 🕸 🛠️ 🏗 🛠️ ⏮️ 🐍 3️⃣.8️
|
||||
|
||||
"_🤙, ⚫️❔ 👆 ✔️ 🏗 👀 💎 💠 & 🇵🇱. 📚 🌌, ⚫️ ⚫️❔ 👤 💚 **🤗** - ⚫️ 🤙 😍 👀 👱 🏗 👈._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">✡ 🗄 - <strong><a href="https://www.hug.rest/" target="_blank">🤗</a> 👼</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(🇦🇪)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">✡ 🗄 - <strong><a href="https://github.com/hugapi/hug" target="_blank">🤗</a> 👼</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(🇦🇪)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ members:
|
||||
- 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: estebanx64
|
||||
avatar_url: https://avatars.githubusercontent.com/u/10840422
|
||||
url: https://github.com/estebanx64
|
||||
|
||||
@@ -321,7 +321,7 @@ This actually inspired updating parts of Pydantic, to support the same validatio
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug was one of the first frameworks to implement the declaration of API parameter types using Python type hints. This was a great idea that inspired other tools to do the same.
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ The key features are:
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -7,6 +7,48 @@ hide:
|
||||
|
||||
## Latest Changes
|
||||
|
||||
## 0.115.3
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆️ Upgrade Starlette to `>=0.40.0,<0.42.0`. PR [#12469](https://github.com/fastapi/fastapi/pull/12469) by [@defnull](https://github.com/defnull).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Fix broken link in docs. PR [#12495](https://github.com/fastapi/fastapi/pull/12495) by [@eltonjncorreia](https://github.com/eltonjncorreia).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/fastapi-cli.md`. PR [#12444](https://github.com/fastapi/fastapi/pull/12444) by [@codingjenny](https://github.com/codingjenny).
|
||||
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/deployment/index.md`. PR [#12439](https://github.com/fastapi/fastapi/pull/12439) by [@codingjenny](https://github.com/codingjenny).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/testing-database.md`. PR [#12472](https://github.com/fastapi/fastapi/pull/12472) by [@GuilhermeRameh](https://github.com/GuilhermeRameh).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/custom-docs-ui-assets.md`. PR [#12473](https://github.com/fastapi/fastapi/pull/12473) by [@devluisrodrigues](https://github.com/devluisrodrigues).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/response-headers.md`. PR [#12458](https://github.com/fastapi/fastapi/pull/12458) by [@leonardopaloschi](https://github.com/leonardopaloschi).
|
||||
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/deployment/cloud.md`. PR [#12440](https://github.com/fastapi/fastapi/pull/12440) by [@codingjenny](https://github.com/codingjenny).
|
||||
* 🌐 Update Portuguese translation for `docs/pt/docs/python-types.md`. PR [#12428](https://github.com/fastapi/fastapi/pull/12428) by [@ceb10n](https://github.com/ceb10n).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/environment-variables.md`. PR [#12436](https://github.com/fastapi/fastapi/pull/12436) by [@wisderfin](https://github.com/wisderfin).
|
||||
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/resources/index.md`. PR [#12443](https://github.com/fastapi/fastapi/pull/12443) by [@codingjenny](https://github.com/codingjenny).
|
||||
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/about/index.md`. PR [#12438](https://github.com/fastapi/fastapi/pull/12438) by [@codingjenny](https://github.com/codingjenny).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/query-param-models.md`. PR [#12414](https://github.com/fastapi/fastapi/pull/12414) by [@ceb10n](https://github.com/ceb10n).
|
||||
* 🌐 Remove Portuguese translation for `docs/pt/docs/deployment.md`. PR [#12427](https://github.com/fastapi/fastapi/pull/12427) by [@ceb10n](https://github.com/ceb10n).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/body-updates.md`. PR [#12381](https://github.com/fastapi/fastapi/pull/12381) by [@andersonrocha0](https://github.com/andersonrocha0).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/response-cookies.md`. PR [#12417](https://github.com/fastapi/fastapi/pull/12417) by [@Paulofalcao2002](https://github.com/Paulofalcao2002).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👷 Update issue manager workflow . PR [#12457](https://github.com/fastapi/fastapi/pull/12457) by [@alejsdev](https://github.com/alejsdev).
|
||||
* 🔧 Update team, include YuriiMotov 🚀. PR [#12453](https://github.com/fastapi/fastapi/pull/12453) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Refactor label-approved, make it an internal script instead of an external GitHub Action. PR [#12280](https://github.com/fastapi/fastapi/pull/12280) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Fix smokeshow, checkout files on CI. PR [#12434](https://github.com/fastapi/fastapi/pull/12434) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Use uv in CI. PR [#12281](https://github.com/fastapi/fastapi/pull/12281) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Update httpx requirement from <0.25.0,>=0.23.0 to >=0.23.0,<0.28.0. PR [#11509](https://github.com/fastapi/fastapi/pull/11509) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
|
||||
## 0.115.2
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆️ Upgrade Starlette to `>=0.37.2,<0.41.0`. PR [#12431](https://github.com/fastapi/fastapi/pull/12431) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.115.1
|
||||
|
||||
### Fixes
|
||||
|
||||
@@ -90,7 +90,7 @@ Sus características principales son:
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ FastAPI یک وب فریمورک مدرن و سریع (با کارایی با
|
||||
|
||||
<div style="text-align: left; direction: ltr;">"<em>Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted <strong>Hug</strong> to be - it's really inspiring to see someone build that."</em></div>
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ Cela a en fait inspiré la mise à jour de certaines parties de Pydantic, afin d
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug a été l'un des premiers frameworks à implémenter la déclaration des types de paramètres d'API en utilisant les type hints Python. C'était une excellente idée qui a inspiré d'autres outils à faire de même.
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Les principales fonctionnalités sont :
|
||||
|
||||
"_Honnêtement, ce que vous avez construit a l'air super solide et élégant. A bien des égards, c'est comme ça que je voulais que **Hug** soit - c'est vraiment inspirant de voir quelqu'un construire ça._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong> Créateur de <a href="https://www.hug.rest/" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong> Créateur de <a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ FastAPI היא תשתית רשת מודרנית ומהירה (ביצועים ג
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ Kulcs funkciók:
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ Le sue caratteristiche principali sono:
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ FastAPI は、Pythonの標準である型ヒントに基づいてPython 以降
|
||||
|
||||
"_正直、超堅実で洗練されているように見えます。いろんな意味で、それは私がハグしたかったものです。_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ De belangrijkste kenmerken zijn:
|
||||
|
||||
"_Wat je hebt gebouwd ziet er echt super solide en gepolijst uit. In veel opzichten is het wat ik wilde dat **Hug** kon zijn - het is echt inspirerend om iemand dit te zien bouwen._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ Kluczowe cechy:
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
55
docs/pt/docs/advanced/response-cookies.md
Normal file
55
docs/pt/docs/advanced/response-cookies.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Cookies de Resposta
|
||||
|
||||
## Usando um parâmetro `Response`
|
||||
|
||||
Você pode declarar um parâmetro do tipo `Response` na sua *função de operação de rota*.
|
||||
|
||||
E então você pode definir cookies nesse objeto de resposta *temporário*.
|
||||
|
||||
```Python hl_lines="1 8-9"
|
||||
{!../../docs_src/response_cookies/tutorial002.py!}
|
||||
```
|
||||
|
||||
Em seguida, você pode retornar qualquer objeto que precise, como normalmente faria (um `dict`, um modelo de banco de dados, etc).
|
||||
|
||||
E se você declarou um `response_model`, ele ainda será usado para filtrar e converter o objeto que você retornou.
|
||||
|
||||
**FastAPI** usará essa resposta *temporária* para extrair os cookies (também os cabeçalhos e código de status) e os colocará na resposta final que contém o valor que você retornou, filtrado por qualquer `response_model`.
|
||||
|
||||
Você também pode declarar o parâmetro `Response` em dependências e definir cookies (e cabeçalhos) nelas.
|
||||
|
||||
## Retornando uma `Response` diretamente
|
||||
|
||||
Você também pode criar cookies ao retornar uma `Response` diretamente no seu código.
|
||||
|
||||
Para fazer isso, você pode criar uma resposta como descrito em [Retornando uma Resposta Diretamente](response-directly.md){.internal-link target=_blank}.
|
||||
|
||||
Então, defina os cookies nela e a retorne:
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!../../docs_src/response_cookies/tutorial001.py!}
|
||||
```
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Lembre-se de que se você retornar uma resposta diretamente em vez de usar o parâmetro `Response`, FastAPI a retornará diretamente.
|
||||
|
||||
Portanto, você terá que garantir que seus dados sejam do tipo correto. E.g. será compatível com JSON se você estiver retornando um `JSONResponse`.
|
||||
|
||||
E também que você não esteja enviando nenhum dado que deveria ter sido filtrado por um `response_model`.
|
||||
|
||||
///
|
||||
|
||||
### Mais informações
|
||||
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
Você também poderia usar `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** fornece as mesmas `starlette.responses` em `fastapi.responses` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
|
||||
|
||||
E como o `Response` pode ser usado frequentemente para definir cabeçalhos e cookies, o **FastAPI** também o fornece em `fastapi.Response`.
|
||||
|
||||
///
|
||||
|
||||
Para ver todos os parâmetros e opções disponíveis, verifique a <a href="https://www.starlette.io/responses/#set-cookie" class="external-link" target="_blank">documentação no Starlette</a>.
|
||||
45
docs/pt/docs/advanced/response-headers.md
Normal file
45
docs/pt/docs/advanced/response-headers.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Cabeçalhos de resposta
|
||||
|
||||
## Usando um parâmetro `Response`
|
||||
|
||||
Você pode declarar um parâmetro do tipo `Response` na sua *função de operação de rota* (assim como você pode fazer para cookies).
|
||||
|
||||
Então você pode definir os cabeçalhos nesse objeto de resposta *temporário*.
|
||||
|
||||
```Python hl_lines="1 7-8"
|
||||
{!../../docs_src/response_headers/tutorial002.py!}
|
||||
```
|
||||
|
||||
Em seguida você pode retornar qualquer objeto que precisar, da maneira que faria normalmente (um `dict`, um modelo de banco de dados, etc.).
|
||||
|
||||
Se você declarou um `response_model`, ele ainda será utilizado para filtrar e converter o objeto que você retornou.
|
||||
|
||||
**FastAPI** usará essa resposta *temporária* para extrair os cabeçalhos (cookies e código de status também) e os colocará na resposta final que contém o valor que você retornou, filtrado por qualquer `response_model`.
|
||||
|
||||
Você também pode declarar o parâmetro `Response` em dependências e definir cabeçalhos (e cookies) nelas.
|
||||
|
||||
## Retornar uma `Response` diretamente
|
||||
|
||||
Você também pode adicionar cabeçalhos quando retornar uma `Response` diretamente.
|
||||
|
||||
Crie uma resposta conforme descrito em [Retornar uma resposta diretamente](response-directly.md){.internal-link target=_blank} e passe os cabeçalhos como um parâmetro adicional:
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!../../docs_src/response_headers/tutorial001.py!}
|
||||
```
|
||||
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
Você também pode usar `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** fornece as mesmas `starlette.responses` como `fastapi.responses` apenas como uma conveniência para você, desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
|
||||
|
||||
E como a `Response` pode ser usada frequentemente para definir cabeçalhos e cookies, **FastAPI** também a fornece em `fastapi.Response`.
|
||||
|
||||
///
|
||||
|
||||
## Cabeçalhos personalizados
|
||||
|
||||
Tenha em mente que cabeçalhos personalizados proprietários podem ser adicionados <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando o prefixo 'X-'</a>.
|
||||
|
||||
Porém, se voce tiver cabeçalhos personalizados que deseja que um cliente no navegador possa ver, você precisa adicioná-los às suas configurações de CORS (saiba mais em [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando o parâmetro `expose_headers` descrito na <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">documentação de CORS do Starlette</a>.
|
||||
@@ -323,7 +323,7 @@ Isso na verdade inspirou a atualização de partes do Pydantic, para dar suporte
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug foi um dos primeiros frameworks a implementar a declaração de tipos de parâmetros usando Python _type hints_. Isso foi uma ótima idéia que inspirou outras ferramentas a fazer o mesmo.
|
||||
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
# Implantação
|
||||
|
||||
Implantar uma aplicação **FastAPI** é relativamente fácil.
|
||||
|
||||
Existem vários modos de realizar o _deploy_ dependendo de seu caso de uso específico e as ferramentas que você utiliza.
|
||||
|
||||
Você verá mais sobre alguns modos de fazer o _deploy_ nas próximas seções.
|
||||
|
||||
## Versões do FastAPI
|
||||
|
||||
**FastAPI** já está sendo utilizado em produção em muitas aplicações e sistemas. E a cobertura de teste é mantida a 100%. Mas seu desenvolvimento continua andando rapidamente.
|
||||
|
||||
Novos recursos são adicionados frequentemente, _bugs_ são corrigidos regularmente, e o código está continuamente melhorando.
|
||||
|
||||
É por isso que as versões atuais estão ainda no `0.x.x`, isso reflete que cada versão poderia ter potencialmente alterações que podem quebrar. Isso segue as convenções de <a href="https://semver.org/" class="external-link" target="_blank">Versionamento Semântico</a>.
|
||||
|
||||
Você pode criar aplicações para produção com **FastAPI** bem agora (e você provavelmente já faça isso por um tempo), você tem que ter certeza de utilizar uma versão que funcione corretamente com o resto do seu código.
|
||||
|
||||
### Anote sua versão `fastapi`
|
||||
|
||||
A primeira coisa que você deve fazer é "fixar" a versão do **FastAPI** que está utilizando para a última versão específica que você sabe que funciona corretamente para a sua aplicação.
|
||||
|
||||
Por exemplo, vamos dizer que você esteja utilizando a versão `0.45.0` no seu _app_.
|
||||
|
||||
Se você usa um arquivo `requirements.txt`, dá para especificar a versão assim:
|
||||
|
||||
```txt
|
||||
fastapi==0.45.0
|
||||
```
|
||||
|
||||
isso significa que você pode usar exatamente a versão `0.45.0`.
|
||||
|
||||
Ou você poderia fixar assim:
|
||||
|
||||
```txt
|
||||
fastapi>=0.45.0,<0.46.0
|
||||
```
|
||||
|
||||
o que significa que você pode usar as versões `0.45.0` ou acima, mas menor que `0.46.0`. Por exemplo, a versão `0.45.2` poderia ser aceita.
|
||||
|
||||
Se você usa qualquer outra ferramenta para gerenciar suas instalações, como Poetry, Pipenv ou outro, todos terão um modo que você possa usar para definir versões específicas para seus pacotes.
|
||||
|
||||
### Versões disponíveis
|
||||
|
||||
Você pode ver as versões disponíveis (por exemplo, para verificar qual é a versão atual) nas [Notas de Lançamento](release-notes.md){.internal-link target=_blank}.
|
||||
|
||||
### Sobre as versões
|
||||
|
||||
Seguindo as convenções do Versionamento Semântico, qualquer versão abaixo de `1.0.0` pode potencialmente adicionar mudanças que quebrem.
|
||||
|
||||
FastAPI também segue a convenção que qualquer versão de _"PATCH"_ seja para ajustes de _bugs_ e mudanças que não quebrem a aplicação.
|
||||
|
||||
/// tip
|
||||
|
||||
O _"PATCH"_ é o último número, por exemplo, em `0.2.3`, a versão do _PATCH_ é `3`.
|
||||
|
||||
///
|
||||
|
||||
Então, você poderia ser capaz de fixar para uma versão como:
|
||||
|
||||
```txt
|
||||
fastapi>=0.45.0,<0.46.0
|
||||
```
|
||||
|
||||
Mudanças que quebram e novos recursos são adicionados em versões _"MINOR"_.
|
||||
|
||||
/// tip
|
||||
|
||||
O _"MINOR"_ é o número do meio, por exemplo, em `0.2.3`, a versão _MINOR_ é `2`.
|
||||
|
||||
///
|
||||
|
||||
### Atualizando as versões FastAPI
|
||||
|
||||
Você pode adicionar testes em sua aplicação.
|
||||
|
||||
Com o **FastAPI** é muito fácil (graças ao Starlette), verifique a documentação: [Testando](tutorial/testing.md){.internal-link target=_blank}
|
||||
|
||||
Após você ter os testes, então você pode fazer o _upgrade_ da versão **FastAPI** para uma mais recente, e ter certeza que todo seu código esteja funcionando corretamente rodando seus testes.
|
||||
|
||||
Se tudo estiver funcionando, ou após você fazer as alterações necessárias, e todos seus testes estiverem passando, então você poderá fixar o `fastapi` para a versão mais recente.
|
||||
|
||||
### Sobre Starlette
|
||||
|
||||
Você não deve fixar a versão do `starlette`.
|
||||
|
||||
Versões diferentes do **FastAPI** irão utilizar uma versão mais nova específica do Starlette.
|
||||
|
||||
Então, você pode deixar que o **FastAPI** use a versão correta do Starlette.
|
||||
|
||||
### Sobre Pydantic
|
||||
|
||||
Pydantic inclui os testes para **FastAPI** em seus próprios testes, então novas versões do Pydantic (acima de `1.0.0`) são sempre compatíveis com FastAPI.
|
||||
|
||||
Você pode fixar o Pydantic para qualquer versão acima de `1.0.0` e abaixo de `2.0.0` que funcionará.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
```txt
|
||||
pydantic>=1.2.0,<2.0.0
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
Nessa seção você verá instruções e _links_ para guias de saber como:
|
||||
|
||||
* Fazer uma imagem/container da sua aplicação **FastAPI** com máxima performance. Em aproximadamente **5 min**.
|
||||
* (Opcionalmente) entender o que você, como desenvolvedor, precisa saber sobre HTTPS.
|
||||
* Inicializar um _cluster_ Docker Swarm Mode com HTTPS automático, mesmo em um simples servidor de $5 dólares/mês. Em aproximadamente **20 min**.
|
||||
* Gere e implante uma aplicação **FastAPI** completa, usando seu _cluster_ Docker Swarm, com HTTPS etc. Em aproxiamadamente **10 min**.
|
||||
|
||||
Você pode usar <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a> para implantação. Ele tem várias vantagens como segurança, replicabilidade, desenvolvimento simplificado etc.
|
||||
|
||||
Se você está usando Docker, você pode utilizar a imagem Docker oficial:
|
||||
|
||||
### <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
|
||||
|
||||
Essa imagem tem um mecanismo incluído de "auto-ajuste", para que você possa apenas adicionar seu código e ter uma alta performance automaticamente. E sem fazer sacrifícios.
|
||||
|
||||
Mas você pode ainda mudar e atualizar todas as configurações com variáveis de ambiente ou arquivos de configuração.
|
||||
|
||||
/// tip
|
||||
|
||||
Para ver todas as configurações e opções, vá para a página da imagem do Docker: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
|
||||
|
||||
///
|
||||
|
||||
### Crie um `Dockerfile`
|
||||
|
||||
* Vá para o diretório de seu projeto.
|
||||
* Crie um `Dockerfile` com:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
|
||||
COPY ./app /app
|
||||
```
|
||||
|
||||
#### Grandes aplicações
|
||||
|
||||
Se você seguiu a seção sobre criação de [Grandes Aplicações com Múltiplos Arquivos](tutorial/bigger-applications.md){.internal-link target=_blank}, seu `Dockerfile` poderia parecer como:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
|
||||
COPY ./app /app/app
|
||||
```
|
||||
|
||||
#### Raspberry Pi e outras arquiteturas
|
||||
|
||||
Se você estiver rodando Docker em um Raspberry Pi (que possui um processador ARM) ou qualquer outra arquitetura, você pode criar um `Dockerfile` do zero, baseado em uma imagem base Python (que é multi-arquitetural) e utilizar Uvicorn sozinho.
|
||||
|
||||
Nesse caso, seu `Dockerfile` poderia parecer assim:
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install fastapi uvicorn
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
### Crie o código **FastAPI**
|
||||
|
||||
* Crie um diretório `app` e entre nele.
|
||||
* Crie um arquivo `main.py` com:
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: str = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
* Você deve ter uma estrutura de diretórios assim:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ └── main.py
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
### Construa a imagem Docker
|
||||
|
||||
* Vá para o diretório do projeto (onde seu `Dockerfile` está, contendo seu diretório `app`.
|
||||
* Construa sua imagem FastAPI:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ docker build -t myimage .
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Inicie o container Docker
|
||||
|
||||
* Rode um container baseado em sua imagem:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ docker run -d --name mycontainer -p 80:80 myimage
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Agora você tem um servidor FastAPI otimizado em um container Docker. Auto-ajustado para seu servidor atual (e número de núcleos de CPU).
|
||||
|
||||
### Verifique
|
||||
|
||||
Você deve ser capaz de verificar na URL de seu container Docker, por exemplo: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> ou <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (ou equivalente, usando seu _host_ Docker).
|
||||
|
||||
Você verá algo como:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
### API interativa de documetação
|
||||
|
||||
Agora você pode ir para <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> ou <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (ou equivalente, usando seu _host_ Docker).
|
||||
|
||||
Você verá a API interativa de documentação (fornecida por <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### APIs alternativas de documentação
|
||||
|
||||
E você pode também ir para <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> ou <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (ou equivalente, usando seu _host_ Docker).
|
||||
|
||||
Você verá a documentação automática alternativa (fornecida por <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## HTTPS
|
||||
|
||||
### Sobre HTTPS
|
||||
|
||||
É fácil assumir que HTTPS seja algo que esteja apenas "habilitado" ou não.
|
||||
|
||||
Mas ele é um pouquinho mais complexo do que isso.
|
||||
|
||||
/// tip
|
||||
|
||||
Se você está com pressa ou não se importa, continue na próxima seção com instruções passo a passo para configurar tudo.
|
||||
|
||||
///
|
||||
|
||||
Para aprender o básico de HTTPS, pela perspectiva de um consumidor, verifique <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
|
||||
|
||||
Agora, pela perspectiva de um desenvolvedor, aqui estão algumas coisas para se ter em mente enquanto se pensa sobre HTTPS:
|
||||
|
||||
* Para HTTPS, o servidor precisa ter "certificados" gerados por terceiros.
|
||||
* Esses certificados são na verdade adquiridos por terceiros, não "gerados".
|
||||
* Certificados tem um prazo de uso.
|
||||
* Eles expiram.
|
||||
* E então eles precisam ser renovados, adquiridos novamente por terceiros.
|
||||
* A encriptação da conexão acontece no nível TCP.
|
||||
* TCP é uma camada abaixo do HTTP.
|
||||
* Então, o controle de certificado e encriptação é feito antes do HTTP.
|
||||
* TCP não conhece nada sobre "domínios". Somente sobre endereços IP.
|
||||
* A informação sobre o domínio requisitado vai nos dados HTTP.
|
||||
* Os certificados HTTPS "certificam" um certo domínio, mas o protocolo e a encriptação acontecem no nível TCP, antes de saber qual domínio está sendo lidado.
|
||||
* Por padrão, isso significa que você pode ter somente um certificado HTTPS por endereço IP.
|
||||
* Não importa quão grande é seu servidor ou quão pequena cada aplicação que você tenha possar ser.
|
||||
* No entanto, existe uma solução para isso.
|
||||
* Existe uma extensão para o protocolo TLS (o que controla a encriptação no nível TCP, antes do HTTP) chamada <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>.
|
||||
* Essa extensão SNI permite um único servidor (com um único endereço IP) a ter vários certificados HTTPS e servir múltiplas aplicações/domínios HTTPS.
|
||||
* Para que isso funcione, um único componente (programa) rodando no servidor, ouvindo no endereço IP público, deve ter todos os certificados HTTPS no servidor.
|
||||
* Após obter uma conexão segura, o protocolo de comunicação ainda é HTTP.
|
||||
* O conteúdo está encriptado, mesmo embora ele esteja sendo enviado com o protocolo HTTP.
|
||||
|
||||
É uma prática comum ter um servidor HTTP/programa rodando no servidor (a máquina, _host_ etc.) e gerenciar todas as partes HTTP: enviar as requisições HTTP decriptadas para a aplicação HTTP rodando no mesmo servidor (a aplicação **FastAPI**, nesse caso), pega a resposta HTTP da aplicação, encripta utilizando o certificado apropriado e enviando de volta para o cliente usando HTTPS. Esse servidor é frequentemente chamado <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS _Termination Proxy_</a>.
|
||||
|
||||
### Vamos encriptar
|
||||
|
||||
Antes de encriptar, esses certificados HTTPS foram vendidos por terceiros de confiança.
|
||||
|
||||
O processo para adquirir um desses certificados costumava ser chato, exigia muita papelada e eram bem caros.
|
||||
|
||||
Mas então <a href="https://letsencrypt.org/" class="external-link" target="_blank">_Let's Encrypt_</a> foi criado.
|
||||
|
||||
É um projeto da Fundação Linux.Ele fornece certificados HTTPS de graça. De um jeito automatizado. Esses certificados utilizam todos os padrões de segurança criptográfica, e tem vida curta (cerca de 3 meses), para que a segurança seja melhor devido ao seu curto período de vida.
|
||||
|
||||
Os domínios são seguramente verificados e os certificados são gerados automaticamente. Isso também permite automatizar a renovação desses certificados.
|
||||
|
||||
A idéia é automatizar a aquisição e renovação desses certificados, para que você possa ter um HTTPS seguro, grátis, para sempre.
|
||||
|
||||
### Traefik
|
||||
|
||||
<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a> é um _proxy_ reverso / _load balancer_ de alta performance. Ele pode fazer o trabalho do _"TLS Termination Proxy"_ (à parte de outros recursos).
|
||||
|
||||
Ele tem integração com _Let's Encrypt_. Assim, ele pode controlar todas as partes HTTPS, incluindo a aquisição e renovação de certificados.
|
||||
|
||||
Ele também tem integrações com Docker. Assim, você pode declarar seus domínios em cada configuração de aplicação e leitura dessas configurações, gerando os certificados HTTPS e servindo o HTTPS para sua aplicação automaticamente, sem exigir qualquer mudança em sua configuração.
|
||||
|
||||
---
|
||||
|
||||
Com essas ferramentas e informações, continue com a próxima seção para combinar tudo.
|
||||
|
||||
## _Cluster_ de Docker Swarm Mode com Traefik e HTTPS
|
||||
|
||||
Você pode ter um _cluster_ de Docker Swarm Mode configurado em minutos (cerca de 20) com o Traefik controlando HTTPS (incluindo aquisição e renovação de certificados).
|
||||
|
||||
Utilizando o Docker Swarm Mode, você pode iniciar com um _"cluster"_ de apenas uma máquina (que pode até ser um servidor por 5 dólares / mês) e então você pode aumentar conforme a necessidade adicionando mais servidores.
|
||||
|
||||
Para configurar um _cluster_ Docker Swarm Mode com Traefik controlando HTTPS, siga essa orientação:
|
||||
|
||||
### <a href="https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232" class="external-link" target="_blank">Docker Swarm Mode and Traefik for an HTTPS cluster</a>
|
||||
|
||||
### Faça o _deploy_ de uma aplicação FastAPI
|
||||
|
||||
O jeito mais fácil de configurar tudo pode ser utilizando o [Gerador de Projetos **FastAPI**](project-generation.md){.internal-link target=_blank}.
|
||||
|
||||
Ele é designado para ser integrado com esse _cluster_ Docker Swarm com Traefik e HTTPS descrito acima.
|
||||
|
||||
Você pode gerar um projeto em cerca de 2 minutos.
|
||||
|
||||
O projeto gerado tem instruções para fazer o _deploy_, fazendo isso leva outros 2 minutos.
|
||||
|
||||
## Alternativamente, faça o _deploy_ **FastAPI** sem Docker
|
||||
|
||||
Você pode fazer o _deploy_ do **FastAPI** diretamente sem o Docker também.
|
||||
|
||||
Você apenas precisa instalar um servidor ASGI compatível como:
|
||||
|
||||
//// tab | Uvicorn
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, um servidor ASGI peso leve, construído sobre uvloop e httptools.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Hypercorn
|
||||
|
||||
* <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, um servidor ASGI também compatível com HTTP/2.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install hypercorn
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
...ou qualquer outro servidor ASGI.
|
||||
|
||||
////
|
||||
|
||||
E rode sua applicação do mesmo modo que você tem feito nos tutoriais, mas sem a opção `--reload`, por exemplo:
|
||||
|
||||
//// tab | Uvicorn
|
||||
|
||||
<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>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Hypercorn
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ hypercorn main:app --bind 0.0.0.0:80
|
||||
|
||||
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
Você deve querer configurar mais algumas ferramentas para ter certeza que ele seja reinicializado automaticamante se ele parar.
|
||||
|
||||
Você também deve querer instalar <a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a> e <a href="https://www.uvicorn.org/#running-with-gunicorn" class="external-link" target="_blank">utilizar ele como um gerenciador para o Uvicorn</a>, ou usar Hypercorn com múltiplos _workers_.
|
||||
|
||||
Tenha certeza de ajustar o número de _workers_ etc.
|
||||
|
||||
Mas se você estiver fazendo tudo isso, você pode apenas usar uma imagem Docker que fará isso automaticamente.
|
||||
205
docs/pt/docs/how-to/custom-docs-ui-assets.md
Normal file
205
docs/pt/docs/how-to/custom-docs-ui-assets.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# Recursos Estáticos Personalizados para a UI de Documentação (Hospedagem Própria)
|
||||
|
||||
A documentação da API usa **Swagger UI** e **ReDoc**, e cada um deles precisa de alguns arquivos JavaScript e CSS.
|
||||
|
||||
Por padrão, esses arquivos são fornecidos por um <abbr title="Content Delivery Network: Um serviço, normalmente composto por vários servidores, que fornece arquivos estáticos, como JavaScript e CSS. É comumente usado para providenciar esses arquivos do servidor mais próximo do cliente, melhorando o desempenho.">CDN</abbr>.
|
||||
|
||||
Mas é possível personalizá-los, você pode definir um CDN específico ou providenciar os arquivos você mesmo.
|
||||
|
||||
## CDN Personalizado para JavaScript e CSS
|
||||
|
||||
Vamos supor que você deseja usar um <abbr title="Content Delivery Network">CDN</abbr> diferente, por exemplo, você deseja usar `https://unpkg.com/`.
|
||||
|
||||
Isso pode ser útil se, por exemplo, você mora em um país que restringe algumas URLs.
|
||||
|
||||
### Desativar a documentação automática
|
||||
|
||||
O primeiro passo é desativar a documentação automática, pois por padrão, ela usa o CDN padrão.
|
||||
|
||||
Para desativá-los, defina suas URLs como `None` ao criar seu aplicativo `FastAPI`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../docs_src/custom_docs_ui/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Incluir a documentação personalizada
|
||||
|
||||
Agora você pode criar as *operações de rota* para a documentação personalizada.
|
||||
|
||||
Você pode reutilizar as funções internas do FastAPI para criar as páginas HTML para a documentação e passar os argumentos necessários:
|
||||
|
||||
* `openapi_url`: a URL onde a página HTML para a documentação pode obter o esquema OpenAPI para a sua API. Você pode usar aqui o atributo `app.openapi_url`.
|
||||
* `title`: o título da sua API.
|
||||
* `oauth2_redirect_url`: você pode usar `app.swagger_ui_oauth2_redirect_url` aqui para usar o padrão.
|
||||
* `swagger_js_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **JavaScript**. Este é o URL do CDN personalizado.
|
||||
* `swagger_css_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **CSS**. Este é o URL do CDN personalizado.
|
||||
|
||||
E de forma semelhante para o ReDoc...
|
||||
|
||||
```Python hl_lines="2-6 11-19 22-24 27-33"
|
||||
{!../../docs_src/custom_docs_ui/tutorial001.py!}
|
||||
```
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
A *operação de rota* para `swagger_ui_redirect` é um auxiliar para quando você usa OAuth2.
|
||||
|
||||
Se você integrar sua API com um provedor OAuth2, você poderá autenticar e voltar para a documentação da API com as credenciais adquiridas. E interagir com ela usando a autenticação OAuth2 real.
|
||||
|
||||
Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse auxiliar de "redirecionamento".
|
||||
|
||||
///
|
||||
|
||||
### Criar uma *operação de rota* para testar
|
||||
|
||||
Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
|
||||
|
||||
```Python hl_lines="36-38"
|
||||
{!../../docs_src/custom_docs_ui/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Teste
|
||||
|
||||
Agora, você deve ser capaz de ir para a documentação em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, e recarregar a página, ela carregará esses recursos do novo CDN.
|
||||
|
||||
## Hospedagem Própria de JavaScript e CSS para a documentação
|
||||
|
||||
Hospedar o JavaScript e o CSS pode ser útil se, por exemplo, você precisa que seu aplicativo continue funcionando mesmo offline, sem acesso aberto à Internet, ou em uma rede local.
|
||||
|
||||
Aqui você verá como providenciar esses arquivos você mesmo, no mesmo aplicativo FastAPI, e configurar a documentação para usá-los.
|
||||
|
||||
### Estrutura de Arquivos do Projeto
|
||||
|
||||
Vamos supor que a estrutura de arquivos do seu projeto se pareça com isso:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
```
|
||||
|
||||
Agora crie um diretório para armazenar esses arquivos estáticos.
|
||||
|
||||
Sua nova estrutura de arquivos poderia se parecer com isso:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
└── static/
|
||||
```
|
||||
|
||||
### Baixe os arquivos
|
||||
|
||||
Baixe os arquivos estáticos necessários para a documentação e coloque-os no diretório `static/`.
|
||||
|
||||
Você provavelmente pode clicar com o botão direito em cada link e selecionar uma opção semelhante a `Salvar link como...`.
|
||||
|
||||
**Swagger UI** usa os arquivos:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
|
||||
|
||||
E o **ReDoc** usa os arquivos:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
|
||||
|
||||
Depois disso, sua estrutura de arquivos deve se parecer com:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
└── static
|
||||
├── redoc.standalone.js
|
||||
├── swagger-ui-bundle.js
|
||||
└── swagger-ui.css
|
||||
```
|
||||
|
||||
### Prover os arquivos estáticos
|
||||
|
||||
* Importe `StaticFiles`.
|
||||
* "Monte" a instância `StaticFiles()` em um caminho específico.
|
||||
|
||||
```Python hl_lines="7 11"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
|
||||
### Teste os arquivos estáticos
|
||||
|
||||
Inicialize seu aplicativo e vá para <a href="http://127.0.0.1:8000/static/redoc.standalone.js" class="external-link" target="_blank">http://127.0.0.1:8000/static/redoc.standalone.js</a>.
|
||||
|
||||
Você deverá ver um arquivo JavaScript muito longo para o **ReDoc**.
|
||||
|
||||
Esse arquivo pode começar com algo como:
|
||||
|
||||
```JavaScript
|
||||
/*!
|
||||
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation
|
||||
* -------------------------------------------------------------
|
||||
* Version: "2.0.0-rc.18"
|
||||
* Repo: https://github.com/Redocly/redoc
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof m
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Isso confirma que você está conseguindo fornecer arquivos estáticos do seu aplicativo e que você colocou os arquivos estáticos para a documentação no local correto.
|
||||
|
||||
Agora, podemos configurar o aplicativo para usar esses arquivos estáticos para a documentação.
|
||||
|
||||
### Desativar a documentação automática para arquivos estáticos
|
||||
|
||||
Da mesma forma que ao usar um CDN personalizado, o primeiro passo é desativar a documentação automática, pois ela usa o CDN padrão.
|
||||
|
||||
Para desativá-los, defina suas URLs como `None` ao criar seu aplicativo `FastAPI`:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
|
||||
### Incluir a documentação personalizada para arquivos estáticos
|
||||
|
||||
E da mesma forma que com um CDN personalizado, agora você pode criar as *operações de rota* para a documentação personalizada.
|
||||
|
||||
Novamente, você pode reutilizar as funções internas do FastAPI para criar as páginas HTML para a documentação e passar os argumentos necessários:
|
||||
|
||||
* `openapi_url`: a URL onde a página HTML para a documentação pode obter o esquema OpenAPI para a sua API. Você pode usar aqui o atributo `app.openapi_url`.
|
||||
* `title`: o título da sua API.
|
||||
* `oauth2_redirect_url`: Você pode usar `app.swagger_ui_oauth2_redirect_url` aqui para usar o padrão.
|
||||
* `swagger_js_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **JavaScript**. Este é o URL do CDN personalizado. **Este é o URL que seu aplicativo está fornecendo**.
|
||||
* `swagger_css_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **CSS**. **Esse é o que seu aplicativo está fornecendo**.
|
||||
|
||||
E de forma semelhante para o ReDoc...
|
||||
|
||||
```Python hl_lines="2-6 14-22 25-27 30-36"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
A *operação de rota* para `swagger_ui_redirect` é um auxiliar para quando você usa OAuth2.
|
||||
|
||||
Se você integrar sua API com um provedor OAuth2, você poderá autenticar e voltar para a documentação da API com as credenciais adquiridas. E, então, interagir com ela usando a autenticação OAuth2 real.
|
||||
|
||||
Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse auxiliar de "redirect".
|
||||
|
||||
///
|
||||
|
||||
### Criar uma *operação de rota* para testar arquivos estáticos
|
||||
|
||||
Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
|
||||
|
||||
```Python hl_lines="39-41"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
|
||||
### Teste a UI de Arquivos Estáticos
|
||||
|
||||
Agora, você deve ser capaz de desconectar o WiFi, ir para a documentação em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, e recarregar a página.
|
||||
|
||||
E mesmo sem Internet, você será capaz de ver a documentação da sua API e interagir com ela.
|
||||
7
docs/pt/docs/how-to/testing-database.md
Normal file
7
docs/pt/docs/how-to/testing-database.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Testando a Base de Dados
|
||||
|
||||
Você pode estudar sobre bases de dados, SQL e SQLModel na <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">documentação de SQLModel</a>. 🤓
|
||||
|
||||
Aqui tem um mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial de como usar SQLModel com FastAPI</a>. ✨
|
||||
|
||||
Esse tutorial inclui uma sessão sobre <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/" class="external-link" target="_blank">testar bases de dados SQL</a>. 😎
|
||||
@@ -78,7 +78,7 @@ Os recursos chave são:
|
||||
|
||||
"*Honestamente, o que você construiu parece super sólido e rebuscado. De muitas formas, eu queria que o **Hug** fosse assim - é realmente inspirador ver alguém que construiu ele.*"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>criador do<a href="https://www.hug.rest/" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>criador do<a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# Introdução aos tipos Python
|
||||
|
||||
**Python 3.6 +** tem suporte para "type hints" opcionais.
|
||||
O Python possui suporte para "dicas de tipo" ou "type hints" (também chamado de "anotações de tipo" ou "type annotations")
|
||||
|
||||
Esses **"type hints"** são uma nova sintaxe (desde Python 3.6+) que permite declarar o <abbr title = "por exemplo: str, int, float, bool"> tipo </abbr> de uma variável.
|
||||
Esses **"type hints"** são uma sintaxe especial que permite declarar o <abbr title = "por exemplo: str, int, float, bool">tipo</abbr> de uma variável.
|
||||
|
||||
Ao declarar tipos para suas variáveis, editores e ferramentas podem oferecer um melhor suporte.
|
||||
|
||||
Este é apenas um **tutorial rápido / atualização** sobre type hints Python. Ele cobre apenas o mínimo necessário para usá-los com o **FastAPI** ... que é realmente muito pouco.
|
||||
Este é apenas um **tutorial rápido / atualização** sobre type hints do Python. Ele cobre apenas o mínimo necessário para usá-los com o **FastAPI**... que é realmente muito pouco.
|
||||
|
||||
O **FastAPI** é baseado nesses type hints, eles oferecem muitas vantagens e benefícios.
|
||||
|
||||
Mas mesmo que você nunca use o **FastAPI**, você se beneficiaria de aprender um pouco sobre eles.
|
||||
|
||||
/// note | "Nota"
|
||||
/// note | Nota
|
||||
|
||||
Se você é um especialista em Python e já sabe tudo sobre type hints, pule para o próximo capítulo.
|
||||
|
||||
@@ -35,8 +35,8 @@ John Doe
|
||||
A função faz o seguinte:
|
||||
|
||||
* Pega um `first_name` e `last_name`.
|
||||
* Converte a primeira letra de cada uma em maiúsculas com `title ()`.
|
||||
* <abbr title = "Agrupa-os, como um. Com o conteúdo de um após o outro."> Concatena </abbr> com um espaço no meio.
|
||||
* Converte a primeira letra de cada uma em maiúsculas com `title()`.
|
||||
* <abbr title = "Agrupa-os, como um. Com o conteúdo de um após o outro.">Concatena</abbr> com um espaço no meio.
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!../../docs_src/python_types/tutorial001.py!}
|
||||
@@ -48,7 +48,7 @@ A função faz o seguinte:
|
||||
|
||||
Mas agora imagine que você estava escrevendo do zero.
|
||||
|
||||
Em algum momento você teria iniciado a definição da função, já tinha os parâmetros prontos ...
|
||||
Em algum momento você teria iniciado a definição da função, já tinha os parâmetros prontos...
|
||||
|
||||
Mas então você deve chamar "esse método que converte a primeira letra em maiúscula".
|
||||
|
||||
@@ -96,37 +96,37 @@ Isso não é o mesmo que declarar valores padrão como seria com:
|
||||
|
||||
Estamos usando dois pontos (`:`), não é igual a (`=`).
|
||||
|
||||
E adicionar type hints normalmente não muda o que acontece do que aconteceria sem elas.
|
||||
E adicionar type hints normalmente não muda o que acontece do que aconteceria sem eles.
|
||||
|
||||
Mas agora, imagine que você está novamente no meio da criação dessa função, mas com type hints.
|
||||
|
||||
No mesmo ponto, você tenta acionar o preenchimento automático com o `Ctrl Space` e vê:
|
||||
No mesmo ponto, você tenta acionar o preenchimento automático com o `Ctrl+Space` e vê:
|
||||
|
||||
<img src="/img/python-types/image02.png">
|
||||
|
||||
Com isso, você pode rolar, vendo as opções, até encontrar o que "toca uma campainha":
|
||||
Com isso, você pode rolar, vendo as opções, até encontrar o que "soa familiar":
|
||||
|
||||
<img src="/img/python-types/image03.png">
|
||||
|
||||
## Mais motivação
|
||||
|
||||
Marque esta função, ela já possui type hints:
|
||||
Verifique esta função, ela já possui type hints:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/python_types/tutorial003.py!}
|
||||
```
|
||||
|
||||
Como o editor conhece os tipos de variáveis, você não apenas obtém a conclusão, mas também as verificações de erro:
|
||||
Como o editor conhece os tipos de variáveis, você não obtém apenas o preenchimento automático, mas também as verificações de erro:
|
||||
|
||||
<img src="/img/python-types/image04.png">
|
||||
|
||||
Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str (age)`:
|
||||
Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`:
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!../../docs_src/python_types/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Tipos de declaração
|
||||
## Declarando Tipos
|
||||
|
||||
Você acabou de ver o local principal para declarar type hints. Como parâmetros de função.
|
||||
|
||||
@@ -151,39 +151,77 @@ Você pode usar, por exemplo:
|
||||
|
||||
Existem algumas estruturas de dados que podem conter outros valores, como `dict`, `list`, `set` e `tuple`. E os valores internos também podem ter seu próprio tipo.
|
||||
|
||||
Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão `typing`.
|
||||
Estes tipos que possuem tipos internos são chamados de tipos "**genéricos**". E é possível declará-los mesmo com os seus tipos internos.
|
||||
|
||||
Ele existe especificamente para suportar esses type hints.
|
||||
Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão `typing`. Ele existe especificamente para suportar esses type hints.
|
||||
|
||||
#### `List`
|
||||
#### Versões mais recentes do Python
|
||||
|
||||
Por exemplo, vamos definir uma variável para ser uma `lista` de `str`.
|
||||
A sintaxe utilizando `typing` é **compatível** com todas as versões, desde o Python 3.6 até as últimas, incluindo o Python 3.9, 3.10, etc.
|
||||
|
||||
Em `typing`, importe `List` (com um `L` maiúsculo):
|
||||
Conforme o Python evolui, **novas versões** chegam com suporte melhorado para esses type annotations, e em muitos casos, você não precisará nem importar e utilizar o módulo `typing` para declarar os type annotations.
|
||||
|
||||
Se você pode escolher uma versão mais recente do Python para o seu projeto, você poderá aproveitar isso ao seu favor.
|
||||
|
||||
Em todos os documentos existem exemplos compatíveis com cada versão do Python (quando existem diferenças).
|
||||
|
||||
Por exemplo, "**Python 3.6+**" significa que é compatível com o Python 3.6 ou superior (incluindo o 3.7, 3.8, 3.9, 3.10, etc). E "**Python 3.9+**" significa que é compatível com o Python 3.9 ou mais recente (incluindo o 3.10, etc).
|
||||
|
||||
Se você pode utilizar a **versão mais recente do Python**, utilize os exemplos para as últimas versões. Eles terão as **melhores e mais simples sintaxes**, como por exemplo, "**Python 3.10+**".
|
||||
|
||||
#### List
|
||||
|
||||
Por exemplo, vamos definir uma variável para ser uma `list` de `str`.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
Declare uma variável com a mesma sintaxe com dois pontos (`:`)
|
||||
|
||||
Como tipo, coloque `list`.
|
||||
|
||||
Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/python_types/tutorial006.py!}
|
||||
{!> ../../docs_src/python_types/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
Declare a variável com a mesma sintaxe de dois pontos (`:`).
|
||||
////
|
||||
|
||||
Como o tipo, coloque a `List`.
|
||||
//// tab | Python 3.8+
|
||||
|
||||
Como a lista é um tipo que contém alguns tipos internos, você os coloca entre colchetes:
|
||||
De `typing`, importe `List` (com o `L` maiúsculo):
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
Declare uma variável com a mesma sintaxe com dois pontos (`:`)
|
||||
|
||||
Como tipo, coloque o `List` que você importou de `typing`.
|
||||
|
||||
Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../docs_src/python_types/tutorial006.py!}
|
||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
/// tip | "Dica"
|
||||
////
|
||||
|
||||
Esses tipos internos entre colchetes são chamados de "parâmetros de tipo".
|
||||
/// info | Informação
|
||||
|
||||
Nesse caso, `str` é o parâmetro de tipo passado para `List`.
|
||||
Estes tipos internos dentro dos colchetes são chamados "parâmetros de tipo" (type parameters).
|
||||
|
||||
Neste caso, `str` é o parâmetro de tipo passado para `List` (ou `list` no Python 3.9 ou superior).
|
||||
|
||||
///
|
||||
|
||||
Isso significa que: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`".
|
||||
Isso significa: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`".
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Se você usa o Python 3.9 ou superior, você não precisa importar `List` de `typing`. Você pode utilizar o mesmo tipo `list` no lugar.
|
||||
|
||||
///
|
||||
|
||||
Ao fazer isso, seu editor pode fornecer suporte mesmo durante o processamento de itens da lista:
|
||||
|
||||
@@ -195,20 +233,32 @@ Observe que a variável `item` é um dos elementos da lista `items`.
|
||||
|
||||
E, ainda assim, o editor sabe que é um `str` e fornece suporte para isso.
|
||||
|
||||
#### `Tuple` e `Set`
|
||||
#### Tuple e Set
|
||||
|
||||
Você faria o mesmo para declarar `tuple`s e `set`s:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial007.py!}
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Isso significa que:
|
||||
|
||||
* A variável `items_t` é uma `tuple` com 3 itens, um `int`, outro `int` e uma `str`.
|
||||
* A variável `items_s` é um `set`, e cada um de seus itens é do tipo `bytes`.
|
||||
|
||||
#### `Dict`
|
||||
#### Dict
|
||||
|
||||
Para definir um `dict`, você passa 2 parâmetros de tipo, separados por vírgulas.
|
||||
|
||||
@@ -216,38 +266,185 @@ O primeiro parâmetro de tipo é para as chaves do `dict`.
|
||||
|
||||
O segundo parâmetro de tipo é para os valores do `dict`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial008.py!}
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Isso significa que:
|
||||
|
||||
* A variável `prices` é um dict`:
|
||||
* As chaves deste `dict` são do tipo `str` (digamos, o nome de cada item).
|
||||
* Os valores deste `dict` são do tipo `float` (digamos, o preço de cada item).
|
||||
|
||||
#### `Opcional`
|
||||
#### Union
|
||||
|
||||
Você também pode usar o `Opcional` para declarar que uma variável tem um tipo, como `str`, mas que é "opcional", o que significa que também pode ser `None`:
|
||||
Você pode declarar que uma variável pode ser de qualquer um dentre **diversos tipos**. Por exemplo, um `int` ou um `str`.
|
||||
|
||||
No Python 3.6 e superior (incluindo o Python 3.10), você pode utilizar o tipo `Union` de `typing`, e colocar dentro dos colchetes os possíveis tipos aceitáveis.
|
||||
|
||||
No Python 3.10 também existe uma **nova sintaxe** onde você pode colocar os possívels tipos separados por uma <abbr title='também chamado de "bitwise ou operador", mas o significado é irrelevante aqui'>barra vertical (`|`)</abbr>.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial008b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Em ambos os casos, isso significa que `item` poderia ser um `int` ou um `str`.
|
||||
|
||||
|
||||
#### Possívelmente `None`
|
||||
|
||||
Você pode declarar que um valor pode ter um tipo, como `str`, mas que ele também pode ser `None`.
|
||||
|
||||
No Python 3.6 e superior (incluindo o Python 3.10) você pode declará-lo importando e utilizando `Optional` do módulo `typing`.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
O uso de `Opcional [str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
|
||||
O uso de `Optional[str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
|
||||
|
||||
`Optional[Something]` é na verdade um atalho para `Union[Something, None]`, eles são equivalentes.
|
||||
|
||||
Isso também significa que no Python 3.10, você pode utilizar `Something | None`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial009_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ alternative
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial009b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
#### Utilizando `Union` ou `Optional`
|
||||
|
||||
Se você está utilizando uma versão do Python abaixo da 3.10, aqui vai uma dica do meu ponto de vista bem **subjetivo**:
|
||||
|
||||
* 🚨 Evite utilizar `Optional[SomeType]`
|
||||
* No lugar, ✨ **use `Union[SomeType, None]`** ✨.
|
||||
|
||||
Ambos são equivalentes, e no final das contas, eles são o mesmo. Mas eu recomendaria o `Union` ao invés de `Optional` porque a palavra **Optional** parece implicar que o valor é opcional, quando na verdade significa "isso pode ser `None`", mesmo que ele não seja opcional e ainda seja obrigatório.
|
||||
|
||||
Eu penso que `Union[SomeType, None]` é mais explícito sobre o que ele significa.
|
||||
|
||||
Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os seus colegas de trabalho pensam sobre o código.
|
||||
|
||||
Por exemplo, vamos pegar esta função:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009c.py!}
|
||||
```
|
||||
|
||||
O paâmetro `name` é definido como `Optional[str]`, mas ele **não é opcional**, você não pode chamar a função sem o parâmetro:
|
||||
|
||||
```Python
|
||||
say_hi() # Oh, no, this throws an error! 😱
|
||||
```
|
||||
|
||||
O parâmetro `name` **ainda é obrigatório** (não *opicional*) porque ele não possui um valor padrão. Mesmo assim, `name` aceita `None` como valor:
|
||||
|
||||
```Python
|
||||
say_hi(name=None) # This works, None is valid 🎉
|
||||
```
|
||||
|
||||
A boa notícia é, quando você estiver no Python 3.10 você não precisará se preocupar mais com isso, pois você poderá simplesmente utilizar o `|` para definir uniões de tipos:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009c_py310.py!}
|
||||
```
|
||||
|
||||
E então você não precisará mais se preocupar com nomes como `Optional` e `Union`. 😎
|
||||
|
||||
#### Tipos genéricos
|
||||
|
||||
Esses tipos que usam parâmetros de tipo entre colchetes, como:
|
||||
Esses tipos que usam parâmetros de tipo entre colchetes são chamados **tipos genéricos** ou **genéricos**. Por exemplo:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
E o mesmo como no Python 3.8, do módulo `typing`:
|
||||
|
||||
* `Union`
|
||||
* `Optional` (o mesmo que com o 3.8)
|
||||
* ...entro outros.
|
||||
|
||||
No Python 3.10, como uma alternativa para a utilização dos genéricos `Union` e `Optional`, você pode usar a <abbr title='também chamado de "bitwise ou operador", mas o significado não é relevante aqui'>barra vertical (`|`)</abbr> para declarar uniões de tipos. Isso é muito melhor e mais simples.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
E o mesmo como no Python 3.8, do módulo `typing`:
|
||||
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...entro outros.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Opcional`
|
||||
* ...e outros.
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...entro outros.
|
||||
|
||||
são chamados **tipos genéricos** ou **genéricos**.
|
||||
////
|
||||
|
||||
### Classes como tipos
|
||||
|
||||
@@ -255,7 +452,7 @@ Você também pode declarar uma classe como o tipo de uma variável.
|
||||
|
||||
Digamos que você tenha uma classe `Person`, com um nome:
|
||||
|
||||
```Python hl_lines="1 2 3"
|
||||
```Python hl_lines="1-3"
|
||||
{!../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
|
||||
@@ -269,9 +466,13 @@ E então, novamente, você recebe todo o suporte do editor:
|
||||
|
||||
<img src="/img/python-types/image06.png">
|
||||
|
||||
Perceba que isso significa que "`one_person` é uma **instância** da classe `Person`".
|
||||
|
||||
Isso não significa que "`one_person` é a **classe** chamada `Person`".
|
||||
|
||||
## Modelos Pydantic
|
||||
|
||||
<a href="https://docs.pydantic.dev/" class="external-link" target="_blank"> Pydantic </a> é uma biblioteca Python para executar a validação de dados.
|
||||
O <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> é uma biblioteca Python para executar a validação de dados.
|
||||
|
||||
Você declara a "forma" dos dados como classes com atributos.
|
||||
|
||||
@@ -283,21 +484,93 @@ E você recebe todo o suporte do editor com esse objeto resultante.
|
||||
|
||||
Retirado dos documentos oficiais dos Pydantic:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
{!../../docs_src/python_types/tutorial011.py!}
|
||||
{!> ../../docs_src/python_types/tutorial011_py310.py!}
|
||||
```
|
||||
|
||||
/// info | "Informação"
|
||||
////
|
||||
|
||||
Para saber mais sobre o <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"> Pydantic, verifique seus documentos </a>.
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info | Informação
|
||||
|
||||
Para saber mais sobre o <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic, verifique a sua documentação</a>.
|
||||
|
||||
///
|
||||
|
||||
**FastAPI** é todo baseado em Pydantic.
|
||||
O **FastAPI** é todo baseado em Pydantic.
|
||||
|
||||
Você verá muito mais disso na prática no [Tutorial - Guia do usuário](tutorial/index.md){.internal-link target=_blank}.
|
||||
|
||||
## Type hints em **FastAPI**
|
||||
/// tip | Dica
|
||||
|
||||
O Pydantic tem um comportamento especial quando você usa `Optional` ou `Union[Something, None]` sem um valor padrão. Você pode ler mais sobre isso na documentação do Pydantic sobre <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">campos Opcionais Obrigatórios</a>.
|
||||
|
||||
///
|
||||
|
||||
|
||||
## Type Hints com Metadados de Anotações
|
||||
|
||||
O Python possui uma funcionalidade que nos permite incluir **<abbr title="Informação sobre a informação, neste caso, informação sobre o tipo, e.g. uma descrição.">metadados</abbr> adicionais** nos type hints utilizando `Annotated`.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
No Python 3.9, `Annotated` é parte da biblioteca padrão, então você pode importá-lo de `typing`.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial013_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
Em versões abaixo do Python 3.9, você importa `Annotated` de `typing_extensions`.
|
||||
|
||||
Ele já estará instalado com o **FastAPI**.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial013.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
O Python em si não faz nada com este `Annotated`. E para editores e outras ferramentas, o tipo ainda é `str`.
|
||||
|
||||
Mas você pode utilizar este espaço dentro do `Annotated` para fornecer ao **FastAPI** metadata adicional sobre como você deseja que a sua aplicação se comporte.
|
||||
|
||||
O importante aqui de se lembrar é que **o primeiro *type parameter*** que você informar ao `Annotated` é o **tipo de fato**. O resto é apenas metadado para outras ferramentas.
|
||||
|
||||
Por hora, você precisa apenas saber que o `Annotated` existe, e que ele é Python padrão. 😎
|
||||
|
||||
Mais tarde você verá o quão **poderoso** ele pode ser.
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
O fato de que isso é **Python padrão** significa que você ainda obtém a **melhor experiência de desenvolvedor possível** no seu editor, com as ferramentas que você utiliza para analisar e refatorar o seu código, etc. ✨
|
||||
|
||||
E também que o seu código será muito compatível com diversas outras ferramentas e bibliotecas Python. 🚀
|
||||
|
||||
///
|
||||
|
||||
|
||||
## Type hints no **FastAPI**
|
||||
|
||||
O **FastAPI** aproveita esses type hints para fazer várias coisas.
|
||||
|
||||
@@ -306,20 +579,20 @@ Com o **FastAPI**, você declara parâmetros com type hints e obtém:
|
||||
* **Suporte ao editor**.
|
||||
* **Verificações de tipo**.
|
||||
|
||||
... e **FastAPI** usa as mesmas declarações para:
|
||||
... e o **FastAPI** usa as mesmas declarações para:
|
||||
|
||||
* **Definir requisitos**: dos parâmetros do caminho da solicitação, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
|
||||
* **Definir requisitos**: dos parâmetros de rota, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
|
||||
* **Converter dados**: da solicitação para o tipo necessário.
|
||||
* **Validar dados**: provenientes de cada solicitação:
|
||||
* A geração de **erros automáticos** retornou ao cliente quando os dados são inválidos.
|
||||
* **Documente** a API usando OpenAPI:
|
||||
* Gerando **erros automáticos** retornados ao cliente quando os dados são inválidos.
|
||||
* **Documentar** a API usando OpenAPI:
|
||||
* que é usado pelas interfaces de usuário da documentação interativa automática.
|
||||
|
||||
Tudo isso pode parecer abstrato. Não se preocupe. Você verá tudo isso em ação no [Tutorial - Guia do usuário](tutorial/index.md){.internal-link target=_blank}.
|
||||
|
||||
O importante é que, usando tipos padrão de Python, em um único local (em vez de adicionar mais classes, decoradores, etc.), o **FastAPI** fará muito trabalho para você.
|
||||
|
||||
/// info | "Informação"
|
||||
/// info | Informação
|
||||
|
||||
Se você já passou por todo o tutorial e voltou para ver mais sobre os tipos, um bom recurso é <a href = "https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class = "external-link "target =" _ blank "> a "cheat sheet" do `mypy` </a>.
|
||||
|
||||
|
||||
204
docs/pt/docs/tutorial/body-updates.md
Normal file
204
docs/pt/docs/tutorial/body-updates.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# Corpo - Atualizações
|
||||
|
||||
## Atualização de dados existentes com `PUT`
|
||||
|
||||
Para atualizar um item, você pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
|
||||
|
||||
Você pode usar `jsonable_encoder` para converter os dados de entrada em dados que podem ser armazenados como JSON (por exemplo, com um banco de dados NoSQL). Por exemplo, convertendo `datetime` em `str`.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="28-33"
|
||||
{!> ../../../docs_src/body_updates/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!> ../../../docs_src/body_updates/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!> ../../../docs_src/body_updates/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
`PUT` é usado para receber dados que devem substituir os dados existentes.
|
||||
|
||||
### Aviso sobre a substituição
|
||||
|
||||
Isso significa que, se você quiser atualizar o item `bar` usando `PUT` com um corpo contendo:
|
||||
|
||||
```Python
|
||||
{
|
||||
"name": "Barz",
|
||||
"price": 3,
|
||||
"description": None,
|
||||
}
|
||||
```
|
||||
|
||||
Como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`.
|
||||
|
||||
E os dados seriam salvos com esse "novo" `tax` de `10.5`.
|
||||
|
||||
## Atualizações parciais com `PATCH`
|
||||
|
||||
Você também pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> para *atualizar* parcialmente os dados.
|
||||
|
||||
Isso significa que você pode enviar apenas os dados que deseja atualizar, deixando o restante intacto.
|
||||
|
||||
/// note | Nota
|
||||
|
||||
`PATCH` é menos comumente usado e conhecido do que `PUT`.
|
||||
|
||||
E muitas equipes usam apenas `PUT`, mesmo para atualizações parciais.
|
||||
|
||||
Você é **livre** para usá-los como preferir, **FastAPI** não impõe restrições.
|
||||
|
||||
Mas este guia te dá uma ideia de como eles são destinados a serem usados.
|
||||
|
||||
///
|
||||
|
||||
### Usando o parâmetro `exclude_unset` do Pydantic
|
||||
|
||||
Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no método `.model_dump()` do modelo do Pydantic.
|
||||
|
||||
Como `item.model_dump(exclude_unset=True)`.
|
||||
|
||||
/// info | Informação
|
||||
|
||||
No Pydantic v1, o método que era chamado `.dict()` e foi depreciado (mas ainda suportado) no Pydantic v2. Agora, deve-se usar o método `.model_dump()`.
|
||||
|
||||
Os exemplos aqui usam `.dict()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` a partir do Pydantic v2.
|
||||
|
||||
///
|
||||
|
||||
Isso gera um `dict` com apenas os dados definidos ao criar o modelo `item`, excluindo os valores padrão.
|
||||
|
||||
Então, você pode usar isso para gerar um `dict` com apenas os dados definidos (enviados na solicitação), omitindo valores padrão:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="32"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!> ../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### Usando o parâmetro `update` do Pydantic
|
||||
|
||||
Agora, você pode criar uma cópia do modelo existente usando `.model_copy()`, e passar o parâmetro `update` com um `dict` contendo os dados para atualizar.
|
||||
|
||||
/// info | Informação
|
||||
|
||||
No Pydantic v1, o método era chamado `.copy()`, ele foi depreciado (mas ainda suportado) no Pydantic v2, e renomeado para `.model_copy()`.
|
||||
|
||||
Os exemplos aqui usam `.copy()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_copy()` com o Pydantic v2.
|
||||
|
||||
///
|
||||
|
||||
Como `stored_item_model.model_copy(update=update_data)`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="33"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!> ../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### Recapitulando as atualizações parciais
|
||||
|
||||
Resumindo, para aplicar atualizações parciais você pode:
|
||||
|
||||
* (Opcionalmente) usar `PATCH` em vez de `PUT`.
|
||||
* Recuperar os dados armazenados.
|
||||
* Colocar esses dados em um modelo do Pydantic.
|
||||
* Gerar um `dict` sem valores padrão a partir do modelo de entrada (usando `exclude_unset`).
|
||||
* Dessa forma, você pode atualizar apenas os valores definidos pelo usuário, em vez de substituir os valores já armazenados com valores padrão em seu modelo.
|
||||
* Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`).
|
||||
* Converter o modelo copiado em algo que possa ser armazenado no seu banco de dados (por exemplo, usando o `jsonable_encoder`).
|
||||
* Isso é comparável ao uso do método `.model_dump()`, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`.
|
||||
* Salvar os dados no seu banco de dados.
|
||||
* Retornar o modelo atualizado.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="28-35"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!> ../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Você pode realmente usar essa mesma técnica com uma operação HTTP `PUT`.
|
||||
|
||||
Mas o exemplo aqui usa `PATCH` porque foi criado para esses casos de uso.
|
||||
|
||||
///
|
||||
|
||||
/// note | Nota
|
||||
|
||||
Observe que o modelo de entrada ainda é validado.
|
||||
|
||||
Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, precisará ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`).
|
||||
|
||||
Para distinguir os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
197
docs/pt/docs/tutorial/query-param-models.md
Normal file
197
docs/pt/docs/tutorial/query-param-models.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Modelos de Parâmetros de Consulta
|
||||
|
||||
Se você possui um grupo de **parâmetros de consultas** que são relacionados, você pode criar um **modelo Pydantic** para declará-los.
|
||||
|
||||
Isso permitiria que você **reutilizasse o modelo** em **diversos lugares**, e também declarasse validações e metadados de todos os parâmetros de uma única vez. 😎
|
||||
|
||||
/// note | Nota
|
||||
|
||||
Isso é suportado desde o FastAPI versão `0.115.0`. 🤓
|
||||
|
||||
///
|
||||
|
||||
## Parâmetros de Consulta com um Modelo Pydantic
|
||||
|
||||
Declare os **parâmetros de consulta** que você precisa em um **modelo Pydantic**, e então declare o parâmetro como `Query`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9-13 17"
|
||||
{!> ../../docs_src/query_param_models/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8-12 16"
|
||||
{!> ../../docs_src/query_param_models/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10-14 18"
|
||||
{!> ../../docs_src/query_param_models/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Prefira utilizar a versão `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9-13 17"
|
||||
{!> ../../docs_src/query_param_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ non-Annotated
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Prefira utilizar a versão `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8-12 16"
|
||||
{!> ../../docs_src/query_param_models/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Prefira utilizar a versão `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9-13 17"
|
||||
{!> ../../docs_src/query_param_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
O **FastAPI** **extrairá** os dados para **cada campo** dos **parâmetros de consulta** presentes na requisição, e fornecerá o modelo Pydantic que você definiu.
|
||||
|
||||
|
||||
## Verifique os Documentos
|
||||
|
||||
Você pode ver os parâmetros de consulta nos documentos de IU em `/docs`:
|
||||
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/query-param-models/image01.png">
|
||||
</div>
|
||||
|
||||
## Restrinja Parâmetros de Consulta Extras
|
||||
|
||||
Em alguns casos especiais (provavelmente não muito comuns), você queira **restrinjir** os parâmetros de consulta que deseja receber.
|
||||
|
||||
Você pode usar a configuração do modelo Pydantic para `forbid` (proibir) qualquer campo `extra`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_param_models/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_param_models/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_param_models/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Prefira utilizar a versão `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_param_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ non-Annotated
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Prefira utilizar a versão `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_param_models/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Prefira utilizar a versão `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_param_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Caso um cliente tente enviar alguns dados **extras** nos **parâmetros de consulta**, eles receberão um retorno de **erro**.
|
||||
|
||||
Por exemplo, se o cliente tentar enviar um parâmetro de consulta `tool` com o valor `plumbus`, como:
|
||||
|
||||
```http
|
||||
https://example.com/items/?limit=10&tool=plumbus
|
||||
```
|
||||
|
||||
Eles receberão um retorno de **erro** informando-os que o parâmentro de consulta `tool` não é permitido:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["query", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Resumo
|
||||
|
||||
Você pode utilizar **modelos Pydantic** para declarar **parâmetros de consulta** no **FastAPI**. 😎
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Alerta de spoiler: você também pode utilizar modelos Pydantic para declarar cookies e cabeçalhos, mas você irá ler sobre isso mais a frente no tutorial. 🤫
|
||||
|
||||
///
|
||||
@@ -357,7 +357,7 @@ Molten мне попался на начальной стадии написан
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug был одним из первых фреймворков, реализовавших объявление параметров API с использованием подсказок типов Python.
|
||||
Эта отличная идея была использована и другими инструментами.
|
||||
|
||||
297
docs/ru/docs/environment-variables.md
Normal file
297
docs/ru/docs/environment-variables.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# Переменные окружения
|
||||
|
||||
/// tip
|
||||
|
||||
Если вы уже знаете, что такое «переменные окружения» и как их использовать, можете пропустить это.
|
||||
|
||||
///
|
||||
|
||||
Переменная окружения (также известная как «**env var**») - это переменная, которая живет **вне** кода Python, в **операционной системе**, и может быть прочитана вашим кодом Python (или другими программами).
|
||||
|
||||
Переменные окружения могут быть полезны для работы с **настройками** приложений, как часть **установки** Python и т.д.
|
||||
|
||||
## Создание и использование переменных окружения
|
||||
|
||||
Можно **создавать** и использовать переменные окружения в **оболочке (терминале)**, не прибегая к помощи Python:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Вы можете создать переменную окружения MY_NAME с помощью
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// Затем её можно использовать в других программах, например
|
||||
$ echo "Hello $MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Создайте переменную окружения MY_NAME
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// Используйте её с другими программами, например
|
||||
$ echo "Hello $Env:MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
## Чтение переменных окружения в python
|
||||
|
||||
Так же существует возможность создания переменных окружения **вне** Python, в терминале (или любым другим способом), а затем **чтения их в Python**.
|
||||
|
||||
Например, у вас есть файл `main.py`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
import os
|
||||
|
||||
name = os.getenv("MY_NAME", "World")
|
||||
print(f"Hello {name} from Python")
|
||||
```
|
||||
|
||||
/// tip
|
||||
|
||||
Второй аргумент <a href=«https://docs.python.org/3.8/library/os.html#os.getenv» class=«external-link» target=«_blank»>`os.getenv()`</a> - это возвращаемое по умолчанию значение.
|
||||
|
||||
Если значение не указано, то по умолчанию оно равно `None`. В данном случае мы указываем `«World»` в качестве значения по умолчанию.
|
||||
///
|
||||
|
||||
Затем можно запустить эту программу на Python:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Здесь мы еще не устанавливаем переменную окружения
|
||||
$ python main.py
|
||||
|
||||
// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// Но если мы сначала создадим переменную окружения
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// А затем снова запустим программу
|
||||
$ python main.py
|
||||
|
||||
// Теперь она прочитает переменную окружения
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Здесь мы еще не устанавливаем переменную окружения
|
||||
$ python main.py
|
||||
|
||||
// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// Но если мы сначала создадим переменную окружения
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// А затем снова запустим программу
|
||||
$ python main.py
|
||||
|
||||
// Теперь она может прочитать переменную окружения
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
Поскольку переменные окружения могут быть установлены вне кода, но могут быть прочитаны кодом, и их не нужно хранить (фиксировать в `git`) вместе с остальными файлами, их принято использовать для конфигураций или **настроек**.
|
||||
|
||||
Вы также можете создать переменную окружения только для **конкретного вызова программы**, которая будет доступна только для этой программы и только на время ее выполнения.
|
||||
|
||||
Для этого создайте её непосредственно перед самой программой, в той же строке:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Создайте переменную окружения MY_NAME в строке для этого вызова программы
|
||||
$ MY_NAME="Wade Wilson" python main.py
|
||||
|
||||
// Теперь она может прочитать переменную окружения
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
|
||||
// После этого переменная окружения больше не существует
|
||||
$ python main.py
|
||||
|
||||
Hello World from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip
|
||||
|
||||
Подробнее об этом можно прочитать на сайте <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>.
|
||||
|
||||
///
|
||||
|
||||
## Типизация и Валидация
|
||||
|
||||
Эти переменные окружения могут работать только с **текстовыми строками**, поскольку они являются внешними по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с различными операционными системами, такими как Linux, Windows, macOS).
|
||||
|
||||
Это означает, что **любое значение**, считанное в Python из переменной окружения, **будет `str`**, и любое преобразование к другому типу или любая проверка должны быть выполнены в коде.
|
||||
|
||||
Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}.
|
||||
|
||||
## Переменная окружения `PATH`
|
||||
|
||||
Существует **специальная** переменная окружения **`PATH`**, которая используется операционными системами (Linux, macOS, Windows) для поиска программ для запуска.
|
||||
|
||||
Значение переменной `PATH` - это длинная строка, состоящая из каталогов, разделенных двоеточием `:` в Linux и macOS, и точкой с запятой `;` в Windows.
|
||||
|
||||
Например, переменная окружения `PATH` может выглядеть следующим образом:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
Это означает, что система должна искать программы в каталогах:
|
||||
|
||||
* `/usr/local/bin`
|
||||
* `/usr/bin`
|
||||
* `/bin`
|
||||
* `/usr/sbin`
|
||||
* `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
|
||||
```
|
||||
|
||||
Это означает, что система должна искать программы в каталогах:
|
||||
|
||||
* `C:\Program Files\Python312\Scripts`
|
||||
* `C:\Program Files\Python312`
|
||||
* `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
Когда вы вводите **команду** в терминале, операционная система **ищет** программу в **каждой из тех директорий**, которые перечислены в переменной окружения `PATH`.
|
||||
|
||||
Например, когда вы вводите `python` в терминале, операционная система ищет программу под названием `python` в **первой директории** в этом списке.
|
||||
|
||||
Если она ее находит, то **использует ее**. В противном случае она продолжает искать в **других каталогах**.
|
||||
|
||||
### Установка Python и обновление `PATH`
|
||||
|
||||
При установке Python вас могут спросить, нужно ли обновить переменную окружения `PATH`.
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
Допустим, вы устанавливаете Python, и он оказывается в каталоге `/opt/custompython/bin`.
|
||||
|
||||
Если вы скажете «да», чтобы обновить переменную окружения `PATH`, то программа установки добавит `/opt/custompython/bin` в переменную окружения `PATH`.
|
||||
|
||||
Это может выглядеть следующим образом:
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
|
||||
```
|
||||
|
||||
Таким образом, когда вы набираете `python` в терминале, система найдет программу Python в `/opt/custompython/bin` (последний каталог) и использует ее.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
Допустим, вы устанавливаете Python, и он оказывается в каталоге `C:\opt\custompython\bin`.
|
||||
|
||||
Если вы согласитесь обновить переменную окружения `PATH`, то программа установки добавит `C:\opt\custompython\bin` в переменную окружения `PATH`.
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
|
||||
```
|
||||
|
||||
Таким образом, когда вы набираете `python` в терминале, система найдет программу Python в `C:\opt\custompython\bin` (последний каталог) и использует ее.
|
||||
|
||||
////
|
||||
|
||||
Итак, если вы напечатаете:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
Система **найдет** программу `python` в `/opt/custompython/bin` и запустит ее.
|
||||
|
||||
Это примерно эквивалентно набору текста:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ /opt/custompython/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
Система **найдет** программу `python` в каталоге `C:\opt\custompython\bin\python` и запустит ее.
|
||||
|
||||
Это примерно эквивалентно набору текста:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ C:\opt\custompython\bin\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
Эта информация будет полезна при изучении [Виртуальных окружений](virtual-environments.md){.internal-link target=_blank}.
|
||||
|
||||
## Вывод
|
||||
|
||||
Благодаря этому вы должны иметь базовое представление о том, что такое **переменные окружения** и как использовать их в Python.
|
||||
|
||||
Подробнее о них вы также можете прочитать в <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">статье о переменных окружения на википедии</a>.
|
||||
|
||||
Во многих случаях не всегда очевидно, как переменные окружения могут быть полезны и применимы. Но они постоянно появляются в различных сценариях разработки, поэтому знать о них полезно.
|
||||
|
||||
Например, эта информация понадобится вам в следующем разделе, посвященном [Виртуальным окружениям](virtual-environments.md).
|
||||
@@ -93,7 +93,7 @@ FastAPI — это современный, быстрый (высокопрои
|
||||
|
||||
"_Честно говоря, то, что вы создали, выглядит очень солидно и отполировано. Во многих смыслах я хотел, чтобы **Hug** был именно таким — это действительно вдохновляет, когда кто-то создаёт такое._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ Bu aslında Pydantic'in de aynı doğrulama stiline geçmesinde ilham kaynağı
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug, Python tip belirteçlerini kullanarak API parametrelerinin tipini belirlemeyi uygulayan ilk framework'lerdendi. Bu, diğer araçlara da ilham kaynağı olan harika bir fikirdi.
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ Falcon — ще один високопродуктивний фреймворк
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
|
||||
Hug був одним із перших фреймворків, який реалізував оголошення типів параметрів API за допомогою підказок типу Python. Це була чудова ідея, яка надихнула інші інструменти зробити те саме.
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ FastAPI - це сучасний, швидкий (високопродуктив
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Những tính năng như:
|
||||
|
||||
"_Thành thật, những gì bạn đã xây dựng nhìn siêu chắc chắn và bóng bẩy. Theo nhiều cách, nó là những gì tôi đã muốn Hug trở thành - thật sự truyền cảm hứng để thấy ai đó xây dựng nó._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - người tạo ra <strong><a href="https://www.hug.rest/" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - người tạo ra <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ FastAPI jẹ́ ìgbàlódé, tí ó yára (iṣẹ-giga), ìlànà wẹ́ẹ́b
|
||||
|
||||
"_Ní tòótọ́, ohun tí o kọ dára ó sì tún dán. Ní ọ̀pọ̀lọpọ̀ ọ̀nà, ohun tí mo fẹ́ kí **Hug** jẹ́ nìyẹn - ó wúni lórí gan-an láti rí ẹnìkan tí ó kọ́ nǹkan bí èyí._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
3
docs/zh-hant/docs/about/index.md
Normal file
3
docs/zh-hant/docs/about/index.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 關於 FastAPI
|
||||
|
||||
關於 FastAPI、其設計、靈感來源等更多資訊。 🤓
|
||||
17
docs/zh-hant/docs/deployment/cloud.md
Normal file
17
docs/zh-hant/docs/deployment/cloud.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# 在雲端部署 FastAPI
|
||||
|
||||
你幾乎可以使用 **任何雲端供應商** 來部署你的 FastAPI 應用程式。
|
||||
|
||||
在大多數情況下,主要的雲端供應商都有部署 FastAPI 的指南。
|
||||
|
||||
## 雲端供應商 - 贊助商
|
||||
|
||||
一些雲端供應商 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這確保了 FastAPI 及其 **生態系統** 持續健康地 **發展**。
|
||||
|
||||
這也展現了他們對 FastAPI 和其 **社群**(包括你)的真正承諾,他們不僅希望為你提供 **優質的服務**,還希望確保你擁有一個 **良好且健康的框架**:FastAPI。🙇
|
||||
|
||||
你可能會想嘗試他們的服務,以下有他們的指南:
|
||||
|
||||
* <a href="https://docs.platform.sh/languages/python.html?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" class="external-link" target="_blank" >Platform.sh</a>
|
||||
* <a href="https://docs.porter.run/language-specific-guides/fastapi" class="external-link" target="_blank">Porter</a>
|
||||
* <a href="https://docs.withcoherence.com/" class="external-link" target="_blank">Coherence</a>
|
||||
21
docs/zh-hant/docs/deployment/index.md
Normal file
21
docs/zh-hant/docs/deployment/index.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 部署
|
||||
|
||||
部署 **FastAPI** 應用程式相對容易。
|
||||
|
||||
## 部署是什麼意思
|
||||
|
||||
**部署** 應用程式指的是執行一系列必要的步驟,使其能夠 **讓使用者存取和使用**。
|
||||
|
||||
對於一個 **Web API**,部署通常涉及將其放置在 **遠端伺服器** 上,並使用性能優良且穩定的 **伺服器程式**,確保使用者能夠高效、無中斷地存取應用程式,且不會遇到問題。
|
||||
|
||||
這與 **開發** 階段形成鮮明對比,在 **開發** 階段,你會不斷更改程式碼、破壞程式碼、修復程式碼,然後停止和重新啟動伺服器等。
|
||||
|
||||
## 部署策略
|
||||
|
||||
根據你的使用場景和使用工具,有多種方法可以實現此目的。
|
||||
|
||||
你可以使用一些工具自行 **部署伺服器**,你也可以使用能為你完成部分工作的 **雲端服務**,或其他可能的選項。
|
||||
|
||||
我將向你展示在部署 **FastAPI** 應用程式時你可能應該記住的一些主要概念(儘管其中大部分適用於任何其他類型的 Web 應用程式)。
|
||||
|
||||
在接下來的部分中,你將看到更多需要記住的細節以及一些技巧。 ✨
|
||||
83
docs/zh-hant/docs/fastapi-cli.md
Normal file
83
docs/zh-hant/docs/fastapi-cli.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# FastAPI CLI
|
||||
|
||||
**FastAPI CLI** 是一個命令列程式,能用來運行你的 FastAPI 應用程式、管理你的 FastAPI 專案等。
|
||||
|
||||
當你安裝 FastAPI(例如使用 `pip install "fastapi[standard]"`),它會包含一個叫做 `fastapi-cli` 的套件,這個套件提供了 `fastapi` 命令。
|
||||
|
||||
要運行你的 FastAPI 應用程式來進行開發,你可以使用 `fastapi dev` 命令:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:single">main.py</u>
|
||||
<font color="#3465A4">INFO </font> Using path <font color="#3465A4">main.py</font>
|
||||
<font color="#3465A4">INFO </font> Resolved absolute path <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font>
|
||||
<font color="#3465A4">INFO </font> Searching for package file structure from directories with <font color="#3465A4">__init__.py</font> files
|
||||
<font color="#3465A4">INFO </font> Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
|
||||
╭─ <font color="#8AE234"><b>Python module file</b></font> ─╮
|
||||
│ │
|
||||
│ 🐍 main.py │
|
||||
│ │
|
||||
╰──────────────────────╯
|
||||
|
||||
<font color="#3465A4">INFO </font> Importing module <font color="#4E9A06">main</font>
|
||||
<font color="#3465A4">INFO </font> Found importable FastAPI app
|
||||
|
||||
╭─ <font color="#8AE234"><b>Importable FastAPI app</b></font> ─╮
|
||||
│ │
|
||||
│ <span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822"> </span> │
|
||||
│ │
|
||||
╰──────────────────────────╯
|
||||
|
||||
<font color="#3465A4">INFO </font> Using import string <font color="#8AE234"><b>main:app</b></font>
|
||||
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">╭────────── FastAPI CLI - Development mode ───────────╮</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ Serving at: http://127.0.0.1:8000 │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ API docs: http://127.0.0.1:8000/docs │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ Running in development mode, for production use: │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ </font></span><span style="background-color:#C4A000"><font color="#555753"><b>fastapi run</b></font></span><span style="background-color:#C4A000"><font color="#2E3436"> │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
|
||||
<span style="background-color:#C4A000"><font color="#2E3436">╰─────────────────────────────────────────────────────╯</font></span>
|
||||
|
||||
<font color="#4E9A06">INFO</font>: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
|
||||
<font color="#4E9A06">INFO</font>: Uvicorn running on <b>http://127.0.0.1:8000</b> (Press CTRL+C to quit)
|
||||
<font color="#4E9A06">INFO</font>: Started reloader process [<font color="#34E2E2"><b>2265862</b></font>] using <font color="#34E2E2"><b>WatchFiles</b></font>
|
||||
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">2265873</font>]
|
||||
<font color="#4E9A06">INFO</font>: Waiting for application startup.
|
||||
<font color="#4E9A06">INFO</font>: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
`fastapi` 命令列程式就是 **FastAPI CLI**。
|
||||
|
||||
FastAPI CLI 接收你的 Python 程式路徑(例如 `main.py`),並自動檢測 FastAPI 實例(通常命名為 `app`),確定正確的引入模組流程,然後運行該應用程式。
|
||||
|
||||
在生產環境,你應該使用 `fastapi run` 命令。 🚀
|
||||
|
||||
**FastAPI CLI** 內部使用了 <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>,這是一個高效能、適合生產環境的 ASGI 伺服器。 😎
|
||||
|
||||
## `fastapi dev`
|
||||
|
||||
執行 `fastapi dev` 會啟動開發模式。
|
||||
|
||||
預設情況下,**auto-reload** 功能是啟用的,當你對程式碼進行修改時,伺服器會自動重新載入。這會消耗較多資源,並且可能比禁用時更不穩定。因此,你應該只在開發環境中使用此功能。它也會在 IP 位址 `127.0.0.1` 上監聽,這是用於你的機器與自身通訊的 IP 位址(`localhost`)。
|
||||
|
||||
## `fastapi run`
|
||||
|
||||
執行 `fastapi run` 會以生產模式啟動 FastAPI。
|
||||
|
||||
預設情況下,**auto-reload** 功能是禁用的。它也會在 IP 位址 `0.0.0.0` 上監聽,表示會監聽所有可用的 IP 地址,這樣任何能與該機器通訊的人都可以公開存取它。這通常是你在生產環境中運行應用程式的方式,例如在容器中運行時。
|
||||
|
||||
在大多數情況下,你會(也應該)有一個「終止代理」來處理 HTTPS,這取決於你如何部署你的應用程式,你的服務供應商可能會為你做這件事,或者你需要自己設置它。
|
||||
|
||||
/// tip
|
||||
|
||||
你可以在[部署文件](deployment/index.md){.internal-link target=_blank}中了解更多相關資訊。
|
||||
|
||||
///
|
||||
@@ -87,7 +87,7 @@ FastAPI 是一個現代、快速(高效能)的 web 框架,用於 Python
|
||||
|
||||
"_老實說,你建造的東西看起來非常堅固和精緻。在很多方面,這就是我想要的,看到有人建造它真的很鼓舞人心。_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
3
docs/zh-hant/docs/resources/index.md
Normal file
3
docs/zh-hant/docs/resources/index.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 資源
|
||||
|
||||
額外的資源、外部連結、文章等。 ✈️
|
||||
@@ -94,7 +94,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
|
||||
|
||||
「_老实说,你的作品看起来非常可靠和优美。在很多方面,这就是我想让 **Hug** 成为的样子 - 看到有人实现了它真的很鼓舞人心。_」
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> 作者</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> 作者</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
||||
|
||||
__version__ = "0.115.1"
|
||||
__version__ = "0.115.3"
|
||||
|
||||
from starlette import status as status
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ classifiers = [
|
||||
"Topic :: Internet :: WWW/HTTP",
|
||||
]
|
||||
dependencies = [
|
||||
"starlette>=0.37.2,<0.39.0",
|
||||
"starlette>=0.40.0,<0.42.0",
|
||||
"pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0",
|
||||
"typing-extensions>=4.8.0",
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# For mkdocstrings and tests
|
||||
httpx >=0.23.0,<0.25.0
|
||||
httpx >=0.23.0,<0.28.0
|
||||
# For linting and generating docs versions
|
||||
ruff ==0.6.4
|
||||
|
||||
@@ -2,3 +2,4 @@ PyGithub>=2.3.0,<3.0.0
|
||||
pydantic>=2.5.3,<3.0.0
|
||||
pydantic-settings>=2.1.0,<3.0.0
|
||||
httpx>=0.27.0,<0.28.0
|
||||
smokeshow
|
||||
|
||||
60
scripts/label_approved.py
Normal file
60
scripts/label_approved.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
from github import Github
|
||||
from github.PullRequestReview import PullRequestReview
|
||||
from pydantic import BaseModel, SecretStr
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
class LabelSettings(BaseModel):
|
||||
await_label: str | None = None
|
||||
number: int
|
||||
|
||||
|
||||
default_config = {"approved-2": LabelSettings(await_label="awaiting-review", number=2)}
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
github_repository: str
|
||||
token: SecretStr
|
||||
debug: bool | None = False
|
||||
config: dict[str, LabelSettings] | Literal[""] = default_config
|
||||
|
||||
|
||||
settings = Settings()
|
||||
if settings.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.debug(f"Using config: {settings.json()}")
|
||||
g = Github(settings.token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
for pr in repo.get_pulls(state="open"):
|
||||
logging.info(f"Checking PR: #{pr.number}")
|
||||
pr_labels = list(pr.get_labels())
|
||||
pr_label_by_name = {label.name: label for label in pr_labels}
|
||||
reviews = list(pr.get_reviews())
|
||||
review_by_user: dict[str, PullRequestReview] = {}
|
||||
for review in reviews:
|
||||
if review.user.login in review_by_user:
|
||||
stored_review = review_by_user[review.user.login]
|
||||
if review.submitted_at >= stored_review.submitted_at:
|
||||
review_by_user[review.user.login] = review
|
||||
else:
|
||||
review_by_user[review.user.login] = review
|
||||
approved_reviews = [
|
||||
review for review in review_by_user.values() if review.state == "APPROVED"
|
||||
]
|
||||
config = settings.config or default_config
|
||||
for approved_label, conf in config.items():
|
||||
logging.debug(f"Processing config: {conf.json()}")
|
||||
if conf.await_label is None or (conf.await_label in pr_label_by_name):
|
||||
logging.debug(f"Processable PR: {pr.number}")
|
||||
if len(approved_reviews) >= conf.number:
|
||||
logging.info(f"Adding label to PR: {pr.number}")
|
||||
pr.add_to_labels(approved_label)
|
||||
if conf.await_label:
|
||||
logging.info(f"Removing label from PR: {pr.number}")
|
||||
pr.remove_from_labels(conf.await_label)
|
||||
logging.info("Finished")
|
||||
Reference in New Issue
Block a user