Compare commits

...

60 Commits

Author SHA1 Message Date
Sebastián Ramírez
f0388915a8 🔖 Release version 0.72.0 2022-01-16 21:09:10 +01:00
Sebastián Ramírez
9e2f5c67b6 📝 Update release notes 2022-01-16 21:08:04 +01:00
github-actions
93e4a19e35 📝 Update release notes 2022-01-16 19:42:33 +00:00
jaystone776
e1c6d7d310 🌐 Update Chinese translation for docs/help-fastapi.md (#3847) 2022-01-16 20:41:59 +01:00
github-actions
d23b295b96 📝 Update release notes 2022-01-16 19:41:49 +00:00
kty4119
26e94116c1 🌐 Fix Korean translation for docs/ko/docs/index.md (#4195)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-16 19:41:13 +00:00
github-actions
24968937e5 📝 Update release notes 2022-01-16 19:37:21 +00:00
MicroPanda123
5c5b889288 🌐 Add Polish translation for docs/pl/docs/index.md (#4245)
Co-authored-by: Dawid Dutkiewicz <dutkiewicz@users.noreply.github.com>
Co-authored-by: Dima Tisnek <dimaqq@gmail.com>
Co-authored-by: Bart Skowron <bxsx@bartskowron.com>
Co-authored-by: Bart Skowron <bart.skowron@rollbar.com>
2022-01-16 19:36:42 +00:00
github-actions
436261b3ea 📝 Update release notes 2022-01-16 19:35:00 +00:00
jaystone776
5c62a59e7b 🌐 Add Chinese translation for docs\tutorial\path-operation-configuration.md (#3312)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-16 19:34:28 +00:00
github-actions
acbe79da37 📝 Update release notes 2022-01-16 19:27:03 +00:00
John Riebold
a85aa125d2 Enable configuring Swagger UI parameters (#2568)
Co-authored-by: Artem Ivanov <artem@worklife.io>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-16 20:26:24 +01:00
github-actions
9af8cc69d5 📝 Update release notes 2022-01-16 14:44:43 +00:00
Sebastián Ramírez
7fe79441c1 📝 Update Python Types docs, add missing 3.6 / 3.9 example (#4434) 2022-01-16 15:44:08 +01:00
github-actions
b8ae84d460 📝 Update release notes 2022-01-16 14:35:21 +00:00
Sebastián Ramírez
ca2b1dbb64 🔧 Enable MkDocs Material Insiders' content.tabs.link (#4399) 2022-01-16 14:34:45 +00:00
Sebastián Ramírez
672c55ac62 🔖 Release version 0.71.0 2022-01-07 18:07:59 +01:00
github-actions
66c27c3e07 📝 Update release notes 2022-01-07 14:19:23 +00:00
github-actions[bot]
44f4885c66 👥 Update FastAPI People (#4354)
Co-authored-by: github-actions <github-actions@github.com>
2022-01-07 15:18:45 +01:00
github-actions
4da33e3031 📝 Update release notes 2022-01-07 14:17:49 +00:00
Sebastián Ramírez
a1ede32f29 🔧 Add FastAPI Trove Classifier for PyPI (#4386) 2022-01-07 14:17:13 +00:00
github-actions
0a82b3a900 📝 Update release notes 2022-01-07 14:12:16 +00:00
Sebastián Ramírez
d08a062ee2 Add docs and tests for Python 3.9 and Python 3.10 (#3712)
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
2022-01-07 15:11:31 +01:00
github-actions
83f6781037 📝 Update release notes 2022-01-07 10:24:43 +00:00
Sebastián Ramírez
764ecae2d4 ⬆ Upgrade MkDocs Material and configs (#4385) 2022-01-07 11:24:00 +01:00
github-actions
4e9f75912f 📝 Update release notes 2022-01-07 09:35:10 +00:00
simondale00
2b10ca1cc4 ⬆️ Upgrade Starlette to 0.17.1 (#4145)
Co-authored-by: Dima Tisnek <dimaqq@gmail.com>
Co-authored-by: simond <simond@surveymonkey.com>
Co-authored-by: Samuel Colvin <s@muelcolvin.com>
Co-authored-by: Samuel Colvin <samcolvin@gmail.com>
2022-01-07 10:34:28 +01:00
Sebastián Ramírez
3efb4f7edf 🔖 Release version 0.70.1 2021-12-12 12:39:32 +01:00
github-actions
9c25f9615c 📝 Update release notes 2021-12-12 11:34:58 +00:00
github-actions[bot]
e7158bc592 👥 Update FastAPI People (#4274)
Co-authored-by: github-actions <github-actions@github.com>
2021-12-12 12:34:18 +01:00
github-actions
6d642ef5fb 📝 Update release notes 2021-12-12 11:29:36 +00:00
Eric Jolibois
b0cd4d7e7e 🐛 Fix JSON Schema for dataclasses, supporting the fixes in Pydantic 1.9 (#4272)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-12 12:28:35 +01:00
github-actions
0a87bc88b8 📝 Update release notes 2021-12-09 10:48:10 +00:00
Nina Hwang
062efcbb5d 🌐 Add Korean translation for docs/tutorial/request-forms-and-files.md (#3744)
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
2021-12-09 11:47:26 +01:00
github-actions
aa4a69f790 📝 Update release notes 2021-12-09 10:45:00 +00:00
github-actions
eb79441a7f 📝 Update release notes 2021-12-09 10:40:14 +00:00
Nina Hwang
fa5639cb35 🌐 Add Korean translation for docs/tutorial/request-files.md (#3743)
Co-authored-by: Spike <rurouni24@gmail.com>
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-08 15:52:01 +00:00
Leandro de Souza
10e3a02582 🌐 Add portuguese translation for docs/tutorial/query-params-str-validations.md (#3965)
Co-authored-by: Mário Victor Ribeiro Silva <mariovictorrs@gmail.com>
Co-authored-by: Leandro de Souza <leandro.souza@fontes.corp>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-08 16:50:35 +01:00
github-actions
fb9c4b31b9 📝 Update release notes 2021-12-08 15:46:19 +00:00
Nina Hwang
39dbee9d56 🌐 Add Korean translation for docs/tutorial/response-status-code.md (#3742)
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-08 16:45:37 +01:00
github-actions
dd463d0dc2 📝 Update release notes 2021-12-08 15:44:10 +00:00
Kwang Soo Jeong
461e0d4cce 🌐 Add Korean translation for Tutorial - JSON Compatible Encoder (#3152) 2021-12-08 16:43:31 +01:00
github-actions
da69a1c4c0 📝 Update release notes 2021-12-08 15:42:12 +00:00
Spike
a5d697b9b5 🌐 Add Korean translation for Tutorial - Path Parameters and Numeric Validations (#2432) 2021-12-08 16:41:26 +01:00
github-actions
8e416875ce 📝 Update release notes 2021-12-08 15:38:10 +00:00
daehyeon kim
446d194c46 🌐 Add Korean translation for docs/ko/docs/deployment/versions.md (#4121)
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
2021-12-08 16:37:30 +01:00
github-actions
cace5a79f7 📝 Update release notes 2021-12-08 15:33:09 +00:00
kimjaeyoonn
dabb4898f1 🌐 Fix Korean translation for docs/ko/docs/tutorial/index.md (#4193) 2021-12-08 15:32:24 +00:00
github-actions
f282c0e207 📝 Update release notes 2021-12-08 15:04:50 +00:00
Sebastián Ramírez
146ff28d9c 🔧 Add CryptAPI sponsor (#4264) 2021-12-08 15:04:04 +00:00
github-actions
58ab733f19 📝 Update release notes 2021-10-26 18:54:22 +00:00
weekwith.me
0a61a6c865 📝 Update docs/tutorial/dependencies/classes-as-dependencies: Add type of query parameters in a description of Classes as dependencies (#4015) 2021-10-26 18:53:40 +00:00
github-actions
fb1f341231 📝 Update release notes 2021-10-26 18:47:42 +00:00
Sam Courtemanche
652cf4bb6b 🌐 Add French translation for Tutorial - First steps (#3455)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-26 18:47:01 +00:00
github-actions
08410ca568 📝 Update release notes 2021-10-26 18:34:11 +00:00
Sam Courtemanche
0d5e0ba5d5 🌐 Add French translation for docs/tutorial/path-params.md (#3548)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-26 18:33:34 +00:00
github-actions
b2c9574fc6 📝 Update release notes 2021-10-26 18:16:12 +00:00
Sam Courtemanche
a859497a72 🌐 Add French translation for docs/tutorial/query-params.md (#3556)
Co-authored-by: Ruidy <ruidy.nemausat@gmail.com>
2021-10-26 20:15:30 +02:00
github-actions
3c93e803d5 📝 Update release notes 2021-10-26 18:14:17 +00:00
bilal alpaslan
0bd8f901df 🌐 Add Turkish translation for docs/python-types.md (#3926) 2021-10-26 20:13:34 +02:00
257 changed files with 17023 additions and 882 deletions

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
fail-fast: false
steps:

View File

@@ -48,6 +48,7 @@ The key features are:
<!-- sponsors -->
<a href="https://bit.ly/2QSouzH" target="_blank" title="Jina: build neural search-as-a-service for any kind of data in just minutes."><img src="https://fastapi.tiangolo.com/img/sponsors/jina.svg"></a>
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
<a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a>
<a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a>
<a href="https://www.vim.so/?utm_source=FastAPI" target="_blank" title="We help you master vim with interactive exercises"><img src="https://fastapi.tiangolo.com/img/sponsors/vimso.png"></a>

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -71,8 +68,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -1,13 +1,13 @@
maintainers:
- login: tiangolo
answers: 1230
prs: 260
prs: 269
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=5cad72c846b7aba2e960546af490edc7375dafc4&v=4
url: https://github.com/tiangolo
experts:
- login: Kludex
count: 299
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
count: 316
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=3682d9b9b93bef272f379ab623dc031c8d71432e&v=4
url: https://github.com/Kludex
- login: dmontagu
count: 262
@@ -30,41 +30,45 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
- login: ArcLightSlavik
count: 68
count: 71
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
url: https://github.com/ArcLightSlavik
- login: raphaelauv
count: 67
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: falkben
count: 57
count: 58
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben
- login: sm-Fifteen
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: raphaelauv
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: insomnes
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: Dustyposa
count: 42
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: includeamin
count: 38
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
- login: Dustyposa
count: 38
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: prostomarkeloff
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
url: https://github.com/prostomarkeloff
- login: STeveShary
count: 32
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
- login: krishnardt
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt
- login: insomnes
count: 30
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: wshayes
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
@@ -73,6 +77,14 @@ experts:
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
url: https://github.com/frankie567
- login: adriangb
count: 28
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
url: https://github.com/adriangb
- login: ghandic
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic
- login: dbanty
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
@@ -85,13 +97,13 @@ experts:
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
- login: STeveShary
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
- login: panla
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla
- login: acnebs
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=bfd127b3e6200f4d00afd714f0fc95c2512df19b&v=4
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
url: https://github.com/acnebs
- login: nsidnev
count: 22
@@ -105,18 +117,10 @@ experts:
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
url: https://github.com/retnikt
- login: ghandic
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic
- login: Hultner
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
url: https://github.com/Hultner
- login: panla
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla
- login: jorgerpo
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
@@ -125,26 +129,30 @@ experts:
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
url: https://github.com/nkhitrov
- login: adriangb
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
url: https://github.com/adriangb
- login: waynerv
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: acidjunk
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: dstlny
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
- login: haizaar
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
url: https://github.com/haizaar
- login: acidjunk
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: David-Lor
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/17401854?u=474680c02b94cba810cb9032fb7eb787d9cc9d22&v=4
url: https://github.com/David-Lor
- login: lowercase00
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/21188280?v=4
url: https://github.com/lowercase00
- login: zamiramir
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
@@ -153,10 +161,6 @@ experts:
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
url: https://github.com/juntatalor
- login: dstlny
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
- login: valentin994
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
@@ -173,43 +177,35 @@ experts:
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/47581948?v=4
url: https://github.com/hellocoldworld
- login: oligond
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/2858306?u=1bb1182a5944e93624b7fb26585f22c8f7a9d76e&v=4
url: https://github.com/oligond
last_month_active:
- login: insomnes
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: raphaelauv
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: jgould22
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: harunyasar
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
url: https://github.com/harunyasar
- login: Kludex
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=3682d9b9b93bef272f379ab623dc031c8d71432e&v=4
url: https://github.com/Kludex
- login: ghandic
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic
- login: STeveShary
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
- login: Honda-a
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/22759187?u=f45bd5fb17b4dca331529b8e9e5eab6122b84b8b&v=4
url: https://github.com/Honda-a
- login: frankie567
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
url: https://github.com/frankie567
- login: panla
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla
- login: dstlny
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
- login: trevorwang
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/121966?v=4
url: https://github.com/trevorwang
- login: klaa97
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/39653693?v=4
url: https://github.com/klaa97
top_contributors:
- login: waynerv
count: 25
@@ -227,14 +223,18 @@ top_contributors:
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: jaystone776
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
- login: mariacamilagl
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
- login: jaystone776
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
- login: Smlep
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: Serrones
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
@@ -245,11 +245,11 @@ top_contributors:
url: https://github.com/RunningIkkyu
- login: Kludex
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=3682d9b9b93bef272f379ab623dc031c8d71432e&v=4
url: https://github.com/Kludex
- login: hard-coders
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: wshayes
count: 5
@@ -263,10 +263,6 @@ top_contributors:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
url: https://github.com/Attsun1031
- login: Smlep
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: jekirl
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
@@ -275,14 +271,22 @@ top_contributors:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
url: https://github.com/jfunez
- login: ycd
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: komtaki
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
url: https://github.com/komtaki
- login: NinaHwang
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
url: https://github.com/NinaHwang
top_reviewers:
- login: Kludex
count: 90
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
count: 91
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=3682d9b9b93bef272f379ab623dc031c8d71432e&v=4
url: https://github.com/Kludex
- login: waynerv
count: 47
@@ -297,29 +301,37 @@ top_reviewers:
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: ycd
count: 43
count: 44
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: AdrianDeAnda
count: 32
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
url: https://github.com/AdrianDeAnda
- login: ArcLightSlavik
count: 27
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
url: https://github.com/ArcLightSlavik
- login: dmontagu
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: cassiobotaro
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
- login: komtaki
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
url: https://github.com/komtaki
- login: cassiobotaro
- login: hard-coders
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: 0417taehyun
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
url: https://github.com/0417taehyun
- login: yanever
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/21978760?v=4
@@ -328,10 +340,14 @@ top_reviewers:
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc
- login: hard-coders
- login: Smlep
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
url: https://github.com/hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: DevDae
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
url: https://github.com/DevDae
- login: pedabraham
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
@@ -340,10 +356,6 @@ top_reviewers:
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
url: https://github.com/delhi09
- login: Smlep
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: lsglucas
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
@@ -360,6 +372,10 @@ top_reviewers:
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
url: https://github.com/sh0nk
- login: yezz123
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
url: https://github.com/yezz123
- login: mariacamilagl
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
@@ -372,18 +388,34 @@ top_reviewers:
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
url: https://github.com/maoyibo
- login: graingert
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
url: https://github.com/graingert
- login: PandaHun
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
url: https://github.com/PandaHun
- login: kty4119
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/49435654?v=4
url: https://github.com/kty4119
- login: bezaca
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
url: https://github.com/bezaca
- login: solomein-sv
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
url: https://github.com/solomein-sv
- login: blt232018
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
url: https://github.com/blt232018
- login: ComicShrimp
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
- login: Serrones
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
@@ -396,10 +428,10 @@ top_reviewers:
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: graingert
- login: BilalAlpaslan
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
url: https://github.com/graingert
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
url: https://github.com/BilalAlpaslan
- login: NastasiaSaby
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
@@ -408,26 +440,26 @@ top_reviewers:
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: solomein-sv
- login: krocdort
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
url: https://github.com/solomein-sv
- login: ComicShrimp
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
avatarUrl: https://avatars.githubusercontent.com/u/34248814?v=4
url: https://github.com/krocdort
- login: jovicon
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
url: https://github.com/jovicon
- login: BilalAlpaslan
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
url: https://github.com/BilalAlpaslan
- login: diogoduartec
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31852339?u=b50fc11c531e9b77922e19edfc9e7233d4d7b92e&v=4
url: https://github.com/diogoduartec
- login: nimctl
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/49960770?u=e39b11d47188744ee07b2a1c7ce1a1bdf3c80760&v=4
url: https://github.com/nimctl
- login: israteneda
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/20668624?u=d7b2961d330aca65fbce5bdb26a0800a3d23ed2d&v=4
url: https://github.com/israteneda
- login: juntatalor
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
@@ -444,35 +476,7 @@ top_reviewers:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
url: https://github.com/oandersonmagalhaes
- login: euri10
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: rkbeatss
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/23391143?u=56ab6bff50be950fa8cae5cf736f2ae66e319ff3&v=4
url: https://github.com/rkbeatss
- login: izaguerreiro
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
url: https://github.com/izaguerreiro
- login: aviramha
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/41201924?u=6883cc4fc13a7b2e60d4deddd4be06f9c5287880&v=4
url: https://github.com/aviramha
- login: Cajuteq
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/26676532?u=8ee0422981810e51480855de1c0d67b6b79cd3f2&v=4
url: https://github.com/Cajuteq
- login: Zxilly
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/31370133?v=4
url: https://github.com/Zxilly
- login: dukkee
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/36825394?u=ccfd86e6a4f2d093dad6f7544cc875af67fa2df8&v=4
url: https://github.com/dukkee
- login: Bluenix2
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/38372706?u=c9d28aff15958d6ebf1971148bfb3154ff943c4f&v=4
url: https://github.com/Bluenix2
- login: qysfblog
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/52229895?v=4
url: https://github.com/qysfblog

View File

@@ -2,6 +2,9 @@ gold:
- url: https://bit.ly/2QSouzH
title: "Jina: build neural search-as-a-service for any kind of data in just minutes."
img: https://fastapi.tiangolo.com/img/sponsors/jina.svg
- url: https://cryptapi.io/
title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg
silver:
- url: https://www.deta.sh/?ref=fastapi
title: The launchpad for all your (team's) ideas

View File

@@ -6,3 +6,4 @@ logins:
- mikeckennedy
- koaning
- deepset-ai
- cryptapi

View File

@@ -233,3 +233,82 @@ Now, to be able to test that everything works, create a *path operation*:
Now, you should be able to disconnect your WiFi, go to your docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, and reload the page.
And even without Internet, you would be able to see the docs for your API and interact with it.
## Configuring Swagger UI
You can configure some extra <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">Swagger UI parameters</a>.
To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.
`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly.
FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs.
### Disable Syntax Highlighting
For example, you could disable syntax highlighting in Swagger UI.
Without changing the settings, syntax highlighting is enabled by default:
<img src="/img/tutorial/extending-openapi/image02.png">
But you can disable it by setting `syntaxHighlight` to `False`:
```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial003.py!}
```
...and then Swagger UI won't show the syntax highlighting anymore:
<img src="/img/tutorial/extending-openapi/image03.png">
### Change the Theme
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial004.py!}
```
That configuration would change the syntax highlighting color theme:
<img src="/img/tutorial/extending-openapi/image04.png">
### Change Default Swagger UI Parameters
FastAPI includes some default configuration parameters appropriate for most of the use cases.
It includes these default configurations:
```Python
{!../../../fastapi/openapi/docs.py[ln:7-13]!}
```
You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial005.py!}
```
### Other Swagger UI Parameters
To see all the other possible configurations you can use, read the official <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">docs for Swagger UI parameters</a>.
### JavaScript-only settings
Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).
FastAPI also includes these JavaScript-only `presets` settings:
```JavaScript
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
]
```
These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.

View File

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 131 KiB

View File

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 108 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -148,37 +148,62 @@ You can use, for example:
There are some data structures that can contain other values, like `dict`, `list`, `set` and `tuple`. And the internal values can have their own type too.
To declare those types and the internal types, you can use the standard Python module `typing`.
These types that have internal types are called "**generic**" types. And it's possible to declare them, even with their internal types.
It exists specifically to support these type hints.
To declare those types and the internal types, you can use the standard Python module `typing`. It exists specifically to support these type hints.
#### `List`
#### Newer versions of Python
The syntax using `typing` is **compatible** with all versions, from Python 3.6 to the latest ones, including Python 3.9, Python 3.10, etc.
As Python advances, **newer versions** come with improved support for these type annotations and in many cases you won't even need to import and use the `typing` module to declare the type annotations.
If you can chose a more recent version of Python for your project, you will be able to take advantage of that extra simplicity. See some examples below.
#### List
For example, let's define a variable to be a `list` of `str`.
From `typing`, import `List` (with a capital `L`):
=== "Python 3.6 and above"
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial006.py!}
```
From `typing`, import `List` (with a capital `L`):
Declare the variable, with the same colon (`:`) syntax.
``` Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial006.py!}
```
As the type, put the `List`.
Declare the variable, with the same colon (`:`) syntax.
As the list is a type that contains some internal types, you put them in square brackets:
As the type, put the `List` that you imported from `typing`.
```Python hl_lines="4"
{!../../../docs_src/python_types/tutorial006.py!}
```
As the list is a type that contains some internal types, you put them in square brackets:
!!! tip
```Python hl_lines="4"
{!> ../../../docs_src/python_types/tutorial006.py!}
```
=== "Python 3.9 and above"
Declare the variable, with the same colon (`:`) syntax.
As the type, put `list`.
As the list is a type that contains some internal types, you put them in square brackets:
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial006_py39.py!}
```
!!! info
Those internal types in the square brackets are called "type parameters".
In this case, `str` is the type parameter passed to `List`.
In this case, `str` is the type parameter passed to `List` (or `list` in Python 3.9 and above).
That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
!!! tip
If you use Python 3.9 or above, you don't have to import `List` from `typing`, you can use the same regular `list` type instead.
By doing that, your editor can provide support even while processing items from the list:
<img src="/img/python-types/image05.png">
@@ -189,20 +214,28 @@ Notice that the variable `item` is one of the elements in the list `items`.
And still, the editor knows it is a `str`, and provides support for that.
#### `Tuple` and `Set`
#### Tuple and Set
You would do the same to declare `tuple`s and `set`s:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial007.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial007.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial007_py39.py!}
```
This means:
* The variable `items_t` is a `tuple` with 3 items, an `int`, another `int`, and a `str`.
* The variable `items_s` is a `set`, and each of its items is of type `bytes`.
#### `Dict`
#### Dict
To define a `dict`, you pass 2 type parameters, separated by commas.
@@ -210,9 +243,17 @@ The first type parameter is for the keys of the `dict`.
The second type parameter is for the values of the `dict`:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial008.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial008.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial008_py39.py!}
```
This means:
@@ -220,9 +261,33 @@ This means:
* The keys of this `dict` are of type `str` (let's say, the name of each item).
* The values of this `dict` are of type `float` (let's say, the price of each item).
#### `Optional`
#### Union
You can also use `Optional` to declare that a variable has a type, like `str`, but that it is "optional", which means that it could also be `None`:
You can declare that a variable can be any of **several types**, for example, an `int` or a `str`.
In Python 3.6 and above (including Python 3.10) you can use the `Union` type from `typing` and put inside the square brackets the possible types to accept.
In Python 3.10 there's also an **alternative syntax** were you can put the possible types separated by a <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr>.
=== "Python 3.6 and above"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial008b.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial008b_py310.py!}
```
In both cases this means that `item` could be an `int` or a `str`.
#### Possibly `None`
You can declare that a value could have a type, like `str`, but that it could also be `None`.
In Python 3.6 and above (including Python 3.10) you can declare it by importing and using `Optional` from the `typing` module.
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial009.py!}
@@ -230,18 +295,73 @@ You can also use `Optional` to declare that a variable has a type, like `str`, b
Using `Optional[str]` instead of just `str` will let the editor help you detecting errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
`Optional[Something]` is actually a shortcut for `Union[Something, None]`, they are equivalent.
This also means that in Python 3.10, you can use `Something | None`:
=== "Python 3.6 and above"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial009.py!}
```
=== "Python 3.6 and above - alternative"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial009b.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial009_py310.py!}
```
#### Generic types
These types that take type parameters in square brackets, like:
These types that take type parameters in square brackets are called **Generic types** or **Generics**, for example:
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Optional`
* ...and others.
=== "Python 3.6 and above"
are called **Generic types** or **Generics**.
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Union`
* `Optional`
* ...and others.
=== "Python 3.9 and above"
You can use the same builtin types as generics (with square brakets and types inside):
* `list`
* `tuple`
* `set`
* `dict`
And the same as with Python 3.6, from the `typing` module:
* `Union`
* `Optional`
* ...and others.
=== "Python 3.10 and above"
You can use the same builtin types as generics (with square brakets and types inside):
* `list`
* `tuple`
* `set`
* `dict`
And the same as with Python 3.6, from the `typing` module:
* `Union`
* `Optional` (the same as with Python 3.6)
* ...and others.
In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> to declare unions of types.
### Classes as types
@@ -275,11 +395,25 @@ Then you create an instance of that class with some values and it will validate
And you get all the editor support with that resulting object.
Taken from the official Pydantic docs:
An example from the official Pydantic docs:
```Python
{!../../../docs_src/python_types/tutorial011.py!}
```
=== "Python 3.6 and above"
```Python
{!> ../../../docs_src/python_types/tutorial011.py!}
```
=== "Python 3.9 and above"
```Python
{!> ../../../docs_src/python_types/tutorial011_py39.py!}
```
=== "Python 3.10 and above"
```Python
{!> ../../../docs_src/python_types/tutorial011_py310.py!}
```
!!! info
To learn more about <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic, check its docs</a>.

View File

@@ -3,6 +3,71 @@
## Latest Changes
## 0.72.0
### Features
* ✨ Enable configuring Swagger UI parameters. Original PR [#2568](https://github.com/tiangolo/fastapi/pull/2568) by [@jmriebold](https://github.com/jmriebold). Here are the new docs: [Configuring Swagger UI](https://fastapi.tiangolo.com/advanced/extending-openapi/#configuring-swagger-ui).
### Docs
* 📝 Update Python Types docs, add missing 3.6 / 3.9 example. PR [#4434](https://github.com/tiangolo/fastapi/pull/4434) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update Chinese translation for `docs/help-fastapi.md`. PR [#3847](https://github.com/tiangolo/fastapi/pull/3847) by [@jaystone776](https://github.com/jaystone776).
* 🌐 Fix Korean translation for `docs/ko/docs/index.md`. PR [#4195](https://github.com/tiangolo/fastapi/pull/4195) by [@kty4119](https://github.com/kty4119).
* 🌐 Add Polish translation for `docs/pl/docs/index.md`. PR [#4245](https://github.com/tiangolo/fastapi/pull/4245) by [@MicroPanda123](https://github.com/MicroPanda123).
* 🌐 Add Chinese translation for `docs\tutorial\path-operation-configuration.md`. PR [#3312](https://github.com/tiangolo/fastapi/pull/3312) by [@jaystone776](https://github.com/jaystone776).
### Internal
* 🔧 Enable MkDocs Material Insiders' `content.tabs.link`. PR [#4399](https://github.com/tiangolo/fastapi/pull/4399) by [@tiangolo](https://github.com/tiangolo).
## 0.71.0
### Features
* ✨ Add docs and tests for Python 3.9 and Python 3.10. PR [#3712](https://github.com/tiangolo/fastapi/pull/3712) by [@tiangolo](https://github.com/tiangolo).
* You can start with [Python Types Intro](https://fastapi.tiangolo.com/python-types/), it explains what changes between different Python versions, in Python 3.9 and in Python 3.10.
* All the FastAPI docs are updated. Each code example in the docs that could use different syntax in Python 3.9 or Python 3.10 now has all the alternatives in tabs.
* ⬆️ Upgrade Starlette to 0.17.1. PR [#4145](https://github.com/tiangolo/fastapi/pull/4145) by [@simondale00](https://github.com/simondale00).
### Internal
* 👥 Update FastAPI People. PR [#4354](https://github.com/tiangolo/fastapi/pull/4354) by [@github-actions[bot]](https://github.com/apps/github-actions).
* 🔧 Add FastAPI Trove Classifier for PyPI as now there's one 🤷😁. PR [#4386](https://github.com/tiangolo/fastapi/pull/4386) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Upgrade MkDocs Material and configs. PR [#4385](https://github.com/tiangolo/fastapi/pull/4385) by [@tiangolo](https://github.com/tiangolo).
## 0.70.1
There's nothing interesting in this particular FastAPI release. It is mainly to enable/unblock the release of the next version of Pydantic that comes packed with features and improvements. 🤩
### Fixes
* 🐛 Fix JSON Schema for dataclasses, supporting the fixes in Pydantic 1.9. PR [#4272](https://github.com/tiangolo/fastapi/pull/4272) by [@PrettyWood](https://github.com/PrettyWood).
### Translations
* 🌐 Add Korean translation for `docs/tutorial/request-forms-and-files.md`. PR [#3744](https://github.com/tiangolo/fastapi/pull/3744) by [@NinaHwang](https://github.com/NinaHwang).
* 🌐 Add Korean translation for `docs/tutorial/request-files.md`. PR [#3743](https://github.com/tiangolo/fastapi/pull/3743) by [@NinaHwang](https://github.com/NinaHwang).
* 🌐 Add portuguese translation for `docs/tutorial/query-params-str-validations.md`. PR [#3965](https://github.com/tiangolo/fastapi/pull/3965) by [@leandrodesouzadev](https://github.com/leandrodesouzadev).
* 🌐 Add Korean translation for `docs/tutorial/response-status-code.md`. PR [#3742](https://github.com/tiangolo/fastapi/pull/3742) by [@NinaHwang](https://github.com/NinaHwang).
* 🌐 Add Korean translation for Tutorial - JSON Compatible Encoder. PR [#3152](https://github.com/tiangolo/fastapi/pull/3152) by [@NEONKID](https://github.com/NEONKID).
* 🌐 Add Korean translation for Tutorial - Path Parameters and Numeric Validations. PR [#2432](https://github.com/tiangolo/fastapi/pull/2432) by [@hard-coders](https://github.com/hard-coders).
* 🌐 Add Korean translation for `docs/ko/docs/deployment/versions.md`. PR [#4121](https://github.com/tiangolo/fastapi/pull/4121) by [@DevDae](https://github.com/DevDae).
* 🌐 Fix Korean translation for `docs/ko/docs/tutorial/index.md`. PR [#4193](https://github.com/tiangolo/fastapi/pull/4193) by [@kimjaeyoonn](https://github.com/kimjaeyoonn).
* 🔧 Add CryptAPI sponsor. PR [#4264](https://github.com/tiangolo/fastapi/pull/4264) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update `docs/tutorial/dependencies/classes-as-dependencies`: Add type of query parameters in a description of `Classes as dependencies`. PR [#4015](https://github.com/tiangolo/fastapi/pull/4015) by [@0417taehyun](https://github.com/0417taehyun).
* 🌐 Add French translation for Tutorial - First steps. PR [#3455](https://github.com/tiangolo/fastapi/pull/3455) by [@Smlep](https://github.com/Smlep).
* 🌐 Add French translation for `docs/tutorial/path-params.md`. PR [#3548](https://github.com/tiangolo/fastapi/pull/3548) by [@Smlep](https://github.com/Smlep).
* 🌐 Add French translation for `docs/tutorial/query-params.md`. PR [#3556](https://github.com/tiangolo/fastapi/pull/3556) by [@Smlep](https://github.com/Smlep).
* 🌐 Add Turkish translation for `docs/python-types.md`. PR [#3926](https://github.com/tiangolo/fastapi/pull/3926) by [@BilalAlpaslan](https://github.com/BilalAlpaslan).
### Internal
* 👥 Update FastAPI People. PR [#4274](https://github.com/tiangolo/fastapi/pull/4274) by [@github-actions[bot]](https://github.com/apps/github-actions).
## 0.70.0
This release just upgrades Starlette to the latest version, `0.16.0`, which includes several bug fixes and some small breaking changes.

View File

@@ -57,9 +57,17 @@ Using `BackgroundTasks` also works with the dependency injection system, you can
**FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards:
```Python hl_lines="13 15 22 25"
{!../../../docs_src/background_tasks/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="13 15 22 25"
{!> ../../../docs_src/background_tasks/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="11 13 20 23"
{!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
```
In this example, the messages will be written to the `log.txt` file *after* the response is sent.

View File

@@ -6,9 +6,17 @@ The same way you can declare additional validation and metadata in *path operati
First, you have to import it:
```Python hl_lines="4"
{!../../../docs_src/body_fields/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="4"
{!> ../../../docs_src/body_fields/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="2"
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
!!! warning
Notice that `Field` is imported directly from `pydantic`, not from `fastapi` as are all the rest (`Query`, `Path`, `Body`, etc).
@@ -17,9 +25,17 @@ First, you have to import it:
You can then use `Field` with model attributes:
```Python hl_lines="11-14"
{!../../../docs_src/body_fields/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="11-14"
{!> ../../../docs_src/body_fields/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="9-12"
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
`Field` works the same way as `Query`, `Path` and `Body`, it has all the same parameters, etc.

View File

@@ -8,9 +8,17 @@ First, of course, you can mix `Path`, `Query` and request body parameter declara
And you can also declare body parameters as optional, by setting the default to `None`:
```Python hl_lines="19-21"
{!../../../docs_src/body_multiple_params/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="19-21"
{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17-19"
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
```
!!! note
Notice that, in this case, the `item` that would be taken from the body is optional. As it has a `None` default value.
@@ -30,9 +38,17 @@ In the previous example, the *path operations* would expect a JSON body with the
But you can also declare multiple body parameters, e.g. `item` and `user`:
```Python hl_lines="22"
{!../../../docs_src/body_multiple_params/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="20"
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
```
In this case, **FastAPI** will notice that there are more than one body parameters in the function (two parameters that are Pydantic models).
@@ -71,14 +87,20 @@ If you declare it as is, because it is a singular value, **FastAPI** will assume
But you can instruct **FastAPI** to treat it as another body key using `Body`:
=== "Python 3.6 and above"
```Python hl_lines="23"
{!../../../docs_src/body_multiple_params/tutorial003.py!}
```
```Python hl_lines="23"
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="21"
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
```
In this case, **FastAPI** will expect a body like:
```JSON
{
"item": {
@@ -107,12 +129,26 @@ As, by default, singular values are interpreted as query parameters, you don't h
q: Optional[str] = None
```
as in:
Or in Python 3.10 and above:
```Python hl_lines="28"
{!../../../docs_src/body_multiple_params/tutorial004.py!}
```Python
q: str | None = None
```
For example:
=== "Python 3.6 and above"
```Python hl_lines="28"
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="26"
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
```
!!! info
`Body` also has all the same extra validation and metadata parameters as `Query`,`Path` and others you will see later.
@@ -131,9 +167,17 @@ item: Item = Body(..., embed=True)
as in:
```Python hl_lines="17"
{!../../../docs_src/body_multiple_params/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="17"
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="15"
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
```
In this case **FastAPI** will expect a body like:

View File

@@ -6,9 +6,17 @@ With **FastAPI**, you can define, validate, document, and use arbitrarily deeply
You can define an attribute to be a subtype. For example, a Python `list`:
```Python hl_lines="14"
{!../../../docs_src/body_nested_models/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="12"
{!> ../../../docs_src/body_nested_models/tutorial001_py310.py!}
```
This will make `tags` be a list of items. Although it doesn't declare the type of each of the items.
@@ -18,19 +26,29 @@ But Python has a specific way to declare lists with internal types, or "type par
### Import typing's `List`
First, import `List` from standard Python's `typing` module:
In Python 3.9 and above you can use the standard `list` to declare these type annotations as we'll see below. 💡
But in Python versions before 3.9 (3.6 and above), you first need to import `List` from standard Python's `typing` module:
```Python hl_lines="1"
{!../../../docs_src/body_nested_models/tutorial002.py!}
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
```
### Declare a `List` with a type parameter
### Declare a `list` with a type parameter
To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`:
* Import them from the `typing` module
* If you are in a Python version lower than 3.9, import their equivalent version from the `typing` module
* Pass the internal type(s) as "type parameters" using square brackets: `[` and `]`
In Python 3.9 it would be:
```Python
my_list: list[str]
```
In versions of Python before 3.9, it would be:
```Python
from typing import List
@@ -43,9 +61,23 @@ Use that same standard syntax for model attributes with internal types.
So, in our example, we can make `tags` be specifically a "list of strings":
```Python hl_lines="14"
{!../../../docs_src/body_nested_models/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial002_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="12"
{!> ../../../docs_src/body_nested_models/tutorial002_py310.py!}
```
## Set types
@@ -53,11 +85,25 @@ But then we think about it, and realize that tags shouldn't repeat, they would p
And Python has a special data type for sets of unique items, the `set`.
Then we can import `Set` and declare `tags` as a `set` of `str`:
Then we can declare `tags` as a set of strings:
```Python hl_lines="1 14"
{!../../../docs_src/body_nested_models/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="1 14"
{!> ../../../docs_src/body_nested_models/tutorial003.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial003_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="12"
{!> ../../../docs_src/body_nested_models/tutorial003_py310.py!}
```
With this, even if you receive a request with duplicate data, it will be converted to a set of unique items.
@@ -79,17 +125,45 @@ All that, arbitrarily nested.
For example, we can define an `Image` model:
```Python hl_lines="9-11"
{!../../../docs_src/body_nested_models/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9-11"
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="9-11"
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7-9"
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
```
### Use the submodel as a type
And then we can use it as the type of an attribute:
```Python hl_lines="20"
{!../../../docs_src/body_nested_models/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="18"
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
```
This would mean that **FastAPI** would expect a body similar to:
@@ -122,9 +196,23 @@ To see all the options you have, checkout the docs for <a href="https://pydantic
For example, as in the `Image` model we have a `url` field, we can declare it to be instead of a `str`, a Pydantic's `HttpUrl`:
```Python hl_lines="4 10"
{!../../../docs_src/body_nested_models/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="4 10"
{!> ../../../docs_src/body_nested_models/tutorial005.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="4 10"
{!> ../../../docs_src/body_nested_models/tutorial005_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="2 8"
{!> ../../../docs_src/body_nested_models/tutorial005_py310.py!}
```
The string will be checked to be a valid URL, and documented in JSON Schema / OpenAPI as such.
@@ -132,9 +220,23 @@ The string will be checked to be a valid URL, and documented in JSON Schema / Op
You can also use Pydantic models as subtypes of `list`, `set`, etc:
```Python hl_lines="20"
{!../../../docs_src/body_nested_models/tutorial006.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial006.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial006_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="18"
{!> ../../../docs_src/body_nested_models/tutorial006_py310.py!}
```
This will expect (convert, validate, document, etc) a JSON body like:
@@ -169,9 +271,23 @@ This will expect (convert, validate, document, etc) a JSON body like:
You can define arbitrarily deeply nested models:
```Python hl_lines="9 14 20 23 27"
{!../../../docs_src/body_nested_models/tutorial007.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9 14 20 23 27"
{!> ../../../docs_src/body_nested_models/tutorial007.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="9 14 20 23 27"
{!> ../../../docs_src/body_nested_models/tutorial007_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7 12 18 21 25"
{!> ../../../docs_src/body_nested_models/tutorial007_py310.py!}
```
!!! info
Notice how `Offer` has a list of `Item`s, which in turn have an optional list of `Image`s
@@ -184,11 +300,25 @@ If the top level value of the JSON body you expect is a JSON `array` (a Python `
images: List[Image]
```
or in Python 3.9 and above:
```Python
images: list[Image]
```
as in:
```Python hl_lines="15"
{!../../../docs_src/body_nested_models/tutorial008.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="15"
{!> ../../../docs_src/body_nested_models/tutorial008.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="13"
{!> ../../../docs_src/body_nested_models/tutorial008_py39.py!}
```
## Editor support everywhere
@@ -218,9 +348,17 @@ That's what we are going to see here.
In this case, you would accept any `dict` as long as it has `int` keys with `float` values:
```Python hl_lines="9"
{!../../../docs_src/body_nested_models/tutorial009.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/body_nested_models/tutorial009.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="7"
{!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
```
!!! tip
Have in mind that JSON only supports `str` as keys.

View File

@@ -6,9 +6,23 @@ To update an item you can use the <a href="https://developer.mozilla.org/en-US/d
You can use the `jsonable_encoder` to convert the input data to data that can be stored as JSON (e.g. with a NoSQL database). For example, converting `datetime` to `str`.
```Python hl_lines="30-35"
{!../../../docs_src/body_updates/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="30-35"
{!> ../../../docs_src/body_updates/tutorial001.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="30-35"
{!> ../../../docs_src/body_updates/tutorial001_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="28-33"
{!> ../../../docs_src/body_updates/tutorial001_py310.py!}
```
`PUT` is used to receive data that should replace the existing data.
@@ -53,9 +67,23 @@ That would generate a `dict` with only the data that was set when creating the `
Then you can use this to generate a `dict` with only the data that was set (sent in the request), omitting default values:
```Python hl_lines="34"
{!../../../docs_src/body_updates/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="34"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="34"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="32"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
### Using Pydantic's `update` parameter
@@ -63,9 +91,23 @@ Now, you can create a copy of the existing model using `.copy()`, and pass the `
Like `stored_item_model.copy(update=update_data)`:
```Python hl_lines="35"
{!../../../docs_src/body_updates/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="35"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="35"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="33"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
### Partial updates recap
@@ -82,9 +124,23 @@ In summary, to apply partial updates you would:
* Save the data to your DB.
* Return the updated model.
```Python hl_lines="30-37"
{!../../../docs_src/body_updates/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="30-37"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="30-37"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="28-35"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
!!! tip
You can actually use this same technique with an HTTP `PUT` operation.

View File

@@ -19,9 +19,17 @@ To declare a **request** body, you use <a href="https://pydantic-docs.helpmanual
First, you need to import `BaseModel` from `pydantic`:
```Python hl_lines="4"
{!../../../docs_src/body/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="4"
{!> ../../../docs_src/body/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="2"
{!> ../../../docs_src/body/tutorial001_py310.py!}
```
## Create your data model
@@ -29,9 +37,17 @@ Then you declare your data model as a class that inherits from `BaseModel`.
Use standard Python types for all the attributes:
```Python hl_lines="7-11"
{!../../../docs_src/body/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="7-11"
{!> ../../../docs_src/body/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="5-9"
{!> ../../../docs_src/body/tutorial001_py310.py!}
```
The same as when declaring query parameters, when a model attribute has a default value, it is not required. Otherwise, it is required. Use `None` to make it just optional.
@@ -59,9 +75,17 @@ For example, this model above declares a JSON "`object`" (or Python `dict`) like
To add it to your *path operation*, declare it the same way you declared path and query parameters:
```Python hl_lines="18"
{!../../../docs_src/body/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="18"
{!> ../../../docs_src/body/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="16"
{!> ../../../docs_src/body/tutorial001_py310.py!}
```
...and declare its type as the model you created, `Item`.
@@ -125,9 +149,17 @@ But you would get the same editor support with <a href="https://www.jetbrains.co
Inside of the function, you can access all the attributes of the model object directly:
```Python hl_lines="21"
{!../../../docs_src/body/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="21"
{!> ../../../docs_src/body/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="19"
{!> ../../../docs_src/body/tutorial002_py310.py!}
```
## Request body + path parameters
@@ -135,9 +167,17 @@ You can declare path parameters and request body at the same time.
**FastAPI** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared to be Pydantic models should be **taken from the request body**.
```Python hl_lines="17-18"
{!../../../docs_src/body/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="17-18"
{!> ../../../docs_src/body/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="15-16"
{!> ../../../docs_src/body/tutorial003_py310.py!}
```
## Request body + path + query parameters
@@ -145,9 +185,17 @@ You can also declare **body**, **path** and **query** parameters, all at the sam
**FastAPI** will recognize each of them and take the data from the correct place.
```Python hl_lines="18"
{!../../../docs_src/body/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="18"
{!> ../../../docs_src/body/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="16"
{!> ../../../docs_src/body/tutorial004_py310.py!}
```
The function parameters will be recognized as follows:

View File

@@ -6,9 +6,17 @@ You can define Cookie parameters the same way you define `Query` and `Path` para
First import `Cookie`:
```Python hl_lines="3"
{!../../../docs_src/cookie_params/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
## Declare `Cookie` parameters
@@ -16,9 +24,17 @@ Then declare the cookie parameters using the same structure as with `Path` and `
The first value is the default value, you can pass all the extra validation or annotation parameters:
```Python hl_lines="9"
{!../../../docs_src/cookie_params/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
!!! note "Technical Details"
`Cookie` is a "sister" class of `Path` and `Query`. It also inherits from the same common `Param` class.

View File

@@ -6,9 +6,17 @@ Before diving deeper into the **Dependency Injection** system, let's upgrade the
In the previous example, we were returning a `dict` from our dependency ("dependable"):
```Python hl_lines="9"
{!../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
But then we get a `dict` in the parameter `commons` of the *path operation function*.
@@ -71,29 +79,53 @@ That also applies to callables with no parameters at all. The same as it would b
Then, we can change the dependency "dependable" `common_parameters` from above to the class `CommonQueryParams`:
```Python hl_lines="11-15"
{!../../../docs_src/dependencies/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="11-15"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="9-13"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
Pay attention to the `__init__` method used to create the instance of the class:
```Python hl_lines="12"
{!../../../docs_src/dependencies/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="10"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
...it has the same parameters as our previous `common_parameters`:
```Python hl_lines="8"
{!../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="8"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="6"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
Those parameters are what **FastAPI** will use to "solve" the dependency.
In both cases, it will have:
* an optional `q` query parameter.
* a `skip` query parameter, with a default of `0`.
* a `limit` query parameter, with a default of `100`.
* An optional `q` query parameter that is a `str`.
* A `skip` query parameter that is an `int`, with a default of `0`.
* A `limit` query parameter that is an `int`, with a default of `100`.
In both cases the data will be converted, validated, documented on the OpenAPI schema, etc.
@@ -101,9 +133,17 @@ In both cases the data will be converted, validated, documented on the OpenAPI s
Now you can declare your dependency using this class.
```Python hl_lines="19"
{!../../../docs_src/dependencies/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
**FastAPI** calls the `CommonQueryParams` class. This creates an "instance" of that class and the instance will be passed as the parameter `commons` to your function.
@@ -143,9 +183,17 @@ commons = Depends(CommonQueryParams)
..as in:
```Python hl_lines="19"
{!../../../docs_src/dependencies/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
```
But declaring the type is encouraged as that way your editor will know what will be passed as the parameter `commons`, and then it can help you with code completion, type checks, etc:
@@ -179,9 +227,17 @@ You declare the dependency as the type of the parameter, and you use `Depends()`
The same example would then look like:
```Python hl_lines="19"
{!../../../docs_src/dependencies/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
```
...and **FastAPI** will know what to do.

View File

@@ -31,9 +31,17 @@ Let's first focus on the dependency.
It is just a function that can take all the same parameters that a *path operation function* can take:
```Python hl_lines="8-9"
{!../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="8-9"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="6-7"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
That's it.
@@ -55,17 +63,33 @@ And then it just returns a `dict` containing those values.
### Import `Depends`
```Python hl_lines="3"
{!../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
### Declare the dependency, in the "dependant"
The same way you use `Body`, `Query`, etc. with your *path operation function* parameters, use `Depends` with a new parameter:
```Python hl_lines="13 18"
{!../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="13 18"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="11 16"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
Although you use `Depends` in the parameters of your function the same way you use `Body`, `Query`, etc, `Depends` works a bit differently.

View File

@@ -6,25 +6,41 @@ They can be as **deep** as you need them to be.
**FastAPI** will take care of solving them.
### First dependency "dependable"
## First dependency "dependable"
You could create a first dependency ("dependable") like:
```Python hl_lines="8-9"
{!../../../docs_src/dependencies/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="8-9"
{!> ../../../docs_src/dependencies/tutorial005.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="6-7"
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
```
It declares an optional query parameter `q` as a `str`, and then it just returns it.
This is quite simple (not very useful), but will help us focus on how the sub-dependencies work.
### Second dependency, "dependable" and "dependant"
## Second dependency, "dependable" and "dependant"
Then you can create another dependency function (a "dependable") that at the same time declares a dependency of its own (so it is a "dependant" too):
```Python hl_lines="13"
{!../../../docs_src/dependencies/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="13"
{!> ../../../docs_src/dependencies/tutorial005.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="11"
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
```
Let's focus on the parameters declared:
@@ -33,13 +49,21 @@ Let's focus on the parameters declared:
* It also declares an optional `last_query` cookie, as a `str`.
* If the user didn't provide any query `q`, we use the last query used, which we saved to a cookie before.
### Use the dependency
## Use the dependency
Then we can use the dependency with:
```Python hl_lines="21"
{!../../../docs_src/dependencies/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="21"
{!> ../../../docs_src/dependencies/tutorial005.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
```
!!! info
Notice that we are only declaring one dependency in the *path operation function*, the `query_or_cookie_extractor`.

View File

@@ -20,9 +20,17 @@ You can use `jsonable_encoder` for that.
It receives an object, like a Pydantic model, and returns a JSON compatible version:
```Python hl_lines="5 22"
{!../../../docs_src/encoder/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="5 22"
{!> ../../../docs_src/encoder/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="4 21"
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
```
In this example, it would convert the Pydantic model to a `dict`, and the `datetime` to a `str`.

View File

@@ -55,12 +55,28 @@ Here are some of the additional data types you can use:
Here's an example *path operation* with parameters using some of the above types.
```Python hl_lines="1 3 12-16"
{!../../../docs_src/extra_data_types/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="1 3 12-16"
{!> ../../../docs_src/extra_data_types/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1 2 11-15"
{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
```
Note that the parameters inside the function have their natural data type, and you can, for example, perform normal date manipulations, like:
```Python hl_lines="18-19"
{!../../../docs_src/extra_data_types/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="18-19"
{!> ../../../docs_src/extra_data_types/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17-18"
{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
```

View File

@@ -17,9 +17,17 @@ This is especially the case for user models, because:
Here's a general idea of how the models could look like with their password fields and the places where they are used:
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
{!../../../docs_src/extra_models/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
{!> ../../../docs_src/extra_models/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
```
### About `**user_in.dict()`
@@ -150,9 +158,17 @@ All the data conversion, validation, documentation, etc. will still work as norm
That way, we can declare just the differences between the models (with plaintext `password`, with `hashed_password` and without password):
```Python hl_lines="9 15-16 19-20 23-24"
{!../../../docs_src/extra_models/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9 15-16 19-20 23-24"
{!> ../../../docs_src/extra_models/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7 13-14 17-18 21-22"
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
```
## `Union` or `anyOf`
@@ -165,19 +181,49 @@ To do that, use the standard Python type hint <a href="https://docs.python.org/3
!!! note
When defining a <a href="https://pydantic-docs.helpmanual.io/usage/types/#unions" class="external-link" target="_blank">`Union`</a>, include the most specific type first, followed by the less specific type. In the example below, the more specific `PlaneItem` comes before `CarItem` in `Union[PlaneItem, CarItem]`.
```Python hl_lines="1 14-15 18-20 33"
{!../../../docs_src/extra_models/tutorial003.py!}
=== "Python 3.6 and above"
```Python hl_lines="1 14-15 18-20 33"
{!> ../../../docs_src/extra_models/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1 14-15 18-20 33"
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
```
### `Union` in Python 3.10
In this example we pass `Union[PlaneItem, CarItem]` as the value of the argument `response_model`.
Because we are passing it as a **value to an argument** instead of putting it in a **type annotation**, we have to use `Union` even in Python 3.10.
If it was in a type annotation we could have used the vertical bar, as:
```Python
some_variable: PlaneItem | CarItem
```
But if we put that in `response_model=PlaneItem | CarItem` we would get an error, because Python would try to perform an **invalid operation** between `PlaneItem` and `CarItem` instead of interpreting that as a type annotation.
## List of models
The same way, you can declare responses of lists of objects.
For that, use the standard Python `typing.List`:
For that, use the standard Python `typing.List` (or just `list` in Python 3.9 and above):
```Python hl_lines="1 20"
{!../../../docs_src/extra_models/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="1 20"
{!> ../../../docs_src/extra_models/tutorial004.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="18"
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
```
## Response with arbitrary `dict`
@@ -185,11 +231,19 @@ You can also declare a response using a plain arbitrary `dict`, declaring just t
This is useful if you don't know the valid field/attribute names (that would be needed for a Pydantic model) beforehand.
In this case, you can use `typing.Dict`:
In this case, you can use `typing.Dict` (or just `dict` in Python 3.9 and above):
```Python hl_lines="1 8"
{!../../../docs_src/extra_models/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="1 8"
{!> ../../../docs_src/extra_models/tutorial005.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="6"
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
```
## Recap

View File

@@ -6,9 +6,17 @@ You can define Header parameters the same way you define `Query`, `Path` and `Co
First import `Header`:
```Python hl_lines="3"
{!../../../docs_src/header_params/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3"
{!> ../../../docs_src/header_params/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
```
## Declare `Header` parameters
@@ -16,9 +24,17 @@ Then declare the header parameters using the same structure as with `Path`, `Que
The first value is the default value, you can pass all the extra validation or annotation parameters:
```Python hl_lines="9"
{!../../../docs_src/header_params/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/header_params/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
```
!!! note "Technical Details"
`Header` is a "sister" class of `Path`, `Query` and `Cookie`. It also inherits from the same common `Param` class.
@@ -44,14 +60,21 @@ So, you can use `user_agent` as you normally would in Python code, instead of ne
If for some reason you need to disable automatic conversion of underscores to hyphens, set the parameter `convert_underscores` of `Header` to `False`:
```Python hl_lines="10"
{!../../../docs_src/header_params/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="10"
{!> ../../../docs_src/header_params/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="8"
{!> ../../../docs_src/header_params/tutorial002_py310.py!}
```
!!! warning
Before setting `convert_underscores` to `False`, bear in mind that some HTTP proxies and servers disallow the usage of headers with underscores.
## Duplicate headers
It is possible to receive duplicate headers. That means, the same header with multiple values.
@@ -62,9 +85,23 @@ You will receive all the values from the duplicate header as a Python `list`.
For example, to declare a header of `X-Token` that can appear more than once, you can write:
```Python hl_lines="9"
{!../../../docs_src/header_params/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/header_params/tutorial003.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="9"
{!> ../../../docs_src/header_params/tutorial003_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/header_params/tutorial003_py310.py!}
```
If you communicate with that *path operation* sending two HTTP headers like:

View File

@@ -13,9 +13,23 @@ You can pass directly the `int` code, like `404`.
But if you don't remember what each number code is for, you can use the shortcut constants in `status`:
```Python hl_lines="3 17"
{!../../../docs_src/path_operation_configuration/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3 17"
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="3 17"
{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1 15"
{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
```
That status code will be used in the response and will be added to the OpenAPI schema.
@@ -28,9 +42,23 @@ That status code will be used in the response and will be added to the OpenAPI s
You can add tags to your *path operation*, pass the parameter `tags` with a `list` of `str` (commonly just one `str`):
```Python hl_lines="17 22 27"
{!../../../docs_src/path_operation_configuration/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="17 22 27"
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="17 22 27"
{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="15 20 25"
{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
```
They will be added to the OpenAPI schema and used by the automatic documentation interfaces:
@@ -40,9 +68,23 @@ They will be added to the OpenAPI schema and used by the automatic documentation
You can add a `summary` and `description`:
```Python hl_lines="20-21"
{!../../../docs_src/path_operation_configuration/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="20-21"
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="20-21"
{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="18-19"
{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
```
## Description from docstring
@@ -50,9 +92,23 @@ As descriptions tend to be long and cover multiple lines, you can declare the *p
You can write <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
```Python hl_lines="19-27"
{!../../../docs_src/path_operation_configuration/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="19-27"
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="19-27"
{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17-25"
{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
```
It will be used in the interactive docs:
@@ -62,9 +118,23 @@ It will be used in the interactive docs:
You can specify the response description with the parameter `response_description`:
```Python hl_lines="21"
{!../../../docs_src/path_operation_configuration/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="21"
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="21"
{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="19"
{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
```
!!! info
Notice that `response_description` refers specifically to the response, the `description` refers to the *path operation* in general.

View File

@@ -6,9 +6,17 @@ The same way you can declare more validations and metadata for query parameters
First, import `Path` from `fastapi`:
```Python hl_lines="3"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
## Declare metadata
@@ -16,13 +24,21 @@ You can declare all the same parameters as for `Query`.
For example, to declare a `title` metadata value for the path parameter `item_id` you can type:
```Python hl_lines="10"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="10"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="8"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
!!! note
A path parameter is always required as it has to be part of the path.
So, you should declare it with `...` to mark it as required.
Nevertheless, even if you declared it with `None` or set a default value, it would not affect anything, it would still be always required.

View File

@@ -4,11 +4,19 @@
Let's take this application as example:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial001.py!}
```
=== "Python 3.6 and above"
The query parameter `q` is of type `Optional[str]`, that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
```
The query parameter `q` is of type `Optional[str]` (or `str | None` in Python 3.10), that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
!!! note
FastAPI will know that the value of `q` is not required because of the default value `= None`.
@@ -23,17 +31,33 @@ We are going to enforce that even though `q` is optional, whenever it is provide
To achieve that, first import `Query` from `fastapi`:
```Python hl_lines="3"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3"
{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1"
{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
## Use `Query` as the default value
And now use it as the default value of your parameter, setting the parameter `max_length` to 50:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
As we have to replace the default value `None` with `Query(None)`, the first parameter to `Query` serves the same purpose of defining that default value.
@@ -49,10 +73,22 @@ q: Optional[str] = Query(None)
q: Optional[str] = None
```
And in Python 3.10 and above:
```Python
q: str | None = Query(None)
```
...makes the parameter optional, the same as:
```Python
q: str | None = None
```
But it declares it explicitly as being a query parameter.
!!! info
Have in mind that FastAPI cares about the part:
Have in mind that the most important part to make a parameter optional is the part:
```Python
= None
@@ -64,9 +100,9 @@ But it declares it explicitly as being a query parameter.
= Query(None)
```
and will use that `None` to detect that the query parameter is not required.
as it will use that `None` as the default value, and that way make the parameter **not required**.
The `Optional` part is only to allow your editor to provide better support.
The `Optional` part allows your editor to provide better support, but it is not what tells FastAPI that this parameter is not required.
Then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:
@@ -80,17 +116,33 @@ This will validate the data, show a clear error when the data is not valid, and
You can also add a parameter `min_length`:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial003_py310.py!}
```
## Add regular expressions
You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> that the parameter should match:
```Python hl_lines="10"
{!../../../docs_src/query_params_str_validations/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="8"
{!> ../../../docs_src/query_params_str_validations/tutorial004_py310.py!}
```
This specific regular expression checks that the received parameter value:
@@ -152,9 +204,23 @@ When you define a query parameter explicitly with `Query` you can also declare i
For example, to declare a query parameter `q` that can appear multiple times in the URL, you can write:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial011.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial011.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial011_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial011_py310.py!}
```
Then, with a URL like:
@@ -186,9 +252,17 @@ The interactive API docs will update accordingly, to allow multiple values:
And you can also define a default `list` of values if none are provided:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial012.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial012.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial012_py39.py!}
```
If you go to:
@@ -209,7 +283,7 @@ the default of `q` will be: `["foo", "bar"]` and your response will be:
#### Using `list`
You can also use `list` directly instead of `List[str]`:
You can also use `list` directly instead of `List[str]` (or `list[str]` in Python 3.9+):
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial013.py!}
@@ -233,15 +307,31 @@ That information will be included in the generated OpenAPI and used by the docum
You can add a `title`:
```Python hl_lines="10"
{!../../../docs_src/query_params_str_validations/tutorial007.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial007.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial007_py310.py!}
```
And a `description`:
```Python hl_lines="13"
{!../../../docs_src/query_params_str_validations/tutorial008.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="13"
{!> ../../../docs_src/query_params_str_validations/tutorial008.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="12"
{!> ../../../docs_src/query_params_str_validations/tutorial008_py310.py!}
```
## Alias parameters
@@ -261,9 +351,17 @@ But you still need it to be exactly `item-query`...
Then you can declare an `alias`, and that alias is what will be used to find the parameter value:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial009.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial009.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params_str_validations/tutorial009_py310.py!}
```
## Deprecating parameters
@@ -273,9 +371,17 @@ You have to leave it there a while because there are clients using it, but you w
Then pass the parameter `deprecated=True` to `Query`:
```Python hl_lines="18"
{!../../../docs_src/query_params_str_validations/tutorial010.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="18"
{!> ../../../docs_src/query_params_str_validations/tutorial010.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17"
{!> ../../../docs_src/query_params_str_validations/tutorial010_py310.py!}
```
The docs will show it like this:

View File

@@ -63,27 +63,38 @@ The parameter values in your function will be:
The same way, you can declare optional query parameters, by setting their default to `None`:
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
```
In this case, the function parameter `q` will be optional, and will be `None` by default.
!!! check
Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.
!!! note
FastAPI will know that `q` is optional because of the `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI (FastAPI will only use the `str` part), but the `Optional[str]` will let your editor help you finding errors in your code.
## Query parameter type conversion
You can also declare `bool` types, and they will be converted:
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/query_params/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7"
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
```
In this case, if you go to:
@@ -126,9 +137,17 @@ And you don't have to declare them in any specific order.
They will be detected by name:
```Python hl_lines="8 10"
{!../../../docs_src/query_params/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="8 10"
{!> ../../../docs_src/query_params/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="6 8"
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
```
## Required query parameters
@@ -184,9 +203,17 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
And of course, you can define some parameters as required, some as having a default value, and some entirely optional:
```Python hl_lines="10"
{!../../../docs_src/query_params/tutorial006.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="10"
{!> ../../../docs_src/query_params/tutorial006.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="8"
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
```
In this case, there are 3 query parameters:

View File

@@ -119,11 +119,19 @@ It's possible to upload several files at the same time.
They would be associated to the same "form field" sent using "form data".
To use that, declare a `List` of `bytes` or `UploadFile`:
To use that, declare a list of `bytes` or `UploadFile`:
```Python hl_lines="10 15"
{!../../../docs_src/request_files/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="10 15"
{!> ../../../docs_src/request_files/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="8 13"
{!> ../../../docs_src/request_files/tutorial002_py39.py!}
```
You will receive, as declared, a `list` of `bytes` or `UploadFile`s.

View File

@@ -8,9 +8,23 @@ You can declare the model used for the response with the parameter `response_mod
* `@app.delete()`
* etc.
```Python hl_lines="17"
{!../../../docs_src/response_model/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="17"
{!> ../../../docs_src/response_model/tutorial001.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="17"
{!> ../../../docs_src/response_model/tutorial001_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="15"
{!> ../../../docs_src/response_model/tutorial001_py310.py!}
```
!!! note
Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your *path operation function*, like all the parameters and body.
@@ -35,15 +49,31 @@ But most importantly:
Here we are declaring a `UserIn` model, it will contain a plaintext password:
```Python hl_lines="9 11"
{!../../../docs_src/response_model/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9 11"
{!> ../../../docs_src/response_model/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7 9"
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
```
And we are using this model to declare our input and the same model to declare our output:
```Python hl_lines="17-18"
{!../../../docs_src/response_model/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="17-18"
{!> ../../../docs_src/response_model/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="15-16"
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
```
Now, whenever a browser is creating a user with a password, the API will return the same password in the response.
@@ -58,21 +88,45 @@ But if we use the same model for another *path operation*, we could be sending o
We can instead create an input model with the plaintext password and an output model without it:
```Python hl_lines="9 11 16"
{!../../../docs_src/response_model/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9 11 16"
{!> ../../../docs_src/response_model/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="7 9 14"
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
Here, even though our *path operation function* is returning the same input user that contains the password:
```Python hl_lines="24"
{!../../../docs_src/response_model/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="22"
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
...we declared the `response_model` to be our model `UserOut`, that doesn't include the password:
```Python hl_lines="22"
{!../../../docs_src/response_model/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="22"
{!> ../../../docs_src/response_model/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="20"
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
So, **FastAPI** will take care of filtering out all the data that is not declared in the output model (using Pydantic).
@@ -90,9 +144,23 @@ And both models will be used for the interactive API documentation:
Your response model could have default values, like:
```Python hl_lines="11 13-14"
{!../../../docs_src/response_model/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="11 13-14"
{!> ../../../docs_src/response_model/tutorial004.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="11 13-14"
{!> ../../../docs_src/response_model/tutorial004_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="9 11-12"
{!> ../../../docs_src/response_model/tutorial004_py310.py!}
```
* `description: Optional[str] = None` has a default of `None`.
* `tax: float = 10.5` has a default of `10.5`.
@@ -106,9 +174,23 @@ For example, if you have models with many optional attributes in a NoSQL databas
You can set the *path operation decorator* parameter `response_model_exclude_unset=True`:
```Python hl_lines="24"
{!../../../docs_src/response_model/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial004.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial004_py39.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="22"
{!> ../../../docs_src/response_model/tutorial004_py310.py!}
```
and those default values won't be included in the response, only the values actually set.
@@ -185,9 +267,17 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
This also applies to `response_model_by_alias` that works similarly.
```Python hl_lines="31 37"
{!../../../docs_src/response_model/tutorial005.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="31 37"
{!> ../../../docs_src/response_model/tutorial005.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="29 35"
{!> ../../../docs_src/response_model/tutorial005_py310.py!}
```
!!! tip
The syntax `{"name", "description"}` creates a `set` with those two values.
@@ -198,9 +288,17 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
If you forget to use a `set` and use a `list` or `tuple` instead, FastAPI will still convert it to a `set` and it will work correctly:
```Python hl_lines="31 37"
{!../../../docs_src/response_model/tutorial006.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="31 37"
{!> ../../../docs_src/response_model/tutorial006.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="29 35"
{!> ../../../docs_src/response_model/tutorial006_py310.py!}
```
## Recap

View File

@@ -8,9 +8,17 @@ Here are several ways to do it.
You can declare an `example` for a Pydantic model using `Config` and `schema_extra`, as described in <a href="https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic's docs: Schema customization</a>:
```Python hl_lines="15-23"
{!../../../docs_src/schema_extra_example/tutorial001.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="15-23"
{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="13-21"
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
```
That extra info will be added as-is to the output **JSON Schema** for that model, and it will be used in the API docs.
@@ -25,9 +33,17 @@ When using `Field()` with Pydantic models, you can also declare extra info for t
You can use this to add `example` for each field:
```Python hl_lines="4 10-13"
{!../../../docs_src/schema_extra_example/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="4 10-13"
{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="2 8-11"
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
```
!!! warning
Keep in mind that those extra arguments passed won't add any validation, only extra information, for documentation purposes.
@@ -50,9 +66,17 @@ you can also declare a data `example` or a group of `examples` with additional i
Here we pass an `example` of the data expected in `Body()`:
```Python hl_lines="21-26"
{!../../../docs_src/schema_extra_example/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="21-26"
{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="19-24"
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
```
### Example in the docs UI
@@ -73,9 +97,17 @@ Each specific example `dict` in the `examples` can contain:
* `value`: This is the actual example shown, e.g. a `dict`.
* `externalValue`: alternative to `value`, a URL pointing to the example. Although this might not be supported by as many tools as `value`.
```Python hl_lines="22-48"
{!../../../docs_src/schema_extra_example/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="22-48"
{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="20-46"
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
```
### Examples in the docs UI

View File

@@ -16,9 +16,17 @@ First, let's create a Pydantic user model.
The same way we use Pydantic to declare bodies, we can use it anywhere else:
```Python hl_lines="5 12-16"
{!../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="5 12-16"
{!> ../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="3 10-14"
{!> ../../../docs_src/security/tutorial002_py310.py!}
```
## Create a `get_current_user` dependency
@@ -30,25 +38,49 @@ Remember that dependencies can have sub-dependencies?
The same as we were doing before in the *path operation* directly, our new dependency `get_current_user` will receive a `token` as a `str` from the sub-dependency `oauth2_scheme`:
```Python hl_lines="25"
{!../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="25"
{!> ../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="23"
{!> ../../../docs_src/security/tutorial002_py310.py!}
```
## Get the user
`get_current_user` will use a (fake) utility function we created, that takes a token as a `str` and returns our Pydantic `User` model:
```Python hl_lines="19-22 26-27"
{!../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="19-22 26-27"
{!> ../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="17-20 24-25"
{!> ../../../docs_src/security/tutorial002_py310.py!}
```
## Inject the current user
So now we can use the same `Depends` with our `get_current_user` in the *path operation*:
```Python hl_lines="31"
{!../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="31"
{!> ../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="29"
{!> ../../../docs_src/security/tutorial002_py310.py!}
```
Notice that we declare the type of `current_user` as the Pydantic model `User`.
@@ -64,7 +96,6 @@ This will help us inside of the function with all the completion and type checks
We are not restricted to having only one dependency that can return that type of data.
## Other models
You can now get the current user directly in the *path operation functions* and deal with the security mechanisms at the **Dependency Injection** level, using `Depends`.
@@ -81,7 +112,6 @@ You actually don't have users that log in to your application but robots, bots,
Just use any kind of model, any kind of class, any kind of database that you need for your application. **FastAPI** has you covered with the dependency injection system.
## Code size
This example might seem verbose. Have in mind that we are mixing security, data models, utility functions and *path operations* in the same file.
@@ -98,9 +128,17 @@ And all of them (or any portion of them that you want) can take the advantage of
And all these thousands of *path operations* can be as small as 3 lines:
```Python hl_lines="30-32"
{!../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="30-32"
{!> ../../../docs_src/security/tutorial002.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="28-30"
{!> ../../../docs_src/security/tutorial002_py310.py!}
```
## Recap

View File

@@ -109,9 +109,17 @@ And another utility to verify if a received password matches the hash stored.
And another one to authenticate and return a user.
```Python hl_lines="7 48 55-56 59-60 69-75"
{!../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="7 48 55-56 59-60 69-75"
{!> ../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="6 47 54-55 58-59 68-74"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
!!! note
If you check the new (fake) database `fake_users_db`, you will see how the hashed password looks like now: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
@@ -144,9 +152,17 @@ Define a Pydantic Model that will be used in the token endpoint for the response
Create a utility function to generate a new access token.
```Python hl_lines="6 12-14 28-30 78-86"
{!../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="6 12-14 28-30 78-86"
{!> ../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="5 11-13 27-29 77-85"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
## Update the dependencies
@@ -156,9 +172,17 @@ Decode the received token, verify it, and return the current user.
If the token is invalid, return an HTTP error right away.
```Python hl_lines="89-106"
{!../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="89-106"
{!> ../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="88-105"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
## Update the `/token` *path operation*
@@ -166,9 +190,17 @@ Create a `timedelta` with the expiration time of the token.
Create a real JWT access token and return it.
```Python hl_lines="115-128"
{!../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="115-128"
{!> ../../../docs_src/security/tutorial004.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="114-127"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
### Technical details about the JWT "subject" `sub`

View File

@@ -49,9 +49,17 @@ Now let's use the utilities provided by **FastAPI** to handle this.
First, import `OAuth2PasswordRequestForm`, and use it as a dependency with `Depends` in the *path operation* for `/token`:
```Python hl_lines="4 76"
{!../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="4 76"
{!> ../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="2 74"
{!> ../../../docs_src/security/tutorial003_py310.py!}
```
`OAuth2PasswordRequestForm` is a class dependency that declares a form body with:
@@ -90,9 +98,17 @@ If there is no such user, we return an error saying "incorrect username or passw
For the error, we use the exception `HTTPException`:
```Python hl_lines="3 77-79"
{!../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3 77-79"
{!> ../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1 75-77"
{!> ../../../docs_src/security/tutorial003_py310.py!}
```
### Check the password
@@ -118,9 +134,17 @@ If your database is stolen, the thief won't have your users' plaintext passwords
So, the thief won't be able to try to use those same passwords in another system (as many users use the same password everywhere, this would be dangerous).
```Python hl_lines="80-83"
{!../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="80-83"
{!> ../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="78-81"
{!> ../../../docs_src/security/tutorial003_py310.py!}
```
#### About `**user_dict`
@@ -156,9 +180,17 @@ For this simple example, we are going to just be completely insecure and return
But for now, let's focus on the specific details we need.
```Python hl_lines="85"
{!../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="85"
{!> ../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="83"
{!> ../../../docs_src/security/tutorial003_py310.py!}
```
!!! tip
By the spec, you should return a JSON with an `access_token` and a `token_type`, the same as in this example.
@@ -181,9 +213,17 @@ Both of these dependencies will just return an HTTP error if the user doesn't ex
So, in our endpoint, we will only get a user if the user exists, was correctly authenticated, and is active:
```Python hl_lines="58-67 69-72 90"
{!../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="58-66 69-72 90"
{!> ../../../docs_src/security/tutorial003.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="55-64 67-70 88"
{!> ../../../docs_src/security/tutorial003_py310.py!}
```
!!! info
The additional header `WWW-Authenticate` with value `Bearer` we are returning here is also part of the spec.

View File

@@ -248,9 +248,23 @@ So, the user will also have a `password` when creating it.
But for security, the `password` won't be in other Pydantic *models*, for example, it won't be sent from the API when reading a user.
```Python hl_lines="3 6-8 11-12 23-24 27-28"
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="3 6-8 11-12 23-24 27-28"
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="3 6-8 11-12 23-24 27-28"
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="1 4-6 9-10 21-22 25-26"
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
#### SQLAlchemy style and Pydantic style
@@ -278,9 +292,23 @@ The same way, when reading a user, we can now declare that `items` will contain
Not only the IDs of those items, but all the data that we defined in the Pydantic *model* for reading items: `Item`.
```Python hl_lines="15-17 31-34"
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="15-17 31-34"
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="15-17 31-34"
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="13-15 29-32"
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
!!! tip
Notice that the `User`, the Pydantic *model* that will be used when reading a user (returning it from the API) doesn't include the `password`.
@@ -293,9 +321,23 @@ This <a href="https://pydantic-docs.helpmanual.io/#config" class="external-link"
In the `Config` class, set the attribute `orm_mode = True`.
```Python hl_lines="15 19-20 31 36-37"
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="15 19-20 31 36-37"
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="15 19-20 31 36-37"
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="13 17-18 29 34-35"
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
!!! tip
Notice it's assigning a value with `=`, like:
@@ -425,9 +467,17 @@ And now in the file `sql_app/main.py` let's integrate and use all the other part
In a very simplistic way create the database tables:
```Python hl_lines="9"
{!../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="9"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="7"
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
#### Alembic Note
@@ -451,9 +501,17 @@ For that, we will create a new dependency with `yield`, as explained before in t
Our dependency will create a new SQLAlchemy `SessionLocal` that will be used in a single request, and then close it once the request is finished.
```Python hl_lines="15-20"
{!../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="15-20"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="13-18"
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
!!! info
We put the creation of the `SessionLocal()` and handling of the requests in a `try` block.
@@ -468,9 +526,17 @@ And then, when using the dependency in a *path operation function*, we declare i
This will then give us better editor support inside the *path operation function*, because the editor will know that the `db` parameter is of type `Session`:
```Python hl_lines="24 32 38 47 53"
{!../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="24 32 38 47 53"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="22 30 36 45 51"
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
!!! info "Technical Details"
The parameter `db` is actually of type `SessionLocal`, but this class (created with `sessionmaker()`) is a "proxy" of a SQLAlchemy `Session`, so, the editor doesn't really know what methods are provided.
@@ -481,9 +547,17 @@ This will then give us better editor support inside the *path operation function
Now, finally, here's the standard **FastAPI** *path operations* code.
```Python hl_lines="23-28 31-34 37-42 45-49 52-55"
{!../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="23-28 31-34 37-42 45-49 52-55"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="21-26 29-32 35-40 43-47 50-53"
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
We are creating the database session before each request in the dependency with `yield`, and then closing it afterwards.
@@ -566,9 +640,23 @@ For example, in a background task worker with <a href="https://docs.celeryprojec
* `sql_app/schemas.py`:
```Python
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.6 and above"
```Python
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
```
=== "Python 3.9 and above"
```Python
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
=== "Python 3.10 and above"
```Python
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
* `sql_app/crud.py`:
@@ -578,9 +666,17 @@ For example, in a background task worker with <a href="https://docs.celeryprojec
* `sql_app/main.py`:
```Python
{!../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.6 and above"
```Python
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
```
=== "Python 3.9 and above"
```Python
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
## Check it
@@ -629,9 +725,17 @@ A "middleware" is basically a function that is always executed for each request,
The middleware we'll add (just a function) will create a new SQLAlchemy `SessionLocal` for each request, add it to the request and then close it once the request is finished.
```Python hl_lines="14-22"
{!../../../docs_src/sql_databases/sql_app/alt_main.py!}
```
=== "Python 3.6 and above"
```Python hl_lines="14-22"
{!> ../../../docs_src/sql_databases/sql_app/alt_main.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="12-20"
{!> ../../../docs_src/sql_databases/sql_app_py39/alt_main.py!}
```
!!! info
We put the creation of the `SessionLocal()` and handling of the requests in a `try` block.

View File

@@ -65,7 +65,7 @@ Now let's extend this example and add more details to see how to test different
### Extended **FastAPI** app file
Let's say you have a file `main_b.py` with your **FastAPI** app.
Let's say that now the file `main.py` with your **FastAPI** app has some other **path operations**.
It has a `GET` operation that could return an error.
@@ -73,16 +73,24 @@ It has a `POST` operation that could return several errors.
Both *path operations* require an `X-Token` header.
```Python
{!../../../docs_src/app_testing/main_b.py!}
```
=== "Python 3.6 and above"
```Python
{!> ../../../docs_src/app_testing/app_b/main.py!}
```
=== "Python 3.10 and above"
```Python
{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
```
### Extended testing file
You could then have a `test_main_b.py`, the same as before, with the extended tests:
You could then update `test_main.py` with the extended tests:
```Python
{!../../../docs_src/app_testing/test_main_b.py!}
{!> ../../../docs_src/app_testing/app_b/test_main.py!}
```
Whenever you need the client to pass information in the request and you don't know how to, you can search (Google) how to do it in `requests`.

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -176,8 +173,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -40,6 +40,12 @@
<img class="sponsor-image" src="/img/sponsors/jina-banner.svg" />
</a>
</div>
<div class="item">
<a title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway." style="display: block; position: relative;" href="https://cryptapi.io/" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/cryptapi-banner.svg" />
</a>
</div>
</div>
</div>
{% endblock %}

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -80,8 +77,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -0,0 +1,334 @@
# Démarrage
Le fichier **FastAPI** le plus simple possible pourrait ressembler à cela :
```Python
{!../../../docs_src/first_steps/tutorial001.py!}
```
Copiez ce code dans un fichier nommé `main.py`.
Démarrez le serveur :
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
</div>
!!! note
La commande `uvicorn main:app` fait référence à :
* `main` : le fichier `main.py` (le module Python).
* `app` : l'objet créé dans `main.py` via la ligne `app = FastAPI()`.
* `--reload` : l'option disant à uvicorn de redémarrer le serveur à chaque changement du code. À ne pas utiliser en production !
Vous devriez voir dans la console, une ligne semblable à la suivante :
```hl_lines="4"
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
Cette ligne montre l'URL par laquelle l'app est actuellement accessible, sur votre machine locale.
### Allez voir le résultat
Ouvrez votre navigateur à l'adresse <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
Vous obtiendrez cette réponse JSON :
```JSON
{"message": "Hello World"}
```
### Documentation interactive de l'API
Rendez-vous sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Vous verrez la documentation interactive de l'API générée automatiquement (via <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>) :
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Documentation alternative
Ensuite, rendez-vous sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
Vous y verrez la documentation alternative (via <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
### OpenAPI
**FastAPI** génère un "schéma" contenant toute votre API dans le standard de définition d'API **OpenAPI**.
#### "Schéma"
Un "schéma" est une définition ou une description de quelque chose. Pas le code qui l'implémente, uniquement une description abstraite.
#### "Schéma" d'API
Ici, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> est une spécification qui dicte comment définir le schéma de votre API.
Le schéma inclut les chemins de votre API, les paramètres potentiels de chaque chemin, etc.
#### "Schéma" de données
Le terme "schéma" peut aussi faire référence à la forme de la donnée, comme un contenu JSON.
Dans ce cas, cela signifierait les attributs JSON, ainsi que les types de ces attributs, etc.
#### OpenAPI et JSON Schema
**OpenAPI** définit un schéma d'API pour votre API. Il inclut des définitions (ou "schémas") de la donnée envoyée et reçue par votre API en utilisant **JSON Schema**, le standard des schémas de données JSON.
#### Allez voir `openapi.json`
Si vous êtes curieux d'à quoi ressemble le schéma brut **OpenAPI**, **FastAPI** génère automatiquement un (schéma) JSON avec les descriptions de toute votre API.
Vous pouvez le voir directement à cette adresse : <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
Le schéma devrait ressembler à ceci :
```JSON
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
...
```
#### À quoi sert OpenAPI
Le schéma **OpenAPI** est ce qui alimente les deux systèmes de documentation interactive.
Et il existe des dizaines d'alternatives, toutes basées sur **OpenAPI**. Vous pourriez facilement ajouter n'importe laquelle de ces alternatives à votre application **FastAPI**.
Vous pourriez aussi l'utiliser pour générer du code automatiquement, pour les clients qui communiquent avec votre API. Comme par exemple, des applications frontend, mobiles ou IOT.
## Récapitulatif, étape par étape
### Étape 1 : import `FastAPI`
```Python hl_lines="1"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` est une classe Python qui fournit toutes les fonctionnalités nécessaires au lancement de votre API.
!!! note "Détails techniques"
`FastAPI` est une classe héritant directement de `Starlette`.
Vous pouvez donc aussi utiliser toutes les fonctionnalités de <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> depuis `FastAPI`.
### Étape 2 : créer une "instance" `FastAPI`
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Ici la variable `app` sera une "instance" de la classe `FastAPI`.
Ce sera le point principal d'interaction pour créer toute votre API.
Cette `app` est la même que celle à laquelle fait référence `uvicorn` dans la commande :
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Si vous créez votre app avec :
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial002.py!}
```
Et la mettez dans un fichier `main.py`, alors vous appeleriez `uvicorn` avec :
<div class="termy">
```console
$ uvicorn main:my_awesome_api --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Étape 3: créer une *opération de chemin*
#### Chemin
Chemin, ou "path" fait référence ici à la dernière partie de l'URL démarrant au premier `/`.
Donc, dans un URL tel que :
```
https://example.com/items/foo
```
...le "path" serait :
```
/items/foo
```
!!! info
Un chemin, ou "path" est aussi souvent appelé route ou "endpoint".
#### Opération
"Opération" fait référence à une des "méthodes" HTTP.
Une de :
* `POST`
* `GET`
* `PUT`
* `DELETE`
...ou une des plus exotiques :
* `OPTIONS`
* `HEAD`
* `PATCH`
* `TRACE`
Dans le protocol HTTP, vous pouvez communiquer avec chaque chemin en utilisant une (ou plus) de ces "méthodes".
---
En construisant des APIs, vous utilisez généralement ces méthodes HTTP spécifiques pour effectuer une action précise.
Généralement vous utilisez :
* `POST` : pour créer de la donnée.
* `GET` : pour lire de la donnée.
* `PUT` : pour mettre à jour de la donnée.
* `DELETE` : pour supprimer de la donnée.
Donc, dans **OpenAPI**, chaque méthode HTTP est appelée une "opération".
Nous allons donc aussi appeler ces dernières des "**opérations**".
#### Définir un *décorateur d'opération de chemin*
```Python hl_lines="6"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Le `@app.get("/")` dit à **FastAPI** que la fonction en dessous est chargée de gérer les requêtes qui vont sur :
* le chemin `/`
* en utilisant une <abbr title="une méthode GET HTTP">opération <code>get</code></abbr>
!!! info "`@décorateur` Info"
Cette syntaxe `@something` en Python est appelée un "décorateur".
Vous la mettez au dessus d'une fonction. Comme un joli chapeau décoratif (j'imagine que ce terme vient de là 🤷🏻‍♂).
Un "décorateur" prend la fonction en dessous et en fait quelque chose.
Dans notre cas, ce décorateur dit à **FastAPI** que la fonction en dessous correspond au **chemin** `/` avec l'**opération** `get`.
C'est le "**décorateur d'opération de chemin**".
Vous pouvez aussi utiliser les autres opérations :
* `@app.post()`
* `@app.put()`
* `@app.delete()`
Tout comme celles les plus exotiques :
* `@app.options()`
* `@app.head()`
* `@app.patch()`
* `@app.trace()`
!!! tip "Astuce"
Vous êtes libres d'utiliser chaque opération (méthode HTTP) comme vous le désirez.
**FastAPI** n'impose pas de sens spécifique à chacune d'elle.
Les informations qui sont présentées ici forment une directive générale, pas des obligations.
Par exemple, quand l'on utilise **GraphQL**, toutes les actions sont effectuées en utilisant uniquement des opérations `POST`.
### Étape 4 : définir la **fonction de chemin**.
Voici notre "**fonction de chemin**" (ou fonction d'opération de chemin) :
* **chemin** : `/`.
* **opération** : `get`.
* **fonction** : la fonction sous le "décorateur" (sous `@app.get("/")`).
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial001.py!}
```
C'est une fonction Python.
Elle sera appelée par **FastAPI** quand une requête sur l'URL `/` sera reçue via une opération `GET`.
Ici, c'est une fonction asynchrone (définie avec `async def`).
---
Vous pourriez aussi la définir comme une fonction classique plutôt qu'avec `async def` :
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial003.py!}
```
!!! note
Si vous ne connaissez pas la différence, allez voir la section [Concurrence : *"Vous êtes pressés ?"*](../async.md#vous-etes-presses){.internal-link target=_blank}.
### Étape 5 : retourner le contenu
```Python hl_lines="8"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Vous pouvez retourner un dictionnaire (`dict`), une liste (`list`), des valeurs seules comme des chaines de caractères (`str`) et des entiers (`int`), etc.
Vous pouvez aussi retourner des models **Pydantic** (qui seront détaillés plus tard).
Il y a de nombreux autres objets et modèles qui seront automatiquement convertis en JSON. Essayez d'utiliser vos favoris, il est fort probable qu'ils soient déjà supportés.
## Récapitulatif
* Importez `FastAPI`.
* Créez une instance d'`app`.
* Ajoutez une **décorateur d'opération de chemin** (tel que `@app.get("/")`).
* Ajoutez une **fonction de chemin** (telle que `def root(): ...` comme ci-dessus).
* Lancez le serveur de développement (avec `uvicorn main:app --reload`).

View File

@@ -0,0 +1,254 @@
# Paramètres de chemin
Vous pouvez déclarer des "paramètres" ou "variables" de chemin avec la même syntaxe que celle utilisée par le
<a href="https://docs.python.org/fr/3/library/string.html#format-string-syntax" class="external-link" target="_blank">formatage de chaîne Python</a> :
```Python hl_lines="6-7"
{!../../../docs_src/path_params/tutorial001.py!}
```
La valeur du paramètre `item_id` sera transmise à la fonction dans l'argument `item_id`.
Donc, si vous exécutez cet exemple et allez sur <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>,
vous verrez comme réponse :
```JSON
{"item_id":"foo"}
```
## Paramètres de chemin typés
Vous pouvez déclarer le type d'un paramètre de chemin dans la fonction, en utilisant les annotations de type Python :
```Python hl_lines="7"
{!../../../docs_src/path_params/tutorial002.py!}
```
Ici, `item_id` est déclaré comme `int`.
!!! hint "Astuce"
Ceci vous permettra d'obtenir des fonctionnalités de l'éditeur dans votre fonction, telles
que des vérifications d'erreur, de l'auto-complétion, etc.
## <abbr title="aussi appelé sérialisation, ou parfois parsing ou marshalling en anglais">Conversion</abbr> de données
Si vous exécutez cet exemple et allez sur <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, vous aurez comme réponse :
```JSON
{"item_id":3}
```
!!! hint "Astuce"
Comme vous l'avez remarqué, la valeur reçue par la fonction (et renvoyée ensuite) est `3`,
en tant qu'entier (`int`) Python, pas la chaîne de caractères (`string`) `"3"`.
Grâce aux déclarations de types, **FastAPI** fournit du
<abbr title="conversion de la chaîne de caractères venant de la requête HTTP en données Python">"parsing"</abbr> automatique.
## Validation de données
Si vous allez sur <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, vous aurez une belle erreur HTTP :
```JSON
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
```
car le paramètre de chemin `item_id` possède comme valeur `"foo"`, qui ne peut pas être convertie en entier (`int`).
La même erreur se produira si vous passez un nombre flottant (`float`) et non un entier, comme ici
<a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>.
!!! hint "Astuce"
Donc, avec ces mêmes déclarations de type Python, **FastAPI** vous fournit de la validation de données.
Notez que l'erreur mentionne le point exact où la validation n'a pas réussi.
Ce qui est incroyablement utile au moment de développer et débugger du code qui interagit avec votre API.
## Documentation
Et quand vous vous rendez sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, vous verrez la
documentation générée automatiquement et interactive :
<img src="/img/tutorial/path-params/image01.png">
!!! info
À nouveau, en utilisant uniquement les déclarations de type Python, **FastAPI** vous fournit automatiquement une documentation interactive (via Swagger UI).
On voit bien dans la documentation que `item_id` est déclaré comme entier.
## Les avantages d'avoir une documentation basée sur une norme, et la documentation alternative.
Le schéma généré suivant la norme <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" class="external-link" target="_blank">OpenAPI</a>,
il existe de nombreux outils compatibles.
Grâce à cela, **FastAPI** lui-même fournit une documentation alternative (utilisant ReDoc), qui peut être lue
sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> :
<img src="/img/tutorial/path-params/image02.png">
De la même façon, il existe bien d'autres outils compatibles, y compris des outils de génération de code
pour de nombreux langages.
## Pydantic
Toute la validation de données est effectué en arrière-plan avec <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>,
dont vous bénéficierez de tous les avantages. Vous savez donc que vous êtes entre de bonnes mains.
## L'ordre importe
Quand vous créez des *fonctions de chemins*, vous pouvez vous retrouver dans une situation où vous avez un chemin fixe.
Tel que `/users/me`, disons pour récupérer les données sur l'utilisateur actuel.
Et vous avez un second chemin : `/users/{user_id}` pour récupérer de la donnée sur un utilisateur spécifique grâce à son identifiant d'utilisateur
Les *fonctions de chemin* étant évaluées dans l'ordre, il faut s'assurer que la fonction correspondant à `/users/me` est déclarée avant celle de `/users/{user_id}` :
```Python hl_lines="6 11"
{!../../../docs_src/path_params/tutorial003.py!}
```
Sinon, le chemin `/users/{user_id}` correspondrait aussi à `/users/me`, la fonction "croyant" qu'elle a reçu un paramètre `user_id` avec pour valeur `"me"`.
## Valeurs prédéfinies
Si vous avez une *fonction de chemin* qui reçoit un *paramètre de chemin*, mais que vous voulez que les valeurs possibles des paramètres soient prédéfinies, vous pouvez utiliser les <abbr title="Enumeration">`Enum`</abbr> de Python.
### Création d'un `Enum`
Importez `Enum` et créez une sous-classe qui hérite de `str` et `Enum`.
En héritant de `str` la documentation sera capable de savoir que les valeurs doivent être de type `string` et pourra donc afficher cette `Enum` correctement.
Créez ensuite des attributs de classe avec des valeurs fixes, qui seront les valeurs autorisées pour cette énumération.
```Python hl_lines="1 6-9"
{!../../../docs_src/path_params/tutorial005.py!}
```
!!! info
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Les énumérations (ou enums) sont disponibles en Python</a> depuis la version 3.4.
!!! tip "Astuce"
Pour ceux qui se demandent, "AlexNet", "ResNet", et "LeNet" sont juste des noms de <abbr title="Techniquement, des architectures de modèles">modèles</abbr> de Machine Learning.
### Déclarer un paramètre de chemin
Créez ensuite un *paramètre de chemin* avec une annotation de type désignant l'énumération créée précédemment (`ModelName`) :
```Python hl_lines="16"
{!../../../docs_src/path_params/tutorial005.py!}
```
### Documentation
Les valeurs disponibles pour le *paramètre de chemin* sont bien prédéfinies, la documentation les affiche correctement :
<img src="/img/tutorial/path-params/image03.png">
### Manipuler les *énumérations* Python
La valeur du *paramètre de chemin* sera un des "membres" de l'énumération.
#### Comparer les *membres d'énumération*
Vous pouvez comparer ce paramètre avec les membres de votre énumération `ModelName` :
```Python hl_lines="17"
{!../../../docs_src/path_params/tutorial005.py!}
```
#### Récupérer la *valeur de l'énumération*
Vous pouvez obtenir la valeur réel d'un membre (une chaîne de caractères ici), avec `model_name.value`, ou en général, `votre_membre_d'enum.value` :
```Python hl_lines="20"
{!../../../docs_src/path_params/tutorial005.py!}
```
!!! tip "Astuce"
Vous pouvez aussi accéder la valeur `"lenet"` avec `ModelName.lenet.value`.
#### Retourner des *membres d'énumération*
Vous pouvez retourner des *membres d'énumération* dans vos *fonctions de chemin*, même imbriquée dans un JSON (e.g. un `dict`).
Ils seront convertis vers leurs valeurs correspondantes (chaînes de caractères ici) avant d'être transmis au client :
```Python hl_lines="18 21 23"
{!../../../docs_src/path_params/tutorial005.py!}
```
Le client recevra une réponse JSON comme celle-ci :
```JSON
{
"model_name": "alexnet",
"message": "Deep Learning FTW!"
}
```
## Paramètres de chemin contenant des chemins
Disons que vous avez une *fonction de chemin* liée au chemin `/files/{file_path}`.
Mais que `file_path` lui-même doit contenir un *chemin*, comme `home/johndoe/myfile.txt` par exemple.
Donc, l'URL pour ce fichier pourrait être : `/files/home/johndoe/myfile.txt`.
### Support d'OpenAPI
OpenAPI ne supporte pas de manière de déclarer un paramètre de chemin contenant un *chemin*, cela pouvant causer des scénarios difficiles à tester et définir.
Néanmoins, cela reste faisable dans **FastAPI**, via les outils internes de Starlette.
Et la documentation fonctionne quand même, bien qu'aucune section ne soit ajoutée pour dire que la paramètre devrait contenir un *chemin*.
### Convertisseur de *chemin*
En utilisant une option de Starlette directement, vous pouvez déclarer un *paramètre de chemin* contenant un *chemin* avec une URL comme :
```
/files/{file_path:path}
```
Dans ce cas, le nom du paramètre est `file_path`, et la dernière partie, `:path`, indique à Starlette que le paramètre devrait correspondre à un *chemin*.
Vous pouvez donc l'utilisez comme tel :
```Python hl_lines="6"
{!../../../docs_src/path_params/tutorial004.py!}
```
!!! tip "Astuce"
Vous pourriez avoir besoin que le paramètre contienne `/home/johndoe/myfile.txt`, avec un slash au début (`/`).
Dans ce cas, l'URL serait : `/files//home/johndoe/myfile.txt`, avec un double slash (`//`) entre `files` et `home`.
## Récapitulatif
Avec **FastAPI**, en utilisant les déclarations de type rapides, intuitives et standards de Python, vous bénéficiez de :
* Support de l'éditeur : vérification d'erreurs, auto-complétion, etc.
* <abbr title="conversion de la chaîne de caractères venant de la requête HTTP en données Python">"Parsing"</abbr> de données.
* Validation de données.
* Annotations d'API et documentation automatique.
Et vous n'avez besoin de le déclarer qu'une fois.
C'est probablement l'avantage visible principal de **FastAPI** comparé aux autres *frameworks* (outre les performances pures).

View File

@@ -0,0 +1,198 @@
# Paramètres de requête
Quand vous déclarez des paramètres dans votre fonction de chemin qui ne font pas partie des paramètres indiqués dans le chemin associé, ces paramètres sont automatiquement considérés comme des paramètres de "requête".
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial001.py!}
```
La partie appelée requête (ou **query**) dans une URL est l'ensemble des paires clés-valeurs placées après le `?` , séparées par des `&`.
Par exemple, dans l'URL :
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
...les paramètres de requête sont :
* `skip` : avec une valeur de`0`
* `limit` : avec une valeur de `10`
Faisant partie de l'URL, ces valeurs sont des chaînes de caractères (`str`).
Mais quand on les déclare avec des types Python (dans l'exemple précédent, en tant qu'`int`), elles sont converties dans les types renseignés.
Toutes les fonctionnalités qui s'appliquent aux paramètres de chemin s'appliquent aussi aux paramètres de requête :
* Support de l'éditeur : vérification d'erreurs, auto-complétion, etc.
* <abbr title="conversion de la chaîne de caractères venant de la requête HTTP en données Python">"Parsing"</abbr> de données.
* Validation de données.
* Annotations d'API et documentation automatique.
## Valeurs par défaut
Les paramètres de requête ne sont pas une partie fixe d'un chemin, ils peuvent être optionnels et avoir des valeurs par défaut.
Dans l'exemple ci-dessus, ils ont des valeurs par défaut qui sont `skip=0` et `limit=10`.
Donc, accéder à l'URL :
```
http://127.0.0.1:8000/items/
```
serait équivalent à accéder à l'URL :
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
Mais si vous accédez à, par exemple :
```
http://127.0.0.1:8000/items/?skip=20
```
Les valeurs des paramètres de votre fonction seront :
* `skip=20` : car c'est la valeur déclarée dans l'URL.
* `limit=10` : car `limit` n'a pas été déclaré dans l'URL, et que la valeur par défaut était `10`.
## Paramètres optionnels
De la même façon, vous pouvez définir des paramètres de requête comme optionnels, en leur donnant comme valeur par défaut `None` :
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial002.py!}
```
Ici, le paramètre `q` sera optionnel, et aura `None` comme valeur par défaut.
!!! check "Remarque"
On peut voir que **FastAPI** est capable de détecter que le paramètre de chemin `item_id` est un paramètre de chemin et que `q` n'en est pas un, c'est donc un paramètre de requête.
!!! note
**FastAPI** saura que `q` est optionnel grâce au `=None`.
Le `Optional` dans `Optional[str]` n'est pas utilisé par **FastAPI** (**FastAPI** n'en utilisera que la partie `str`), mais il servira tout de même à votre editeur de texte pour détecter des erreurs dans votre code.
## Conversion des types des paramètres de requête
Vous pouvez aussi déclarer des paramètres de requête comme booléens (`bool`), **FastAPI** les convertira :
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial003.py!}
```
Avec ce code, en allant sur :
```
http://127.0.0.1:8000/items/foo?short=1
```
ou
```
http://127.0.0.1:8000/items/foo?short=True
```
ou
```
http://127.0.0.1:8000/items/foo?short=true
```
ou
```
http://127.0.0.1:8000/items/foo?short=on
```
ou
```
http://127.0.0.1:8000/items/foo?short=yes
```
ou n'importe quelle autre variation de casse (tout en majuscules, uniquement la première lettre en majuscule, etc.), votre fonction considérera le paramètre `short` comme ayant une valeur booléenne à `True`. Sinon la valeur sera à `False`.
## Multiples paramètres de chemin et de requête
Vous pouvez déclarer plusieurs paramètres de chemin et paramètres de requête dans la même fonction, **FastAPI** saura comment les gérer.
Et vous n'avez pas besoin de les déclarer dans un ordre spécifique.
Ils seront détectés par leurs noms :
```Python hl_lines="8 10"
{!../../../docs_src/query_params/tutorial004.py!}
```
## Paramètres de requête requis
Quand vous déclarez une valeur par défaut pour un paramètre qui n'est pas un paramètre de chemin (actuellement, nous n'avons vu que les paramètres de requête), alors ce paramètre n'est pas requis.
Si vous ne voulez pas leur donner de valeur par défaut mais juste les rendre optionnels, utilisez `None` comme valeur par défaut.
Mais si vous voulez rendre un paramètre de requête obligatoire, vous pouvez juste ne pas y affecter de valeur par défaut :
```Python hl_lines="6-7"
{!../../../docs_src/query_params/tutorial005.py!}
```
Ici le paramètre `needy` est un paramètre requis (ou obligatoire) de type `str`.
Si vous ouvrez une URL comme :
```
http://127.0.0.1:8000/items/foo-item
```
...sans ajouter le paramètre requis `needy`, vous aurez une erreur :
```JSON
{
"detail": [
{
"loc": [
"query",
"needy"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
```
La présence de `needy` étant nécessaire, vous auriez besoin de l'insérer dans l'URL :
```
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
```
...ce qui fonctionnerait :
```JSON
{
"item_id": "foo-item",
"needy": "sooooneedy"
}
```
Et bien sur, vous pouvez définir certains paramètres comme requis, certains avec des valeurs par défaut et certains entièrement optionnels :
```Python hl_lines="10"
{!../../../docs_src/query_params/tutorial006.py!}
```
Ici, on a donc 3 paramètres de requête :
* `needy`, requis et de type `str`.
* `skip`, un `int` avec comme valeur par défaut `0`.
* `limit`, un `int` optionnel.
!!! tip "Astuce"
Vous pouvez utiliser les `Enum`s de la même façon qu'avec les [Paramètres de chemin](path-params.md#valeurs-predefinies){.internal-link target=_blank}.

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -59,6 +56,9 @@ nav:
- fastapi-people.md
- python-types.md
- Tutoriel - Guide utilisateur:
- tutorial/first-steps.md
- tutorial/path-params.md
- tutorial/query-params.md
- tutorial/body.md
- tutorial/background-tasks.md
- async.md
@@ -82,8 +82,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -110,8 +107,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -0,0 +1,88 @@
# FastAPI 버전들에 대하여
**FastAPI** 는 이미 많은 응용 프로그램과 시스템들을 만드는데 사용되고 있습니다. 그리고 100%의 테스트 정확성을 가지고 있습니다. 하지만 이것은 아직까지도 빠르게 발전하고 있습니다.
새로운 특징들이 빈번하게 추가되고, 오류들이 지속적으로 수정되고 있습니다. 그리고 코드가 계속적으로 향상되고 있습니다.
이것이 아직도 최신 버전이 `0.x.x`인 이유입니다. 이것은 각각의 버전들이 잠재적으로 변할 수 있다는 것을 보여줍니다. 이는 <a href="https://semver.org/" class="external-link" target="_blank">유의적 버전</a> 관습을 따릅니다.
지금 바로 **FastAPI**로 응용 프로그램을 만들 수 있습니다. 이때 (아마 지금까지 그래 왔던 것처럼), 사용하는 버전이 코드와 잘 맞는지 확인해야합니다.
## `fastapi` 버전을 표시
가장 먼저 해야할 것은 응용 프로그램이 잘 작동하는 가장 최신의 구체적인 **FastAPI** 버전을 표시하는 것입니다.
예를 들어, 응용 프로그램에 `0.45.0` 버전을 사용했다고 가정합니다.
만약에 `requirements.txt` 파일을 사용했다면, 다음과 같이 버전을 명세할 수 있습니다:
```txt
fastapi==0.45.0
```
이것은 `0.45.0` 버전을 사용했다는 것을 의미합니다.
또는 다음과 같이 표시할 수 있습니다:
```txt
fastapi>=0.45.0,<0.46.0
```
이것은 `0.45.0` 버전과 같거나 높으면서 `0.46.0` 버전 보다는 낮은 버전을 사용했다는 것을 의미합니다. 예를 들어, `0.45.2` 버전과 같은 경우는 해당 조건을 만족합니다.
만약에 Poetry, Pipenv, 또는 그밖의 다양한 설치 도구를 사용한다면, 패키지에 구체적인 버전을 정의할 수 있는 방법을 가지고 있을 것입니다.
## 이용가능한 버전들
[Release Notes](../release-notes.md){.internal-link target=_blank}를 통해 사용할 수 있는 버전들을 확인할 수 있습니다.(예를 들어, 가장 최신의 버전을 확인할 수 있습니다.)
## 버전들에 대해
유의적 버전 관습을 따라서, `1.0.0` 이하의 모든 버전들은 잠재적으로 급변할 수 있습니다.
FastAPI는 오류를 수정하고, 일반적인 변경사항을 위해 "패치"버전의 관습을 따릅니다.
!!! tip "팁"
여기서 말하는 "패치"란 버전의 마지막 숫자로, 예를 들어 `0.2.3` 버전에서 "패치"는 `3`을 의미합니다.
따라서 다음과 같이 버전을 표시할 수 있습니다:
```txt
fastapi>=0.45.0,<0.46.0
```
수정된 사항과 새로운 요소들이 "마이너" 버전에 추가되었습니다.
!!! tip "팁"
"마이너"란 버전 넘버의 가운데 숫자로, 예를 들어서 `0.2.3`의 "마이너" 버전은 `2`입니다.
## FastAPI 버전의 업그레이드
응용 프로그램을 검사해야합니다.
(Starlette 덕분에), **FastAPI** 를 이용하여 굉장히 쉽게 할 수 있습니다. [Testing](../tutorial/testing.md){.internal-link target=_blank}문서를 확인해 보십시오:
검사를 해보고 난 후에, **FastAPI** 버전을 더 최신으로 업그레이드 할 수 있습니다. 그리고 코드들이 테스트에 정상적으로 작동하는지 확인을 해야합니다.
만약에 모든 것이 정상 작동하거나 필요한 부분을 변경하고, 모든 검사를 통과한다면, 새로운 버전의 `fastapi`를 표시할 수 있습니다.
## Starlette에 대해
`starlette`의 버전은 표시할 수 없습니다.
서로다른 버전의 **FastAPI**가 구체적이고 새로운 버전의 Starlette을 사용할 것입니다.
그러므로 **FastAPI**가 알맞은 Starlette 버전을 사용하도록 하십시오.
## Pydantic에 대해
Pydantic은 **FastAPI** 를 위한 검사를 포함하고 있습니다. 따라서, 새로운 버전의 Pydantic(`1.0.0`이상)은 항상 FastAPI와 호환됩니다.
작업을 하고 있는 `1.0.0` 이상의 모든 버전과 `2.0.0` 이하의 Pydantic 버전을 표시할 수 있습니다.
예를 들어 다음과 같습니다:
```txt
pydantic>=1.2.0,<2.0.0
```

View File

@@ -35,7 +35,7 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
* **직관적**: 훌륭한 편집기 지원. 모든 곳에서 <abbr title="also known as auto-complete, autocompletion, IntelliSense">자동완성</abbr>. 적은 디버깅 시간.
* **쉬움**: 쉽게 사용하고 배우도록 설계. 적은 문서 읽기 시간.
* **짧음**: 코드 중복 최소화. 각 매개변수 선언의 여러 기능. 적은 버그.
* **견고함**: 준비된 프로덕션 용 코드를 얻으세요. 자동 대화형 문서와 함께.
* **견고함**: 준비된 프로덕션 용 코드를 얻으십시오. 자동 대화형 문서와 함께.
* **표준 기반**: API에 대한 (완전히 호환되는) 개방형 표준 기반: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (이전에 Swagger로 알려졌던) 및 <a href="http://json-schema.org/" class="external-link" target="_blank">JSON 스키마</a>.
<small>* 내부 개발팀의 프로덕션 애플리케이션을 빌드한 테스트에 근거한 측정</small>
@@ -89,9 +89,9 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
---
"_REST API를 만들기 위해 **현대적인 프레임워크**를 찾고 있다면 **FastAPI**를 확인해 보세요. [...] 빠르고, 쓰기 쉽고, 배우기도 쉽습니다 [...]_"
"_REST API를 만들기 위해 **현대적인 프레임워크**를 찾고 있다면 **FastAPI**를 확인해 보십시오. [...] 빠르고, 쓰기 쉽고, 배우기도 쉽습니다 [...]_"
"_우리 **API**를 **FastAPI**로 바꿨습니다 [...] 아마 여러분도 좋아하실 니다 [...]_"
"_우리 **API**를 **FastAPI**로 바꿨습니다 [...] 아마 여러분도 좋아하실 것입니다 [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> 설립자 - <a href="https://spacy.io" target="_blank">spaCy</a> 제작자</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
@@ -193,7 +193,7 @@ async def read_item(item_id: int, q: Optional[str] = None):
### 실행하기
서버를 실행하세요:
서버를 실행하십시오:
<div class="termy">
@@ -239,7 +239,7 @@ INFO: Application startup complete.
### 대화형 API 문서
이제 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>로 가보세요.
이제 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>로 가보십시오.
자동 대화형 API 문서를 볼 수 있습니다 (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> 제공):
@@ -388,7 +388,7 @@ item: Item
우리는 그저 수박 겉핡기만 했을 뿐인데 여러분은 벌써 어떻게 작동하는지 알고 있습니다.
다음 줄을 바꿔보세요:
다음 줄을 바꿔보십시오:
```Python
return {"item_name": item.name, "item_id": item_id}
@@ -447,7 +447,7 @@ Starlette이 사용하는:
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - 기본 템플릿 설정을 사용하려면 필요.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - `request.form()`과 함께 <abbr title="HTTP 요청에서 파이썬 데이터로 가는 문자열 변환">"parsing"</abbr>의 지원을 원하면 필요.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` 지원을 위해 필요.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Starlette의 `SchemaGenerator` 지원을 위해 필요 (FastAPI와 쓸때는 필요 없을 니다).
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Starlette의 `SchemaGenerator` 지원을 위해 필요 (FastAPI와 쓸때는 필요 없을 것입니다).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - `GraphQLApp` 지원을 위해 필요.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse`를 사용하려면 필요.

View File

@@ -0,0 +1,34 @@
# JSON 호환 가능 인코더
데이터 유형(예: Pydantic 모델)을 JSON과 호환된 형태로 반환해야 하는 경우가 있습니다. (예: `dict`, `list` 등)
예를 들면, 데이터베이스에 저장해야하는 경우입니다.
이를 위해, **FastAPI** 에서는 `jsonable_encoder()` 함수를 제공합니다.
## `jsonable_encoder` 사용
JSON 호환 가능 데이터만 수신하는 `fake_db` 데이터베이스가 존재한다고 가정하겠습니다.
예를 들면, `datetime` 객체는 JSON과 호환되는 데이터가 아니므로 이 데이터는 받아들여지지 않습니다.
따라서 `datetime` 객체는 <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO format</a> 데이터를 포함하는 `str`로 변환되어야 합니다.
같은 방식으로 이 데이터베이스는 Pydantic 모델(속성이 있는 객체)을 받지 않고, `dict` 만을 받습니다.
이를 위해 `jsonable_encoder` 를 사용할 수 있습니다.
Pydantic 모델과 같은 객체를 받고 JSON 호환 가능한 버전으로 반환합니다:
```Python hl_lines="5 22"
{!../../../docs_src/encoder/tutorial001.py!}
```
이 예시는 Pydantic 모델을 `dict`로, `datetime` 형식을 `str`로 변환합니다.
이렇게 호출한 결과는 파이썬 표준인 <a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a>로 인코딩 할 수 있습니다.
길이가 긴 문자열 형태의 JSON 형식(문자열)의 데이터가 들어있는 상황에서는 `str`로 반환하지 않습니다. JSON과 모두 호환되는 값과 하위 값이 있는 Python 표준 데이터 구조 (예: `dict`)를 반환합니다.
!!! note "참고"
실제로 `jsonable_encoder`는 **FastAPI** 에서 내부적으로 데이터를 변환하는 데 사용하지만, 다른 많은 곳에서도 이는 유용합니다.

View File

@@ -2,11 +2,11 @@
이 자습서는 **FastAPI**의 대부분의 기능을 단계별로 사용하는 방법을 보여줍니다.
각 섹션은 이전 섹션을 기반해서 점진적으로 만들어 졌지만, 주제를 구분하여 구성 되었기 때문에 특정 API 요구사항을 해결하기 위해 어 특정 항목던지 직접 이동할 수 있습니다.
각 섹션은 이전 섹션을 기반해서 점진적으로 만들어 졌지만, 주제에 따라 다르게 구성되었기 때문에 특정 API 요구사항을 해결하기 위해서라면 특정 항목으로던지 직접 이동할 수 있습니다.
또한 향후 참조가 될 수 있도록 만들어졌습니다.
그러므로 다시 돌아와서 정확히 필요한 것을 수 있습니다.
그러므로 다시 돌아와서 정확히 필요한 것을 확인할 수 있습니다.
## 코드 실행하기
@@ -30,7 +30,7 @@ $ uvicorn main:app --reload
코드를 작성하거나 복사, 편집할 때, 로컬에서 실행하는 것을 **강력히 장려**합니다.
편집기에서 이렇게 사용면, 모든 타입 검사, 자동완성 등 작성해야 하는 코드가 얼마나 적은지 보면서 FastAPI의 장점을 실제로 확인할 수 있습니다.
편집기에서 이렇게 사용한다면, 모든 타입 검사 자동완성 등 작성해야 하는 코드가 얼마나 적은지 보면서 FastAPI의 장점을 실제로 확인할 수 있습니다.
---
@@ -77,4 +77,4 @@ $ pip install fastapi[all]
하지만 (지금 읽고 있는) **자습서 - 사용자 안내서**를 먼저 읽는게 좋습니다.
**자습서 - 사용자 안내서**만으로 완전한 애플리케이션을 구축한 다음, **고급 사용자 안내서** 몇 가지 추가 아이디어를 사용하여 필요에 따라 다양한 방식으로 확장할 수 있도록 설계되었습니다.
**자습서 - 사용자 안내서**만으로 완전한 애플리케이션을 구축할 수 있으며, 필요에 따라 **고급 사용자 안내서**에서 제공하는 몇 가지 추가적인 기능을 사용하여 다양한 방식으로 확장할 수 있도록 설계되었습니다.

View File

@@ -0,0 +1,122 @@
# 경로 매개변수와 숫자 검증
`Query`를 사용하여 쿼리 매개변수에 더 많은 검증과 메타데이터를 선언하는 방법과 동일하게 `Path`를 사용하여 경로 매개변수에 검증과 메타데이터를 같은 타입으로 선언할 수 있습니다.
## 경로 임포트
먼저 `fastapi`에서 `Path`를 임포트합니다:
```Python hl_lines="3"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
## 메타데이터 선언
`Query`에 동일한 매개변수를 선언할 수 있습니다.
예를 들어, `title` 메타데이터 값을 경로 매개변수 `item_id`에 선언하려면 다음과 같이 입력할 수 있습니다:
```Python hl_lines="10"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
!!! note "참고"
경로 매개변수는 경로의 일부여야 하므로 언제나 필수적입니다.
즉, `...`로 선언해서 필수임을 나타내는게 좋습니다.
그럼에도 `None`으로 선언하거나 기본값을 지정할지라도 아무 영향을 끼치지 않으며 언제나 필수입니다.
## 필요한 경우 매개변수 정렬하기
`str` 형인 쿼리 매개변수 `q`를 필수로 선언하고 싶다고 해봅시다.
해당 매개변수에 대해 아무런 선언을 할 필요가 없으므로 `Query`를 정말로 써야할 필요는 없습니다.
하지만 `item_id` 경로 매개변수는 여전히 `Path`를 사용해야 합니다.
파이썬은 "기본값"이 없는 값 앞에 "기본값"이 있는 값을 입력하면 불평합니다.
그러나 매개변수들을 재정렬함으로써 기본값(쿼리 매개변수 `q`)이 없는 값을 처음 부분에 위치 할 수 있습니다.
**FastAPI**에서는 중요하지 않습니다. 이름, 타입 그리고 선언구(`Query`, `Path` 등)로 매개변수를 감지하며 순서는 신경 쓰지 않습니다.
따라서 함수를 다음과 같이 선언 할 수 있습니다:
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
## 필요한 경우 매개변수 정렬하기, 트릭
`Query`나 아무런 기본값으로도 `q` 경로 매개변수를 선언하고 싶지 않지만 `Path`를 사용하여 경로 매개변수를 `item_id` 다른 순서로 선언하고 싶다면, 파이썬은 이를 위한 작고 특별한 문법이 있습니다.
`*`를 함수의 첫 번째 매개변수로 전달하세요.
파이썬은 `*`으로 아무런 행동도 하지 않지만, 따르는 매개변수들은 <abbr title="유래: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>로도 알려진 키워드 인자(키-값 쌍)여야 함을 인지합니다. 기본값을 가지고 있지 않더라도 그렇습니다.
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
## 숫자 검증: 크거나 같음
`Query`와 `Path`(나중에 볼 다른 것들도)를 사용하여 문자열 뿐만 아니라 숫자의 제약을 선언할 수 있습니다.
여기서 `ge=1`인 경우, `item_id`는 `1`보다 "크거나(`g`reater) 같은(`e`qual)" 정수형 숫자여야 합니다.
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
## 숫자 검증: 크거나 같음 및 작거나 같음
동일하게 적용됩니다:
* `gt`: 크거나(`g`reater `t`han)
* `le`: 작거나 같은(`l`ess than or `e`qual)
```Python hl_lines="9"
{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
## 숫자 검증: 부동소수, 크거나 및 작거나
숫자 검증은 `float` 값에도 동작합니다.
여기에서 <abbr title="greater than or equal"><code>ge</code></abbr>뿐만 아니라 <abbr title="greater than"><code>gt</code></abbr>를 선언 할 수있는 것이 중요해집니다. 예를 들어 필요한 경우, 값이 `1`보다 작더라도 반드시 `0`보다 커야합니다.
즉, `0.5`는 유효한 값입니다. 그러나 `0.0` 또는 `0`은 그렇지 않습니다.
<abbr title="less than"><code>lt</code></abbr> 역시 마찬가지입니다.
```Python hl_lines="11"
{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
## 요약
`Query`, `Path`(아직 보지 못한 다른 것들도)를 사용하면 [쿼리 매개변수와 문자열 검증](query-params-str-validations.md){.internal-link target=_blank}에서와 마찬가지로 메타데이터와 문자열 검증을 선언할 수 있습니다.
그리고 숫자 검증 또한 선언할 수 있습니다:
* `gt`: 크거나(`g`reater `t`han)
* `ge`: 크거나 같은(`g`reater than or `e`qual)
* `lt`: 작거나(`l`ess `t`han)
* `le`: 작거나 같은(`l`ess than or `e`qual)
!!! info "정보"
`Query`, `Path`, 그리고 나중에게 보게될 것들은 (여러분이 사용할 필요가 없는) 공통 `Param` 클래스의 서브 클래스입니다.
그리고 이들 모두는 여태까지 본 추가 검증과 메타데이터의 동일한 모든 매개변수를 공유합니다.
!!! note "기술 세부사항"
`fastapi`에서 `Query`, `Path` 등을 임포트 할 때, 이것들은 실제로 함수입니다.
호출되면 동일한 이름의 클래스의 인스턴스를 반환합니다.
즉, 함수인 `Query`를 임포트한 겁니다. 그리고 호출하면 `Query`라는 이름을 가진 클래스의 인스턴스를 반환합니다.
편집기에서 타입에 대한 오류를 표시하지 않도록 하기 위해 (클래스를 직접 사용하는 대신) 이러한 함수들이 있습니다.
이렇게 하면 오류를 무시하기 위한 사용자 설정을 추가하지 않고도 일반 편집기와 코딩 도구를 사용할 수 있습니다.

View File

@@ -0,0 +1,144 @@
# 파일 요청
`File`을 사용하여 클라이언트가 업로드할 파일들을 정의할 수 있습니다.
!!! info "정보"
업로드된 파일을 전달받기 위해 먼저 <a href="https://andrew-d.github.io/python-multipart/" class="external-link" target="_blank">`python-multipart`</a>를 설치해야합니다.
예시) `pip install python-multipart`.
업로드된 파일들은 "폼 데이터"의 형태로 전송되기 때문에 이 작업이 필요합니다.
## `File` 임포트
`fastapi` 에서 `File``UploadFile` 을 임포트 합니다:
```Python hl_lines="1"
{!../../../docs_src/request_files/tutorial001.py!}
```
## `File` 매개변수 정의
`Body` 및 `Form` 과 동일한 방식으로 파일의 매개변수를 생성합니다:
```Python hl_lines="7"
{!../../../docs_src/request_files/tutorial001.py!}
```
!!! info "정보"
`File` 은 `Form` 으로부터 직접 상속된 클래스입니다.
하지만 `fastapi`로부터 `Query`, `Path`, `File` 등을 임포트 할 때, 이것들은 특별한 클래스들을 반환하는 함수라는 것을 기억하기 바랍니다.
!!! tip "팁"
File의 본문을 선언할 때, 매개변수가 쿼리 매개변수 또는 본문(JSON) 매개변수로 해석되는 것을 방지하기 위해 `File` 을 사용해야합니다.
파일들은 "폼 데이터"의 형태로 업로드 됩니다.
*경로 작동 함수*의 매개변수를 `bytes` 로 선언하는 경우 **FastAPI**는 파일을 읽고 `bytes` 형태의 내용을 전달합니다.
이것은 전체 내용이 메모리에 저장된다는 것을 의미한다는 걸 염두하기 바랍니다. 이는 작은 크기의 파일들에 적합합니다.
어떤 경우에는 `UploadFile` 을 사용하는 것이 더 유리합니다.
## `File` 매개변수와 `UploadFile`
`File` 매개변수를 `UploadFile` 타입으로 정의합니다:
```Python hl_lines="12"
{!../../../docs_src/request_files/tutorial001.py!}
```
`UploadFile` 을 사용하는 것은 `bytes` 과 비교해 다음과 같은 장점이 있습니다:
* "스풀 파일"을 사용합니다.
* 최대 크기 제한까지만 메모리에 저장되며, 이를 초과하는 경우 디스크에 저장됩니다.
* 따라서 이미지, 동영상, 큰 이진코드와 같은 대용량 파일들을 많은 메모리를 소모하지 않고 처리하기에 적합합니다.
* 업로드 된 파일의 메타데이터를 얻을 수 있습니다.
* <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> `async` 인터페이스를 갖고 있습니다.
* file-like object를 필요로하는 다른 라이브러리에 직접적으로 전달할 수 있는 파이썬 <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> 객체를 반환합니다.
### `UploadFile`
`UploadFile` 은 다음과 같은 어트리뷰트가 있습니다:
* `filename` : 문자열(`str`)로 된 업로드된 파일의 파일명입니다 (예: `myimage.jpg`).
* `content_type` : 문자열(`str`)로 된 파일 형식(MIME type / media type)입니다 (예: `image/jpeg`).
* `file` : <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> (<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">파일류</a> 객체)입니다. 이것은 "파일류" 객체를 필요로하는 다른 라이브러리에 직접적으로 전달할 수 있는 실질적인 파이썬 파일입니다.
`UploadFile` 에는 다음의 `async` 메소드들이 있습니다. 이들은 내부적인 `SpooledTemporaryFile` 을 사용하여 해당하는 파일 메소드를 호출합니다.
* `write(data)`: `data`(`str` 또는 `bytes`)를 파일에 작성합니다.
* `read(size)`: 파일의 바이트 및 글자의 `size`(`int`)를 읽습니다.
* `seek(offset)`: 파일 내 `offset`(`int`) 위치의 바이트로 이동합니다.
* 예) `await myfile.seek(0)` 를 사용하면 파일의 시작부분으로 이동합니다.
* `await myfile.read()` 를 사용한 후 내용을 다시 읽을 때 유용합니다.
* `close()`: 파일을 닫습니다.
상기 모든 메소드들이 `async` 메소드이기 때문에 “await”을 사용하여야 합니다.
예를들어, `async` *경로 작동 함수*의 내부에서 다음과 같은 방식으로 내용을 가져올 수 있습니다:
```Python
contents = await myfile.read()
```
만약 일반적인 `def` *경로 작동 함수*의 내부라면, 다음과 같이 `UploadFile.file` 에 직접 접근할 수 있습니다:
```Python
contents = myfile.file.read()
```
!!! note "`async` 기술적 세부사항"
`async` 메소드들을 사용할 때 **FastAPI**는 스레드풀에서 파일 메소드들을 실행하고 그들을 기다립니다.
!!! note "Starlette 기술적 세부사항"
**FastAPI**의 `UploadFile` 은 **Starlette**의 `UploadFile` 을 직접적으로 상속받지만, **Pydantic** 및 FastAPI의 다른 부분들과의 호환성을 위해 필요한 부분들이 추가되었습니다.
## "폼 데이터"란
HTML의 폼들(`<form></form>`)이 서버에 데이터를 전송하는 방식은 대개 데이터에 JSON과는 다른 "특별한" 인코딩을 사용합니다.
**FastAPI**는 JSON 대신 올바른 위치에서 데이터를 읽을 수 있도록 합니다.
!!! note "기술적 세부사항"
폼의 데이터는 파일이 포함되지 않은 경우 일반적으로 "미디어 유형" `application/x-www-form-urlencoded` 을 사용해 인코딩 됩니다.
하지만 파일이 포함된 경우, `multipart/form-data`로 인코딩됩니다. `File`을 사용하였다면, **FastAPI**는 본문의 적합한 부분에서 파일을 가져와야 한다는 것을 인지합니다.
인코딩과 폼 필드에 대해 더 알고싶다면, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><code>POST</code>에 관한<abbr title="Mozilla Developer Network">MDN</abbr>웹 문서</a> 를 참고하기 바랍니다,.
!!! warning "주의"
다수의 `File` 과 `Form` 매개변수를 한 *경로 작동*에 선언하는 것이 가능하지만, 요청의 본문이 `application/json` 가 아닌 `multipart/form-data` 로 인코딩 되기 때문에 JSON으로 받아야하는 `Body` 필드를 함께 선언할 수는 없습니다.
이는 **FastAPI**의 한계가 아니라, HTTP 프로토콜에 의한 것입니다.
## 다중 파일 업로드
여러 파일을 동시에 업로드 할 수 있습니다.
그들은 "폼 데이터"를 사용하여 전송된 동일한 "폼 필드"에 연결됩니다.
이 기능을 사용하기 위해 , `bytes` 의 `List` 또는 `UploadFile` 를 선언하기 바랍니다:
```Python hl_lines="10 15"
{!../../../docs_src/request_files/tutorial002.py!}
```
선언한대로, `bytes` 의 `list` 또는 `UploadFile` 들을 전송받을 것입니다.
!!! note "참고"
2019년 4월 14일부터 Swagger UI가 하나의 폼 필드로 다수의 파일을 업로드하는 것을 지원하지 않습니다. 더 많은 정보를 원하면, <a href="https://github.com/swagger-api/swagger-ui/issues/4276" class="external-link" target="_blank">#4276</a>과 <a href="https://github.com/swagger-api/swagger-ui/issues/3641" class="external-link" target="_blank">#3641</a>을 참고하세요.
그럼에도, **FastAPI**는 표준 Open API를 사용해 이미 호환이 가능합니다.
따라서 Swagger UI 또는 기타 그 외의 OpenAPI를 지원하는 툴이 다중 파일 업로드를 지원하는 경우, 이들은 **FastAPI**와 호환됩니다.
!!! note "기술적 세부사항"
`from starlette.responses import HTMLResponse` 역시 사용할 수 있습니다.
**FastAPI**는 개발자의 편의를 위해 `fastapi.responses` 와 동일한 `starlette.responses` 도 제공합니다. 하지만 대부분의 응답들은 Starlette로부터 직접 제공됩니다.
## 요약
폼 데이터로써 입력 매개변수로 업로드할 파일을 선언할 경우 `File` 을 사용하기 바랍니다.

View File

@@ -0,0 +1,35 @@
# 폼 및 파일 요청
`File``Form` 을 사용하여 파일과 폼을 함께 정의할 수 있습니다.
!!! info "정보"
파일과 폼 데이터를 함께, 또는 각각 업로드하기 위해 먼저 <a href="https://andrew-d.github.io/python-multipart/" class="external-link" target="_blank">`python-multipart`</a>를 설치해야합니다.
예 ) `pip install python-multipart`.
## `File` 및 `Form` 업로드
```Python hl_lines="1"
{!../../../docs_src/request_forms_and_files/tutorial001.py!}
```
## `File` 및 `Form` 매개변수 정의
`Body` 및 `Query`와 동일한 방식으로 파일과 폼의 매개변수를 생성합니다:
```Python hl_lines="8"
{!../../../docs_src/request_forms_and_files/tutorial001.py!}
```
파일과 폼 필드는 폼 데이터 형식으로 업로드되어 파일과 폼 필드로 전달됩니다.
어떤 파일들은 `bytes`로, 또 어떤 파일들은 `UploadFile`로 선언할 수 있습니다.
!!! warning "주의"
다수의 `File`과 `Form` 매개변수를 한 *경로 작동*에 선언하는 것이 가능하지만, 요청의 본문이 `application/json`가 아닌 `multipart/form-data`로 인코딩 되기 때문에 JSON으로 받아야하는 `Body` 필드를 함께 선언할 수는 없습니다.
이는 **FastAPI**의 한계가 아니라, HTTP 프로토콜에 의한 것입니다.
## 요약
하나의 요청으로 데이터와 파일들을 받아야 할 경우 `File`과 `Form`을 함께 사용하기 바랍니다.

View File

@@ -0,0 +1,89 @@
# 응답 상태 코드
응답 모델과 같은 방법으로, 어떤 *경로 작동*이든 `status_code` 매개변수를 사용하여 응답에 대한 HTTP 상태 코드를 선언할 수 있습니다.
* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
* 기타
```Python hl_lines="6"
{!../../../docs_src/response_status_code/tutorial001.py!}
```
!!! note "참고"
`status_code` 는 "데코레이터" 메소드(`get`, `post` 등)의 매개변수입니다. 모든 매개변수들과 본문처럼 *경로 작동 함수*가 아닙니다.
`status_code` 매개변수는 HTTP 상태 코드를 숫자로 입력받습니다.
!!! info "정보"
`status_code` 는 파이썬의 `http.HTTPStatus` 와 같은 `IntEnum` 을 입력받을 수도 있습니다.
`status_code` 매개변수는:
* 응답에서 해당 상태 코드를 반환합니다.
* 상태 코드를 OpenAPI 스키마(및 사용자 인터페이스)에 문서화 합니다.
<img src="https://fastapi.tiangolo.com/img/tutorial/response-status-code/image01.png">
!!! note "참고"
어떤 응답 코드들은 해당 응답에 본문이 없다는 것을 의미하기도 합니다 (다음 항목 참고).
이에 따라 FastAPI는 응답 본문이 없음을 명시하는 OpenAPI를 생성합니다.
## HTTP 상태 코드에 대하여
!!! note "참고"
만약 HTTP 상태 코드에 대하여 이미 알고있다면, 다음 항목으로 넘어가십시오.
HTTP는 세자리의 숫자 상태 코드를 응답의 일부로 전송합니다.
이 상태 코드들은 각자를 식별할 수 있도록 지정된 이름이 있으나, 중요한 것은 숫자 코드입니다.
요약하자면:
* `**1xx**` 상태 코드는 "정보"용입니다. 이들은 직접적으로는 잘 사용되지는 않습니다. 이 상태 코드를 갖는 응답들은 본문을 가질 수 없습니다.
* `**2xx**` 상태 코드는 "성공적인" 응답을 위해 사용됩니다. 가장 많이 사용되는 유형입니다.
* `200` 은 디폴트 상태 코드로, 모든 것이 "성공적임"을 의미합니다.
* 다른 예로는 `201` "생성됨"이 있습니다. 일반적으로 데이터베이스에 새로운 레코드를 생성한 후 사용합니다.
* 단, `204` "내용 없음"은 특별한 경우입니다. 이것은 클라이언트에게 반환할 내용이 없는 경우 사용합니다. 따라서 응답은 본문을 가질 수 없습니다.
* `**3xx**` 상태 코드는 "리다이렉션"용입니다. 본문을 가질 수 없는 `304` "수정되지 않음"을 제외하고, 이 상태 코드를 갖는 응답에는 본문이 있을 수도, 없을 수도 있습니다.
* `**4xx**` 상태 코드는 "클라이언트 오류" 응답을 위해 사용됩니다. 이것은 아마 가장 많이 사용하게 될 두번째 유형입니다.
* 일례로 `404` 는 "찾을 수 없음" 응답을 위해 사용합니다.
* 일반적인 클라이언트 오류의 경우 `400` 을 사용할 수 있습니다.
* `**5xx**` 상태 코드는 서버 오류에 사용됩니다. 이것들을 직접 사용할 일은 거의 없습니다. 응용 프로그램 코드나 서버의 일부에서 문제가 발생하면 자동으로 이들 상태 코드 중 하나를 반환합니다.
!!! tip "팁"
각각의 상태 코드와 이들이 의미하는 내용에 대해 더 알고싶다면 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> HTTP 상태 코드에 관한 문서</a> 를 확인하십시오.
## 이름을 기억하는 쉬운 방법
상기 예시 참고:
```Python hl_lines="6"
{!../../../docs_src/response_status_code/tutorial001.py!}
```
`201` 은 "생성됨"를 의미하는 상태 코드입니다.
하지만 모든 상태 코드들이 무엇을 의미하는지 외울 필요는 없습니다.
`fastapi.status` 의 편의 변수를 사용할 수 있습니다.
```Python hl_lines="1 6"
{!../../../docs_src/response_status_code/tutorial002.py!}
```
이것은 단순히 작업을 편리하게 하기 위한 것으로, HTTP 상태 코드와 동일한 번호를 갖고있지만, 이를 사용하면 편집기의 자동완성 기능을 사용할 수 있습니다:
<img src="https://fastapi.tiangolo.com/img/tutorial/response-status-code/image02.png">
!!! note "기술적 세부사항"
`from starlette import status` 역시 사용할 수 있습니다.
**FastAPI**는 개발자인 당신의 편의를 위해 `fastapi.status` 와 동일한 `starlette.status` 도 제공합니다. 하지만 이것은 Starlette로부터 직접 제공됩니다.
## 기본값 변경
추후 여기서 선언하는 기본 상태 코드가 아닌 다른 상태 코드를 반환하는 방법을 [숙련된 사용자 지침서](https://fastapi.tiangolo.com/ko/advanced/response-change-status-code/){.internal-link target=_blank}에서 확인할 수 있습니다.

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -61,6 +58,10 @@ nav:
- tutorial/path-params.md
- tutorial/query-params.md
- tutorial/header-params.md
- tutorial/path-params-numeric-validations.md
- tutorial/response-status-code.md
- tutorial/request-files.md
- tutorial/request-forms-and-files.md
markdown_extensions:
- toc:
permalink: true
@@ -76,8 +77,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -1,12 +1,8 @@
{!../../../docs/missing-translation.md!}
<p align="center">
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
</p>
<p align="center">
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
<em>FastAPI to szybki, prosty w nauce i gotowy do użycia w produkcji framework</em>
</p>
<p align="center">
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
@@ -22,29 +18,28 @@
---
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
**Dokumentacja**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
**Kod żródłowy**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
FastAPI to nowoczesny, wydajny framework webowy do budowania API z użyciem Pythona 3.6+ bazujący na standardowym typowaniu Pythona.
The key features are:
Kluczowe cechy:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Wydajność**: FastAPI jest bardzo wydajny, na równi z **NodeJS** oraz **Go** (dzięki Starlette i Pydantic). [Jeden z najszybszych dostępnych frameworków Pythonowych](#wydajnosc).
* **Szybkość kodowania**: Przyśpiesza szybkość pisania nowych funkcjonalności o około 200% do 300%. *
* **Mniejsza ilość błędów**: Zmniejsza ilość ludzkich (dewelopera) błędy o około 40%. *
* **Intuicyjność**: Wspaniałe wsparcie dla edytorów kodu. Dostępne wszędzie <abbr title="znane jako auto-complete, autocompletion, IntelliSense">automatyczne uzupełnianie</abbr> kodu. Krótszy czas debugowania.
* **Łatwość**: Zaprojektowany by być prosty i łatwy do nauczenia. Mniej czasu spędzonego na czytanie dokumentacji.
* **Kompaktowość**: Minimalizacja powtarzającego się kodu. Wiele funkcjonalności dla każdej deklaracji parametru. Mniej błędów.
* **Solidność**: Kod gotowy dla środowiska produkcyjnego. Wraz z automatyczną interaktywną dokumentacją.
* **Bazujący na standardach**: Oparty na (i w pełni kompatybilny z) otwartych standardach API: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (wcześniej znane jako Swagger) oraz <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* oszacowania bazowane na testach wykonanych przez wewnętrzny zespół deweloperów, budujących aplikacie używane na środowisku produkcyjnym.</small>
<small>* estimation based on tests on an internal development team, building production applications.</small>
## Sponsors
## Sponsorzy
<!-- sponsors -->
@@ -59,9 +54,9 @@ The key features are:
<!-- /sponsors -->
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Inni sponsorzy</a>
## Opinions
## Opinie
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
@@ -101,24 +96,24 @@ The key features are:
---
## **Typer**, the FastAPI of CLIs
## **Typer**, FastAPI aplikacji konsolowych
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
Jeżeli tworzysz aplikacje <abbr title="aplikacja z interfejsem konsolowym">CLI</abbr>, która ma być używana w terminalu zamiast API, sprawdź <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
**Typer** to młodsze rodzeństwo FastAPI. Jego celem jest pozostanie **FastAPI aplikacji konsolowych** . ⌨️ 🚀
## Requirements
## Wymagania
Python 3.6+
FastAPI stands on the shoulders of giants:
FastAPI oparty jest na:
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> dla części webowej.
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> dla części obsługujących dane.
## Installation
## Instalacja
<div class="termy">
@@ -130,7 +125,7 @@ $ pip install fastapi
</div>
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
Na serwerze produkcyjnym będziesz także potrzebował serwera ASGI, np. <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> lub <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
@@ -142,11 +137,11 @@ $ pip install uvicorn[standard]
</div>
## Example
## Przykład
### Create it
### Stwórz
* Create a file `main.py` with:
* Utwórz plik o nazwie `main.py` z:
```Python
from typing import Optional
@@ -167,9 +162,9 @@ def read_item(item_id: int, q: Optional[str] = None):
```
<details markdown="1">
<summary>Or use <code>async def</code>...</summary>
<summary>Albo użyj <code>async def</code>...</summary>
If your code uses `async` / `await`, use `async def`:
Jeżeli twój kod korzysta z `async` / `await`, użyj `async def`:
```Python hl_lines="9 14"
from typing import Optional
@@ -189,15 +184,15 @@ async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
**Note**:
**Przypis**:
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
Jeżeli nie znasz, sprawdź sekcję _"In a hurry?"_ o <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` i `await` w dokumentacji</a>.
</details>
### Run it
### Uruchom
Run the server with:
Uruchom serwer używając:
<div class="termy">
@@ -214,54 +209,53 @@ INFO: Application startup complete.
</div>
<details markdown="1">
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
<summary>O komendzie <code>uvicorn main:app --reload</code>...</summary>
Komenda `uvicorn main:app` odnosi się do:
The command `uvicorn main:app` refers to:
* `main`: the file `main.py` (the Python "module").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
* `--reload`: make the server restart after code changes. Only do this for development.
* `main`: plik `main.py` ("moduł" w Pythonie).
* `app`: obiekt stworzony w `main.py` w lini `app = FastAPI()`.
* `--reload`: spraw by serwer resetował się po każdej zmianie w kodzie. Używaj tego tylko w środowisku deweloperskim.
</details>
### Check it
### Wypróbuj
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
Otwórz link <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a> w przeglądarce.
You will see the JSON response as:
Zobaczysz następującą odpowiedź JSON:
```JSON
{"item_id": 5, "q": "somequery"}
```
You already created an API that:
Właśnie stworzyłeś API które:
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
* Otrzymuje żądania HTTP w _ścieżce_ `/` i `/items/{item_id}`.
* Obie _ścieżki_ używają <em>operacji</em> `GET` (znane także jako _metody_ HTTP).
* _Ścieżka_ `/items/{item_id}` ma _parametr ścieżki_ `item_id` który powinien być obiektem typu `int`.
* _Ścieżka_ `/items/{item_id}` ma opcjonalny _parametr zapytania_ typu `str` o nazwie `q`.
### Interactive API docs
### Interaktywna dokumentacja API
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Otwórz teraz stronę <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
Zobaczysz automatyczną interaktywną dokumentację API (dostarczoną z pomocą <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Alternative API docs
### Alternatywna dokumentacja API
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
Otwórz teraz <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
Zobaczysz alternatywną, lecz wciąż automatyczną dokumentację (wygenerowaną z pomocą <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Example upgrade
## Aktualizacja przykładu
Now modify the file `main.py` to receive a body from a `PUT` request.
Zmodyfikuj teraz plik `main.py`, aby otrzmywał treść (body) żądania `PUT`.
Declare the body using standard Python types, thanks to Pydantic.
Zadeklaruj treść żądania, używając standardowych typów w Pythonie dzięki Pydantic.
```Python hl_lines="4 9-12 25-27"
from typing import Optional
@@ -293,175 +287,175 @@ def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
Serwer powinien przeładować się automatycznie (ponieważ dodałeś `--reload` do komendy `uvicorn` powyżej).
### Interactive API docs upgrade
### Zaktualizowana interaktywna dokumentacja API
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Wejdź teraz na <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
* The interactive API documentation will be automatically updated, including the new body:
* Interaktywna dokumentacja API zaktualizuje sie automatycznie, także z nową treścią żądania (body):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
* Kliknij przycisk "Try it out" (wypróbuj), pozwoli Ci to wypełnić parametry i bezpośrednio użyć API:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
* Kliknij potem przycisk "Execute" (wykonaj), interfejs użytkownika połączy się z API, wyśle parametry, otrzyma odpowiedź i wyświetli ją na ekranie:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### Alternative API docs upgrade
### Zaktualizowana alternatywna dokumentacja API
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
Otwórz teraz <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
* The alternative documentation will also reflect the new query parameter and body:
* Alternatywna dokumentacja również pokaże zaktualizowane parametry i treść żądania (body):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Recap
### Podsumowanie
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
Podsumowując, musiałeś zadeklarować typy parametrów, treści żądania (body) itp. tylko **raz**, i są one dostępne jako parametry funkcji.
You do that with standard modern Python types.
Robisz to tak samo jak ze standardowymi typami w Pythonie.
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
Nie musisz sie uczyć żadnej nowej składni, metod lub klas ze specyficznych bibliotek itp.
Just standard **Python 3.6+**.
Po prostu standardowy **Python 3.6+**.
For example, for an `int`:
Na przykład, dla danych typu `int`:
```Python
item_id: int
```
or for a more complex `Item` model:
albo dla bardziej złożonego obiektu `Item`:
```Python
item: Item
```
...and with that single declaration you get:
...i z pojedyńczą deklaracją otrzymujesz:
* Editor support, including:
* Completion.
* Type checks.
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* Wsparcie edytorów kodu, wliczając:
* Auto-uzupełnianie.
* Sprawdzanie typów.
* Walidacja danych:
* Automatyczne i przejrzyste błędy gdy dane są niepoprawne.
* Walidacja nawet dla głęboko zagnieżdżonych obiektów JSON.
* <abbr title="znane również jako: serializacja, przetwarzanie, marshalling">Konwersja</abbr> danych wejściowych: przychodzących z sieci na Pythonowe typy. Pozwala na przetwarzanie danych:
* JSON.
* Path parameters.
* Query parameters.
* Cookies.
* Headers.
* Forms.
* Files.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
* `datetime` objects.
* `UUID` objects.
* Database models.
* ...and many more.
* Automatic interactive API documentation, including 2 alternative user interfaces:
* Parametrów ścieżki.
* Parametrów zapytania.
* Dane cookies.
* Dane nagłówków (headers).
* Formularze.
* Pliki.
* <abbr title="znane również jako: serializacja, przetwarzanie, marshalling">Konwersja</abbr> danych wyjściowych: wychodzących z Pythona do sieci (jako JSON):
* Przetwarzanie Pythonowych typów (`str`, `int`, `float`, `bool`, `list`, itp).
* Obiekty `datetime`.
* Obiekty `UUID`.
* Modele baz danych.
* ...i wiele więcej.
* Automatyczne interaktywne dokumentacje API, wliczając 2 alternatywne interfejsy użytkownika:
* Swagger UI.
* ReDoc.
---
Coming back to the previous code example, **FastAPI** will:
Wracając do poprzedniego przykładu, **FastAPI** :
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
* If it is not, the client will see a useful, clear error.
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
* As the `q` parameter is declared with `= None`, it is optional.
* Without the `None` it would be required (as is the body in the case with `PUT`).
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
* Check that it has a required attribute `name` that should be a `str`.
* Check that it has a required attribute `price` that has to be a `float`.
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
* All this would also work for deeply nested JSON objects.
* Convert from and to JSON automatically.
* Document everything with OpenAPI, that can be used by:
* Interactive documentation systems.
* Automatic client code generation systems, for many languages.
* Provide 2 interactive documentation web interfaces directly.
* Potwierdzi, że w ścieżce jest `item_id` dla żądań `GET` i `PUT`.
* Potwierdzi, że `item_id` jest typu `int` dla żądań `GET` i `PUT`.
* Jeżeli nie jest, odbiorca zobaczy przydatną, przejrzystą wiadomość z błędem.
* Sprawdzi czy w ścieżce jest opcjonalny parametr zapytania `q` (np. `http://127.0.0.1:8000/items/foo?q=somequery`) dla żądania `GET`.
* Jako że parametr `q` jest zadeklarowany jako `= None`, jest on opcjonalny.
* Gdyby tego `None` nie było, parametr ten byłby wymagany (tak jak treść żądania w żądaniu `PUT`).
* Dla żądania `PUT` z ścieżką `/items/{item_id}`, odczyta treść żądania jako JSON:
* Sprawdzi czy posiada wymagany atrybut `name`, który powinien być typu `str`.
* Sprawdzi czy posiada wymagany atrybut `price`, który musi być typu `float`.
* Sprawdzi czy posiada opcjonalny atrybut `is_offer`, który (jeżeli obecny) powinien być typu `bool`.
* To wszystko będzie również działać dla głęboko zagnieżdżonych obiektów JSON.
* Automatycznie konwertuje z i do JSON.
* Dokumentuje wszystko w OpenAPI, które może być używane przez:
* Interaktywne systemy dokumentacji.
* Systemy automatycznego generowania kodu klienckiego, dla wielu języków.
* Dostarczy bezpośrednio 2 interaktywne dokumentacje webowe.
---
We just scratched the surface, but you already get the idea of how it all works.
To dopiero początek, ale już masz mniej-więcej pojęcie jak to wszystko działa.
Try changing the line with:
Spróbuj zmienić linijkę:
```Python
return {"item_name": item.name, "item_id": item_id}
```
...from:
...z:
```Python
... "item_name": item.name ...
```
...to:
...na:
```Python
... "item_price": item.price ...
```
...and see how your editor will auto-complete the attributes and know their types:
...i zobacz jak edytor kodu automatycznie uzupełni atrybuty i będzie znał ich typy:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
Dla bardziej kompletnych przykładów posiadających więcej funkcjonalności, zobacz <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
**Spoiler alert**: the tutorial - user guide includes:
**Uwaga Spoiler**: tutorial - user guide zawiera:
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* Deklaracje **parametrów** z innych miejsc takich jak: **nagłówki**, **pliki cookies**, **formularze** i **pliki**.
* Jak ustawić **ograniczenia walidacyjne** takie jak `maksymalna długość` lub `regex`.
* Potężny i łatwy w użyciu system **<abbr title="znane jako komponenty, resources, providers, services, injectables">Dependency Injection</abbr>**.
* Zabezpieczenia i autentykacja, wliczając wsparcie dla **OAuth2** z **tokenami JWT** oraz autoryzacją **HTTP Basic**.
* Bardziej zaawansowane (ale równie proste) techniki deklarowania **głęboko zagnieżdżonych modeli JSON** (dzięki Pydantic).
* Wiele dodatkowych funkcji (dzięki Starlette) takie jak:
* **WebSockety**
* **GraphQL**
* extremely easy tests based on `requests` and `pytest`
* bardzo proste testy bazujące na `requests` oraz `pytest`
* **CORS**
* **Cookie Sessions**
* ...and more.
* **Sesje cookie**
* ...i więcej.
## Performance
## Wydajność
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
Niezależne benchmarki TechEmpower pokazują, że **FastAPI** (uruchomiony na serwerze Uvicorn) <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">jest jednym z najszybszych dostępnych Pythonowych frameworków</a>, zaraz po Starlette i Uvicorn (używanymi wewnątrznie przez FastAPI). (*)
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
Aby dowiedzieć się o tym więcej, zobacz sekcję <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
## Optional Dependencies
## Opcjonalne zależności
Used by Pydantic:
Używane przez Pydantic:
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - dla szybszego <abbr title="przetwarzania stringa który przychodzi z żądaniem HTTP na dane używane przez Pythona">"parsowania"</abbr> danych JSON.
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - dla walidacji adresów email.
Used by Starlette:
Używane przez Starlette:
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Wymagane jeżeli chcesz korzystać z `TestClient`.
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Wymagane jeżeli chcesz korzystać z `FileResponse` albo `StaticFiles`.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Wymagane jeżeli chcesz używać domyślnej konfiguracji szablonów.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Wymagane jeżelich chcesz wsparcie <abbr title="przetwarzania stringa którzy przychodzi z żądaniem HTTP na dane używane przez Pythona">"parsowania"</abbr> formularzy, używając `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Wymagany dla wsparcia `SessionMiddleware`.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Wymagane dla wsparcia `SchemaGenerator` z Starlette (z FastAPI prawdopodobnie tego nie potrzebujesz).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Wymagane dla wsparcia `GraphQLApp`.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Wymagane jeżeli chcesz korzystać z `UJSONResponse`.
Used by FastAPI / Starlette:
Używane przez FastAPI / Starlette:
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - jako serwer, który ładuje i obsługuje Twoją aplikację.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Wymagane jeżeli chcesz używać `ORJSONResponse`.
You can install all of these with `pip install fastapi[all]`.
Możesz zainstalować wszystkie te aplikacje przy pomocy `pip install fastapi[all]`.
## License
## Licencja
This project is licensed under the terms of the MIT license.
Ten projekt jest na licencji MIT.

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -0,0 +1,303 @@
# Parâmetros de consulta e validações de texto
O **FastAPI** permite que você declare informações adicionais e validações aos seus parâmetros.
Vamos utilizar essa aplicação como exemplo:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial001.py!}
```
O parâmetro de consulta `q` é do tipo `Optional[str]`, o que significa que é do tipo `str` mas que também pode ser `None`, e de fato, o valor padrão é `None`, então o FastAPI saberá que não é obrigatório.
!!! note "Observação"
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
O `Optional` em `Optional[str]` não é usado pelo FastAPI, mas permitirá que seu editor lhe dê um melhor suporte e detecte erros.
## Validação adicional
Nós iremos forçar que mesmo o parâmetro `q` seja opcional, sempre que informado, **seu tamanho não exceda 50 caracteres**.
### Importe `Query`
Para isso, primeiro importe `Query` de `fastapi`:
```Python hl_lines="3"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
## Use `Query` como o valor padrão
Agora utilize-o como valor padrão do seu parâmetro, definindo o parâmetro `max_length` para 50:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
Note que substituímos o valor padrão de `None` para `Query(None)`, o primeiro parâmetro de `Query` serve para o mesmo propósito: definir o valor padrão do parâmetro.
Então:
```Python
q: Optional[str] = Query(None)
```
...Torna o parâmetro opcional, da mesma maneira que:
```Python
q: Optional[str] = None
```
Mas o declara explicitamente como um parâmetro de consulta.
!!! info "Informação"
Tenha em mente que o FastAPI se preocupa com a parte:
```Python
= None
```
Ou com:
```Python
= Query(None)
```
E irá utilizar o `None` para detectar que o parâmetro de consulta não é obrigatório.
O `Optional` é apenas para permitir que seu editor de texto lhe dê um melhor suporte.
Então, podemos passar mais parâmetros para `Query`. Neste caso, o parâmetro `max_length` que se aplica a textos:
```Python
q: str = Query(None, max_length=50)
```
Isso irá validar os dados, mostrar um erro claro quando os dados forem inválidos, e documentar o parâmetro na *operação de rota* do esquema OpenAPI..
## Adicionando mais validações
Você também pode incluir um parâmetro `min_length`:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial003.py!}
```
## Adicionando expressões regulares
Você pode definir uma <abbr title="Uma expressão regular, regex ou regexp é uma sequência de caracteres que define um parâmetro de busca para textos.">expressão regular</abbr> que combine com um padrão esperado pelo parâmetro:
```Python hl_lines="10"
{!../../../docs_src/query_params_str_validations/tutorial004.py!}
```
Essa expressão regular específica verifica se o valor recebido no parâmetro:
* `^`: Inicia com os seguintes caracteres, ou seja, não contém caracteres anteriores.
* `fixedquery`: contém o valor exato `fixedquery`.
* `$`: termina aqui, não contém nenhum caractere após `fixedquery`.
Se você se sente perdido com todo esse assunto de **"expressão regular"**, não se preocupe. Esse é um assunto complicado para a maioria das pessoas. Você ainda pode fazer muitas coisas sem utilizar expressões regulares.
Mas assim que você precisar e já tiver aprendido sobre, saiba que você poderá usá-las diretamente no **FastAPI**.
## Valores padrão
Da mesma maneira que você utiliza `None` como o primeiro argumento para ser utilizado como um valor padrão, você pode usar outros valores.
Vamos dizer que você queira que o parâmetro de consulta `q` tenha um `min_length` de `3`, e um valor padrão de `"fixedquery"`, então declararíamos assim:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial005.py!}
```
!!! note "Observação"
O parâmetro torna-se opcional quando possui um valor padrão.
## Torne-o obrigatório
Quando você não necessita de validações ou de metadados adicionais, podemos fazer com que o parâmetro de consulta `q` seja obrigatório por não declarar um valor padrão, dessa forma:
```Python
q: str
```
em vez desta:
```Python
q: Optional[str] = None
```
Mas agora nós o estamos declarando como `Query`, conforme abaixo:
```Python
q: Optional[str] = Query(None, min_length=3)
```
Então, quando você precisa declarar um parâmetro obrigatório utilizando o `Query`, você pode utilizar `...` como o primeiro argumento:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial006.py!}
```
!!! info "Informação"
Se você nunca viu os `...` antes: é um valor único especial, faz <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">parte do Python e é chamado "Ellipsis"</a>.
Dessa forma o **FastAPI** saberá que o parâmetro é obrigatório.
## Lista de parâmetros de consulta / múltiplos valores
Quando você declara explicitamente um parâmetro com `Query` você pode declará-lo para receber uma lista de valores, ou podemos dizer, que irá receber mais de um valor.
Por exemplo, para declarar que o parâmetro `q` pode aparecer diversas vezes na URL, você escreveria:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial011.py!}
```
Então, com uma URL assim:
```
http://localhost:8000/items/?q=foo&q=bar
```
você receberá os múltiplos *parâmetros de consulta* `q` com os valores (`foo` e `bar`) em uma lista (`list`) Python dentro da *função de operação de rota*, no *parâmetro da função* `q`.
Assim, a resposta para essa URL seria:
```JSON
{
"q": [
"foo",
"bar"
]
}
```
!!! tip "Dica"
Para declarar um parâmetro de consulta com o tipo `list`, como no exemplo acima, você precisa usar explicitamente o `Query`, caso contrário será interpretado como um corpo da requisição.
A documentação interativa da API irá atualizar de acordo, permitindo múltiplos valores:
<img src="/img/tutorial/query-params-str-validations/image02.png">
### Lista de parâmetros de consulta / múltiplos valores por padrão
E você também pode definir uma lista (`list`) de valores padrão caso nenhum seja informado:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial012.py!}
```
Se você for até:
```
http://localhost:8000/items/
```
O valor padrão de `q` será: `["foo", "bar"]` e sua resposta será:
```JSON
{
"q": [
"foo",
"bar"
]
}
```
#### Usando `list`
Você também pode utilizar o tipo `list` diretamente em vez de `List[str]`:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial013.py!}
```
!!! note "Observação"
Tenha em mente que neste caso, o FastAPI não irá validar os conteúdos da lista.
Por exemplo, um `List[int]` iria validar (e documentar) que os contéudos da lista são números inteiros. Mas apenas `list` não.
## Declarando mais metadados
Você pode adicionar mais informações sobre o parâmetro.
Essa informações serão inclusas no esquema do OpenAPI e utilizado pela documentação interativa e ferramentas externas.
!!! note "Observação"
Tenha em mente que cada ferramenta oferece diferentes níveis de suporte ao OpenAPI.
Algumas delas não exibem todas as informações extras que declaramos, ainda que na maioria dos casos, esses recursos estão planejados para desenvolvimento.
Você pode adicionar um `title`:
```Python hl_lines="10"
{!../../../docs_src/query_params_str_validations/tutorial007.py!}
```
E uma `description`:
```Python hl_lines="13"
{!../../../docs_src/query_params_str_validations/tutorial008.py!}
```
## Apelidos (alias) de parâmetros
Imagine que você queira que um parâmetro tenha o nome `item-query`.
Desta maneira:
```
http://127.0.0.1:8000/items/?item-query=foobaritems
```
Mas o nome `item-query` não é um nome de váriavel válido no Python.
O que mais se aproxima é `item_query`.
Mas ainda você precisa que o nome seja exatamente `item-query`...
Então você pode declarar um `alias`, e esse apelido (alias) que será utilizado para encontrar o valor do parâmetro:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial009.py!}
```
## Parâmetros descontinuados
Agora vamos dizer que você não queria mais utilizar um parâmetro.
Você tem que deixá-lo ativo por um tempo, já que existem clientes o utilizando. Mas você quer que a documentação deixe claro que este parâmetro será <abbr title="obsoleto, recomenda-se que não deve ser utilizado">descontinuado</abbr>.
Então você passa o parâmetro `deprecated=True` para `Query`:
```Python hl_lines="18"
{!../../../docs_src/query_params_str_validations/tutorial010.py!}
```
Na documentação aparecerá assim:
<img src="/img/tutorial/query-params-str-validations/image01.png">
## Recapitulando
Você pode adicionar validações e metadados adicionais aos seus parâmetros.
Validações genéricas e metadados:
* `alias`
* `title`
* `description`
* `deprecated`
Validações específicas para textos:
* `min_length`
* `max_length`
* `regex`
Nesses exemplos você viu como declarar validações em valores do tipo `str`.
Leia os próximos capítulos para ver como declarar validação de outros tipos, como números.

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -62,6 +59,7 @@ nav:
- tutorial/first-steps.md
- tutorial/path-params.md
- tutorial/body-fields.md
- tutorial/query-params-str-validations.md
- Segurança:
- tutorial/security/index.md
- Guia de Usuário Avançado:
@@ -89,8 +87,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -0,0 +1,314 @@
# Python Veri Tiplerine Giriş
Python isteğe bağlı olarak "tip belirteçlerini" destekler.
**"Tip belirteçleri"** bir değişkenin <abbr title="örneğin: str, int, float, bool">tipinin</abbr> belirtilmesine olanak sağlayan özel bir sözdizimidir.
Değişkenlerin tiplerini belirterek editör ve araçlardan daha fazla destek alabilirsiniz.
Bu pythonda tip belirteçleri için **hızlı bir başlangıç / bilgi tazeleme** rehberidir . Bu rehber **FastAPI** kullanmak için gereken minimum konuyu kapsar ki bu da çok az bir miktardır.
**FastAPI' nin** tamamı bu tür tip belirteçleri ile donatılmıştır ve birçok avantaj sağlamaktadır.
**FastAPI** kullanmayacak olsanız bile tür belirteçleri hakkında bilgi edinmenizde fayda var.
!!! not
Python uzmanıysanız ve tip belirteçleri ilgili her şeyi zaten biliyorsanız, sonraki bölüme geçin.
## Motivasyon
Basit bir örnek ile başlayalım:
```Python
{!../../../docs_src/python_types/tutorial001.py!}
```
Programın çıktısı:
```
John Doe
```
Fonksiyon sırayla şunları yapar:
* `first_name` ve `last_name` değerlerini alır.
* `title()` ile değişkenlerin ilk karakterlerini büyütür.
* Değişkenleri aralarında bir boşlukla beraber <abbr title="Onları bir bütün olarak sırayla birleştirir.">Birleştirir</abbr>.
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial001.py!}
```
### Düzenle
Bu çok basit bir program.
Ama şimdi sıfırdan yazdığınızı hayal edin.
Bir noktada fonksiyonun tanımına başlayacaktınız, parametreleri hazır hale getirdiniz...
Ama sonra "ilk harfi büyük harfe dönüştüren yöntemi" çağırmanız gerekir.
`upper` mıydı ? Yoksa `uppercase`' mi? `first_uppercase`? `capitalize`?
Ardından, programcıların en iyi arkadaşı olan otomatik tamamlama ile denediniz.
'first_name', ardından bir nokta ('.') yazıp otomatik tamamlamayı tetiklemek için 'Ctrl+Space' tuşlarına bastınız.
Ancak, ne yazık ki, yararlı hiçbir şey elde edemediniz:
<img src="/img/python-types/image01.png">
### Tipleri ekle
Önceki sürümden sadece bir satırı değiştirelim.
Tam olarak bu parçayı, işlevin parametrelerini değiştireceğiz:
```Python
first_name, last_name
```
ve bu hale getireceğiz:
```Python
first_name: str, last_name: str
```
Bu kadar.
İşte bunlar "tip belirteçleri":
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial002.py!}
```
Bu, aşağıdaki gibi varsayılan değerleri bildirmekle aynı şey değildir:
```Python
first_name="john", last_name="doe"
```
Bu tamamen farklı birşey
İki nokta üst üste (`:`) kullanıyoruz , eşittir (`=`) değil.
Normalde tip belirteçleri eklemek, kod üzerinde olacakları değiştirmez.
Şimdi programı sıfırdan birdaha yazdığınızı hayal edin.
Aynı noktada, `Ctrl+Space` ile otomatik tamamlamayı tetiklediniz ve şunu görüyorsunuz:
<img src="/img/python-types/image02.png">
Aradığınızı bulana kadar seçenekleri kaydırabilirsiniz:
<img src="/img/python-types/image03.png">
## Daha fazla motivasyon
Bu fonksiyon, zaten tür belirteçlerine sahip:
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial003.py!}
```
Editör değişkenlerin tiplerini bildiğinden, yalnızca otomatik tamamlama değil, hata kontrolleri de sağlar:
<img src="/img/python-types/image04.png">
Artık `age` değişkenini `str(age)` olarak kullanmanız gerektiğini biliyorsunuz:
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial004.py!}
```
## Tip bildirme
Az önce tip belirteçlerinin en çok kullanıldığı yeri gördünüz.
**FastAPI**ile çalışırken tip belirteçlerini en çok kullanacağımız yer yine fonksiyonlardır.
### Basit tipler
Yalnızca `str` değil, tüm standart Python tiplerinin bildirebilirsiniz.
Örneğin şunları kullanabilirsiniz:
* `int`
* `float`
* `bool`
* `bytes`
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial005.py!}
```
### Tip parametreleri ile Generic tipler
"dict", "list", "set" ve "tuple" gibi diğer değerleri içerebilen bazı veri yapıları vardır. Ve dahili değerlerinin de tip belirtecleri olabilir.
Bu tipleri ve dahili tpileri bildirmek için standart Python modülünü "typing" kullanabilirsiniz.
Bu tür tip belirteçlerini desteklemek için özel olarak mevcuttur.
#### `List`
Örneğin `str` değerlerden oluşan bir `list` tanımlayalım.
From `typing`, import `List` (büyük harf olan `L` ile):
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial006.py!}
```
Değişkenin tipini yine iki nokta üstüste (`:`) ile belirleyin.
tip olarak `List` kullanın.
Liste, bazı dahili tipleri içeren bir tür olduğundan, bunları köşeli parantez içine alırsınız:
```Python hl_lines="4"
{!../../../docs_src/python_types/tutorial006.py!}
```
!!! ipucu
Köşeli parantez içindeki bu dahili tiplere "tip parametreleri" denir.
Bu durumda `str`, `List`e iletilen tür parametresidir.
Bunun anlamı şudur: "`items` değişkeni bir `list`tir ve bu listedeki öğelerin her biri bir `str`dir".
Bunu yaparak, düzenleyicinizin listedeki öğeleri işlerken bile destek sağlamasını sağlayabilirsiniz:
<img src="/img/python-types/image05.png">
Tip belirteçleri olmadan, bunu başarmak neredeyse imkansızdır.
`item` değişkeninin `items` listesindeki öğelerden biri olduğuna dikkat edin.
Ve yine, editör bunun bir `str` olduğunu biliyor ve bunun için destek sağlıyor.
#### `Tuple` ve `Set`
`Tuple` ve `set`lerin tiplerini bildirmek için de aynısını yapıyoruz:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial007.py!}
```
Bu şu anlama geliyor:
* `items_t` değişkeni sırasıyla `int`, `int`, ve `str` tiplerinden oluşan bir `tuple` türündedir .
* `items_s` ise her öğesi `bytes` türünde olan bir `set` örneğidir.
#### `Dict`
Bir `dict` tanımlamak için virgülle ayrılmış iki parametre verebilirsiniz.
İlk tip parametresi `dict` değerinin `key` değeri içindir.
İkinci parametre ise `dict` değerinin `value` değeri içindir:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial008.py!}
```
Bu şu anlama gelir:
* `prices` değişkeni `dict` tipindedir:
* `dict` değişkeninin `key` değeri `str` tipindedir (herbir item'ın "name" değeri).
* `dict` değişkeninin `value` değeri `float` tipindedir (lherbir item'ın "price" değeri).
#### `Optional`
`Optional` bir değişkenin `str`gibi bir tipi olabileceğini ama isteğe bağlı olarak tipinin `None` olabileceğini belirtir:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial009.py!}
```
`str` yerine `Optional[str]` kullanmak editorün bu değerin her zaman `str` tipinde değil bazen `None` tipinde de olabileceğini belirtir ve hataları tespit etmemizde yardımcı olur.
#### Generic tipler
Köşeli parantez içinde tip parametreleri alan bu türler, örneğin:
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Optional`
* ...and others.
**Generic types** yada **Generics** olarak adlandırılır.
### Tip olarak Sınıflar
Bir değişkenin tipini bir sınıf ile bildirebilirsiniz.
Diyelim ki `name` değerine sahip `Person` sınıfınız var:
```Python hl_lines="1-3"
{!../../../docs_src/python_types/tutorial010.py!}
```
Sonra bir değişkeni 'Person' tipinde tanımlayabilirsiniz:
```Python hl_lines="6"
{!../../../docs_src/python_types/tutorial010.py!}
```
Ve yine bütün editör desteğini alırsınız:
<img src="/img/python-types/image06.png">
## Pydantic modelleri
<a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> veri doğrulaması yapmak için bir Python kütüphanesidir.
Verilerin "biçimini" niteliklere sahip sınıflar olarak düzenlersiniz.
Ve her niteliğin bir türü vardır.
Sınıfın bazı değerlerle bir örneğini oluşturursunuz ve değerleri doğrular, bunları uygun türe dönüştürür ve size tüm verileri içeren bir nesne verir.
Ve ortaya çıkan nesne üzerindeki bütün editör desteğini alırsınız.
Resmi Pydantic dokümanlarından alınmıştır:
```Python
{!../../../docs_src/python_types/tutorial011.py!}
```
!!! info
Daha fazla şey öğrenmek için <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic'i takip edin</a>.
**FastAPI** tamamen Pydantic'e dayanmaktadır.
Daha fazlasini görmek için [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
## **FastAPI** tip belirteçleri
**FastAPI** birkaç şey yapmak için bu tür tip belirteçlerinden faydalanır.
**FastAPI** ile parametre tiplerini bildirirsiniz ve şunları elde edersiniz:
* **Editor desteği**.
* **Tip kontrolü**.
...ve **FastAPI** aynı belirteçleri şunlar için de kullanıyor:
* **Gereksinimleri tanımlama**: request path parameters, query parameters, headers, bodies, dependencies, ve benzeri gereksinimlerden
* **Verileri çevirme**: Gönderilen veri tipinden istenilen veri tipine çevirme.
* **Verileri doğrulama**: Her gönderilen verinin:
* doğrulanması ve geçersiz olduğunda **otomatik hata** oluşturma.
* OpenAPI kullanarak apinizi **Belgeleyin** :
* bu daha sonra otomatik etkileşimli dokümantasyon kullanıcı arayüzü tarafından kullanılır.
Bütün bunlar kulağa soyut gelebilir. Merak etme. Tüm bunları çalışırken göreceksiniz. [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
Önemli olan, standart Python türlerini tek bir yerde kullanarak (daha fazla sınıf, dekoratör vb. eklemek yerine), **FastAPI**'nin bizim için işi yapmasını sağlamak.
!!! info
Tüm öğreticiyi zaten okuduysanız ve türler hakkında daha fazla bilgi için geri döndüyseniz, iyi bir kaynak:<a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank"> the "cheat sheet" from `mypy`</a>.

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -57,6 +54,7 @@ nav:
- zh: /zh/
- features.md
- fastapi-people.md
- python-types.md
markdown_extensions:
- toc:
permalink: true
@@ -72,8 +70,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -70,8 +67,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

@@ -1,107 +1,149 @@
# 帮助 FastAPI - 获取帮
# 帮助 FastAPI 与求
喜欢 **FastAPI** 吗?
喜欢 **FastAPI** 吗?
您愿意去帮助 FastAPI,帮助其他用户以及作者
帮助 FastAPI?其它用户?还有项目作者?
者你想要获得有关 **FastAPI** 的帮助
要求助怎么使用 **FastAPI**
下面是一些非常简单的方式去提供帮助(有些只需击一两次链接)。
以下几种帮助的方式都非常简单(有些只需要点击一两下鼠标)。
以及几种获取帮助的途径
求助的渠道也很多
## 在 GitHub 上 Star **FastAPI**
## 订阅新闻邮件
可以在 GitHub 上 "star" FastAPI点击右上角的 star 按钮):<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>。
可以订阅 [**FastAPI 和它的小伙伴** 新闻邮件](/newsletter/){.internal-link target=_blank}(不会经常收到)
通过添加 star其他用户将会更容易发现 FastAPI并了解已经有许多人认为它有用。
* FastAPI 及其小伙伴的新闻 🚀
* 指南 📝
* 功能 ✨
* 破坏性更改 🚨
* 开发技巧 ✅
## Watch GitHub 仓库的版本发布
## 在推特上关注 FastAPI
你可以在 GitHub 上 "watch" FastAPI点击右上角的 watch 按钮):<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>
<a href="https://twitter.com/fastapi" class="external-link" target="_blank">**Twitter** 上关注 @fastapi</a> 获取 **FastAPI** 的最新消息。🐦
这时你可以选择 "Releases only" 选项。
## 在 GitHub 上为 **FastAPI** 加星
之后,只要有 **FastAPI** 的新版本(包含缺陷修复和新功能)发布,你都会(通过电子邮件)收到通知。
您可以在 GitHub 上 **Star** FastAPI只要点击右上角的星星就可以了 <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi。</a>⭐️
## 加入聊天室
**Star** 以后,其它用户就能更容易找到 FastAPI并了解到已经有其他用户在使用它了。
加入 Gitter 上的聊天室:<a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>。
## 关注 GitHub 资源库的版本发布
在这里你可以快速提问、帮助他人、分享想法等。
您还可以在 GitHub 上 **Watch** FastAPI点击右上角的 **Watch** 按钮)<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi。</a>👀
## 与作者联系
您可以选择只关注发布(**Releases only**)。
你可以联系 <a href="https://tiangolo.com" class="external-link" target="_blank">我 (Sebastián Ramírez / `tiangolo`)</a> - FastAPI 的作者
这样,您就可以(在电子邮件里)接收到 **FastAPI** 新版发布的通知,及时了解 bug 修复与新功能
你可以:
## 联系作者
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">**GitHub** 上关注我</a>。
* 查看我创建的其他的可能对你有帮助的开源项目。
* 关注我以了解我创建的新开源项目。
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">在 **Twitter** 上关注我</a>。
* 告诉我你是如何使用 FastAPI 的(我很乐意听到)。
* 提出问题。
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">在 **Linkedin** 上联系我</a>。
* 与我交流。
* 认可我的技能或推荐我 :)
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">在 **Medium** 上阅读我写的文章(或关注我)</a>。
* 阅读我创建的其他想法,文章和工具。
* 关注我以了解我发布的新内容。
您可以联系项目作者,就是<a href="https://tiangolo.com" class="external-link" target="_blank">Sebastián Ramírez / `tiangolo`</a>
## 发布和 **FastAPI** 有关的推特
您可以:
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank"> 发布和 **FastAPI** 有关的推特</a> 让我和其他人知道你为什么喜欢它。
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">在 **GitHub** 上关注我</a>
* 了解其它我创建的开源项目,或许对您会有帮助
* 关注我什么时候创建新的开源项目
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">在 **Twitter** 上关注我</a>
* 告诉我您使用 FastAPI我非常乐意听到这种消息
* 接收我发布公告或新工具的消息
* 您还可以关注<a href="https://twitter.com/fastapi" class="external-link" target="_blank">@fastapi on Twitter</a>,这是个独立的账号
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">在**领英**上联系我</a>
* 接收我发布公告或新工具的消息(虽然我用 Twitter 比较多)
* 阅读我在 <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> 或 <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a> 上的文章,或关注我
* 阅读我的其它想法、文章,了解我创建的工具
* 关注我,这样就可以随时看到我发布的新文章
## 告诉我你正在如何使用 **FastAPI**
## Tweet about **FastAPI**
我很乐意听到有关 **FastAPI** 被如何使用、你喜欢它的哪一点、被投入使用的项目/公司等等信息。
<a href="https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/tiangolo/fastapi" class="external-link" target="_blank">Tweet about **FastAPI**</a> 让我和大家知道您为什么喜欢 FastAPI。🎉
你可以通过以下平台让我知道:
* <a href="https://twitter.com/compose/tweet?text=Hey @tiangolo, I'm using FastAPI at..." class="external-link" target="_blank">**Twitter**</a>。
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**Linkedin**</a>。
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>。
知道有人使用 **FastAPI**,我会很开心,我也想知道您为什么喜欢 FastAPI以及您在什么项目/哪些公司使用 FastAPI等等。
## 为 FastAPI 投票
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">在 Slant 上为 **FastAPI** 投票</a>
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">在 Slant 上为 **FastAPI** 投票</a>
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">在 AlternativeTo 上为 **FastAPI** 投票</a>
## 帮助他人解决 GitHub 的 issues
## GitHub 上帮助其他人解决问题
可以查看 <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">已有的 issues</a> 并尝试帮助其他人
可以查看<a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">现有 issues</a>并尝试帮助其他人解决问题,说不定您能解决这些问题呢。🤓
## Watch GitHub 仓库
如果帮助很多人解决了问题,您就有可能成为 [FastAPI 的官方专家](fastapi-people.md#experts){.internal-link target=_blank}。🎉
你可以在 GitHub 上 "watch" FastAPI点击右上角的 "watch" 按钮):<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>。
## 监听 GitHub 资源库
如果你选择的是 "Watching" 而不是 "Releases only" 选项,你会在其他人创建了新的 issue 时收到通知。
您可以在 GitHub 上「监听」FastAPI点击右上角的 "watch" 按钮): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
然后你可以尝试帮助他们解决这些 issue
如果您选择 "Watching" 而不是 "Releases only",有人创建新 Issue 时,您会接收到通知
## 创建 issue
然后您就可以尝试并帮助他们解决问题。
你可以在 GitHub 仓库中 <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">创建一个新 issue</a> 用来:
## 创建 Issue
* 报告 bug 或问题。
* 提议新的特性。
* 提问。
您可以在 GitHub 资源库中<a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">创建 Issue</a>,例如:
## 创建 Pull Request
* 提出**问题**或**意见**
* 提出新**特性**建议
你可以 <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">创建一个 Pull Request</a> 用来:
**注意**:如果您创建 Issue我会要求您也要帮助别的用户。😉
* 纠正你在文档中发现的错别字。
* 添加新的文档内容。
* 修复已有的 bug 或问题。
* 添加新的特性。
## 创建 PR
您可以创建 PR 为源代码做[贡献](contributing.md){.internal-link target=_blank},例如:
* 修改文档错别字
* <a href="https://github.com/tiangolo/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">编辑这个文件</a>,分享 FastAPI 的文章、视频、博客,不论是您自己的,还是您看到的都成
* 注意,添加的链接要放在对应区块的开头
* [翻译文档](contributing.md#translations){.internal-link target=_blank}
* 审阅别人翻译的文档
* 添加新的文档内容
* 修复现有问题/Bug
* 添加新功能
## 加入聊天
快加入 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord 聊天服务器</a> 👥 和 FastAPI 社区里的小伙伴一起哈皮吧。
!!! tip "提示"
如有问题,请在 <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">GitHub Issues</a> 里提问,在这里更容易得到 [FastAPI 专家](fastapi-people.md#experts){.internal-link target=_blank}的帮助。
聊天室仅供闲聊。
我们之前还使用过 <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">Gitter chat</a>,但它不支持频道等高级功能,聊天也比较麻烦,所以现在推荐使用 Discord。
### 别在聊天室里提问
注意,聊天室更倾向于“闲聊”,经常有人会提出一些笼统得让人难以回答的问题,所以在这里提问一般没人回答。
GitHub Issues 里提供了模板,指引您提出正确的问题,有利于获得优质的回答,甚至可能解决您还没有想到的问题。而且就算答疑解惑要耗费不少时间,我还是会尽量在 GitHub 里回答问题。但在聊天室里,我就没功夫这么做了。😅
聊天室里的聊天内容也不如 GitHub 里好搜索,聊天里的问答很容易就找不到了。只有在 GitHub Issues 里的问答才能帮助您成为 [FastAPI 专家](fastapi-people.md#experts){.internal-link target=_blank},在 GitHub Issues 中为您带来更多关注。
另一方面,聊天室里有成千上万的用户,在这里,您有很大可能遇到聊得来的人。😄
## 赞助作者
还可以通过 <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a> 在经济上支持作者(我)。
还可以通过 <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub 赞助商</a>资助本项目的作者(就是我)。
这样你可以给我买杯咖啡☕️以示谢意😄。
给我买杯咖啡 ☕️ 以示感谢 😄
当然您也可以成为 FastAPI 的金牌或银牌赞助商。🏅🎉
## 赞助 FastAPI 使用的工具
如您在本文档中所见FastAPI 站在巨人的肩膀上,它们分别是 Starlette 和 Pydantic。
您还可以赞助:
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin Pydantic</a>
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode Starlette, Uvicorn</a>
---
谢!
谢!🚀

View File

@@ -0,0 +1,101 @@
# 路径操作配置
*路径操作装饰器*支持多种配置参数。
!!! warning "警告"
注意:以下参数应直接传递给**路径操作装饰器**,不能传递给*路径操作函数*。
## `status_code` 状态码
`status_code` 用于定义*路径操作*响应中的 HTTP 状态码。
可以直接传递 `int` 代码, 比如 `404`
如果记不住数字码的涵义,也可以用 `status` 的快捷常量:
```Python hl_lines="3 17"
{!../../../docs_src/path_operation_configuration/tutorial001.py!}
```
状态码在响应中使用,并会被添加到 OpenAPI 概图。
!!! note "技术细节"
也可以使用 `from starlette import status` 导入状态码。
**FastAPI** 的`fastapi.status` 和 `starlette.status` 一样,只是快捷方式。实际上,`fastapi.status` 直接继承自 Starlette。
## `tags` 参数
`tags` 参数的值是由 `str` 组成的 `list` (一般只有一个 `str` `tags` 用于为*路径操作*添加标签:
```Python hl_lines="17 22 27"
{!../../../docs_src/path_operation_configuration/tutorial002.py!}
```
OpenAPI 概图会自动添加标签,供 API 文档接口使用:
<img src="/img/tutorial/path-operation-configuration/image01.png">
## `summary` 和 `description` 参数
路径装饰器还支持 `summary` 和 `description` 这两个参数:
```Python hl_lines="20-21"
{!../../../docs_src/path_operation_configuration/tutorial003.py!}
```
## 文档字符串(`docstring`
描述内容比较长且占用多行时,可以在函数的 <abbr title="函数中作为第一个表达式,用于文档目的的一个多行字符串(并没有被分配个任何变量)">docstring</abbr> 中声明*路径操作*的描述,**FastAPI** 支持从文档字符串中读取描述内容。
文档字符串支持 <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>,能正确解析和显示 Markdown 的内容,但要注意文档字符串的缩进。
```Python hl_lines="19-27"
{!../../../docs_src/path_operation_configuration/tutorial004.py!}
```
下图为 Markdown 文本在 API 文档中的显示效果:
<img src="/img/tutorial/path-operation-configuration/image02.png">
## 响应描述
`response_description` 参数用于定义响应的描述说明:
```Python hl_lines="21"
{!../../../docs_src/path_operation_configuration/tutorial005.py!}
```
!!! info "说明"
注意,`response_description` 只用于描述响应,`description` 一般则用于描述*路径操作*。
!!! check "检查"
OpenAPI 规定每个*路径操作*都要有响应描述。
如果没有定义响应描述,**FastAPI** 则自动生成内容为 "Successful response" 的响应描述。
<img src="/img/tutorial/path-operation-configuration/image03.png">
## 弃用*路径操作*
`deprecated` 参数可以把*路径操作*标记为<abbr title="过时,建议不要使用">弃用</abbr>,无需直接删除:
```Python hl_lines="16"
{!../../../docs_src/path_operation_configuration/tutorial006.py!}
```
API 文档会把该路径操作标记为弃用:
<img src="/img/tutorial/path-operation-configuration/image04.png">
下图显示了正常*路径操作*与弃用*路径操作* 的区别:
<img src="/img/tutorial/path-operation-configuration/image05.png">
## 小结
通过传递参数给*路径操作装饰器* ,即可轻松地配置*路径操作*、添加元数据。

View File

@@ -29,9 +29,6 @@ theme:
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
plugins:
- search
- markdownextradata:
@@ -81,6 +78,7 @@ nav:
- tutorial/request-files.md
- tutorial/request-forms-and-files.md
- tutorial/handling-errors.md
- tutorial/path-operation-configuration.md
- tutorial/body-updates.md
- 依赖项:
- tutorial/dependencies/index.md
@@ -120,8 +118,12 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi

View File

View File

@@ -1,6 +1,6 @@
from fastapi.testclient import TestClient
from .main_b import app
from .main import app
client = TestClient(app)

View File

View File

@@ -0,0 +1,36 @@
from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel
fake_secret_token = "coneofsilence"
fake_db = {
"foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},
"bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
}
app = FastAPI()
class Item(BaseModel):
id: str
title: str
description: str | None = None
@app.get("/items/{item_id}", response_model=Item)
async def read_main(item_id: str, x_token: str = Header(...)):
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item_id not in fake_db:
raise HTTPException(status_code=404, detail="Item not found")
return fake_db[item_id]
@app.post("/items/", response_model=Item)
async def create_item(item: Item, x_token: str = Header(...)):
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item.id in fake_db:
raise HTTPException(status_code=400, detail="Item already exists")
fake_db[item.id] = item
return item

View File

@@ -0,0 +1,65 @@
from fastapi.testclient import TestClient
from .main import app
client = TestClient(app)
def test_read_item():
response = client.get("/items/foo", headers={"X-Token": "coneofsilence"})
assert response.status_code == 200
assert response.json() == {
"id": "foo",
"title": "Foo",
"description": "There goes my hero",
}
def test_read_item_bad_token():
response = client.get("/items/foo", headers={"X-Token": "hailhydra"})
assert response.status_code == 400
assert response.json() == {"detail": "Invalid X-Token header"}
def test_read_inexistent_item():
response = client.get("/items/baz", headers={"X-Token": "coneofsilence"})
assert response.status_code == 404
assert response.json() == {"detail": "Item not found"}
def test_create_item():
response = client.post(
"/items/",
headers={"X-Token": "coneofsilence"},
json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"},
)
assert response.status_code == 200
assert response.json() == {
"id": "foobar",
"title": "Foo Bar",
"description": "The Foo Barters",
}
def test_create_item_bad_token():
response = client.post(
"/items/",
headers={"X-Token": "hailhydra"},
json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"},
)
assert response.status_code == 400
assert response.json() == {"detail": "Invalid X-Token header"}
def test_create_existing_item():
response = client.post(
"/items/",
headers={"X-Token": "coneofsilence"},
json={
"id": "foo",
"title": "The Foo ID Stealers",
"description": "There goes my stealer",
},
)
assert response.status_code == 400
assert response.json() == {"detail": "Item already exists"}

View File

@@ -0,0 +1,24 @@
from fastapi import BackgroundTasks, Depends, FastAPI
app = FastAPI()
def write_log(message: str):
with open("log.txt", mode="a") as log:
log.write(message)
def get_query(background_tasks: BackgroundTasks, q: str | None = None):
if q:
message = f"found query: {q}\n"
background_tasks.add_task(write_log, message)
return q
@app.post("/send-notification/{email}")
async def send_notification(
email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)
):
message = f"message to {email}\n"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}

View File

@@ -0,0 +1,17 @@
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item

View File

@@ -0,0 +1,21 @@
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict

View File

@@ -0,0 +1,17 @@
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}

View File

@@ -0,0 +1,20 @@
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: str | None = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result

View File

@@ -0,0 +1,19 @@
from fastapi import Body, FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = Field(
None, title="The description of the item", max_length=300
)
price: float = Field(..., gt=0, description="The price must be greater than zero")
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,26 @@
from fastapi import FastAPI, Path
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
q: str | None = None,
item: Item | None = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
if item:
results.update({"item": item})
return results

View File

@@ -0,0 +1,22 @@
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
class User(BaseModel):
username: str
full_name: str | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):
results = {"item_id": item_id, "item": item, "user": user}
return results

View File

@@ -0,0 +1,24 @@
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
class User(BaseModel):
username: str
full_name: str | None = None
@app.put("/items/{item_id}")
async def update_item(
item_id: int, item: Item, user: User, importance: int = Body(...)
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
return results

View File

@@ -0,0 +1,31 @@
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
class User(BaseModel):
username: str
full_name: str | None = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Item,
user: User,
importance: int = Body(..., gt=0),
q: str | None = None
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
if q:
results.update({"q": q})
return results

View File

@@ -0,0 +1,17 @@
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,18 @@
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: list = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,18 @@
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: list[str] = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,20 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: list[str] = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,18 @@
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,20 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: set[str] = set()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,24 @@
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = []
image: Image | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,26 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: set[str] = []
image: Optional[Image] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,24 @@
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
image: Image | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,26 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: set[str] = set()
image: Optional[Image] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,24 @@
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
images: list[Image] | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -0,0 +1,26 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: set[str] = set()
images: Optional[list[Image]] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

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