From e239c5637152f9322cbbe56b3b59b19fdd45c324 Mon Sep 17 00:00:00 2001 From: Alper Date: Sun, 4 Feb 2024 17:28:44 +0300 Subject: [PATCH 01/70] :globe_with_meridians: Update Turkish translation for `docs/tr/docs/fastapi-people.md` (#10547) --- docs/tr/docs/fastapi-people.md | 107 +++++++++++++++++---------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/docs/tr/docs/fastapi-people.md b/docs/tr/docs/fastapi-people.md index 3e459036a..4ab43ac00 100644 --- a/docs/tr/docs/fastapi-people.md +++ b/docs/tr/docs/fastapi-people.md @@ -1,10 +1,15 @@ +--- +hide: + - navigation +--- + # FastAPI Topluluğu FastAPI, her kökenden insanı ağırlayan harika bir topluluğa sahip. ## Yazan - Geliştiren -Hey! 👋 +Merhaba! 👋 İşte bu benim: @@ -12,38 +17,37 @@ Hey! 👋
{% for user in people.maintainers %} -
@{{ user.login }}
Answers: {{ user.answers }}
Pull Requests: {{ user.prs }}
+
@{{ user.login }}
Cevaplar: {{ user.answers }}
Pull Request'ler: {{ user.prs }}
{% endfor %}
{% endif %} -Ben **FastAPI** 'nin yazarı ve geliştiricisiyim. Bununla ilgili daha fazla bilgiyi şurada okuyabilirsiniz: - [FastAPI yardım - yardım al - Yazar ile iletişime geç](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}. +Ben **FastAPI**'ın geliştiricisiyim. Bununla ilgili daha fazla bilgiyi şurada okuyabilirsiniz: [FastAPI yardım - yardım al - benimle iletişime geç](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}. -... Burada size harika FastAPI topluluğunu göstermek istiyorum. +...burada size harika FastAPI topluluğunu göstermek istiyorum. --- -**FastAPI** topluluğundan destek alıyor. Ve katkıda bulunanları vurgulamak istiyorum. +**FastAPI**, topluluğundan çok destek alıyor. Ben de onların katkılarını vurgulamak istiyorum. -İşte o mükemmel insanlar: +Bu insanlar: -* [GitHubdaki sorunları (issues) çözmelerinde diğerlerine yardım et](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}. -* [Pull Requests oluşturun](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}. -* Pull Requests 'leri gözden geçirin, [özelliklede çevirileri](contributing.md#translations){.internal-link target=_blank}. +* [GitHubdaki soruları cevaplayarak diğerlerine yardım ediyor](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank}. +* [Pull Request'ler oluşturuyor](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}. +* Pull Request'leri gözden geçiriyorlar, [özellikle çeviriler için bu çok önemli](contributing.md#translations){.internal-link target=_blank}. -Onlara bir alkış. 👏 🙇 +Onları bir alkışlayalım. 👏 🙇 -## Geçen ayın en aktif kullanıcıları +## Geçen Ayın En Aktif Kullanıcıları -Bunlar geçen ay boyunca [GitHub' da başkalarına sorunlarında (issues) en çok yardımcı olan ](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} kullanıcılar ☕ +Geçtiğimiz ay boyunca [GitHub'da diğerlerine en çok yardımcı olan](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank} kullanıcılar. ☕ {% if people %}
{% for user in people.last_month_active %} -
@{{ user.login }}
Issues replied: {{ user.count }}
+
@{{ user.login }}
Cevaplanan soru sayısı: {{ user.count }}
{% endfor %}
@@ -53,57 +57,57 @@ Bunlar geçen ay boyunca [GitHub' da başkalarına sorunlarında (issues) en ço İşte **FastAPI Uzmanları**. 🤓 -Bunlar *tüm zamanlar boyunca* [GitHub' da başkalarına sorunlarında (issues) en çok yardımcı olan](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} kullanıcılar. +Uzmanlarımız ise *tüm zamanlar boyunca* [GitHub'da insanların sorularına en çok yardımcı olan](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank} insanlar. -Başkalarına yardım ederek uzman olduklarını kanıtladılar. ✨ +Bir çok kullanıcıya yardım ederek uzman olduklarını kanıtladılar! ✨ {% if people %}
{% for user in people.experts %} -
@{{ user.login }}
Issues replied: {{ user.count }}
+
@{{ user.login }}
Cevaplanan soru sayısı: {{ user.count }}
{% endfor %}
{% endif %} -## En fazla katkıda bulunanlar +## En Fazla Katkıda Bulunanlar -işte **En fazla katkıda bulunanlar**. 👷 +Şimdi ise sıra **en fazla katkıda bulunanlar**da. 👷 -Bu kullanıcılar en çok [Pull Requests oluşturan](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} ve onu kaynak koduna *birleştirenler*. +Bu kullanıcılar en fazla [kaynak koduyla birleştirilen Pull Request'lere](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} sahip! -Kaynak koduna, belgelere, çevirilere vb. katkıda bulundular. 📦 +Kaynak koduna, dökümantasyona, çevirilere ve bir sürü şeye katkıda bulundular. 📦 {% if people %}
{% for user in people.top_contributors %} -
@{{ user.login }}
Pull Requests: {{ user.count }}
+
@{{ user.login }}
Pull Request sayısı: {{ user.count }}
{% endfor %}
{% endif %} -Çok fazla katkıda bulunan var (binden fazla), hepsini şurda görebilirsin: FastAPI GitHub Katkıda Bulunanlar. 👷 +Bunlar dışında katkıda bulunan, yüzden fazla, bir sürü insan var. Hepsini FastAPI GitHub Katkıda Bulunanlar sayfasında görebilirsin. 👷 -## En fazla inceleme yapanlar +## En Fazla Değerlendirme Yapanlar -İşte **En fazla inceleme yapanlar**. 🕵️ +İşte **en çok değerlendirme yapanlar**. 🕵️ -### Çeviri için İncelemeler +### Çeviri Değerlendirmeleri -Yalnızca birkaç dil konuşabiliyorum (ve çok da iyi değilim 😅). Bu yüzden döküman çevirilerini [**onaylama yetkisi**](contributing.md#translations){.internal-link target=_blank} siz inceleyenlere aittir. Sizler olmadan diğer birkaç dilde dokümantasyon olmazdı. +Yalnızca birkaç dil konuşabiliyorum (ve çok da iyi değilim 😅). Bu yüzden değerlendirme yapanların da döküman çevirilerini [**onaylama yetkisi**](contributing.md#translations){.internal-link target=_blank} var. Onlar olmasaydı çeşitli dillerde dökümantasyon da olmazdı. --- -**En fazla inceleme yapanlar** 🕵️ kodun, belgelerin ve özellikle **çevirilerin** kalitesini sağlamak için diğerlerinden daha fazla pull requests incelemiştir. +**En fazla değerlendirme yapanlar** 🕵️ kodun, dökümantasyonun ve özellikle **çevirilerin** Pull Request'lerini inceleyerek kalitesinden emin oldular. {% if people %}
{% for user in people.top_reviewers %} -
@{{ user.login }}
Reviews: {{ user.count }}
+
@{{ user.login }}
Değerlendirme sayısı: {{ user.count }}
{% endfor %}
@@ -113,66 +117,67 @@ Yalnızca birkaç dil konuşabiliyorum (ve çok da iyi değilim 😅). Bu yüzde işte **Sponsorlarımız**. 😎 -**FastAPI** ve diğer projelerde çalışmamı destekliyorlar, özellikle de GitHub Sponsorları. +Çoğunlukla GitHub Sponsorları aracılığıyla olmak üzere, **FastAPI** ve diğer projelerdeki çalışmalarımı destekliyorlar. + +{% if sponsors %} + +{% if sponsors.gold %} ### Altın Sponsorlar -{% if sponsors %} {% for sponsor in sponsors.gold -%} {% endfor %} {% endif %} +{% if sponsors.silver %} + ### Gümüş Sponsorlar -{% if sponsors %} {% for sponsor in sponsors.silver -%} {% endfor %} {% endif %} +{% if sponsors.bronze %} + ### Bronz Sponsorlar -{% if sponsors %} {% for sponsor in sponsors.bronze -%} {% endfor %} {% endif %} +{% endif %} + ### Bireysel Sponsorlar -{% if people %} -{% if people.sponsors_50 %} +{% if github_sponsors %} +{% for group in github_sponsors.sponsors %}
-{% for user in people.sponsors_50 %} + +{% for user in group %} +{% if user.login not in sponsors_badge.logins %} + +{% endif %} {% endfor %}
-{% endif %} -{% endif %} - -{% if people %} -
-{% for user in people.sponsors %} - - {% endfor %} - -
{% endif %} -## Veriler hakkında - Teknik detaylar +## Veriler - Teknik detaylar Bu sayfanın temel amacı, topluluğun başkalarına yardım etme çabasını vurgulamaktır. -Özellikle normalde daha az görünür olan ve çoğu durumda daha zahmetli olan, diğerlerine sorunlar konusunda yardımcı olmak ve pull requests'leri gözden geçirmek gibi çabalar dahil. +Özellikle normalde daha az görünür olan ve çoğu durumda daha zahmetli olan, diğerlerine sorularında yardımcı olmak, çevirileri ve Pull Request'leri gözden geçirmek gibi çabalar dahil. -Veriler ayda bir hesaplanır, işte kaynak kodu okuyabilirsin :source code here. +Veriler ayda bir hesaplanır, kaynak kodu buradan okuyabilirsin. -Burada sponsorların katkılarını da tekrardan vurgulamak isterim. +Burada sponsorların katkılarını da vurguluyorum. -Ayrıca algoritmayı, bölümleri, eşikleri vb. güncelleme hakkımı da saklı tutarım (her ihtimale karşı 🤷). +Ayrıca algoritmayı, bölümleri, eşikleri vb. güncelleme hakkımı da saklı tutuyorum (her ihtimale karşı 🤷). From 6944ae15a2396ac83ef9f1fa738ac535d24c54d4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 4 Feb 2024 14:29:04 +0000 Subject: [PATCH 02/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 2cbeb74d2..2dcfac473 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Translations + +* :globe_with_meridians: Update Turkish translation for `docs/tr/docs/fastapi-people.md`. PR [#10547](https://github.com/tiangolo/fastapi/pull/10547) by [@alperiox](https://github.com/alperiox). + ## 0.109.1 ### Security fixes From 739739c9d25d2ae578b540d3a7eb1c446cffde73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 4 Feb 2024 21:56:59 +0100 Subject: [PATCH 03/70] =?UTF-8?q?=F0=9F=8D=B1=20Add=20new=20FastAPI=20logo?= =?UTF-8?q?=20(#11090)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/img/favicon.png | Bin 412 -> 5043 bytes docs/en/docs/img/github-social-preview.png | Bin 58136 -> 62301 bytes docs/en/docs/img/github-social-preview.svg | 89 +++++++----------- docs/en/docs/img/icon-transparent-bg.png | Bin 4461 -> 0 bytes docs/en/docs/img/icon-white-bg.png | Bin 5210 -> 0 bytes docs/en/docs/img/icon-white.svg | 33 +++---- .../docs/img/logo-margin/logo-teal-vector.svg | 72 +++++--------- docs/en/docs/img/logo-margin/logo-teal.png | Bin 17680 -> 19843 bytes docs/en/docs/img/logo-margin/logo-teal.svg | 53 ++++++----- .../en/docs/img/logo-margin/logo-white-bg.png | Bin 21502 -> 20841 bytes docs/en/docs/img/logo-teal-vector.svg | 75 ++++++--------- docs/en/docs/img/logo-teal.svg | 59 +++++++----- docs/en/overrides/partials/copyright.html | 11 +++ 13 files changed, 178 insertions(+), 214 deletions(-) mode change 100755 => 100644 docs/en/docs/img/favicon.png delete mode 100644 docs/en/docs/img/icon-transparent-bg.png delete mode 100644 docs/en/docs/img/icon-white-bg.png create mode 100644 docs/en/overrides/partials/copyright.html diff --git a/docs/en/docs/img/favicon.png b/docs/en/docs/img/favicon.png old mode 100755 new mode 100644 index b3dcdd3090e52a3d94affb00a40df2fe8a56d4ba..e5b7c3ada7d093d237711560e03f6a841a4a41b2 GIT binary patch literal 5043 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 literal 58136 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 z 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 diff --git a/docs/en/docs/img/github-social-preview.svg b/docs/en/docs/img/github-social-preview.svg index 08450929e..f03a0eefd 100644 --- a/docs/en/docs/img/github-social-preview.svg +++ b/docs/en/docs/img/github-social-preview.svg @@ -1,42 +1,15 @@ - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - @@ -57,42 +29,47 @@ width="338.66666" height="169.33333" x="-1.0833333e-05" - y="0.71613133" - inkscape:export-xdpi="96" - inkscape:export-ydpi="96" /> + y="0.71613133" /> - + id="g2" + transform="matrix(0.73293148,0,0,0.73293148,42.286898,36.073041)"> + + + + FastAPI + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#009688;fill-opacity:1;stroke-width:1.99288" + y="59.410606" + x="82.667519" + id="tspan977-7">FastAPI High performance, easy to learn,High performance, easy to learn,fast to code, ready for production diff --git a/docs/en/docs/img/icon-transparent-bg.png b/docs/en/docs/img/icon-transparent-bg.png deleted file mode 100644 index c3481da4ac551129e253450e0fccdc7518dbc31d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4461 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 diff --git a/docs/en/docs/img/icon-white-bg.png b/docs/en/docs/img/icon-white-bg.png deleted file mode 100644 index 00888b5226bf07ace0ddf47f6e3e8b8de5a8603a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5210 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 diff --git a/docs/en/docs/img/icon-white.svg b/docs/en/docs/img/icon-white.svg index cf7c0c7ec..19f0825cc 100644 --- a/docs/en/docs/img/icon-white.svg +++ b/docs/en/docs/img/icon-white.svg @@ -1,15 +1,15 @@ + width="6.3499999mm" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - - - - - + + diff --git a/docs/en/docs/img/logo-margin/logo-teal-vector.svg b/docs/en/docs/img/logo-margin/logo-teal-vector.svg index 02183293c..3eb945c7e 100644 --- a/docs/en/docs/img/logo-margin/logo-teal-vector.svg +++ b/docs/en/docs/img/logo-margin/logo-teal-vector.svg @@ -1,15 +1,15 @@ + id="svg8" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + + + + + - - - - - - - - - - - + transform="translate(83.131114,-6.0791148)" /> diff --git a/docs/en/docs/img/logo-margin/logo-teal.png b/docs/en/docs/img/logo-margin/logo-teal.png index 57d9eec137c0458dd83539835397fdd299e650ed..f08144cd92e7ae62f57e34044605c56a92c1504c 100644 GIT binary patch literal 19843 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 DDxOq& literal 17680 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 XuqwmUh9A!VCZQy!E?XsS^7a1$wHKYW diff --git a/docs/en/docs/img/logo-margin/logo-teal.svg b/docs/en/docs/img/logo-margin/logo-teal.svg index 2fad25ef7..ce9db533b 100644 --- a/docs/en/docs/img/logo-margin/logo-teal.svg +++ b/docs/en/docs/img/logo-margin/logo-teal.svg @@ -1,15 +1,15 @@ + id="svg8" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + + + + + + + - - FastAPI - + transform="translate(83.131114,-6.0791148)" /> diff --git a/docs/en/docs/img/logo-margin/logo-white-bg.png b/docs/en/docs/img/logo-margin/logo-white-bg.png index 89256db06f02eca727a47a373f33a313833b4952..b84fd285ee52d721a29af6e79fafb6ade5987469 100644 GIT binary patch literal 20841 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 + viewBox="0 0 346.52395 63.977134" + height="63.977139mm" + width="346.52396mm" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - - + id="g2149"> + id="g2141"> + + + + - - - - - - + style="font-size:79.7151px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;letter-spacing:0px;word-spacing:0px;fill:#009688;stroke-width:1.99288" + d="M 89.523017,59.410606 V 4.1680399 H 122.84393 V 10.784393 H 97.255382 V 27.44485 h 22.718808 v 6.536638 H 97.255382 v 25.429118 z m 52.292963,-5.340912 q 2.6306,0 4.62348,-0.07972 2.07259,-0.15943 3.42774,-0.47829 V 41.155848 q -0.79715,-0.398576 -2.63059,-0.637721 -1.75374,-0.31886 -4.30462,-0.31886 -1.67402,0 -3.58718,0.239145 -1.83345,0.239145 -3.42775,1.036296 -1.51459,0.717436 -2.55088,2.072593 -1.0363,1.275442 -1.0363,3.427749 0,3.985755 2.55089,5.580058 2.55088,1.514586 6.93521,1.514586 z m -0.63772,-37.147238 q 4.46404,0 7.49322,1.195727 3.10889,1.116011 4.94233,3.268319 1.91317,2.072593 2.71032,5.022052 0.79715,2.869743 0.79715,6.377208 V 58.69317 q -0.95658,0.159431 -2.71031,0.478291 -1.67402,0.239145 -3.82633,0.478291 -2.15231,0.239145 -4.70319,0.398575 -2.47117,0.239146 -4.94234,0.239146 -3.50746,0 -6.45692,-0.717436 -2.94946,-0.717436 -5.10177,-2.232023 -2.1523,-1.594302 -3.34803,-4.145186 -1.19573,-2.550883 -1.19573,-6.138063 0,-3.427749 1.35516,-5.898917 1.43487,-2.471168 3.82632,-3.985755 2.39146,-1.514587 5.58006,-2.232023 3.18861,-0.717436 6.69607,-0.717436 1.11601,0 2.31174,0.15943 1.19572,0.07972 2.23202,0.31886 1.11601,0.159431 1.91316,0.318861 0.79715,0.15943 1.11601,0.239145 v -2.072593 q 0,-1.833447 -0.39857,-3.587179 -0.39858,-1.833448 -1.43487,-3.188604 -1.0363,-1.434872 -2.86975,-2.232023 -1.75373,-0.876866 -4.62347,-0.876866 -3.6669,0 -6.45693,0.558005 -2.71031,0.478291 -4.06547,1.036297 l -0.87686,-6.138063 q 1.43487,-0.637721 4.7829,-1.195727 3.34804,-0.637721 7.25408,-0.637721 z m 37.86462,37.147238 q 4.54377,0 6.69607,-1.195726 2.23203,-1.195727 2.23203,-3.826325 0,-2.710314 -2.15231,-4.304616 -2.15231,-1.594302 -7.09465,-3.587179 -2.39145,-0.956581 -4.62347,-1.913163 -2.15231,-1.036296 -3.74661,-2.391453 -1.5943,-1.355157 -2.55088,-3.268319 -0.95659,-1.913163 -0.95659,-4.703191 0,-5.500342 4.06547,-8.688946 4.06547,-3.26832 11.0804,-3.26832 1.75374,0 3.50747,0.239146 1.75373,0.15943 3.26832,0.47829 1.51458,0.239146 2.6306,0.558006 1.19572,0.31886 1.83344,0.558006 l -1.35515,6.377208 q -1.19573,-0.637721 -3.74661,-1.275442 -2.55089,-0.717436 -6.13807,-0.717436 -3.10889,0 -5.42062,1.275442 -2.31174,1.195727 -2.31174,3.826325 0,1.355157 0.47829,2.391453 0.55801,1.036296 1.5943,1.913163 1.11601,0.797151 2.71031,1.514587 1.59431,0.717436 3.82633,1.514587 2.94946,1.116011 5.2612,2.232022 2.31173,1.036297 3.90604,2.471169 1.67401,1.434871 2.55088,3.507464 0.87687,1.992878 0.87687,4.942337 0,5.739487 -4.30462,8.688946 -4.2249,2.949459 -12.1167,2.949459 -5.50034,0 -8.60923,-0.956582 -3.10889,-0.876866 -4.2249,-1.355156 l 1.35516,-6.377209 q 1.27544,0.478291 4.06547,1.434872 2.79003,0.956581 7.4135,0.956581 z m 32.84256,-36.110941 h 15.70387 v 6.217778 h -15.70387 v 19.131625 q 0,3.108889 0.47829,5.181481 0.47829,1.992878 1.43487,3.188604 0.95658,1.116012 2.39145,1.594302 1.43487,0.478291 3.34804,0.478291 3.34803,0 5.34091,-0.717436 2.07259,-0.797151 2.86974,-1.116011 l 1.43487,6.138063 q -1.11601,0.558005 -3.90604,1.355156 -2.79003,0.876867 -6.37721,0.876867 -4.2249,0 -7.01492,-1.036297 -2.71032,-1.116011 -4.38434,-3.268319 -1.67401,-2.152308 -2.39145,-5.261197 -0.63772,-3.188604 -0.63772,-7.333789 V 6.4000628 l 7.41351,-1.2754417 z m 62.49652,41.451853 q -1.35516,-3.587179 -2.55088,-7.014929 -1.19573,-3.507464 -2.47117,-7.094644 h -25.03054 l -5.02205,14.109573 h -8.05123 q 3.18861,-8.768661 5.97863,-16.182166 2.79003,-7.493219 5.42063,-14.189288 2.71031,-6.696069 5.34091,-12.754416 2.6306,-6.138063 5.50034,-12.1166961 h 7.09465 q 2.86974,5.9786331 5.50034,12.1166961 2.6306,6.058347 5.2612,12.754416 2.71031,6.696069 5.50034,14.189288 2.79003,7.413505 5.97863,16.182166 z m -7.25407,-20.486781 q -2.55089,-6.935214 -5.10177,-13.392137 -2.47117,-6.536639 -5.18148,-12.515272 -2.79003,5.978633 -5.34091,12.515272 -2.47117,6.456923 -4.94234,13.392137 z M 304.99242,3.6100342 q 11.6384,0 17.85618,4.4640458 6.29749,4.384331 6.29749,13.152992 0,4.782906 -1.75373,8.210656 -1.67402,3.348034 -4.94234,5.500342 -3.1886,2.072592 -7.81208,3.029174 -4.62347,0.956581 -10.44268,0.956581 h -6.13806 v 20.486781 h -7.73236 V 4.9651909 q 3.26832,-0.797151 7.25407,-1.0362963 4.06547,-0.3188604 7.41351,-0.3188604 z m 0.63772,6.7757838 q -4.94234,0 -7.57294,0.239145 v 21.682508 h 5.8192 q 3.98576,0 7.17436,-0.47829 3.18861,-0.558006 5.34092,-1.753733 2.23202,-1.275441 3.42774,-3.427749 1.19573,-2.152308 1.19573,-5.500342 0,-3.188604 -1.27544,-5.261197 -1.19573,-2.072593 -3.34803,-3.268319 -2.0726,-1.275442 -4.86263,-1.753732 -2.79002,-0.478291 -5.89891,-0.478291 z M 338.7916,4.1680399 h 7.73237 V 59.410606 h -7.73237 z" + id="text979" + aria-label="FastAPI" /> diff --git a/docs/en/docs/img/logo-teal.svg b/docs/en/docs/img/logo-teal.svg index 0d1136eb4..bc699860f 100644 --- a/docs/en/docs/img/logo-teal.svg +++ b/docs/en/docs/img/logo-teal.svg @@ -1,15 +1,15 @@ + width="346.52396mm" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - - - FastAPI + id="g2149"> + + + + + + FastAPI + diff --git a/docs/en/overrides/partials/copyright.html b/docs/en/overrides/partials/copyright.html new file mode 100644 index 000000000..dcca89abe --- /dev/null +++ b/docs/en/overrides/partials/copyright.html @@ -0,0 +1,11 @@ + From 43f9cbc0fced5be44ac469e1c543620ac42df880 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 4 Feb 2024 20:57:18 +0000 Subject: [PATCH 04/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 2dcfac473..6e42281cf 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -11,6 +11,10 @@ hide: * :globe_with_meridians: Update Turkish translation for `docs/tr/docs/fastapi-people.md`. PR [#10547](https://github.com/tiangolo/fastapi/pull/10547) by [@alperiox](https://github.com/alperiox). +### Internal + +* 🍱 Add new FastAPI logo. PR [#11090](https://github.com/tiangolo/fastapi/pull/11090) by [@tiangolo](https://github.com/tiangolo). + ## 0.109.1 ### Security fixes From 4a2be2abff43260fdd49ecf72cde2425adffdfe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 4 Feb 2024 22:14:53 +0100 Subject: [PATCH 05/70] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20version=20?= =?UTF-8?q?of=20Starlette=20to=20`>=3D=200.36.3`=20(#11086)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 31d9c59b3..c23e82ef4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", ] dependencies = [ - "starlette>=0.35.0,<0.36.0", + "starlette>=0.36.3,<0.37.0", "pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0", "typing-extensions>=4.8.0", ] From 50e558e944860fb237cb5934e899ce3c5ecc37f9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 4 Feb 2024 21:15:15 +0000 Subject: [PATCH 06/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 6e42281cf..490952466 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Upgrades + +* ⬆️ Upgrade version of Starlette to `>= 0.36.3`. PR [#11086](https://github.com/tiangolo/fastapi/pull/11086) by [@tiangolo](https://github.com/tiangolo). + ### Translations * :globe_with_meridians: Update Turkish translation for `docs/tr/docs/fastapi-people.md`. PR [#10547](https://github.com/tiangolo/fastapi/pull/10547) by [@alperiox](https://github.com/alperiox). From 57b0983948617c6ac051f9c29947bd9db6547e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 4 Feb 2024 22:21:53 +0100 Subject: [PATCH 07/70] =?UTF-8?q?=F0=9F=94=96=20Release=20FastAPI=20versio?= =?UTF-8?q?n=200.109.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 ++ fastapi/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 490952466..71b79bccc 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,8 @@ hide: ## Latest Changes +## 0.109.2 + ### Upgrades * ⬆️ Upgrade version of Starlette to `>= 0.36.3`. PR [#11086](https://github.com/tiangolo/fastapi/pull/11086) by [@tiangolo](https://github.com/tiangolo). diff --git a/fastapi/__init__.py b/fastapi/__init__.py index fedd8b419..3458b9e5b 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.109.1" +__version__ = "0.109.2" from starlette import status as status From 141e34f281ed746431766d712d56d357e306a689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 4 Feb 2024 22:24:21 +0100 Subject: [PATCH 08/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 71b79bccc..c0e47b9f5 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -15,7 +15,7 @@ hide: ### Translations -* :globe_with_meridians: Update Turkish translation for `docs/tr/docs/fastapi-people.md`. PR [#10547](https://github.com/tiangolo/fastapi/pull/10547) by [@alperiox](https://github.com/alperiox). +* 🌐 Update Turkish translation for `docs/tr/docs/fastapi-people.md`. PR [#10547](https://github.com/tiangolo/fastapi/pull/10547) by [@alperiox](https://github.com/alperiox). ### Internal From 0880a5c6a0d2702b057cef8064690f63ff1afc78 Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Tue, 6 Feb 2024 12:21:29 -0500 Subject: [PATCH 09/70] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20minor=20typo?= =?UTF-8?q?=20in=20`fastapi/applications.py`=20(#11099)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/applications.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index 597c60a56..ffe9da358 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -297,7 +297,7 @@ class FastAPI(Starlette): browser tabs open). Or if you want to leave fixed the possible URLs. If the servers `list` is not provided, or is an empty `list`, the - default value would be a a `dict` with a `url` value of `/`. + default value would be a `dict` with a `url` value of `/`. Each item in the `list` is a `dict` containing: From d9cacacf7f786e43eb30ec430ca20ca0d9960171 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 6 Feb 2024 17:21:53 +0000 Subject: [PATCH 10/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index c0e47b9f5..1f0a9a7d2 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Docs + +* ✏️ Fix minor typo in `fastapi/applications.py`. PR [#11099](https://github.com/tiangolo/fastapi/pull/11099) by [@JacobHayes](https://github.com/JacobHayes). + ## 0.109.2 ### Upgrades From b9766d7ee9af21daf0eaa6caac9634feff487afb Mon Sep 17 00:00:00 2001 From: Alejandra <90076947+alejsdev@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:56:23 -0500 Subject: [PATCH 11/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Spanish=20translatio?= =?UTF-8?q?n=20for=20`docs/es/docs/advanced/response-change-status-code.md?= =?UTF-8?q?`=20(#11100)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../advanced/response-change-status-code.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/es/docs/advanced/response-change-status-code.md diff --git a/docs/es/docs/advanced/response-change-status-code.md b/docs/es/docs/advanced/response-change-status-code.md new file mode 100644 index 000000000..ecd9fad41 --- /dev/null +++ b/docs/es/docs/advanced/response-change-status-code.md @@ -0,0 +1,33 @@ +# Response - Cambiar el Status Code + +Probablemente ya has leído con anterioridad que puedes establecer un [Response Status Code](../tutorial/response-status-code.md){.internal-link target=_blank} por defecto. + +Pero en algunos casos necesitas retornar un status code diferente al predeterminado. + +## Casos de uso + +Por ejemplo, imagina que quieres retornar un HTTP status code de "OK" `200` por defecto. + +Pero si los datos no existen, quieres crearlos y retornar un HTTP status code de "CREATED" `201`. + +Pero aún quieres poder filtrar y convertir los datos que retornas con un `response_model`. + +Para esos casos, puedes usar un parámetro `Response`. + +## Usar un parámetro `Response` + +Puedes declarar un parámetro de tipo `Response` en tu *función de la operación de path* (como puedes hacer para cookies y headers). + +Y luego puedes establecer el `status_code` en ese objeto de respuesta *temporal*. + +```Python hl_lines="1 9 12" +{!../../../docs_src/response_change_status_code/tutorial001.py!} +``` + +Y luego puedes retornar cualquier objeto que necesites, como normalmente lo harías (un `dict`, un modelo de base de datos, etc). + +Y si declaraste un `response_model`, aún se usará para filtrar y convertir el objeto que retornaste. + +**FastAPI** usará esa respuesta *temporal* para extraer el código de estado (también cookies y headers), y los pondrá en la respuesta final que contiene el valor que retornaste, filtrado por cualquier `response_model`. + +También puedes declarar la dependencia del parámetro `Response`, y establecer el código de estado en ellos. Pero ten en cuenta que el último en establecerse será el que gane. From e79bd168a441b931eb6a9762966e63b40ab3575b Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 6 Feb 2024 19:56:42 +0000 Subject: [PATCH 12/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 1f0a9a7d2..5ce56a3ac 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -11,6 +11,10 @@ hide: * ✏️ Fix minor typo in `fastapi/applications.py`. PR [#11099](https://github.com/tiangolo/fastapi/pull/11099) by [@JacobHayes](https://github.com/JacobHayes). +### Translations + +* 🌐 Add Spanish translation for `docs/es/docs/advanced/response-change-status-code.md`. PR [#11100](https://github.com/tiangolo/fastapi/pull/11100) by [@alejsdev](https://github.com/alejsdev). + ## 0.109.2 ### Upgrades From f48912633a586b726559eefcadea29ab30dc994e Mon Sep 17 00:00:00 2001 From: pablocm83 Date: Wed, 7 Feb 2024 06:39:50 -0500 Subject: [PATCH 13/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Spanish=20translatio?= =?UTF-8?q?n=20for=20`docs/es/docs/benchmarks.md`=20(#10928)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> Co-authored-by: Sebastián Ramírez --- docs/es/docs/benchmarks.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/es/docs/benchmarks.md diff --git a/docs/es/docs/benchmarks.md b/docs/es/docs/benchmarks.md new file mode 100644 index 000000000..3e02d4e9f --- /dev/null +++ b/docs/es/docs/benchmarks.md @@ -0,0 +1,33 @@ +# Benchmarks + +Los benchmarks independientes de TechEmpower muestran aplicaciones de **FastAPI** que se ejecutan en Uvicorn como uno de los frameworks de Python más rápidos disponibles, solo por debajo de Starlette y Uvicorn (utilizados internamente por FastAPI). (*) + +Pero al comprobar benchmarks y comparaciones debes tener en cuenta lo siguiente. + +## Benchmarks y velocidad + +Cuando revisas los benchmarks, es común ver varias herramientas de diferentes tipos comparadas como equivalentes. + +Específicamente, para ver Uvicorn, Starlette y FastAPI comparadas entre sí (entre muchas otras herramientas). + +Cuanto más sencillo sea el problema resuelto por la herramienta, mejor rendimiento obtendrá. Y la mayoría de los benchmarks no prueban las funciones adicionales proporcionadas por la herramienta. + +La jerarquía sería: + +* **Uvicorn**: como servidor ASGI + * **Starlette**: (usa Uvicorn) un microframework web + * **FastAPI**: (usa Starlette) un microframework API con varias características adicionales para construir APIs, con validación de datos, etc. +* **Uvicorn**: + * Tendrá el mejor rendimiento, ya que no tiene mucho código extra aparte del propio servidor. + * No escribirías una aplicación directamente en Uvicorn. Eso significaría que tu código tendría que incluir más o menos, al menos, todo el código proporcionado por Starlette (o **FastAPI**). Y si hicieras eso, tu aplicación final tendría la misma sobrecarga que si hubieras usado un framework y minimizado el código de tu aplicación y los errores. + * Si estás comparando Uvicorn, compáralo con los servidores de aplicaciones Daphne, Hypercorn, uWSGI, etc. +* **Starlette**: + * Tendrá el siguiente mejor desempeño, después de Uvicorn. De hecho, Starlette usa Uvicorn para correr. Por lo tanto, probablemente sólo pueda volverse "más lento" que Uvicorn al tener que ejecutar más código. + * Pero te proporciona las herramientas para crear aplicaciones web simples, con routing basado en paths, etc. + * Si estás comparando Starlette, compáralo con Sanic, Flask, Django, etc. Frameworks web (o microframeworks). +* **FastAPI**: + * De la misma manera que Starlette usa Uvicorn y no puede ser más rápido que él, **FastAPI** usa Starlette, por lo que no puede ser más rápido que él. + * * FastAPI ofrece más características además de las de Starlette. Funciones que casi siempre necesitas al crear una API, como validación y serialización de datos. Y al usarlo, obtienes documentación automática de forma gratuita (la documentación automática ni siquiera agrega gastos generales a las aplicaciones en ejecución, se genera al iniciar). + * Si no usaras FastAPI y usaras Starlette directamente (u otra herramienta, como Sanic, Flask, Responder, etc.), tendrías que implementar toda la validación y serialización de datos tu mismo. Por lo tanto, tu aplicación final seguirá teniendo la misma sobrecarga que si se hubiera creado con FastAPI. Y en muchos casos, esta validación y serialización de datos constituye la mayor cantidad de código escrito en las aplicaciones. + * Entonces, al usar FastAPI estás ahorrando tiempo de desarrollo, errores, líneas de código y probablemente obtendrías el mismo rendimiento (o mejor) que obtendrías si no lo usaras (ya que tendrías que implementarlo todo en tu código). + * Si estás comparando FastAPI, compáralo con un framework de aplicaciones web (o conjunto de herramientas) que proporciona validación, serialización y documentación de datos, como Flask-apispec, NestJS, Molten, etc. Frameworks con validación, serialización y documentación automáticas integradas. From 2a60a055f0cf543f463c0b07d3ed53aa7c4ee74a Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Feb 2024 11:40:11 +0000 Subject: [PATCH 14/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 5ce56a3ac..a37ad3e33 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Spanish translation for `docs/es/docs/benchmarks.md`. PR [#10928](https://github.com/tiangolo/fastapi/pull/10928) by [@pablocm83](https://github.com/pablocm83). * 🌐 Add Spanish translation for `docs/es/docs/advanced/response-change-status-code.md`. PR [#11100](https://github.com/tiangolo/fastapi/pull/11100) by [@alejsdev](https://github.com/alejsdev). ## 0.109.2 From 957e6600a77516736141900184786ed0cdaa870f Mon Sep 17 00:00:00 2001 From: Pablo Date: Wed, 7 Feb 2024 08:55:38 -0300 Subject: [PATCH 15/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Spanish=20translatio?= =?UTF-8?q?n=20for=20`docs/es/docs/deployment/index.md`=20and=20`~/deploym?= =?UTF-8?q?ent/versions.md`=20(#9669)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> Co-authored-by: Sebastián Ramírez --- docs/es/docs/deployment/index.md | 21 +++++++ docs/es/docs/deployment/versions.md | 87 +++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 docs/es/docs/deployment/index.md create mode 100644 docs/es/docs/deployment/versions.md diff --git a/docs/es/docs/deployment/index.md b/docs/es/docs/deployment/index.md new file mode 100644 index 000000000..74b0e22f0 --- /dev/null +++ b/docs/es/docs/deployment/index.md @@ -0,0 +1,21 @@ +# Despliegue - Introducción + +Desplegar una aplicación hecha con **FastAPI** es relativamente fácil. + +## ¿Qué significa desplegar una aplicación? + +**Desplegar** una aplicación significa realizar una serie de pasos para hacerla **disponible para los usuarios**. + +Para una **API web**, normalmente implica ponerla en una **máquina remota**, con un **programa de servidor** que proporcione un buen rendimiento, estabilidad, etc, para que sus **usuarios** puedan **acceder** a la aplicación de manera eficiente y sin interrupciones o problemas. + +Esto difiere en las fases de **desarrollo**, donde estás constantemente cambiando el código, rompiéndolo y arreglándolo, deteniendo y reiniciando el servidor de desarrollo, etc. + +## Estrategias de despliegue + +Existen varias formas de hacerlo dependiendo de tu caso de uso específico y las herramientas que uses. + +Puedes **desplegar un servidor** tú mismo usando un conjunto de herramientas, puedes usar **servicios en la nube** que haga parte del trabajo por ti, o usar otras posibles opciones. + +Te enseñaré algunos de los conceptos principales que debes tener en cuenta al desplegar aplicaciones hechas con **FastAPI** (aunque la mayoría de estos conceptos aplican para cualquier otro tipo de aplicación web). + +Podrás ver más detalles para tener en cuenta y algunas de las técnicas para hacerlo en las próximas secciones.✨ diff --git a/docs/es/docs/deployment/versions.md b/docs/es/docs/deployment/versions.md new file mode 100644 index 000000000..d8719d6bd --- /dev/null +++ b/docs/es/docs/deployment/versions.md @@ -0,0 +1,87 @@ +# Acerca de las versiones de FastAPI + +**FastAPI** está siendo utilizado en producción en muchas aplicaciones y sistemas. La cobertura de los tests se mantiene al 100%. Sin embargo, su desarrollo sigue siendo rápido. + +Se agregan nuevas características frecuentemente, se corrigen errores continuamente y el código está constantemente mejorando. + +Por eso las versiones actuales siguen siendo `0.x.x`, esto significa que cada versión puede potencialmente tener *breaking changes*. Las versiones siguen las convenciones de *Semantic Versioning*. + +Puedes crear aplicaciones listas para producción con **FastAPI** ahora mismo (y probablemente lo has estado haciendo por algún tiempo), solo tienes que asegurarte de usar la versión que funciona correctamente con el resto de tu código. + +## Fijar la versión de `fastapi` + +Lo primero que debes hacer en tu proyecto es "fijar" la última versión específica de **FastAPI** que sabes que funciona bien con tu aplicación. + +Por ejemplo, digamos que estás usando la versión `0.45.0` en tu aplicación. + +Si usas el archivo `requirements.txt` puedes especificar la versión con: + +```txt +fastapi==0.45.0 +``` + +esto significa que usarás específicamente la versión `0.45.0`. + +También puedes fijar las versiones de esta forma: + +```txt +fastapi>=0.45.0,<0.46.0 +``` + +esto significa que usarás la versión `0.45.0` o superiores, pero menores a la versión `0.46.0`, por ejemplo, la versión `0.45.2` sería aceptada. + +Si usas cualquier otra herramienta para manejar tus instalaciones, como Poetry, Pipenv, u otras, todas tienen una forma que puedes usar para definir versiones específicas para tus paquetes. + +## Versiones disponibles + +Puedes ver las versiones disponibles (por ejemplo, para revisar cuál es la actual) en las [Release Notes](../release-notes.md){.internal-link target=_blank}. + +## Acerca de las versiones + +Siguiendo las convenciones de *Semantic Versioning*, cualquier versión por debajo de `1.0.0` puede potencialmente tener *breaking changes*. + +FastAPI también sigue la convención de que cualquier cambio hecho en una "PATCH" version es para solucionar errores y *non-breaking changes*. + +!!! tip + El "PATCH" es el último número, por ejemplo, en `0.2.3`, la PATCH version es `3`. + +Entonces, deberías fijar la versión así: + +```txt +fastapi>=0.45.0,<0.46.0 +``` + +En versiones "MINOR" son añadidas nuevas características y posibles breaking changes. + +!!! tip + La versión "MINOR" es el número en el medio, por ejemplo, en `0.2.3`, la "MINOR" version es `2`. + +## Actualizando las versiones de FastAPI + +Para esto es recomendable primero añadir tests a tu aplicación. + +Con **FastAPI** es muy fácil (gracias a Starlette), revisa la documentación [Testing](../tutorial/testing.md){.internal-link target=_blank} + +Luego de tener los tests, puedes actualizar la versión de **FastAPI** a una más reciente y asegurarte de que tu código funciona correctamente ejecutando los tests. + +Si todo funciona correctamente, o haces los cambios necesarios para que esto suceda, y todos tus tests pasan, entonces puedes fijar tu versión de `fastapi` a la más reciente. + +## Acerca de Starlette + +No deberías fijar la versión de `starlette`. + +Diferentes versiones de **FastAPI** pueden usar una versión específica de Starlette. + +Entonces, puedes dejar que **FastAPI** se asegure por sí mismo de qué versión de Starlette usar. + +## Acerca de Pydantic + +Pydantic incluye los tests para **FastAPI** dentro de sus propios tests, esto significa que las versiones de Pydantic (superiores a `1.0.0`) son compatibles con FastAPI. + +Puedes fijar Pydantic a cualquier versión superior a `1.0.0` e inferior a `2.0.0` que funcione para ti. + +Por ejemplo: + +```txt +pydantic>=1.2.0,<2.0.0 +``` From 712eee66ca88035adf51a35a4a6a187f532740d9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Feb 2024 11:55:58 +0000 Subject: [PATCH 16/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index a37ad3e33..250316242 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Spanish translation for `docs/es/docs/deployment/index.md` and `~/deployment/versions.md`. PR [#9669](https://github.com/tiangolo/fastapi/pull/9669) by [@pabloperezmoya](https://github.com/pabloperezmoya). * 🌐 Add Spanish translation for `docs/es/docs/benchmarks.md`. PR [#10928](https://github.com/tiangolo/fastapi/pull/10928) by [@pablocm83](https://github.com/pablocm83). * 🌐 Add Spanish translation for `docs/es/docs/advanced/response-change-status-code.md`. PR [#11100](https://github.com/tiangolo/fastapi/pull/11100) by [@alejsdev](https://github.com/alejsdev). From 1926ade7a8ead911bc48b368917c935a310a1750 Mon Sep 17 00:00:00 2001 From: "Ich bin Xaraxx! :P" Date: Wed, 7 Feb 2024 07:51:12 -0500 Subject: [PATCH 17/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Spanish=20translatio?= =?UTF-8?q?n=20for=20`docs/es/docs/advanced/response-headers.md`=20(#2276)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Xaraxx Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sebastián Ramírez --- docs/es/docs/advanced/response-headers.md | 44 +++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 docs/es/docs/advanced/response-headers.md diff --git a/docs/es/docs/advanced/response-headers.md b/docs/es/docs/advanced/response-headers.md new file mode 100644 index 000000000..aec88a584 --- /dev/null +++ b/docs/es/docs/advanced/response-headers.md @@ -0,0 +1,44 @@ +# Headers de Respuesta + +## Usar un parámetro `Response` + +Puedes declarar un parámetro de tipo `Response` en tu *función de operación de path* (de manera similar como se hace con las cookies). + +Y entonces, podrás configurar las cookies en ese objeto de response *temporal*. + +```Python hl_lines="1 7-8" +{!../../../docs_src/response_headers/tutorial002.py!} +``` + +Posteriormente, puedes devolver cualquier objeto que necesites, como normalmente harías (un `dict`, un modelo de base de datos, etc). + +Si declaraste un `response_model`, este se continuará usando para filtrar y convertir el objeto que devolviste. + +**FastAPI** usará ese response *temporal* para extraer los headers (al igual que las cookies y el status code), además las pondrá en el response final que contendrá el valor retornado y filtrado por algún `response_model`. + +También puedes declarar el parámetro `Response` en dependencias, así como configurar los headers (y las cookies) en ellas. + + +## Retornar una `Response` directamente + +Adicionalmente, puedes añadir headers cuando se retorne una `Response` directamente. + +Crea un response tal como se describe en [Retornar una respuesta directamente](response-directly.md){.internal-link target=_blank} y pasa los headers como un parámetro adicional: + +```Python hl_lines="10-12" +{!../../../docs_src/response_headers/tutorial001.py!} +``` + +!!! note "Detalles Técnicos" + También podrías utilizar `from starlette.responses import Response` o `from starlette.responses import JSONResponse`. + + **FastAPI** proporciona las mismas `starlette.responses` en `fastapi.responses` sólo que de una manera más conveniente para ti, el desarrollador. En otras palabras, muchas de las responses disponibles provienen directamente de Starlette. + + + Y como la `Response` puede ser usada frecuentemente para configurar headers y cookies, **FastAPI** también la provee en `fastapi.Response`. + +## Headers Personalizados + +Ten en cuenta que se pueden añadir headers propietarios personalizados usando el prefijo 'X-'. + +Si tienes headers personalizados y deseas que un cliente pueda verlos en el navegador, es necesario que los añadas a tus configuraciones de CORS (puedes leer más en [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando el parámetro `expose_headers` documentado en Starlette's CORS docs. From d442afa1752dedb04c918ca2bc51a27d118e3dd9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Feb 2024 12:51:31 +0000 Subject: [PATCH 18/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 250316242..754b386d3 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Spanish translation for `docs/es/docs/advanced/response-headers.md`. PR [#2276](https://github.com/tiangolo/fastapi/pull/2276) by [@Xaraxx](https://github.com/Xaraxx). * 🌐 Add Spanish translation for `docs/es/docs/deployment/index.md` and `~/deployment/versions.md`. PR [#9669](https://github.com/tiangolo/fastapi/pull/9669) by [@pabloperezmoya](https://github.com/pabloperezmoya). * 🌐 Add Spanish translation for `docs/es/docs/benchmarks.md`. PR [#10928](https://github.com/tiangolo/fastapi/pull/10928) by [@pablocm83](https://github.com/pablocm83). * 🌐 Add Spanish translation for `docs/es/docs/advanced/response-change-status-code.md`. PR [#11100](https://github.com/tiangolo/fastapi/pull/11100) by [@alejsdev](https://github.com/alejsdev). From fe4bed62ff28b9f7c55c4fb0266e80245be401bf Mon Sep 17 00:00:00 2001 From: "Ich bin Xaraxx! :P" Date: Wed, 7 Feb 2024 08:02:32 -0500 Subject: [PATCH 19/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Spanish=20translatio?= =?UTF-8?q?n=20for=20`docs/es/docs/advanced/security/index.md`=20(#2278)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Xaraxx Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sebastián Ramírez --- docs/es/docs/advanced/security/index.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/es/docs/advanced/security/index.md diff --git a/docs/es/docs/advanced/security/index.md b/docs/es/docs/advanced/security/index.md new file mode 100644 index 000000000..e393fde4e --- /dev/null +++ b/docs/es/docs/advanced/security/index.md @@ -0,0 +1,16 @@ +# Seguridad Avanzada + +## Características Adicionales + +Hay algunas características adicionales para manejar la seguridad además de las que se tratan en el [Tutorial - Guía de Usuario: Seguridad](../../tutorial/security/){.internal-link target=_blank}. + +!!! tip + Las siguientes secciones **no necesariamente son "avanzadas"**. + + Y es posible que para tu caso de uso, la solución esté en alguna de ellas. + +## Leer primero el Tutorial + +En las siguientes secciones asumimos que ya has leído el principal [Tutorial - Guía de Usuario: Seguridad](../../tutorial/security/){.internal-link target=_blank}. + +Están basadas en los mismos conceptos, pero permiten algunas funcionalidades adicionales. From 2db35873ecb02a5a7c7ac56462f6c45f358d8ee5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Feb 2024 13:02:52 +0000 Subject: [PATCH 20/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 754b386d3..bfb6a6fe3 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Spanish translation for `docs/es/docs/advanced/security/index.md`. PR [#2278](https://github.com/tiangolo/fastapi/pull/2278) by [@Xaraxx](https://github.com/Xaraxx). * 🌐 Add Spanish translation for `docs/es/docs/advanced/response-headers.md`. PR [#2276](https://github.com/tiangolo/fastapi/pull/2276) by [@Xaraxx](https://github.com/Xaraxx). * 🌐 Add Spanish translation for `docs/es/docs/deployment/index.md` and `~/deployment/versions.md`. PR [#9669](https://github.com/tiangolo/fastapi/pull/9669) by [@pabloperezmoya](https://github.com/pabloperezmoya). * 🌐 Add Spanish translation for `docs/es/docs/benchmarks.md`. PR [#10928](https://github.com/tiangolo/fastapi/pull/10928) by [@pablocm83](https://github.com/pablocm83). From 572a47cd1e6ea96e8b3d1c15b383bcfb1e8ee225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emirhan=20Soyta=C5=9F?= Date: Thu, 8 Feb 2024 16:10:29 +0300 Subject: [PATCH 21/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Turkish=20translatio?= =?UTF-8?q?n=20for=20`docs/tr/docs/tutorial/path-params.md`=20(#11073)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tr/docs/tutorial/path-params.md | 254 +++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 docs/tr/docs/tutorial/path-params.md diff --git a/docs/tr/docs/tutorial/path-params.md b/docs/tr/docs/tutorial/path-params.md new file mode 100644 index 000000000..cfcf881fd --- /dev/null +++ b/docs/tr/docs/tutorial/path-params.md @@ -0,0 +1,254 @@ +# Yol Parametreleri + +Yol "parametrelerini" veya "değişkenlerini" Python string biçimlemede kullanılan sözdizimi ile tanımlayabilirsiniz. + +```Python hl_lines="6-7" +{!../../../docs_src/path_params/tutorial001.py!} +``` + +Yol parametresi olan `item_id`'nin değeri, fonksiyonunuza `item_id` argümanı olarak aktarılacaktır. + +Eğer bu örneği çalıştırıp http://127.0.0.1:8000/items/foo sayfasına giderseniz, şöyle bir çıktı ile karşılaşırsınız: + +```JSON +{"item_id":"foo"} +``` + +## Tip İçeren Yol Parametreleri + +Standart Python tip belirteçlerini kullanarak yol parametresinin tipini fonksiyonun içerisinde tanımlayabilirsiniz. + +```Python hl_lines="7" +{!../../../docs_src/path_params/tutorial002.py!} +``` + +Bu durumda, `item_id` bir `int` olarak tanımlanacaktır. + +!!! check "Ek bilgi" + Bu sayede, fonksiyon içerisinde hata denetimi, kod tamamlama gibi konularda editör desteğine kavuşacaksınız. + +## Veri Dönüşümü + +Eğer bu örneği çalıştırıp tarayıcınızda http://127.0.0.1:8000/items/3 sayfasını açarsanız, şöyle bir yanıt ile karşılaşırsınız: + +```JSON +{"item_id":3} +``` + +!!! check "Ek bilgi" + Dikkatinizi çekerim ki, fonksiyonunuzun aldığı (ve döndürdüğü) değer olan `3` bir string `"3"` değil aksine bir Python `int`'idir. + + Bu tanımlamayla birlikte, **FastAPI** size otomatik istek "ayrıştırma" özelliği sağlar. + +## Veri Doğrulama + +Eğer tarayıcınızda http://127.0.0.1:8000/items/foo sayfasını açarsanız, şuna benzer güzel bir HTTP hatası ile karşılaşırsınız: + +```JSON +{ + "detail": [ + { + "type": "int_parsing", + "loc": [ + "path", + "item_id" + ], + "msg": "Input should be a valid integer, unable to parse string as an integer", + "input": "foo", + "url": "https://errors.pydantic.dev/2.1/v/int_parsing" + } + ] +} +``` + +Çünkü burada `item_id` yol parametresi `int` tipinde bir değer beklerken `"foo"` yani `string` tipinde bir değer almıştı. + +Aynı hata http://127.0.0.1:8000/items/4.2 sayfasında olduğu gibi `int` yerine `float` bir değer verseydik de ortaya çıkardı. + +!!! check "Ek bilgi" + Böylece, aynı Python tip tanımlaması ile birlikte, **FastAPI** veri doğrulama özelliği sağlar. + + Dikkatinizi çekerim ki, karşılaştığınız hata, doğrulamanın geçersiz olduğu mutlak noktayı da açık bir şekilde belirtiyor. + + Bu özellik, API'ınızla iletişime geçen kodu geliştirirken ve ayıklarken inanılmaz derecede yararlı olacaktır. + +## Dokümantasyon + +Ayrıca, tarayıcınızı http://127.0.0.1:8000/docs adresinde açarsanız, aşağıdaki gibi otomatik ve interaktif bir API dökümantasyonu ile karşılaşırsınız: + + + +!!! check "Ek bilgi" + Üstelik, sadece aynı Python tip tanımlaması ile, **FastAPI** size otomatik ve interaktif (Swagger UI ile entegre) bir dokümantasyon sağlar. + + Dikkatinizi çekerim ki, yol parametresi integer olarak tanımlanmıştır. + +## Standartlara Dayalı Avantajlar, Alternatif Dokümantasyon + +Oluşturulan şema OpenAPI standardına uygun olduğu için birçok uyumlu araç mevcuttur. + +Bu sayede, **FastAPI**'ın bizzat kendisi http://127.0.0.1:8000/redoc sayfasından erişebileceğiniz alternatif (ReDoc kullanan) bir API dokümantasyonu sağlar: + + + +Aynı şekilde, farklı diller için kod türetme araçları da dahil olmak üzere çok sayıda uyumlu araç bulunur. + +## Pydantic + +Tüm veri doğrulamaları Pydantic tarafından arka planda gerçekleştirilir, bu sayede tüm avantajlardan faydalanabilirsiniz. Böylece, emin ellerde olduğunuzu hissedebilirsiniz. + +Aynı tip tanımlamalarını `str`, `float`, `bool` ve diğer karmaşık veri tipleri ile kullanma imkanınız vardır. + +Bunlardan birkaçı, bu eğitimin ileriki bölümlerinde irdelenmiştir. + +## Sıralama Önem Arz Eder + +*Yol operasyonları* tasarlarken sabit yol barındıran durumlar ile karşılaşabilirsiniz. + +Farz edelim ki `/users/me` yolu geçerli kullanıcı hakkında bilgi almak için kullanılıyor olsun. + +Benzer şekilde `/users/{user_id}` gibi tanımlanmış ve belirli bir kullanıcı hakkında veri almak için kullanıcının ID bilgisini kullanan bir yolunuz da mevcut olabilir. + +*Yol operasyonları* sıralı bir şekilde gözden geçirildiğinden dolayı `/users/me` yolunun `/users/{user_id}` yolundan önce tanımlanmış olmasından emin olmanız gerekmektedir: + +```Python hl_lines="6 11" +{!../../../docs_src/path_params/tutorial003.py!} +``` + +Aksi halde, `/users/{user_id}` yolu `"me"` değerinin `user_id` parametresi için gönderildiğini "düşünerek" `/users/me` ile de eşleşir. + +Benzer şekilde, bir yol operasyonunu yeniden tanımlamanız mümkün değildir: + +```Python hl_lines="6 11" +{!../../../docs_src/path_params/tutorial003b.py!} +``` + +Yol, ilk kısım ile eşleştiğinden dolayı her koşulda ilk yol operasyonu kullanılacaktır. + +## Ön Tanımlı Değerler + +Eğer *yol parametresi* alan bir *yol operasyonunuz* varsa ve alabileceği *yol parametresi* değerlerinin ön tanımlı olmasını istiyorsanız, standart Python `Enum` tipini kullanabilirsiniz. + +### Bir `Enum` Sınıfı Oluşturalım + +`Enum` sınıfını projemize dahil edip `str` ile `Enum` sınıflarını miras alan bir alt sınıf yaratalım. + +`str` sınıfı miras alındığından dolayı, API dokümanı, değerlerin `string` tipinde olması gerektiğini anlayabilecek ve doğru bir şekilde işlenecektir. + +Sonrasında, sınıf içerisinde, mevcut ve geçerli değerler olacak olan sabit değerli özelliklerini oluşturalım: + +```Python hl_lines="1 6-9" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +!!! info "Bilgi" + 3.4 sürümünden beri enumerationlar (ya da enumlar) Python'da mevcuttur. + +!!! tip "İpucu" + Merak ediyorsanız söyleyeyim, "AlexNet", "ResNet" ve "LeNet" isimleri Makine Öğrenmesi modellerini temsil eder. + +### Bir *Yol Parametresi* Tanımlayalım + +Sonrasında, yarattığımız enum sınıfını (`ModelName`) kullanarak tip belirteci aracılığıyla bir *yol parametresi* oluşturalım: + +```Python hl_lines="16" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +### Dokümana Göz Atalım + +*Yol parametresi* için mevcut değerler ön tanımlı olduğundan dolayı, interaktif döküman onları güzel bir şekilde gösterebilir: + + + +### Python *Enumerationları* ile Çalışmak + +*Yol parametresinin* değeri bir *enumeration üyesi* olacaktır. + +#### *Enumeration Üyelerini* Karşılaştıralım + +Parametreyi, yarattığınız enum olan `ModelName` içerisindeki *enumeration üyesi* ile karşılaştırabilirsiniz: + +```Python hl_lines="17" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +#### *Enumeration Değerini* Edinelim + +`model_name.value` veya genel olarak `your_enum_member.value` tanımlarını kullanarak (bu durumda bir `str` olan) gerçek değere ulaşabilirsiniz: + +```Python hl_lines="20" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +!!! tip "İpucu" + `"lenet"` değerine `ModelName.lenet.value` tanımı ile de ulaşabilirsiniz. + +#### *Enumeration Üyelerini* Döndürelim + +JSON gövdesine (örneğin bir `dict`) gömülü olsalar bile *yol operasyonundaki* *enum üyelerini* döndürebilirsiniz. + +Bu üyeler istemciye iletilmeden önce kendilerine karşılık gelen değerlerine (bu durumda string) dönüştürüleceklerdir: + +```Python hl_lines="18 21 23" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +İstemci tarafında şuna benzer bir JSON yanıtı ile karşılaşırsınız: + +```JSON +{ + "model_name": "alexnet", + "message": "Deep Learning FTW!" +} +``` + +## Yol İçeren Yol Parametreleri + +Farz edelim ki elinizde `/files/{file_path}` isminde bir *yol operasyonu* var. + +Fakat `file_path` değerinin `home/johndoe/myfile.txt` gibi bir *yol* barındırmasını istiyorsunuz. + +Sonuç olarak, oluşturmak istediğin URL `/files/home/johndoe/myfile.txt` gibi bir şey olacaktır. + +### OpenAPI Desteği + +Test etmesi ve tanımlaması zor senaryolara sebebiyet vereceğinden dolayı OpenAPI, *yol* barındıran *yol parametrelerini* tanımlayacak bir çözüm sunmuyor. + +Ancak bunu, Starlette kütüphanesinin dahili araçlarından birini kullanarak **FastAPI**'da gerçekleştirebilirsiniz. + +Parametrenin bir yol içermesi gerektiğini belirten herhangi bir doküman eklemememize rağmen dokümanlar yine de çalışacaktır. + +### Yol Dönüştürücü + +Direkt olarak Starlette kütüphanesinden gelen bir opsiyon sayesinde aşağıdaki gibi *yol* içeren bir *yol parametresi* bağlantısı tanımlayabilirsiniz: + +``` +/files/{file_path:path} +``` + +Bu durumda, parametrenin adı `file_path` olacaktır ve son kısım olan `:path` kısmı, parametrenin herhangi bir *yol* ile eşleşmesi gerektiğini belirtecektir. + +Böylece şunun gibi bir kullanım yapabilirsiniz: + +```Python hl_lines="6" +{!../../../docs_src/path_params/tutorial004.py!} +``` + +!!! tip "İpucu" + Parametrenin başında `/home/johndoe/myfile.txt` yolunda olduğu gibi (`/`) işareti ile birlikte kullanmanız gerektiği durumlar olabilir. + + Bu durumda, URL, `files` ile `home` arasında iki eğik çizgiye (`//`) sahip olup `/files//home/johndoe/myfile.txt` gibi gözükecektir. + +## Özet + +**FastAPI** ile kısa, sezgisel ve standart Python tip tanımlamaları kullanarak şunları elde edersiniz: + +* Editör desteği: hata denetimi, otomatik tamamlama, vb. +* Veri "dönüştürme" +* Veri doğrulama +* API tanımlamaları ve otomatik dokümantasyon + +Ve sadece, bunları bir kez tanımlamanız yeterli. + +Diğer frameworkler ile karşılaştırıldığında (ham performans dışında), üstte anlatılan durum muhtemelen **FastAPI**'ın göze çarpan başlıca avantajıdır. From 0c13911af894eeb2374ee8c37f8a41fdf0720cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hasan=20Sezer=20Ta=C5=9Fan?= <13135006+hasansezertasan@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:10:55 +0300 Subject: [PATCH 22/70] =?UTF-8?q?=F0=9F=8C=90=20Update=20Turkish=20transla?= =?UTF-8?q?tion=20for=20`docs/tr/docs/tutorial/first-steps.md`=20(#11094)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tr/docs/tutorial/first-steps.md | 333 ++++++++++++++++++++++++++ docs/tr/docs/tutorial/first_steps.md | 336 --------------------------- 2 files changed, 333 insertions(+), 336 deletions(-) create mode 100644 docs/tr/docs/tutorial/first-steps.md delete mode 100644 docs/tr/docs/tutorial/first_steps.md diff --git a/docs/tr/docs/tutorial/first-steps.md b/docs/tr/docs/tutorial/first-steps.md new file mode 100644 index 000000000..e66f73034 --- /dev/null +++ b/docs/tr/docs/tutorial/first-steps.md @@ -0,0 +1,333 @@ +# İlk Adımlar + +En sade FastAPI dosyası şu şekilde görünür: + +```Python +{!../../../docs_src/first_steps/tutorial001.py!} +``` + +Yukarıdaki içeriği bir `main.py` dosyasına kopyalayalım. + +Uygulamayı çalıştıralım: + +
+ +```console +$ uvicorn main:app --reload + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +INFO: Started reloader process [28720] +INFO: Started server process [28722] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +
+ +!!! note "Not" + `uvicorn main:app` komutunu şu şekilde açıklayabiliriz: + + * `main`: dosya olan `main.py` (yani Python "modülü"). + * `app`: ise `main.py` dosyasının içerisinde `app = FastAPI()` satırında oluşturduğumuz `FastAPI` nesnesi. + * `--reload`: kod değişikliklerinin ardından sunucuyu otomatik olarak yeniden başlatır. Bu parameteyi sadece geliştirme aşamasında kullanmalıyız. + +Çıktı olarak şöyle bir satır ile karşılaşacaksınız: + +```hl_lines="4" +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +Bu satır, yerel makinenizde uygulamanızın çalıştığı bağlantıyı gösterir. + +### Kontrol Edelim + +Tarayıcınızı açıp http://127.0.0.1:8000 bağlantısına gidin. + +Şu şekilde bir JSON yanıtı ile karşılaşacağız: + +```JSON +{"message": "Hello World"} +``` + +### Etkileşimli API Dokümantasyonu + +Şimdi http://127.0.0.1:8000/docs bağlantısını açalım. + +Swagger UI tarafından sağlanan otomatik etkileşimli bir API dokümantasyonu göreceğiz: + +![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) + +### Alternatif API Dokümantasyonu + +Şimdi http://127.0.0.1:8000/redoc bağlantısını açalım. + +ReDoc tarafından sağlanan otomatik dokümantasyonu göreceğiz: + +![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) + +### OpenAPI + +**FastAPI**, **OpenAPI** standardını kullanarak tüm API'ınızın tamamını tanımlayan bir "şema" oluşturur. + +#### "Şema" + +"Şema", bir şeyin tanımı veya açıklamasıdır. Geliştirilen koddan ziyade soyut bir açıklamadır. + +#### API "Şeması" + +Bu durumda, OpenAPI, API şemasını nasıl tanımlayacağınızı belirten bir şartnamedir. + +Bu şema tanımı, API yollarınızla birlikte yollarınızın aldığı olası parametreler gibi tanımlamaları içerir. + +#### Veri "Şeması" + +"Şema" terimi, JSON içeriği gibi bazı verilerin şeklini de ifade edebilir. + +Bu durumda, JSON özellikleri ve sahip oldukları veri türleri gibi anlamlarına gelir. + +#### OpenAPI ve JSON Şema + +OpenAPI, API'niz için bir API şeması tanımlar. Ve bu şema, JSON veri şemaları standardı olan **JSON Şema** kullanılarak API'niz tarafından gönderilen ve alınan verilerin tanımlarını (veya "şemalarını") içerir. + +#### `openapi.json` Dosyasına Göz At + +Ham OpenAPI şemasının nasıl göründüğünü merak ediyorsanız, FastAPI otomatik olarak tüm API'ınızın tanımlamalarını içeren bir JSON (şeması) oluşturur. + +Bu şemayı direkt olarak http://127.0.0.1:8000/openapi.json bağlantısından görüntüleyebilirsiniz. + +Aşağıdaki gibi başlayan bir JSON ile karşılaşacaksınız: + +```JSON +{ + "openapi": "3.1.0", + "info": { + "title": "FastAPI", + "version": "0.1.0" + }, + "paths": { + "/items/": { + "get": { + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + + + +... +``` + +#### OpenAPI Ne İşe Yarar? + +OpenAPI şeması, FastAPI projesinde bulunan iki etkileşimli dokümantasyon sistemine güç veren şeydir. + +OpenAPI'ya dayalı düzinelerce alternatif etkileşimli dokümantasyon aracı mevcuttur. **FastAPI** ile oluşturulmuş uygulamanıza bu alternatiflerden herhangi birini kolayca ekleyebilirsiniz. + +Ayrıca, API'ınızla iletişim kuracak önyüz, mobil veya IoT uygulamaları gibi istemciler için otomatik olarak kod oluşturabilirsiniz. + +## Adım Adım Özetleyelim + +### Adım 1: `FastAPI`yı Projemize Dahil Edelim + +```Python hl_lines="1" +{!../../../docs_src/first_steps/tutorial001.py!} +``` + +`FastAPI`, API'niz için tüm işlevselliği sağlayan bir Python sınıfıdır. + +!!! note "Teknik Detaylar" + `FastAPI` doğrudan `Starlette`'i miras alan bir sınıftır. + + Starlette'in tüm işlevselliğini `FastAPI` ile de kullanabilirsiniz. + +### Adım 2: Bir `FastAPI` "Örneği" Oluşturalım + +```Python hl_lines="3" +{!../../../docs_src/first_steps/tutorial001.py!} +``` + +Burada `app` değişkeni `FastAPI` sınıfının bir örneği olacaktır. + +Bu, tüm API'yı oluşturmak için ana etkileşim noktası olacaktır. + +Bu `app` değişkeni, `uvicorn` komutunda atıfta bulunulan değişkenin ta kendisidir. + +
+ +```console +$ uvicorn main:app --reload + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +Uygulamanızı aşağıdaki gibi oluşturursanız: + +```Python hl_lines="3" +{!../../../docs_src/first_steps/tutorial002.py!} +``` + +Ve bunu `main.py` dosyasına yerleştirirseniz eğer `uvicorn` komutunu şu şekilde çalıştırabilirsiniz: + +
+ +```console +$ uvicorn main:my_awesome_api --reload + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +### Adım 3: Bir *Yol Operasyonu* Oluşturalım + +#### Yol + +Burada "yol" bağlantıda bulunan ilk `/` ile başlayan ve sonrasında gelen kısmı ifade eder. + +Yani, şu şekilde bir bağlantıda: + +``` +https://example.com/items/foo +``` + +... yol şöyle olur: + +``` +/items/foo +``` + +!!! info "Bilgi" + "Yol" genellikle "endpoint" veya "route" olarak adlandırılır. + +Bir API oluştururken, "yol", "kaynaklar" ile "endişeleri" ayırmanın ana yöntemidir. + +#### Operasyonlar + +Burada "operasyon" HTTP "metodlarından" birini ifade eder. + +Bunlardan biri: + +* `POST` +* `GET` +* `PUT` +* `DELETE` + +...veya daha az kullanılan diğerleri: + +* `OPTIONS` +* `HEAD` +* `PATCH` +* `TRACE` + +HTTP protokolünde, bu "metodlardan" birini (veya daha fazlasını) kullanarak her bir yol ile iletişim kurabilirsiniz. + +--- + +API oluştururkan, belirli bir amaca hizmet eden belirli HTTP metodlarını kullanırsınız. + +Normalde kullanılan: + +* `POST`: veri oluşturmak. +* `GET`: veri okumak. +* `PUT`: veriyi güncellemek. +* `DELETE`: veriyi silmek. + +Bu nedenle, OpenAPI'da HTTP metodlarından her birine "operasyon" denir. + +Biz de onları "**operasyonlar**" olarak adlandıracağız. + +#### Bir *Yol Operasyonu Dekoratörü* Tanımlayalım + +```Python hl_lines="6" +{!../../../docs_src/first_steps/tutorial001.py!} +``` + +`@app.get("/")` dekoratörü, **FastAPI**'a hemen altındaki fonksiyonun aşağıdaki durumlardan sorumlu olduğunu söyler: + +* get operasyonu ile +* `/` yoluna gelen istekler + +!!! info "`@decorator` Bilgisi" + Python'da `@something` sözdizimi "dekoratör" olarak adlandırılır. + + Dekoratörler, dekoratif bir şapka gibi (sanırım terim buradan geliyor) fonksiyonların üzerlerine yerleştirilirler. + + Bir "dekoratör" hemen altında bulunan fonksiyonu alır ve o fonksiyon ile bazı işlemler gerçekleştirir. + + Bizim durumumuzda, kullandığımız dekoratör, **FastAPI**'a altındaki fonksiyonun `/` yoluna gelen `get` metodlu isteklerden sorumlu olduğunu söyler. + + Bu bir **yol operasyonu dekoratörüdür**. + +Ayrıca diğer operasyonları da kullanabilirsiniz: + +* `@app.post()` +* `@app.put()` +* `@app.delete()` + +Daha az kullanılanları da kullanabilirsiniz: + +* `@app.options()` +* `@app.head()` +* `@app.patch()` +* `@app.trace()` + +!!! tip "İpucu" + Her işlemi (HTTP metod) istediğiniz gibi kullanmakta özgürsünüz. + + **FastAPI** herhangi bir özel amacı veya anlamı olması konusunda ısrarcı olmaz. + + Buradaki bilgiler bir gereklilik değil, bir kılavuz olarak sunulmaktadır. + + Mesela GraphQL kullanırkan genelde tüm işlemleri yalnızca `POST` operasyonunu kullanarak gerçekleştirirsiniz. + +### Adım 4: **Yol Operasyonu Fonksiyonunu** Tanımlayın + +Aşağıdaki, bizim **yol operasyonu fonksiyonumuzdur**: + +* **yol**: `/` +* **operasyon**: `get` +* **fonksiyon**: "dekoratör"ün (`@app.get("/")`'in) altındaki fonksiyondur. + +```Python hl_lines="7" +{!../../../docs_src/first_steps/tutorial001.py!} +``` + +Bu bir Python fonksiyonudur. + +Bu fonksiyon bir `GET` işlemi kullanılarak "`/`" bağlantısına bir istek geldiğinde **FastAPI** tarafından çağrılır. + +Bu durumda bu fonksiyon bir `async` fonksiyondur. + +--- + +Bu fonksiyonu `async def` yerine normal bir fonksiyon olarak da tanımlayabilirsiniz. + +```Python hl_lines="7" +{!../../../docs_src/first_steps/tutorial003.py!} +``` + +!!! note "Not" + Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} sayfasını kontrol edebilirsiniz. + +### Adım 5: İçeriği Geri Döndürün + +```Python hl_lines="8" +{!../../../docs_src/first_steps/tutorial001.py!} +``` + +Bir `dict`, `list` veya `str`, `int` gibi tekil değerler döndürebilirsiniz. + +Ayrıca, Pydantic modelleri de döndürebilirsiniz (bu konu ileriki aşamalarda irdelenecektir). + +Otomatik olarak JSON'a dönüştürülecek (ORM'ler vb. dahil) başka birçok nesne ve model vardır. En beğendiklerinizi kullanmayı deneyin, yüksek ihtimalle destekleniyordur. + +## Özet + +* `FastAPI`'yı projemize dahil ettik. +* Bir `app` örneği oluşturduk. +* Bir **yol operasyonu dekoratörü** (`@app.get("/")` gibi) yazdık. +* Bir **yol operasyonu fonksiyonu** (`def root(): ...` gibi) yazdık. +* Geliştirme sunucumuzu (`uvicorn main:app --reload` gibi) çalıştırdık. diff --git a/docs/tr/docs/tutorial/first_steps.md b/docs/tr/docs/tutorial/first_steps.md deleted file mode 100644 index b39802f5d..000000000 --- a/docs/tr/docs/tutorial/first_steps.md +++ /dev/null @@ -1,336 +0,0 @@ -# İlk Adımlar - -En basit FastAPI dosyası şu şekildedir: - -```Python -{!../../../docs_src/first_steps/tutorial001.py!} -``` - -Bunu bir `main.py` dosyasına kopyalayın. - -Projeyi çalıştırın: - -
- -```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [28720] -INFO: Started server process [28722] -INFO: Waiting for application startup. -INFO: Application startup complete. -``` - -
- -!!! note - `uvicorn main:app` komutu şunu ifade eder: - - * `main`: `main.py` dosyası (the Python "module"). - * `app`: `main.py` dosyası içerisinde `app = FastAPI()` satırıyla oluşturulan nesne. - * `--reload`: Kod değişikliği sonrasında sunucunun yeniden başlatılmasını sağlar. Yalnızca geliştirme için kullanın. - -Çıktıda şu şekilde bir satır vardır: - -```hl_lines="4" -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -Bu satır, yerel makinenizde uygulamanızın sunulduğu URL'yi gösterir. - -### Kontrol Et - -Tarayıcınızda http://127.0.0.1:8000 adresini açın. - -Bir JSON yanıtı göreceksiniz: - -```JSON -{"message": "Hello World"} -``` - -### İnteraktif API dokümantasyonu - -http://127.0.0.1:8000/docs adresine gidin. - -Otomatik oluşturulmuş( Swagger UI tarafından sağlanan) interaktif bir API dokümanı göreceksiniz: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternatif API dokümantasyonu - -Şimdi, http://127.0.0.1:8000/redoc adresine gidin. - -Otomatik oluşturulmuş(ReDoc tarafından sağlanan) bir API dokümanı göreceksiniz: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -### OpenAPI - -**FastAPI**, **OpenAPI** standardını kullanarak tüm API'lerinizi açıklayan bir "şema" oluşturur. - -#### "Şema" - -Bir "şema", bir şeyin tanımı veya açıklamasıdır. Soyut bir açıklamadır, uygulayan kod değildir. - -#### API "şemaları" - -Bu durumda, OpenAPI, API şemasını nasıl tanımlayacağınızı belirten şartnamelerdir. - -Bu şema tanımı, API yollarınızı, aldıkları olası parametreleri vb. içerir. - -#### Data "şema" - -"Şema" terimi, JSON içeriği gibi bazı verilerin şeklini de ifade edebilir. - -Bu durumda, JSON öznitelikleri ve sahip oldukları veri türleri vb. anlamına gelir. - -#### OpenAPI and JSON Şema - -OpenAPI, API'niz için bir API şeması tanımlar. Ve bu şema, JSON veri şemaları standardı olan **JSON Şema** kullanılarak API'niz tarafından gönderilen ve alınan verilerin tanımlarını (veya "şemalarını") içerir. - -#### `openapi.json` kontrol et - -OpenAPI şemasının nasıl göründüğünü merak ediyorsanız, FastAPI otomatik olarak tüm API'nizin açıklamalarını içeren bir JSON (şema) oluşturur. - -Doğrudan şu adreste görebilirsiniz: http://127.0.0.1:8000/openapi.json. - -Aşağıdaki gibi bir şeyle başlayan bir JSON gösterecektir: - -```JSON -{ - "openapi": "3.0.2", - "info": { - "title": "FastAPI", - "version": "0.1.0" - }, - "paths": { - "/items/": { - "get": { - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - - - -... -``` - -#### OpenAPI ne içindir? - -OpenAPI şeması, dahili olarak bulunan iki etkileşimli dokümantasyon sistemine güç veren şeydir. - -Ve tamamen OpenAPI'ye dayalı düzinelerce alternatif vardır. **FastAPI** ile oluşturulmuş uygulamanıza bu alternatiflerden herhangi birini kolayca ekleyebilirsiniz. - -API'nizle iletişim kuran istemciler için otomatik olarak kod oluşturmak için de kullanabilirsiniz. Örneğin, frontend, mobil veya IoT uygulamaları. - -## Adım adım özet - -### Adım 1: `FastAPI`yi içe aktarın - -```Python hl_lines="1" -{!../../../docs_src/first_steps/tutorial001.py!} -``` - -`FastAPI`, API'niz için tüm fonksiyonları sağlayan bir Python sınıfıdır. - -!!! note "Teknik Detaylar" - `FastAPI` doğrudan `Starlette` kalıtım alan bir sınıftır. - - Tüm Starlette fonksiyonlarını `FastAPI` ile de kullanabilirsiniz. - -### Adım 2: Bir `FastAPI` örneği oluşturun - -```Python hl_lines="3" -{!../../../docs_src/first_steps/tutorial001.py!} -``` - -Burada `app` değişkeni `FastAPI` sınıfının bir örneği olacaktır. - -Bu tüm API'yi oluşturmak için ana etkileşim noktası olacaktır. - -`uvicorn` komutunda atıfta bulunulan `app` ile aynıdır. - -
- -```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -Uygulamanızı aşağıdaki gibi oluşturursanız: - -```Python hl_lines="3" -{!../../../docs_src/first_steps/tutorial002.py!} -``` - -Ve bunu `main.py` dosyasına koyduktan sonra `uvicorn` komutunu şu şekilde çağırabilirsiniz: - -
- -```console -$ uvicorn main:my_awesome_api --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -### Adım 3: *Path işlemleri* oluşturmak - -#### Path - -Burada "Path" URL'de ilk "\" ile başlayan son bölümü ifade eder. - -Yani, şu şekilde bir URL'de: - -``` -https://example.com/items/foo -``` - -... path şöyle olabilir: - -``` -/items/foo -``` - -!!! info - Genellikle bir "path", "endpoint" veya "route" olarak adlandırılabilir. - -Bir API oluştururken, "path", "resource" ile "concern" ayırmanın ana yoludur. - -#### İşlemler - -Burada "işlem" HTTP methodlarından birini ifade eder. - -Onlardan biri: - -* `POST` -* `GET` -* `PUT` -* `DELETE` - -... ve daha egzotik olanları: - -* `OPTIONS` -* `HEAD` -* `PATCH` -* `TRACE` - -HTTP protokolünde, bu "methodlardan" birini (veya daha fazlasını) kullanarak her path ile iletişim kurabilirsiniz. - ---- - -API'lerinizi oluştururkan, belirli bir işlemi gerçekleştirirken belirli HTTP methodlarını kullanırsınız. - -Normalde kullanılan: - -* `POST`: veri oluşturmak. -* `GET`: veri okumak. -* `PUT`: veriyi güncellemek. -* `DELETE`: veriyi silmek. - -Bu nedenle, OpenAPI'de HTTP methodlarından her birine "işlem" denir. - -Bizde onlara "**işlemler**" diyeceğiz. - -#### Bir *Path işlem decoratorleri* tanımlanmak - -```Python hl_lines="6" -{!../../../docs_src/first_steps/tutorial001.py!} -``` - -`@app.get("/")` **FastAPI'ye** aşağıdaki fonksiyonun adresine giden istekleri işlemekten sorumlu olduğunu söyler: - -* path `/` -* get işlemi kullanılarak - - -!!! info "`@decorator` Bilgisi" - Python `@something` şeklinde ifadeleri "decorator" olarak adlandırır. - - Decoratoru bir fonksiyonun üzerine koyarsınız. Dekoratif bir şapka gibi (Sanırım terim buradan gelmektedir). - - Bir "decorator" fonksiyonu alır ve bazı işlemler gerçekleştir. - - Bizim durumumzda decarator **FastAPI'ye** fonksiyonun bir `get` işlemi ile `/` pathine geldiğini söyler. - - Bu **path işlem decoratordür** - -Ayrıca diğer işlemleri de kullanabilirsiniz: - -* `@app.post()` -* `@app.put()` -* `@app.delete()` - -Ve daha egzotik olanları: - -* `@app.options()` -* `@app.head()` -* `@app.patch()` -* `@app.trace()` - -!!! tip - Her işlemi (HTTP method) istediğiniz gibi kullanmakta özgürsünüz. - - **FastAPI** herhangi bir özel anlamı zorlamaz. - - Buradaki bilgiler bir gereklilik değil, bir kılavuz olarak sunulmaktadır. - - Örneğin, GraphQL kullanırkan normalde tüm işlemleri yalnızca `POST` işlemini kullanarak gerçekleştirirsiniz. - -### Adım 4: **path işlem fonksiyonunu** tanımlayın - -Aşağıdakiler bizim **path işlem fonksiyonlarımızdır**: - -* **path**: `/` -* **işlem**: `get` -* **function**: "decorator"ün altındaki fonksiyondur (`@app.get("/")` altında). - -```Python hl_lines="7" -{!../../../docs_src/first_steps/tutorial001.py!} -``` - -Bu bir Python fonksiyonudur. - -Bir `GET` işlemi kullanarak "`/`" URL'sine bir istek geldiğinde **FastAPI** tarafından çağrılır. - -Bu durumda bir `async` fonksiyonudur. - ---- - -Bunu `async def` yerine normal bir fonksiyon olarakta tanımlayabilirsiniz. - -```Python hl_lines="7" -{!../../../docs_src/first_steps/tutorial003.py!} -``` - -!!! note - - Eğer farkı bilmiyorsanız, [Async: *"Acelesi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} kontrol edebilirsiniz. - -### Adım 5: İçeriği geri döndürün - - -```Python hl_lines="8" -{!../../../docs_src/first_steps/tutorial001.py!} -``` - -Bir `dict`, `list` döndürebilir veya `str`, `int` gibi tekil değerler döndürebilirsiniz. - -Ayrıca, Pydantic modellerini de döndürebilirsiniz. (Bununla ilgili daha sonra ayrıntılı bilgi göreceksiniz.) - -Otomatik olarak JSON'a dönüştürülecek(ORM'ler vb. dahil) başka birçok nesne ve model vardır. En beğendiklerinizi kullanmayı deneyin, yüksek ihtimalle destekleniyordur. - -## Özet - -* `FastAPI`'yi içe aktarın. -* Bir `app` örneği oluşturun. -* **path işlem decorator** yazın. (`@app.get("/")` gibi) -* **path işlem fonksiyonu** yazın. (`def root(): ...` gibi) -* Development sunucunuzu çalıştırın. (`uvicorn main:app --reload` gibi) From 1f6a33ce729c1b7040c276cb1ff37a0effed3bb1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 8 Feb 2024 13:11:17 +0000 Subject: [PATCH 23/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index bfb6a6fe3..e8e9166aa 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Update Turkish translation for `docs/tr/docs/tutorial/first-steps.md`. PR [#11094](https://github.com/tiangolo/fastapi/pull/11094) by [@hasansezertasan](https://github.com/hasansezertasan). * 🌐 Add Spanish translation for `docs/es/docs/advanced/security/index.md`. PR [#2278](https://github.com/tiangolo/fastapi/pull/2278) by [@Xaraxx](https://github.com/Xaraxx). * 🌐 Add Spanish translation for `docs/es/docs/advanced/response-headers.md`. PR [#2276](https://github.com/tiangolo/fastapi/pull/2276) by [@Xaraxx](https://github.com/Xaraxx). * 🌐 Add Spanish translation for `docs/es/docs/deployment/index.md` and `~/deployment/versions.md`. PR [#9669](https://github.com/tiangolo/fastapi/pull/9669) by [@pabloperezmoya](https://github.com/pabloperezmoya). From 378623294e936132edbe2c36be174feaf585ac24 Mon Sep 17 00:00:00 2001 From: Kani Kim Date: Fri, 9 Feb 2024 19:33:00 +0900 Subject: [PATCH 24/70] =?UTF-8?q?=F0=9F=8C=90=20Update=20Korean=20translat?= =?UTF-8?q?ion=20for=20`/docs/ko/docs/deployment/docker.md`=20(#11113)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/deployment/docker.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/ko/docs/deployment/docker.md b/docs/ko/docs/deployment/docker.md index 587b445fc..1c7bced2c 100644 --- a/docs/ko/docs/deployment/docker.md +++ b/docs/ko/docs/deployment/docker.md @@ -4,7 +4,7 @@ FastAPI 어플리케이션을 배포할 때 일반적인 접근 방법은 **리 리눅스 컨테이너를 사용하는 데에는 **보안**, **반복 가능성**, **단순함** 등의 장점이 있습니다. -!!! 팁 +!!! tip "팁" 시간에 쫓기고 있고 이미 이런것들을 알고 있다면 [`Dockerfile`👇](#build-a-docker-image-for-fastapi)로 점프할 수 있습니다.
@@ -130,7 +130,7 @@ Successfully installed fastapi pydantic uvicorn -!!! 정보 +!!! info "정보" 패키지 종속성을 정의하고 설치하기 위한 방법과 도구는 다양합니다. 나중에 아래 세션에서 Poetry를 사용한 예시를 보이겠습니다. 👇 @@ -222,7 +222,7 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] 프로그램이 `/code`에서 시작하고 그 속에 `./app` 디렉터리가 여러분의 코드와 함께 들어있기 때문에, **Uvicorn**은 이를 보고 `app`을 `app.main`으로부터 **불러 올** 것입니다. -!!! 팁 +!!! tip "팁" 각 코드 라인을 코드의 숫자 버블을 클릭하여 리뷰할 수 있습니다. 👆 이제 여러분은 다음과 같은 디렉터리 구조를 가지고 있을 것입니다: @@ -293,7 +293,7 @@ $ docker build -t myimage . -!!! 팁 +!!! tip "팁" 맨 끝에 있는 `.` 에 주목합시다. 이는 `./`와 동등하며, 도커에게 컨테이너 이미지를 빌드하기 위한 디렉터리를 알려줍니다. 이 경우에는 현재 디렉터리(`.`)와 같습니다. @@ -394,7 +394,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] **HTTPS**와 **인증서**의 **자동** 취득을 다루는 것은 다른 컨테이너가 될 수 있는데, 예를 들어 Traefik을 사용하는 것입니다. -!!! 팁 +!!! tip "팁" Traefik은 도커, 쿠버네티스, 그리고 다른 도구와 통합되어 있어 여러분의 컨테이너를 포함하는 HTTPS를 셋업하고 설정하는 것이 매우 쉽습니다. 대안적으로, HTTPS는 클라우드 제공자에 의해 서비스의 일환으로 다루어질 수도 있습니다 (이때도 어플리케이션은 여전히 컨테이너에서 실행될 것입니다). @@ -423,7 +423,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] 이 요소가 요청들의 **로드**를 읽어들이고 각 워커에게 (바라건대) **균형적으로** 분배한다면, 이 요소는 일반적으로 **로드 밸런서**라고 불립니다. -!!! 팁 +!!! tip "팁" HTTPS를 위해 사용된 **TLS 종료 프록시** 요소 또한 **로드 밸런서**가 될 수 있습니다. 또한 컨테이너로 작업할 때, 컨테이너를 시작하고 관리하기 위해 사용한 것과 동일한 시스템은 이미 해당 **로드 밸런서**로 부터 여러분의 앱에 해당하는 컨테이너로 **네트워크 통신**(예를 들어, HTTP 요청)을 전송하는 내부적인 도구를 가지고 있을 것입니다 (여기서도 로드 밸런서는 **TLS 종료 프록시**일 수 있습니다). @@ -503,7 +503,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] 만약 여러분이 **여러개의 컨테이너**를 가지고 있다면, 아마도 각각의 컨테이너는 **하나의 프로세스**를 가지고 있을 것입니다(예를 들어, **쿠버네티스** 클러스터에서). 그러면 여러분은 복제된 워커 컨테이너를 실행하기 **이전에**, 하나의 컨테이너에 있는 **이전의 단계들을** 수행하는 단일 프로세스를 가지는 **별도의 컨테이너들**을 가지고 싶을 것입니다. -!!! 정보 +!!! info "정보" 만약 여러분이 쿠버네티스를 사용하고 있다면, 아마도 이는 Init Container일 것입니다. 만약 여러분의 이용 사례에서 이전 단계들을 **병렬적으로 여러번** 수행하는데에 문제가 없다면 (예를 들어 데이터베이스 이전을 실행하지 않고 데이터베이스가 준비되었는지 확인만 하는 경우), 메인 프로세스를 시작하기 전에 이 단계들을 각 컨테이너에 넣을 수 있습니다. @@ -520,7 +520,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] * tiangolo/uvicorn-gunicorn-fastapi. -!!! 경고 +!!! warning "경고" 여러분이 이 베이스 이미지 또는 다른 유사한 이미지를 필요로 하지 **않을** 높은 가능성이 있으며, [위에서 설명된 것처럼: FastAPI를 위한 도커 이미지 빌드하기](#build-a-docker-image-for-fastapi) 처음부터 이미지를 빌드하는 것이 더 나을 수 있습니다. 이 이미지는 가능한 CPU 코어에 기반한 **몇개의 워커 프로세스**를 설정하는 **자동-튜닝** 메커니즘을 포함하고 있습니다. @@ -529,7 +529,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] 또한 스크립트를 통해 **시작하기 전 사전 단계**를 실행하는 것을 지원합니다. -!!! 팁 +!!! tip "팁" 모든 설정과 옵션을 보려면, 도커 이미지 페이지로 이동합니다: tiangolo/uvicorn-gunicorn-fastapi. ### 공식 도커 이미지에 있는 프로세스 개수 @@ -657,7 +657,7 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] 11. `uvicorn` 커맨드를 실행하여, `app.main`에서 불러온 `app` 객체를 사용하도록 합니다. -!!! 팁 +!!! tip "팁" 버블 숫자를 클릭해 각 줄이 하는 일을 알아볼 수 있습니다. **도커 스테이지**란 `Dockefile`의 일부로서 나중에 사용하기 위한 파일들을 생성하기 위한 **일시적인 컨테이너 이미지**로 작동합니다. From d2f69cf311bc2a628b3c4283b95e66828c8f9518 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 10:33:22 +0000 Subject: [PATCH 25/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index e8e9166aa..246b0d0c0 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Update Korean translation for `/docs/ko/docs/deployment/docker.md`. PR [#11113](https://github.com/tiangolo/fastapi/pull/11113) by [@KaniKim](https://github.com/KaniKim). * 🌐 Update Turkish translation for `docs/tr/docs/tutorial/first-steps.md`. PR [#11094](https://github.com/tiangolo/fastapi/pull/11094) by [@hasansezertasan](https://github.com/hasansezertasan). * 🌐 Add Spanish translation for `docs/es/docs/advanced/security/index.md`. PR [#2278](https://github.com/tiangolo/fastapi/pull/2278) by [@Xaraxx](https://github.com/Xaraxx). * 🌐 Add Spanish translation for `docs/es/docs/advanced/response-headers.md`. PR [#2276](https://github.com/tiangolo/fastapi/pull/2276) by [@Xaraxx](https://github.com/Xaraxx). From b7e15512861612214f01a196c162d107d6d9515e Mon Sep 17 00:00:00 2001 From: Kani Kim Date: Fri, 9 Feb 2024 19:34:13 +0900 Subject: [PATCH 26/70] =?UTF-8?q?=F0=9F=8C=90=20Update=20Korean=20translat?= =?UTF-8?q?ion=20for=20`/docs/ko/docs/dependencies/index.md`=20(#11114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/tutorial/dependencies/index.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/ko/docs/tutorial/dependencies/index.md b/docs/ko/docs/tutorial/dependencies/index.md index d5d113860..cde88eb6c 100644 --- a/docs/ko/docs/tutorial/dependencies/index.md +++ b/docs/ko/docs/tutorial/dependencies/index.md @@ -51,7 +51,7 @@ === "Python 3.10+ Annotated가 없는 경우" - !!! 팁 + !!! tip "팁" 가능하다면 `Annotated`가 달린 버전을 권장합니다. ```Python hl_lines="6-7" @@ -60,7 +60,7 @@ === "Python 3.8+ Annotated가 없는 경우" - !!! 팁 + !!! tip "팁" 가능하다면 `Annotated`가 달린 버전을 권장합니다. ```Python hl_lines="8-11" @@ -114,7 +114,7 @@ === "Python 3.10+ Annotated가 없는 경우" - !!! 팁 + !!! tip "팁" 가능하다면 `Annotated`가 달린 버전을 권장합니다. ```Python hl_lines="1" @@ -123,7 +123,7 @@ === "Python 3.8+ Annotated가 없는 경우" - !!! 팁 + !!! tip "팁" 가능하다면 `Annotated`가 달린 버전을 권장합니다. ```Python hl_lines="3" @@ -154,7 +154,7 @@ === "Python 3.10+ Annotated가 없는 경우" - !!! 팁 + !!! tip "팁" 가능하다면 `Annotated`가 달린 버전을 권장합니다. ```Python hl_lines="11 16" @@ -163,7 +163,7 @@ === "Python 3.8+ Annotated가 없는 경우" - !!! 팁 + !!! tip "팁" 가능하다면 `Annotated`가 달린 버전을 권장합니다. ```Python hl_lines="15 20" @@ -180,7 +180,7 @@ 그리고 그 함수는 *경로 작동 함수*가 작동하는 것과 같은 방식으로 매개변수를 받습니다. -!!! 팁 +!!! tip "팁" 여러분은 다음 장에서 함수를 제외하고서, "다른 것들"이 어떻게 의존성으로 사용되는지 알게 될 것입니다. 새로운 요청이 도착할 때마다, **FastAPI**는 다음을 처리합니다: @@ -202,7 +202,7 @@ common_parameters --> read_users 이렇게 하면 공용 코드를 한번만 적어도 되며, **FastAPI**는 *경로 작동*을 위해 이에 대한 호출을 처리합니다. -!!! 확인 +!!! check "확인" 특별한 클래스를 만들지 않아도 되며, 이러한 것 혹은 비슷한 종류를 **FastAPI**에 "등록"하기 위해 어떤 곳에 넘겨주지 않아도 됩니다. 단순히 `Depends`에 넘겨주기만 하면 되며, **FastAPI**는 나머지를 어찌할지 알고 있습니다. @@ -237,7 +237,7 @@ commons: Annotated[dict, Depends(common_parameters)] {!> ../../../docs_src/dependencies/tutorial001_02_an.py!} ``` -!!! 팁 +!!! tip "팁" 이는 그저 표준 파이썬이고 "type alias"라고 부르며 사실 **FastAPI**에 국한되는 것은 아닙니다. 하지만, `Annotated`를 포함하여, **FastAPI**가 파이썬 표준을 기반으로 하고 있기에, 이를 여러분의 코드 트릭으로 사용할 수 있습니다. 😎 @@ -256,7 +256,7 @@ commons: Annotated[dict, Depends(common_parameters)] 아무 문제 없습니다. **FastAPI**는 무엇을 할지 알고 있습니다. -!!! 참고 +!!! note "참고" 잘 모르시겠다면, [Async: *"In a hurry?"*](../../async.md){.internal-link target=_blank} 문서에서 `async`와 `await`에 대해 확인할 수 있습니다. ## OpenAPI와 통합 From d048b485cdfa718c5ce0ef9257291ff71af2e6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AA=85=EA=B8=B0?= Date: Fri, 9 Feb 2024 19:34:57 +0900 Subject: [PATCH 27/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Korean=20translation?= =?UTF-8?q?=20for=20`/docs/ko/docs/tutorial/cookie-params.md`=20(#11118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/tutorial/cookie-params.md | 97 ++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/ko/docs/tutorial/cookie-params.md diff --git a/docs/ko/docs/tutorial/cookie-params.md b/docs/ko/docs/tutorial/cookie-params.md new file mode 100644 index 000000000..d4f3d57a3 --- /dev/null +++ b/docs/ko/docs/tutorial/cookie-params.md @@ -0,0 +1,97 @@ +# 쿠키 매개변수 + +쿠키 매개변수를 `Query`와 `Path` 매개변수들과 같은 방식으로 정의할 수 있습니다. + +## `Cookie` 임포트 + +먼저 `Cookie`를 임포트합니다: + +=== "Python 3.10+" + + ```Python hl_lines="3" + {!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="3" + {!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="3" + {!> ../../../docs_src/cookie_params/tutorial001_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="1" + {!> ../../../docs_src/cookie_params/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="3" + {!> ../../../docs_src/cookie_params/tutorial001.py!} + ``` + +## `Cookie` 매개변수 선언 + +그런 다음, `Path`와 `Query`처럼 동일한 구조를 사용하는 쿠키 매개변수를 선언합니다. + +첫 번째 값은 기본값이며, 추가 검증이나 어노테이션 매개변수 모두 전달할 수 있습니다: + +=== "Python 3.10+" + + ```Python hl_lines="9" + {!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="9" + {!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="10" + {!> ../../../docs_src/cookie_params/tutorial001_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="7" + {!> ../../../docs_src/cookie_params/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="9" + {!> ../../../docs_src/cookie_params/tutorial001.py!} + ``` + +!!! note "기술 세부사항" + `Cookie`는 `Path` 및 `Query`의 "자매"클래스입니다. 이 역시 동일한 공통 `Param` 클래스를 상속합니다. + + `Query`, `Path`, `Cookie` 그리고 다른 것들은 `fastapi`에서 임포트 할 때, 실제로는 특별한 클래스를 반환하는 함수임을 기억하세요. + +!!! info "정보" + 쿠키를 선언하기 위해서는 `Cookie`를 사용해야 합니다. 그렇지 않으면 해당 매개변수를 쿼리 매개변수로 해석하기 때문입니다. + +## 요약 + +`Cookie`는 `Query`, `Path`와 동일한 패턴을 사용하여 선언합니다. From 75e3aac8d3bd2bc080bf43bd85b85530e3aded1c Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 10:35:36 +0000 Subject: [PATCH 28/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 246b0d0c0..17c13fbec 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Update Korean translation for `/docs/ko/docs/dependencies/index.md`. PR [#11114](https://github.com/tiangolo/fastapi/pull/11114) by [@KaniKim](https://github.com/KaniKim). * 🌐 Update Korean translation for `/docs/ko/docs/deployment/docker.md`. PR [#11113](https://github.com/tiangolo/fastapi/pull/11113) by [@KaniKim](https://github.com/KaniKim). * 🌐 Update Turkish translation for `docs/tr/docs/tutorial/first-steps.md`. PR [#11094](https://github.com/tiangolo/fastapi/pull/11094) by [@hasansezertasan](https://github.com/hasansezertasan). * 🌐 Add Spanish translation for `docs/es/docs/advanced/security/index.md`. PR [#2278](https://github.com/tiangolo/fastapi/pull/2278) by [@Xaraxx](https://github.com/Xaraxx). From a5edc3f85b4a85a9fdd8f9f6fe7991abd5350656 Mon Sep 17 00:00:00 2001 From: Kani Kim Date: Fri, 9 Feb 2024 19:36:26 +0900 Subject: [PATCH 29/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Korean=20translation?= =?UTF-8?q?=20for=20`/docs/ko/docs/tutorial/body-fields.md`=20(#11112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/tutorial/body-fields.md | 116 +++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/ko/docs/tutorial/body-fields.md diff --git a/docs/ko/docs/tutorial/body-fields.md b/docs/ko/docs/tutorial/body-fields.md new file mode 100644 index 000000000..a739756bd --- /dev/null +++ b/docs/ko/docs/tutorial/body-fields.md @@ -0,0 +1,116 @@ +# 본문 - 필드 + +`Query`, `Path`와 `Body`를 사용해 *경로 동작 함수* 매개변수 내에서 추가적인 검증이나 메타데이터를 선언한 것처럼 Pydantic의 `Field`를 사용하여 모델 내에서 검증과 메타데이터를 선언할 수 있습니다. + +## `Field` 임포트 + +먼저 이를 임포트해야 합니다: + +=== "Python 3.10+" + + ```Python hl_lines="4" + {!> ../../../docs_src/body_fields/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="4" + {!> ../../../docs_src/body_fields/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="4" + {!> ../../../docs_src/body_fields/tutorial001_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! 팁 + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="2" + {!> ../../../docs_src/body_fields/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="4" + {!> ../../../docs_src/body_fields/tutorial001.py!} + ``` + +!!! warning "경고" + `Field`는 다른 것들처럼 (`Query`, `Path`, `Body` 등) `fastapi`에서가 아닌 `pydantic`에서 바로 임포트 되는 점에 주의하세요. + +## 모델 어트리뷰트 선언 + +그 다음 모델 어트리뷰트와 함께 `Field`를 사용할 수 있습니다: + +=== "Python 3.10+" + + ```Python hl_lines="11-14" + {!> ../../../docs_src/body_fields/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="11-14" + {!> ../../../docs_src/body_fields/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="12-15" + {!> ../../../docs_src/body_fields/tutorial001_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="9-12" + {!> ../../../docs_src/body_fields/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="11-14" + {!> ../../../docs_src/body_fields/tutorial001.py!} + ``` + +`Field`는 `Query`, `Path`와 `Body`와 같은 방식으로 동작하며, 모두 같은 매개변수들 등을 가집니다. + +!!! note "기술적 세부사항" + 실제로 `Query`, `Path`등, 여러분이 앞으로 볼 다른 것들은 공통 클래스인 `Param` 클래스의 서브클래스 객체를 만드는데, 그 자체로 Pydantic의 `FieldInfo` 클래스의 서브클래스입니다. + + 그리고 Pydantic의 `Field` 또한 `FieldInfo`의 인스턴스를 반환합니다. + + `Body` 또한 `FieldInfo`의 서브클래스 객체를 직접적으로 반환합니다. 그리고 `Body` 클래스의 서브클래스인 것들도 여러분이 나중에 보게될 것입니다. + + `Query`, `Path`와 그 외 것들을 `fastapi`에서 임포트할 때, 이는 실제로 특별한 클래스를 반환하는 함수인 것을 기억해 주세요. + +!!! tip "팁" + 주목할 점은 타입, 기본 값 및 `Field`로 이루어진 각 모델 어트리뷰트가 `Path`, `Query`와 `Body`대신 `Field`를 사용하는 *경로 작동 함수*의 매개변수와 같은 구조를 가진다는 점 입니다. + +## 별도 정보 추가 + +`Field`, `Query`, `Body`, 그 외 안에 별도 정보를 선언할 수 있습니다. 이는 생성된 JSON 스키마에 포함됩니다. + +여러분이 예제를 선언할 때 나중에 이 공식 문서에서 별도 정보를 추가하는 방법을 배울 것입니다. + +!!! warning "경고" + 별도 키가 전달된 `Field` 또한 여러분의 어플리케이션의 OpenAPI 스키마에 나타날 것입니다. + 이런 키가 OpenAPI 명세서, [the OpenAPI validator](https://validator.swagger.io/)같은 몇몇 OpenAPI 도구들에 포함되지 못할 수 있으며, 여러분이 생성한 스키마와 호환되지 않을 수 있습니다. + +## 요약 + +모델 어트리뷰트를 위한 추가 검증과 메타데이터 선언하기 위해 Pydantic의 `Field` 를 사용할 수 있습니다. + +또한 추가적인 JSON 스키마 메타데이터를 전달하기 위한 별도의 키워드 인자를 사용할 수 있습니다. From 564d5591ad3f56094e9b74ff8620f7af240c88f4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 10:36:41 +0000 Subject: [PATCH 30/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 17c13fbec..eaca64f11 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Korean translation for `/docs/ko/docs/tutorial/cookie-params.md`. PR [#11118](https://github.com/tiangolo/fastapi/pull/11118) by [@riroan](https://github.com/riroan). * 🌐 Update Korean translation for `/docs/ko/docs/dependencies/index.md`. PR [#11114](https://github.com/tiangolo/fastapi/pull/11114) by [@KaniKim](https://github.com/KaniKim). * 🌐 Update Korean translation for `/docs/ko/docs/deployment/docker.md`. PR [#11113](https://github.com/tiangolo/fastapi/pull/11113) by [@KaniKim](https://github.com/KaniKim). * 🌐 Update Turkish translation for `docs/tr/docs/tutorial/first-steps.md`. PR [#11094](https://github.com/tiangolo/fastapi/pull/11094) by [@hasansezertasan](https://github.com/hasansezertasan). From 76e14214bd5c11974d88a4bcb43388750863e5d9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 10:39:15 +0000 Subject: [PATCH 31/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index eaca64f11..0e66f5ca4 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Korean translation for `/docs/ko/docs/tutorial/body-fields.md`. PR [#11112](https://github.com/tiangolo/fastapi/pull/11112) by [@KaniKim](https://github.com/KaniKim). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/cookie-params.md`. PR [#11118](https://github.com/tiangolo/fastapi/pull/11118) by [@riroan](https://github.com/riroan). * 🌐 Update Korean translation for `/docs/ko/docs/dependencies/index.md`. PR [#11114](https://github.com/tiangolo/fastapi/pull/11114) by [@KaniKim](https://github.com/KaniKim). * 🌐 Update Korean translation for `/docs/ko/docs/deployment/docker.md`. PR [#11113](https://github.com/tiangolo/fastapi/pull/11113) by [@KaniKim](https://github.com/KaniKim). From 383870a2751b82bec24eff46afd13eee655a5202 Mon Sep 17 00:00:00 2001 From: Kani Kim Date: Fri, 9 Feb 2024 21:35:46 +0900 Subject: [PATCH 32/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Korean=20translation?= =?UTF-8?q?=20for=20`/docs/ko/docs/tutorial/schema-extra-example.md`=20(#1?= =?UTF-8?q?1121)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/tutorial/schema-extra-example.md | 326 ++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 docs/ko/docs/tutorial/schema-extra-example.md diff --git a/docs/ko/docs/tutorial/schema-extra-example.md b/docs/ko/docs/tutorial/schema-extra-example.md new file mode 100644 index 000000000..4e319e075 --- /dev/null +++ b/docs/ko/docs/tutorial/schema-extra-example.md @@ -0,0 +1,326 @@ +# 요청 예제 데이터 선언 + +여러분의 앱이 받을 수 있는 데이터 예제를 선언할 수 있습니다. + +여기 이를 위한 몇가지 방식이 있습니다. + +## Pydantic 모델 속 추가 JSON 스키마 데이터 + +생성된 JSON 스키마에 추가될 Pydantic 모델을 위한 `examples`을 선언할 수 있습니다. + +=== "Python 3.10+ Pydantic v2" + + ```Python hl_lines="13-24" + {!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!} + ``` + +=== "Python 3.10+ Pydantic v1" + + ```Python hl_lines="13-23" + {!> ../../../docs_src/schema_extra_example/tutorial001_py310_pv1.py!} + ``` + +=== "Python 3.8+ Pydantic v2" + + ```Python hl_lines="15-26" + {!> ../../../docs_src/schema_extra_example/tutorial001.py!} + ``` + +=== "Python 3.8+ Pydantic v1" + + ```Python hl_lines="15-25" + {!> ../../../docs_src/schema_extra_example/tutorial001_pv1.py!} + ``` + +추가 정보는 있는 그대로 해당 모델의 **JSON 스키마** 결과에 추가되고, API 문서에서 사용합니다. + +=== "Pydantic v2" + + Pydantic 버전 2에서 Pydantic 공식 문서: Model Config에 나와 있는 것처럼 `dict`를 받는 `model_config` 어트리뷰트를 사용할 것입니다. + + `"json_schema_extra"`를 생성된 JSON 스키마에서 보여주고 싶은 별도의 데이터와 `examples`를 포함하는 `dict`으로 설정할 수 있습니다. + +=== "Pydantic v1" + + Pydantic v1에서 Pydantic 공식 문서: Schema customization에서 설명하는 것처럼, 내부 클래스인 `Config`와 `schema_extra`를 사용할 것입니다. + + `schema_extra`를 생성된 JSON 스키마에서 보여주고 싶은 별도의 데이터와 `examples`를 포함하는 `dict`으로 설정할 수 있습니다. + +!!! tip "팁" + JSON 스키마를 확장하고 여러분의 별도의 자체 데이터를 추가하기 위해 같은 기술을 사용할 수 있습니다. + + 예를 들면, 프론트엔드 사용자 인터페이스에 메타데이터를 추가하는 등에 사용할 수 있습니다. + +!!! info "정보" + (FastAPI 0.99.0부터 쓰이기 시작한) OpenAPI 3.1.0은 **JSON 스키마** 표준의 일부인 `examples`에 대한 지원을 추가했습니다. + + 그 전에는, 하나의 예제만 가능한 `example` 키워드만 지원했습니다. 이는 아직 OpenAPI 3.1.0에서 지원하지만, 지원이 종료될 것이며 JSON 스키마 표준에 포함되지 않습니다. 그렇기에 `example`을 `examples`으로 이전하는 것을 추천합니다. 🤓 + + 이 문서 끝에 더 많은 읽을거리가 있습니다. + +## `Field` 추가 인자 + +Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를 선언할 수 있습니다: + +=== "Python 3.10+" + + ```Python hl_lines="2 8-11" + {!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="4 10-13" + {!> ../../../docs_src/schema_extra_example/tutorial002.py!} + ``` + +## JSON Schema에서의 `examples` - OpenAPI + +이들 중에서 사용합니다: + +* `Path()` +* `Query()` +* `Header()` +* `Cookie()` +* `Body()` +* `Form()` +* `File()` + +**OpenAPI**의 **JSON 스키마**에 추가될 부가적인 정보를 포함한 `examples` 모음을 선언할 수 있습니다. + +### `examples`를 포함한 `Body` + +여기, `Body()`에 예상되는 예제 데이터 하나를 포함한 `examples`를 넘겼습니다: + +=== "Python 3.10+" + + ```Python hl_lines="22-29" + {!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="22-29" + {!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="23-30" + {!> ../../../docs_src/schema_extra_example/tutorial003_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="18-25" + {!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="20-27" + {!> ../../../docs_src/schema_extra_example/tutorial003.py!} + ``` + +### 문서 UI 예시 + +위의 어느 방법과 함께라면 `/docs`에서 다음과 같이 보일 것입니다: + + + +### 다중 `examples`를 포함한 `Body` + +물론 여러 `examples`를 넘길 수 있습니다: + +=== "Python 3.10+" + + ```Python hl_lines="23-38" + {!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="23-38" + {!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="24-39" + {!> ../../../docs_src/schema_extra_example/tutorial004_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="19-34" + {!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="21-36" + {!> ../../../docs_src/schema_extra_example/tutorial004.py!} + ``` + +이와 같이 하면 이 예제는 그 본문 데이터를 위한 내부 **JSON 스키마**의 일부가 될 것입니다. + +그럼에도 불구하고, 지금 이 문서를 작성하는 시간에, 문서 UI를 보여주는 역할을 맡은 Swagger UI는 **JSON 스키마** 속 데이터를 위한 여러 예제의 표현을 지원하지 않습니다. 하지만 해결 방안을 밑에서 읽어보세요. + +### OpenAPI-특화 `examples` + +**JSON 스키마**가 `examples`를 지원하기 전 부터, OpenAPI는 `examples`이라 불리는 다른 필드를 지원해 왔습니다. + +이 **OpenAPI-특화** `examples`는 OpenAPI 명세서의 다른 구역으로 들어갑니다. 각 JSON 스키마 내부가 아니라 **각 *경로 작동* 세부 정보**에 포함됩니다. + +그리고 Swagger UI는 이 특정한 `examples` 필드를 한동안 지원했습니다. 그래서, 이를 다른 **문서 UI에 있는 예제**를 **표시**하기 위해 사용할 수 있습니다. + +이 OpenAPI-특화 필드인 `examples`의 형태는 (`list`대신에) **다중 예제**가 포함된 `dict`이며, 각각의 별도 정보 또한 **OpenAPI**에 추가될 것입니다. + +이는 OpenAPI에 포함된 JSON 스키마 안으로 포함되지 않으며, *경로 작동*에 직접적으로 포함됩니다. + +### `openapi_examples` 매개변수 사용하기 + +다음 예시 속에 OpenAPI-특화 `examples`를 FastAPI 안에서 매개변수 `openapi_examples` 매개변수와 함께 선언할 수 있습니다: + +* `Path()` +* `Query()` +* `Header()` +* `Cookie()` +* `Body()` +* `Form()` +* `File()` + +`dict`의 키가 또 다른 `dict`인 각 예제와 값을 구별합니다. + +각각의 특정 `examples` 속 `dict` 예제는 다음을 포함할 수 있습니다: + +* `summary`: 예제에 대한 짧은 설명문. +* `description`: 마크다운 텍스트를 포함할 수 있는 긴 설명문. +* `value`: 실제로 보여지는 예시, 예를 들면 `dict`. +* `externalValue`: `value`의 대안이며 예제를 가르키는 URL. 비록 `value`처럼 많은 도구를 지원하지 못할 수 있습니다. + +이를 다음과 같이 사용할 수 있습니다: + +=== "Python 3.10+" + + ```Python hl_lines="23-49" + {!> ../../../docs_src/schema_extra_example/tutorial005_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="23-49" + {!> ../../../docs_src/schema_extra_example/tutorial005_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="24-50" + {!> ../../../docs_src/schema_extra_example/tutorial005_an.py!} + ``` + +=== "Python 3.10+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="19-45" + {!> ../../../docs_src/schema_extra_example/tutorial005_py310.py!} + ``` + +=== "Python 3.8+ Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="21-47" + {!> ../../../docs_src/schema_extra_example/tutorial005.py!} + ``` + +### 문서 UI에서의 OpenAPI 예시 + +`Body()`에 추가된 `openapi_examples`를 포함한 `/docs`는 다음과 같이 보일 것입니다: + + + +## 기술적 세부 사항 + +!!! tip "팁" + 이미 **FastAPI**의 **0.99.0 혹은 그 이상** 버전을 사용하고 있다면, 이 세부 사항을 **스킵**해도 상관 없을 것입니다. + + 세부 사항은 OpenAPI 3.1.0이 사용가능하기 전, 예전 버전과 더 관련있습니다. + + 간략한 OpenAPI와 JSON 스키마 **역사 강의**로 생각할 수 있습니다. 🤓 + +!!! warning "경고" + 표준 **JSON 스키마**와 **OpenAPI**에 대한 아주 기술적인 세부사항입니다. + + 만약 위의 생각이 작동한다면, 그것으로 충분하며 이 세부 사항은 필요없을 것이니, 마음 편하게 스킵하셔도 됩니다. + +OpenAPI 3.1.0 전에 OpenAPI는 오래된 **JSON 스키마**의 수정된 버전을 사용했습니다. + +JSON 스키마는 `examples`를 가지고 있지 않았고, 따라서 OpenAPI는 그들만의 `example` 필드를 수정된 버전에 추가했습니다. + +OpenAPI는 또한 `example`과 `examples` 필드를 명세서의 다른 부분에 추가했습니다: + +* `(명세서에 있는) Parameter Object`는 FastAPI의 다음 기능에서 쓰였습니다: + * `Path()` + * `Query()` + * `Header()` + * `Cookie()` +* (명세서에 있는)`Media Type Object`속 `content`에 있는 `Request Body Object`는 FastAPI의 다음 기능에서 쓰였습니다: + * `Body()` + * `File()` + * `Form()` + +!!! info "정보" + 이 예전 OpenAPI-특화 `examples` 매개변수는 이제 FastAPI `0.103.0`부터 `openapi_examples`입니다. + +### JSON 스키마의 `examples` 필드 + +하지만, 후에 JSON 스키마는 `examples`필드를 명세서의 새 버전에 추가했습니다. + +그리고 새로운 OpenAPI 3.1.0은 이 새로운 `examples` 필드가 포함된 최신 버전 (JSON 스키마 2020-12)을 기반으로 했습니다. + +이제 새로운 `examples` 필드는 이전의 단일 (그리고 커스텀) `example` 필드보다 우선되며, `example`은 사용하지 않는 것이 좋습니다. + +JSON 스키마의 새로운 `examples` 필드는 예제 속 **단순한 `list`**이며, (위에서 상술한 것처럼) OpenAPI의 다른 곳에 존재하는 dict으로 된 추가적인 메타데이터가 아닙니다. + +!!! info "정보" + 더 쉽고 새로운 JSON 스키마와의 통합과 함께 OpenAPI 3.1.0가 배포되었지만, 잠시동안 자동 문서 생성을 제공하는 도구인 Swagger UI는 OpenAPI 3.1.0을 지원하지 않았습니다 (5.0.0 버전부터 지원합니다 🎉). + + 이로인해, FastAPI 0.99.0 이전 버전은 아직 OpenAPI 3.1.0 보다 낮은 버전을 사용했습니다. + +### Pydantic과 FastAPI `examples` + +`examples`를 Pydantic 모델 속에 추가할 때, `schema_extra` 혹은 `Field(examples=["something"])`를 사용하면 Pydantic 모델의 **JSON 스키마**에 해당 예시가 추가됩니다. + +그리고 Pydantic 모델의 **JSON 스키마**는 API의 **OpenAPI**에 포함되고, 그 후 문서 UI 속에서 사용됩니다. + +FastAPI 0.99.0 이전 버전에서 (0.99.0 이상 버전은 새로운 OpenAPI 3.1.0을 사용합니다), `example` 혹은 `examples`를 다른 유틸리티(`Query()`, `Body()` 등)와 함께 사용했을 때, 저러한 예시는 데이터를 설명하는 JSON 스키마에 추가되지 않으며 (심지어 OpenAPI의 자체 JSON 스키마에도 포함되지 않습니다), OpenAPI의 *경로 작동* 선언에 직접적으로 추가됩니다 (JSON 스키마를 사용하는 OpenAPI 부분 외에도). + +하지만 지금은 FastAPI 0.99.0 및 이후 버전에서는 JSON 스키마 2020-12를 사용하는 OpenAPI 3.1.0과 Swagger UI 5.0.0 및 이후 버전을 사용하며, 모든 것이 더 일관성을 띄고 예시는 JSON 스키마에 포함됩니다. + +### Swagger UI와 OpenAPI-특화 `examples` + +현재 (2023-08-26), Swagger UI가 다중 JSON 스키마 예시를 지원하지 않으며, 사용자는 다중 예시를 문서에 표시하는 방법이 없었습니다. + +이를 해결하기 위해, FastAPI `0.103.0`은 새로운 매개변수인 `openapi_examples`를 포함하는 예전 **OpenAPI-특화** `examples` 필드를 선언하기 위한 **지원을 추가**했습니다. 🤓 + +### 요약 + +저는 역사를 그다지 좋아하는 편이 아니라고 말하고는 했지만... "기술 역사" 강의를 가르치는 지금의 저를 보세요. + +요약하자면 **FastAPI 0.99.0 혹은 그 이상의 버전**으로 업그레이드하는 것은 많은 것들이 더 **쉽고, 일관적이며 직관적이게** 되며, 여러분은 이 모든 역사적 세부 사항을 알 필요가 없습니다. 😎 From 9f4db6d6d39f13cd80f2833ecf31ea5b17c43e07 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 12:36:07 +0000 Subject: [PATCH 33/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 0e66f5ca4..0ee96b453 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Korean translation for `/docs/ko/docs/tutorial/schema-extra-example.md`. PR [#11121](https://github.com/tiangolo/fastapi/pull/11121) by [@KaniKim](https://github.com/KaniKim). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/body-fields.md`. PR [#11112](https://github.com/tiangolo/fastapi/pull/11112) by [@KaniKim](https://github.com/KaniKim). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/cookie-params.md`. PR [#11118](https://github.com/tiangolo/fastapi/pull/11118) by [@riroan](https://github.com/riroan). * 🌐 Update Korean translation for `/docs/ko/docs/dependencies/index.md`. PR [#11114](https://github.com/tiangolo/fastapi/pull/11114) by [@KaniKim](https://github.com/KaniKim). From c0df02355746b232fda33506161458bdfe233a7b Mon Sep 17 00:00:00 2001 From: Kani Kim Date: Sun, 11 Feb 2024 22:48:31 +0900 Subject: [PATCH 34/70] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20minor=20typos?= =?UTF-8?q?=20in=20`docs/ko/docs/`=20(#11126)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/tutorial/background-tasks.md | 12 ++++++------ docs/ko/docs/tutorial/body-fields.md | 2 +- docs/ko/docs/tutorial/body-multiple-params.md | 6 +++--- .../dependencies/classes-as-dependencies.md | 4 ++-- docs/ko/docs/tutorial/dependencies/index.md | 2 +- docs/ko/docs/tutorial/first-steps.md | 2 +- .../tutorial/path-operation-configuration.md | 2 +- .../tutorial/query-params-str-validations.md | 2 +- docs/ko/docs/tutorial/request-files.md | 2 +- .../docs/tutorial/request-forms-and-files.md | 2 +- docs/ko/docs/tutorial/response-model.md | 18 +++++++++--------- .../docs/tutorial/security/get-current-user.md | 2 +- 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/ko/docs/tutorial/background-tasks.md b/docs/ko/docs/tutorial/background-tasks.md index a951ead16..ee83d6570 100644 --- a/docs/ko/docs/tutorial/background-tasks.md +++ b/docs/ko/docs/tutorial/background-tasks.md @@ -13,7 +13,7 @@ FastAPI에서는 응답을 반환한 후에 실행할 백그라운드 작업을 ## `백그라운드 작업` 사용 -먼저 아래와 같이 `BackgroundTasks`를 임포트하고, `BackgroundTasks`를 _경로 동작 함수_ 에서 매개변수로 가져오고 정의합니다. +먼저 아래와 같이 `BackgroundTasks`를 임포트하고, `BackgroundTasks`를 _경로 작동 함수_ 에서 매개변수로 가져오고 정의합니다. ```Python hl_lines="1 13" {!../../../docs_src/background_tasks/tutorial001.py!} @@ -39,7 +39,7 @@ FastAPI에서는 응답을 반환한 후에 실행할 백그라운드 작업을 ## 백그라운드 작업 추가 -_경로 동작 함수_ 내에서 작업 함수를 `.add_task()` 함수 통해 _백그라운드 작업_ 개체에 전달합니다. +_경로 작동 함수_ 내에서 작업 함수를 `.add_task()` 함수 통해 _백그라운드 작업_ 개체에 전달합니다. ```Python hl_lines="14" {!../../../docs_src/background_tasks/tutorial001.py!} @@ -53,7 +53,7 @@ _경로 동작 함수_ 내에서 작업 함수를 `.add_task()` 함수 통해 _ ## 의존성 주입 -`BackgroundTasks`를 의존성 주입 시스템과 함께 사용하면 _경로 동작 함수_, 종속성, 하위 종속성 등 여러 수준에서 BackgroundTasks 유형의 매개변수를 선언할 수 있습니다. +`BackgroundTasks`를 의존성 주입 시스템과 함께 사용하면 _경로 작동 함수_, 종속성, 하위 종속성 등 여러 수준에서 BackgroundTasks 유형의 매개변수를 선언할 수 있습니다. **FastAPI**는 각 경우에 수행할 작업과 동일한 개체를 내부적으로 재사용하기에, 모든 백그라운드 작업이 함께 병합되고 나중에 백그라운드에서 실행됩니다. @@ -73,7 +73,7 @@ _경로 동작 함수_ 내에서 작업 함수를 `.add_task()` 함수 통해 _ 요청에 쿼리가 있는 경우 백그라운드 작업의 로그에 기록됩니다. -그리고 _경로 동작 함수_ 에서 생성된 또 다른 백그라운드 작업은 경로 매개 변수를 활용하여 사용하여 메시지를 작성합니다. +그리고 _경로 작동 함수_ 에서 생성된 또 다른 백그라운드 작업은 경로 매개 변수를 활용하여 사용하여 메시지를 작성합니다. ## 기술적 세부사항 @@ -81,7 +81,7 @@ _경로 동작 함수_ 내에서 작업 함수를 `.add_task()` 함수 통해 _ `BackgroundTasks` 클래스는 FastAPI에서 직접 임포트하거나 포함하기 때문에 실수로 `BackgroundTask` (끝에 `s`가 없음)을 임포트하더라도 starlette.background에서 `BackgroundTask`를 가져오는 것을 방지할 수 있습니다. -(`BackgroundTask`가 아닌) `BackgroundTasks`를 사용하면, _경로 동작 함수_ 매개변수로 사용할 수 있게 되고 나머지는 **FastAPI**가 대신 처리하도록 할 수 있습니다. 이것은 `Request` 객체를 직접 사용하는 것과 같은 방식입니다. +(`BackgroundTask`가 아닌) `BackgroundTasks`를 사용하면, _경로 작동 함수_ 매개변수로 사용할 수 있게 되고 나머지는 **FastAPI**가 대신 처리하도록 할 수 있습니다. 이것은 `Request` 객체를 직접 사용하는 것과 같은 방식입니다. FastAPI에서 `BackgroundTask`를 단독으로 사용하는 것은 여전히 가능합니다. 하지만 객체를 코드에서 생성하고, 이 객체를 포함하는 Starlette `Response`를 반환해야 합니다. @@ -99,4 +99,4 @@ RabbitMQ 또는 Redis와 같은 메시지/작업 큐 시스템 보다 복잡한 ## 요약 -백그라운드 작업을 추가하기 위해 _경로 동작 함수_ 에 매개변수로 `BackgroundTasks`를 가져오고 사용합니다. +백그라운드 작업을 추가하기 위해 _경로 작동 함수_ 에 매개변수로 `BackgroundTasks`를 가져오고 사용합니다. diff --git a/docs/ko/docs/tutorial/body-fields.md b/docs/ko/docs/tutorial/body-fields.md index a739756bd..fc7209726 100644 --- a/docs/ko/docs/tutorial/body-fields.md +++ b/docs/ko/docs/tutorial/body-fields.md @@ -1,6 +1,6 @@ # 본문 - 필드 -`Query`, `Path`와 `Body`를 사용해 *경로 동작 함수* 매개변수 내에서 추가적인 검증이나 메타데이터를 선언한 것처럼 Pydantic의 `Field`를 사용하여 모델 내에서 검증과 메타데이터를 선언할 수 있습니다. +`Query`, `Path`와 `Body`를 사용해 *경로 작동 함수* 매개변수 내에서 추가적인 검증이나 메타데이터를 선언한 것처럼 Pydantic의 `Field`를 사용하여 모델 내에서 검증과 메타데이터를 선언할 수 있습니다. ## `Field` 임포트 diff --git a/docs/ko/docs/tutorial/body-multiple-params.md b/docs/ko/docs/tutorial/body-multiple-params.md index 034c2e84c..2cf5df7f3 100644 --- a/docs/ko/docs/tutorial/body-multiple-params.md +++ b/docs/ko/docs/tutorial/body-multiple-params.md @@ -19,7 +19,7 @@ ## 다중 본문 매개변수 -이전 예제에서 보듯이, *경로 동작*은 아래와 같이 `Item` 속성을 가진 JSON 본문을 예상합니다: +이전 예제에서 보듯이, *경로 작동*은 아래와 같이 `Item` 속성을 가진 JSON 본문을 예상합니다: ```JSON { @@ -161,9 +161,9 @@ item: Item = Body(..., embed=True) ## 정리 -요청이 단 한개의 본문을 가지고 있더라도, *경로 동작 함수*로 다중 본문 매개변수를 추가할 수 있습니다. +요청이 단 한개의 본문을 가지고 있더라도, *경로 작동 함수*로 다중 본문 매개변수를 추가할 수 있습니다. -하지만, **FastAPI**는 이를 처리하고, 함수에 올바른 데이터를 제공하며, *경로 동작*으로 올바른 스키마를 검증하고 문서화 합니다. +하지만, **FastAPI**는 이를 처리하고, 함수에 올바른 데이터를 제공하며, *경로 작동*으로 올바른 스키마를 검증하고 문서화 합니다. 또한, 단일 값을 본문의 일부로 받도록 선언할 수 있습니다. diff --git a/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md index bbf3a8283..38cdc2e1a 100644 --- a/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md @@ -71,9 +71,9 @@ fluffy = Cat(name="Mr Fluffy") FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래스 또는 다른 모든 것)과 정의된 매개변수들입니다. -"호출 가능"한 것을 의존성으로서 **FastAPI**에 전달하면, 그 "호출 가능"한 것의 매개변수들을 분석한 후 이를 *경로 동작 함수*를 위한 매개변수와 동일한 방식으로 처리합니다. 하위-의존성 또한 같은 방식으로 처리합니다. +"호출 가능"한 것을 의존성으로서 **FastAPI**에 전달하면, 그 "호출 가능"한 것의 매개변수들을 분석한 후 이를 *경로 작동 함수*를 위한 매개변수와 동일한 방식으로 처리합니다. 하위-의존성 또한 같은 방식으로 처리합니다. -매개변수가 없는 "호출 가능"한 것 역시 매개변수가 없는 *경로 동작 함수*와 동일한 방식으로 적용됩니다. +매개변수가 없는 "호출 가능"한 것 역시 매개변수가 없는 *경로 작동 함수*와 동일한 방식으로 적용됩니다. 그래서, 우리는 위 예제에서의 `common_paramenters` 의존성을 클래스 `CommonQueryParams`로 바꿀 수 있습니다. diff --git a/docs/ko/docs/tutorial/dependencies/index.md b/docs/ko/docs/tutorial/dependencies/index.md index cde88eb6c..c56dddae3 100644 --- a/docs/ko/docs/tutorial/dependencies/index.md +++ b/docs/ko/docs/tutorial/dependencies/index.md @@ -6,7 +6,7 @@ ## "의존성 주입"은 무엇입니까? -**"의존성 주입"**은 프로그래밍에서 여러분의 코드(이 경우, 경로 동작 함수)가 작동하고 사용하는 데 필요로 하는 것, 즉 "의존성"을 선언할 수 있는 방법을 의미합니다. +**"의존성 주입"**은 프로그래밍에서 여러분의 코드(이 경우, 경로 작동 함수)가 작동하고 사용하는 데 필요로 하는 것, 즉 "의존성"을 선언할 수 있는 방법을 의미합니다. 그 후에, 시스템(이 경우 FastAPI)은 여러분의 코드가 요구하는 의존성을 제공하기 위해 필요한 모든 작업을 처리합니다.(의존성을 "주입"합니다) diff --git a/docs/ko/docs/tutorial/first-steps.md b/docs/ko/docs/tutorial/first-steps.md index 0eb4d6bd5..e3b42bce7 100644 --- a/docs/ko/docs/tutorial/first-steps.md +++ b/docs/ko/docs/tutorial/first-steps.md @@ -309,7 +309,7 @@ URL "`/`"에 대한 `GET` 작동을 사용하는 요청을 받을 때마다 **Fa {!../../../docs_src/first_steps/tutorial003.py!} ``` -!!! note 참고 +!!! note "참고" 차이점을 모르겠다면 [Async: *"In a hurry?"*](../async.md#in-a-hurry){.internal-link target=_blank}을 확인하세요. ### 5 단계: 콘텐츠 반환 diff --git a/docs/ko/docs/tutorial/path-operation-configuration.md b/docs/ko/docs/tutorial/path-operation-configuration.md index 22aad0421..411c43493 100644 --- a/docs/ko/docs/tutorial/path-operation-configuration.md +++ b/docs/ko/docs/tutorial/path-operation-configuration.md @@ -1,4 +1,4 @@ -# 경로 동작 설정 +# 경로 작동 설정 *경로 작동 데코레이터*를 설정하기 위해서 전달할수 있는 몇 가지 매개변수가 있습니다. diff --git a/docs/ko/docs/tutorial/query-params-str-validations.md b/docs/ko/docs/tutorial/query-params-str-validations.md index 7ae100dcc..2e6396ccc 100644 --- a/docs/ko/docs/tutorial/query-params-str-validations.md +++ b/docs/ko/docs/tutorial/query-params-str-validations.md @@ -74,7 +74,7 @@ q: Optional[str] = None q: str = Query(None, max_length=50) ``` -이는 데이터를 검증할 것이고, 데이터가 유효하지 않다면 명백한 오류를 보여주며, OpenAPI 스키마 *경로 동작*에 매개변수를 문서화 합니다. +이는 데이터를 검증할 것이고, 데이터가 유효하지 않다면 명백한 오류를 보여주며, OpenAPI 스키마 *경로 작동*에 매개변수를 문서화 합니다. ## 검증 추가 diff --git a/docs/ko/docs/tutorial/request-files.md b/docs/ko/docs/tutorial/request-files.md index decefe981..03a6d593a 100644 --- a/docs/ko/docs/tutorial/request-files.md +++ b/docs/ko/docs/tutorial/request-files.md @@ -108,7 +108,7 @@ HTML의 폼들(`
`)이 서버에 데이터를 전송하는 방식은 인코딩과 폼 필드에 대해 더 알고싶다면, POST에 관한MDN웹 문서 를 참고하기 바랍니다,. -!!! warning "주의" +!!! warning "경고" 다수의 `File` 과 `Form` 매개변수를 한 *경로 작동*에 선언하는 것이 가능하지만, 요청의 본문이 `application/json` 가 아닌 `multipart/form-data` 로 인코딩 되기 때문에 JSON으로 받아야하는 `Body` 필드를 함께 선언할 수는 없습니다. 이는 **FastAPI**의 한계가 아니라, HTTP 프로토콜에 의한 것입니다. diff --git a/docs/ko/docs/tutorial/request-forms-and-files.md b/docs/ko/docs/tutorial/request-forms-and-files.md index ddf232e7f..fdf8dbad0 100644 --- a/docs/ko/docs/tutorial/request-forms-and-files.md +++ b/docs/ko/docs/tutorial/request-forms-and-files.md @@ -25,7 +25,7 @@ 어떤 파일들은 `bytes`로, 또 어떤 파일들은 `UploadFile`로 선언할 수 있습니다. -!!! warning "주의" +!!! warning "경고" 다수의 `File`과 `Form` 매개변수를 한 *경로 작동*에 선언하는 것이 가능하지만, 요청의 본문이 `application/json`가 아닌 `multipart/form-data`로 인코딩 되기 때문에 JSON으로 받아야하는 `Body` 필드를 함께 선언할 수는 없습니다. 이는 **FastAPI**의 한계가 아니라, HTTP 프로토콜에 의한 것입니다. diff --git a/docs/ko/docs/tutorial/response-model.md b/docs/ko/docs/tutorial/response-model.md index fa90c10ae..0c9d5c16e 100644 --- a/docs/ko/docs/tutorial/response-model.md +++ b/docs/ko/docs/tutorial/response-model.md @@ -1,6 +1,6 @@ # 응답 모델 -어떤 *경로 동작*이든 매개변수 `response_model`를 사용하여 응답을 위한 모델을 선언할 수 있습니다: +어떤 *경로 작동*이든 매개변수 `response_model`를 사용하여 응답을 위한 모델을 선언할 수 있습니다: * `@app.get()` * `@app.post()` @@ -13,7 +13,7 @@ ``` !!! note "참고" - `response_model`은 "데코레이터" 메소드(`get`, `post`, 등)의 매개변수입니다. 모든 매개변수들과 본문(body)처럼 *경로 동작 함수*가 아닙니다. + `response_model`은 "데코레이터" 메소드(`get`, `post`, 등)의 매개변수입니다. 모든 매개변수들과 본문(body)처럼 *경로 작동 함수*가 아닙니다. Pydantic 모델 어트리뷰트를 선언한 것과 동일한 타입을 수신하므로 Pydantic 모델이 될 수 있지만, `List[Item]`과 같이 Pydantic 모델들의 `list`일 수도 있습니다. @@ -21,7 +21,7 @@ FastAPI는 이 `response_model`를 사용하여: * 출력 데이터를 타입 선언으로 변환. * 데이터 검증. -* OpenAPI *경로 동작*의 응답에 JSON 스키마 추가. +* OpenAPI *경로 작동*의 응답에 JSON 스키마 추가. * 자동 생성 문서 시스템에 사용. 하지만 가장 중요한 것은: @@ -49,7 +49,7 @@ FastAPI는 이 `response_model`를 사용하여: 이 경우, 사용자가 스스로 비밀번호를 발신했기 때문에 문제가 되지 않을 수 있습니다. -그러나 동일한 모델을 다른 *경로 동작*에서 사용할 경우, 모든 클라이언트에게 사용자의 비밀번호를 발신할 수 있습니다. +그러나 동일한 모델을 다른 *경로 작동*에서 사용할 경우, 모든 클라이언트에게 사용자의 비밀번호를 발신할 수 있습니다. !!! danger "위험" 절대로 사용자의 평문 비밀번호를 저장하거나 응답으로 발신하지 마십시오. @@ -62,7 +62,7 @@ FastAPI는 이 `response_model`를 사용하여: {!../../../docs_src/response_model/tutorial003.py!} ``` -여기서 *경로 동작 함수*가 비밀번호를 포함하는 동일한 입력 사용자를 반환할지라도: +여기서 *경로 작동 함수*가 비밀번호를 포함하는 동일한 입력 사용자를 반환할지라도: ```Python hl_lines="24" {!../../../docs_src/response_model/tutorial003.py!} @@ -104,7 +104,7 @@ FastAPI는 이 `response_model`를 사용하여: ### `response_model_exclude_unset` 매개변수 사용 -*경로 동작 데코레이터* 매개변수를 `response_model_exclude_unset=True`로 설정 할 수 있습니다: +*경로 작동 데코레이터* 매개변수를 `response_model_exclude_unset=True`로 설정 할 수 있습니다: ```Python hl_lines="24" {!../../../docs_src/response_model/tutorial004.py!} @@ -112,7 +112,7 @@ FastAPI는 이 `response_model`를 사용하여: 이러한 기본값은 응답에 포함되지 않고 실제로 설정된 값만 포함됩니다. -따라서 해당 *경로 동작*에 ID가 `foo`인 항목(items)을 요청으로 보내면 (기본값을 제외한) 응답은 다음과 같습니다: +따라서 해당 *경로 작동*에 ID가 `foo`인 항목(items)을 요청으로 보내면 (기본값을 제외한) 응답은 다음과 같습니다: ```JSON { @@ -173,7 +173,7 @@ ID가 `baz`인 항목(items)처럼 기본값과 동일한 값을 갖는다면: ### `response_model_include` 및 `response_model_exclude` -*경로 동작 데코레이터* 매개변수 `response_model_include` 및 `response_model_exclude`를 사용할 수 있습니다. +*경로 작동 데코레이터* 매개변수 `response_model_include` 및 `response_model_exclude`를 사용할 수 있습니다. 이들은 포함(나머지 생략)하거나 제외(나머지 포함) 할 어트리뷰트의 이름과 `str`의 `set`을 받습니다. @@ -205,6 +205,6 @@ Pydantic 모델이 하나만 있고 출력에서 ​​일부 데이터를 제 ## 요약 -응답 모델을 정의하고 개인정보가 필터되는 것을 보장하기 위해 *경로 동작 데코레이터*의 매개변수 `response_model`을 사용하세요. +응답 모델을 정의하고 개인정보가 필터되는 것을 보장하기 위해 *경로 작동 데코레이터*의 매개변수 `response_model`을 사용하세요. 명시적으로 설정된 값만 반환하려면 `response_model_exclude_unset`을 사용하세요. diff --git a/docs/ko/docs/tutorial/security/get-current-user.md b/docs/ko/docs/tutorial/security/get-current-user.md index ce944b16d..5bc2cee7a 100644 --- a/docs/ko/docs/tutorial/security/get-current-user.md +++ b/docs/ko/docs/tutorial/security/get-current-user.md @@ -36,7 +36,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다 `get_current_user`는 이전에 생성한 것과 동일한 `oauth2_scheme`과 종속성을 갖게 됩니다. -이전에 *경로 동작*에서 직접 수행했던 것과 동일하게 새 종속성 `get_current_user`는 하위 종속성 `oauth2_scheme`에서 `str`로 `token`을 수신합니다. +이전에 *경로 작동*에서 직접 수행했던 것과 동일하게 새 종속성 `get_current_user`는 하위 종속성 `oauth2_scheme`에서 `str`로 `token`을 수신합니다. === "파이썬 3.7 이상" From 44c4cdd73b77d3ca8e45f381f7201bcd6d627986 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 11 Feb 2024 13:48:54 +0000 Subject: [PATCH 35/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 0ee96b453..8536742c5 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,6 +9,7 @@ hide: ### Docs +* ✏️ Fix minor typos in `docs/ko/docs/`. PR [#11126](https://github.com/tiangolo/fastapi/pull/11126) by [@KaniKim](https://github.com/KaniKim). * ✏️ Fix minor typo in `fastapi/applications.py`. PR [#11099](https://github.com/tiangolo/fastapi/pull/11099) by [@JacobHayes](https://github.com/JacobHayes). ### Translations From b1fa0f262e6bdf683a99d6ae7ccafef5448a2b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AA=85=EA=B8=B0?= Date: Sun, 11 Feb 2024 22:49:45 +0900 Subject: [PATCH 36/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Korean=20translation?= =?UTF-8?q?=20for=20`/docs/ko/docs/tutorial/dependencies/dependencies-in-p?= =?UTF-8?q?ath-operation-decorators.md`=20(#11124)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...pendencies-in-path-operation-decorators.md | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md diff --git a/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md new file mode 100644 index 000000000..92b2c7d1c --- /dev/null +++ b/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md @@ -0,0 +1,139 @@ +# 경로 작동 데코레이터에서의 의존성 + +몇몇 경우에는, *경로 작동 함수* 안에서 의존성의 반환 값이 필요하지 않습니다. + +또는 의존성이 값을 반환하지 않습니다. + +그러나 여전히 실행/해결될 필요가 있습니다. + +그런 경우에, `Depends`를 사용하여 *경로 작동 함수*의 매개변수로 선언하는 것보다 *경로 작동 데코레이터*에 `dependencies`의 `list`를 추가할 수 있습니다. + +## *경로 작동 데코레이터*에 `dependencies` 추가하기 + +*경로 작동 데코레이터*는 `dependencies`라는 선택적인 인자를 받습니다. + +`Depends()`로 된 `list`이어야합니다: + +=== "Python 3.9+" + + ```Python hl_lines="19" + {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="18" + {!> ../../../docs_src/dependencies/tutorial006_an.py!} + ``` + +=== "Python 3.8 Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="17" + {!> ../../../docs_src/dependencies/tutorial006.py!} + ``` + +이러한 의존성들은 기존 의존성들과 같은 방식으로 실행/해결됩니다. 그러나 값은 (무엇이든 반환한다면) *경로 작동 함수*에 제공되지 않습니다. + +!!! tip "팁" + 일부 편집기에서는 사용되지 않는 함수 매개변수를 검사하고 오류로 표시합니다. + + *경로 작동 데코레이터*에서 `dependencies`를 사용하면 편집기/도구 오류를 피하며 실행되도록 할 수 있습니다. + + 또한 코드에서 사용되지 않는 매개변수를 보고 불필요하다고 생각할 수 있는 새로운 개발자의 혼란을 방지하는데 도움이 될 수 있습니다. + +!!! info "정보" + 이 예시에서 `X-Key`와 `X-Token`이라는 커스텀 헤더를 만들어 사용했습니다. + + 그러나 실제로 보안을 구현할 때는 통합된 [보안 유틸리티 (다음 챕터)](../security/index.md){.internal-link target=_blank}를 사용하는 것이 더 많은 이점을 얻을 수 있습니다. + +## 의존성 오류와 값 반환하기 + +평소에 사용하던대로 같은 의존성 *함수*를 사용할 수 있습니다. + +### 의존성 요구사항 + +(헤더같은) 요청 요구사항이나 하위-의존성을 선언할 수 있습니다: + +=== "Python 3.9+" + + ```Python hl_lines="8 13" + {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="7 12" + {!> ../../../docs_src/dependencies/tutorial006_an.py!} + ``` + +=== "Python 3.8 Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="6 11" + {!> ../../../docs_src/dependencies/tutorial006.py!} + ``` + +### 오류 발생시키기 + +다음 의존성은 기존 의존성과 동일하게 예외를 `raise`를 일으킬 수 있습니다: + +=== "Python 3.9+" + + ```Python hl_lines="10 15" + {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="9 14" + {!> ../../../docs_src/dependencies/tutorial006_an.py!} + ``` + +=== "Python 3.8 Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="8 13" + {!> ../../../docs_src/dependencies/tutorial006.py!} + ``` + +### 값 반환하기 + +값을 반환하거나, 그러지 않을 수 있으며 값은 사용되지 않습니다. + +그래서 이미 다른 곳에서 사용된 (값을 반환하는) 일반적인 의존성을 재사용할 수 있고, 비록 값은 사용되지 않지만 의존성은 실행될 것입니다: + +=== "Python 3.9+" + + ```Python hl_lines="11 16" + {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="10 15" + {!> ../../../docs_src/dependencies/tutorial006_an.py!} + ``` + +=== "Python 3.8 Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="9 14" + {!> ../../../docs_src/dependencies/tutorial006.py!} + ``` + +## *경로 작동* 모음에 대한 의존성 + +나중에 여러 파일을 가지고 있을 수 있는 더 큰 애플리케이션을 구조화하는 법([더 큰 애플리케이션 - 여러 파일들](../../tutorial/bigger-applications.md){.internal-link target=_blank})을 읽을 때, *경로 작동* 모음에 대한 단일 `dependencies` 매개변수를 선언하는 법에 대해서 배우게 될 것입니다. + +## 전역 의존성 + +다음으로 각 *경로 작동*에 적용되도록 `FastAPI` 애플리케이션 전체에 의존성을 추가하는 법을 볼 것입니다. From a315048357dc6412348fa5a52f62ed46db90bd53 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 11 Feb 2024 13:52:06 +0000 Subject: [PATCH 37/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 8536742c5..9c3c309e8 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#11124](https://github.com/tiangolo/fastapi/pull/11124) by [@riroan](https://github.com/riroan). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/schema-extra-example.md`. PR [#11121](https://github.com/tiangolo/fastapi/pull/11121) by [@KaniKim](https://github.com/KaniKim). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/body-fields.md`. PR [#11112](https://github.com/tiangolo/fastapi/pull/11112) by [@KaniKim](https://github.com/KaniKim). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/cookie-params.md`. PR [#11118](https://github.com/tiangolo/fastapi/pull/11118) by [@riroan](https://github.com/riroan). From b8941c31eaf251e5e13cabaf998d7080bba3461b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AA=85=EA=B8=B0?= Date: Thu, 15 Feb 2024 00:05:47 +0900 Subject: [PATCH 38/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Korean=20translation?= =?UTF-8?q?=20for=20`/docs/ko/docs/tutorial/dependencies/global-dependenci?= =?UTF-8?q?es.md`=20(#11123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dependencies/global-dependencies.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs/ko/docs/tutorial/dependencies/global-dependencies.md diff --git a/docs/ko/docs/tutorial/dependencies/global-dependencies.md b/docs/ko/docs/tutorial/dependencies/global-dependencies.md new file mode 100644 index 000000000..930f6e678 --- /dev/null +++ b/docs/ko/docs/tutorial/dependencies/global-dependencies.md @@ -0,0 +1,34 @@ +# 전역 의존성 + +몇몇 애플리케이션에서는 애플리케이션 전체에 의존성을 추가하고 싶을 수 있습니다. + +[*경로 작동 데코레이터*에 `dependencies` 추가하기](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}와 유사한 방법으로 `FastAPI` 애플리케이션에 그것들을 추가할 수 있습니다. + +그런 경우에, 애플리케이션의 모든 *경로 작동*에 적용될 것입니다: + +=== "Python 3.9+" + + ```Python hl_lines="16" + {!> ../../../docs_src/dependencies/tutorial012_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="16" + {!> ../../../docs_src/dependencies/tutorial012_an.py!} + ``` + +=== "Python 3.8 Annotated가 없는 경우" + + !!! tip "팁" + 가능하다면 `Annotated`가 달린 버전을 권장합니다. + + ```Python hl_lines="15" + {!> ../../../docs_src/dependencies/tutorial012.py!} + ``` + +그리고 [*경로 작동 데코레이터*에 `dependencies` 추가하기](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}에 대한 아이디어는 여전히 적용되지만 여기에서는 앱에 있는 모든 *경로 작동*에 적용됩니다. + +## *경로 작동* 모음에 대한 의존성 + +이후에 여러 파일들을 가지는 더 큰 애플리케이션을 구조화하는 법([더 큰 애플리케이션 - 여러 파일들](../../tutorial/bigger-applications.md){.internal-link target=_blank})을 읽을 때, *경로 작동* 모음에 대한 단일 `dependencies` 매개변수를 선언하는 법에 대해서 배우게 될 것입니다. From 8ad6acfe6aeb7afb25218abbc65c1a97df072a8b Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 14 Feb 2024 15:06:07 +0000 Subject: [PATCH 39/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 9c3c309e8..920ae414d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/global-dependencies.md`. PR [#11123](https://github.com/tiangolo/fastapi/pull/11123) by [@riroan](https://github.com/riroan). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#11124](https://github.com/tiangolo/fastapi/pull/11124) by [@riroan](https://github.com/riroan). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/schema-extra-example.md`. PR [#11121](https://github.com/tiangolo/fastapi/pull/11121) by [@KaniKim](https://github.com/KaniKim). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/body-fields.md`. PR [#11112](https://github.com/tiangolo/fastapi/pull/11112) by [@KaniKim](https://github.com/KaniKim). From 33f6026c6cdeb91ea17f7448962bc3bdadff3a59 Mon Sep 17 00:00:00 2001 From: Max Su Date: Fri, 16 Feb 2024 20:06:22 +0800 Subject: [PATCH 40/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Traditional=20Chines?= =?UTF-8?q?e=20translation=20for=20`docs/zh-hant/docs/learn/index.md`=20(#?= =?UTF-8?q?11142)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-hant/docs/learn/index.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/zh-hant/docs/learn/index.md diff --git a/docs/zh-hant/docs/learn/index.md b/docs/zh-hant/docs/learn/index.md new file mode 100644 index 000000000..eb7d7096a --- /dev/null +++ b/docs/zh-hant/docs/learn/index.md @@ -0,0 +1,5 @@ +# 學習 + +以下是學習 FastAPI 的入門介紹和教學。 + +你可以將其視為一本**書籍**或一門**課程**,這是**官方**認可並推薦的 FastAPI 學習方式。 😎 From be876902554a0bd886167de144f0d593ed2e6ad7 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 16 Feb 2024 12:06:46 +0000 Subject: [PATCH 41/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 920ae414d..6a366b06c 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/learn/index.md`. PR [#11142](https://github.com/tiangolo/fastapi/pull/11142) by [@hsuanchi](https://github.com/hsuanchi). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/global-dependencies.md`. PR [#11123](https://github.com/tiangolo/fastapi/pull/11123) by [@riroan](https://github.com/riroan). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#11124](https://github.com/tiangolo/fastapi/pull/11124) by [@riroan](https://github.com/riroan). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/schema-extra-example.md`. PR [#11121](https://github.com/tiangolo/fastapi/pull/11121) by [@KaniKim](https://github.com/KaniKim). From ec464f0938a7c623d3acad1eb8ca0b069cf799d2 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Sun, 18 Feb 2024 13:18:33 +0100 Subject: [PATCH 42/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/newsletter.md`=20(#10853)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/newsletter.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/de/docs/newsletter.md diff --git a/docs/de/docs/newsletter.md b/docs/de/docs/newsletter.md new file mode 100644 index 000000000..31995b164 --- /dev/null +++ b/docs/de/docs/newsletter.md @@ -0,0 +1,5 @@ +# FastAPI und Freunde Newsletter + + + + From 122713b168f0538eba33f0ad4a921e9409ff5055 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 18 Feb 2024 12:18:59 +0000 Subject: [PATCH 43/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 6a366b06c..5ee0017a2 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/newsletter.md`. PR [#10853](https://github.com/tiangolo/fastapi/pull/10853) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/learn/index.md`. PR [#11142](https://github.com/tiangolo/fastapi/pull/11142) by [@hsuanchi](https://github.com/hsuanchi). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/global-dependencies.md`. PR [#11123](https://github.com/tiangolo/fastapi/pull/11123) by [@riroan](https://github.com/riroan). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#11124](https://github.com/tiangolo/fastapi/pull/11124) by [@riroan](https://github.com/riroan). From 73ca60c273977e98a7632871653e3c0ad3dad4f8 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Sun, 18 Feb 2024 13:19:32 +0100 Subject: [PATCH 44/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/reference/fastapi.md`=20(#10813)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/reference/fastapi.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 docs/de/docs/reference/fastapi.md diff --git a/docs/de/docs/reference/fastapi.md b/docs/de/docs/reference/fastapi.md new file mode 100644 index 000000000..4e6a56971 --- /dev/null +++ b/docs/de/docs/reference/fastapi.md @@ -0,0 +1,31 @@ +# `FastAPI`-Klasse + +Hier sind die Referenzinformationen für die Klasse `FastAPI` mit all ihren Parametern, Attributen und Methoden. + +Sie können die `FastAPI`-Klasse direkt von `fastapi` importieren: + +```python +from fastapi import FastAPI +``` + +::: fastapi.FastAPI + options: + members: + - openapi_version + - webhooks + - state + - dependency_overrides + - openapi + - websocket + - include_router + - get + - put + - post + - delete + - options + - head + - patch + - trace + - on_event + - middleware + - exception_handler From 7ca6f1cd1aeb3f148df22af9375069cc82f3c06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emirhan=20Soyta=C5=9F?= Date: Sun, 18 Feb 2024 15:20:41 +0300 Subject: [PATCH 45/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Turkish=20translatio?= =?UTF-8?q?n=20for=20`docs/tr/docs/tutorial/query-params.md`=20(#11078)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tr/docs/tutorial/query-params.md | 227 ++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 docs/tr/docs/tutorial/query-params.md diff --git a/docs/tr/docs/tutorial/query-params.md b/docs/tr/docs/tutorial/query-params.md new file mode 100644 index 000000000..61232d5b3 --- /dev/null +++ b/docs/tr/docs/tutorial/query-params.md @@ -0,0 +1,227 @@ +# Sorgu Parametreleri + +Fonksiyonda yol parametrelerinin parçası olmayan diğer tanımlamalar otomatik olarak "sorgu" parametresi olarak yorumlanır. + +```Python hl_lines="9" +{!../../../docs_src/query_params/tutorial001.py!} +``` + +Sorgu, bağlantıdaki `?` kısmından sonra gelen ve `&` işareti ile ayrılan anahtar-değer çiftlerinin oluşturduğu bir kümedir. + +Örneğin, aşağıdaki bağlantıda: + +``` +http://127.0.0.1:8000/items/?skip=0&limit=10 +``` + +...sorgu parametreleri şunlardır: + +* `skip`: değeri `0`'dır +* `limit`: değeri `10`'dır + +Parametreler bağlantının bir parçası oldukları için doğal olarak string olarak değerlendirilirler. + +Fakat, Python tipleri ile tanımlandıkları zaman (yukarıdaki örnekte `int` oldukları gibi), parametreler o tiplere dönüştürülür ve o tipler çerçevesinde doğrulanırlar. + +Yol parametreleri için geçerli olan her türlü işlem aynı şekilde sorgu parametreleri için de geçerlidir: + +* Editör desteği (şüphesiz) +* Veri "ayrıştırma" +* Veri doğrulama +* Otomatik dokümantasyon + +## Varsayılanlar + +Sorgu parametreleri, adres yolunun sabit bir parçası olmadıklarından dolayı isteğe bağlı ve varsayılan değere sahip olabilirler. + +Yukarıdaki örnekte `skip=0` ve `limit=10` varsayılan değere sahiplerdir. + +Yani, aşağıdaki bağlantıya gitmek: + +``` +http://127.0.0.1:8000/items/ +``` + +şu adrese gitmek ile aynı etkiye sahiptir: + +``` +http://127.0.0.1:8000/items/?skip=0&limit=10 +``` + +Ancak, mesela şöyle bir adresi ziyaret ederseniz: + +``` +http://127.0.0.1:8000/items/?skip=20 +``` + +Fonksiyonunuzdaki parametre değerleri aşağıdaki gibi olacaktır: + +* `skip=20`: çünkü bağlantıda böyle tanımlandı. +* `limit=10`: çünkü varsayılan değer buydu. + +## İsteğe Bağlı Parametreler + +Aynı şekilde, varsayılan değerlerini `None` olarak atayarak isteğe bağlı parametreler tanımlayabilirsiniz: + +=== "Python 3.10+" + + ```Python hl_lines="7" + {!> ../../../docs_src/query_params/tutorial002_py310.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="9" + {!> ../../../docs_src/query_params/tutorial002.py!} + ``` + +Bu durumda, `q` fonksiyon parametresi isteğe bağlı olacak ve varsayılan değer olarak `None` alacaktır. + +!!! check "Ek bilgi" + Ayrıca, dikkatinizi çekerim ki; **FastAPI**, `item_id` parametresinin bir yol parametresi olduğunu ve `q` parametresinin yol değil bir sorgu parametresi olduğunu fark edecek kadar beceriklidir. + +## Sorgu Parametresi Tip Dönüşümü + +Aşağıda görüldüğü gibi dönüştürülmek üzere `bool` tipleri de tanımlayabilirsiniz: + +=== "Python 3.10+" + + ```Python hl_lines="7" + {!> ../../../docs_src/query_params/tutorial003_py310.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="9" + {!> ../../../docs_src/query_params/tutorial003.py!} + ``` + +Bu durumda, eğer şu adrese giderseniz: + +``` +http://127.0.0.1:8000/items/foo?short=1 +``` + +veya + +``` +http://127.0.0.1:8000/items/foo?short=True +``` + +veya + +``` +http://127.0.0.1:8000/items/foo?short=true +``` + +veya + +``` +http://127.0.0.1:8000/items/foo?short=on +``` + +veya + +``` +http://127.0.0.1:8000/items/foo?short=yes +``` + +veya adres, herhangi farklı bir harf varyasyonu içermesi durumuna rağmen (büyük harf, sadece baş harfi büyük kelime, vb.) fonksiyonunuz, `bool` tipli `short` parametresini `True` olarak algılayacaktır. Aksi halde `False` olarak algılanacaktır. + + +## Çoklu Yol ve Sorgu Parametreleri + +**FastAPI** neyin ne olduğunu ayırt edebileceğinden dolayı aynı anda birden fazla yol ve sorgu parametresi tanımlayabilirsiniz. + +Ve parametreleri, herhangi bir sıraya koymanıza da gerek yoktur. + +İsimlerine göre belirleneceklerdir: + +=== "Python 3.10+" + + ```Python hl_lines="6 8" + {!> ../../../docs_src/query_params/tutorial004_py310.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="8 10" + {!> ../../../docs_src/query_params/tutorial004.py!} + ``` + +## Zorunlu Sorgu Parametreleri + +Türü yol olmayan bir parametre (şu ana kadar sadece sorgu parametrelerini gördük) için varsayılan değer tanımlarsanız o parametre zorunlu olmayacaktır. + +Parametre için belirli bir değer atamak istemeyip parametrenin sadece isteğe bağlı olmasını istiyorsanız değerini `None` olarak atayabilirsiniz. + +Fakat, bir sorgu parametresini zorunlu yapmak istiyorsanız varsayılan bir değer atamamanız yeterli olacaktır: + +```Python hl_lines="6-7" +{!../../../docs_src/query_params/tutorial005.py!} +``` + +Burada `needy` parametresi `str` tipinden oluşan zorunlu bir sorgu parametresidir. + +Eğer tarayıcınızda şu bağlantıyı: + +``` +http://127.0.0.1:8000/items/foo-item +``` + +...`needy` parametresini eklemeden açarsanız şuna benzer bir hata ile karşılaşırsınız: + +```JSON +{ + "detail": [ + { + "type": "missing", + "loc": [ + "query", + "needy" + ], + "msg": "Field required", + "input": null, + "url": "https://errors.pydantic.dev/2.1/v/missing" + } + ] +} +``` + +`needy` zorunlu bir parametre olduğundan dolayı bağlantıda tanımlanması gerekir: + +``` +http://127.0.0.1:8000/items/foo-item?needy=sooooneedy +``` + +...bu iş görür: + +```JSON +{ + "item_id": "foo-item", + "needy": "sooooneedy" +} +``` + +Ve elbette, bazı parametreleri zorunlu, bazılarını varsayılan değerli ve bazılarını tamamen opsiyonel olarak tanımlayabilirsiniz: + +=== "Python 3.10+" + + ```Python hl_lines="8" + {!> ../../../docs_src/query_params/tutorial006_py310.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="10" + {!> ../../../docs_src/query_params/tutorial006.py!} + ``` + +Bu durumda, 3 tane sorgu parametresi var olacaktır: + +* `needy`, zorunlu bir `str`. +* `skip`, varsayılan değeri `0` olan bir `int`. +* `limit`, isteğe bağlı bir `int`. + +!!! tip "İpucu" + Ayrıca, [Yol Parametreleri](path-params.md#predefined-values){.internal-link target=_blank}nde de kullanıldığı şekilde `Enum` sınıfından faydalanabilirsiniz. From f1ff930e6828088cd39b0045af0110bba410f73e Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 18 Feb 2024 12:20:55 +0000 Subject: [PATCH 46/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 5ee0017a2..b23e0c897 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/reference/fastapi.md`. PR [#10813](https://github.com/tiangolo/fastapi/pull/10813) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/newsletter.md`. PR [#10853](https://github.com/tiangolo/fastapi/pull/10853) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/learn/index.md`. PR [#11142](https://github.com/tiangolo/fastapi/pull/11142) by [@hsuanchi](https://github.com/hsuanchi). * 🌐 Add Korean translation for `/docs/ko/docs/tutorial/dependencies/global-dependencies.md`. PR [#11123](https://github.com/tiangolo/fastapi/pull/11123) by [@riroan](https://github.com/riroan). From 3808d618fdebdd54840e8b8ba5252d4c2edb4c64 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 18 Feb 2024 12:21:32 +0000 Subject: [PATCH 47/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index b23e0c897..98fea7bb4 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11078](https://github.com/tiangolo/fastapi/pull/11078) by [@emrhnsyts](https://github.com/emrhnsyts). * 🌐 Add German translation for `docs/de/docs/reference/fastapi.md`. PR [#10813](https://github.com/tiangolo/fastapi/pull/10813) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/newsletter.md`. PR [#10853](https://github.com/tiangolo/fastapi/pull/10853) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/learn/index.md`. PR [#11142](https://github.com/tiangolo/fastapi/pull/11142) by [@hsuanchi](https://github.com/hsuanchi). From 6062ec86f3039f044a9bafa637b2544947c12afc Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Mon, 19 Feb 2024 16:53:18 +0100 Subject: [PATCH 48/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/reference/request.md`=20(#10821)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/reference/request.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/de/docs/reference/request.md diff --git a/docs/de/docs/reference/request.md b/docs/de/docs/reference/request.md new file mode 100644 index 000000000..b170c1e40 --- /dev/null +++ b/docs/de/docs/reference/request.md @@ -0,0 +1,14 @@ +# `Request`-Klasse + +Sie können einen Parameter in einer *Pfadoperation-Funktion* oder einer Abhängigkeit als vom Typ `Request` deklarieren und dann direkt auf das Requestobjekt zugreifen, ohne jegliche Validierung, usw. + +Sie können es direkt von `fastapi` importieren: + +```python +from fastapi import Request +``` + +!!! tip "Tipp" + Wenn Sie Abhängigkeiten definieren möchten, die sowohl mit HTTP als auch mit WebSockets kompatibel sein sollen, können Sie einen Parameter definieren, der eine `HTTPConnection` anstelle eines `Request` oder eines `WebSocket` akzeptiert. + +::: fastapi.Request From 646e7eb3c7cc28572fbf3183b8784077a652e2c6 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Mon, 19 Feb 2024 16:53:39 +0100 Subject: [PATCH 49/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/reference/responses.md`=20(#10825)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/reference/responses.md | 164 ++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 docs/de/docs/reference/responses.md diff --git a/docs/de/docs/reference/responses.md b/docs/de/docs/reference/responses.md new file mode 100644 index 000000000..c0e9f07e7 --- /dev/null +++ b/docs/de/docs/reference/responses.md @@ -0,0 +1,164 @@ +# Benutzerdefinierte Responseklassen – File, HTML, Redirect, Streaming, usw. + +Es gibt mehrere benutzerdefinierte Responseklassen, von denen Sie eine Instanz erstellen und diese direkt von Ihren *Pfadoperationen* zurückgeben können. + +Lesen Sie mehr darüber in der [FastAPI-Dokumentation zu benutzerdefinierten Responses – HTML, Stream, Datei, andere](../advanced/custom-response.md). + +Sie können diese direkt von `fastapi.responses` importieren: + +```python +from fastapi.responses import ( + FileResponse, + HTMLResponse, + JSONResponse, + ORJSONResponse, + PlainTextResponse, + RedirectResponse, + Response, + StreamingResponse, + UJSONResponse, +) +``` + +## FastAPI-Responses + +Es gibt einige benutzerdefinierte FastAPI-Responseklassen, welche Sie verwenden können, um die JSON-Performanz zu optimieren. + +::: fastapi.responses.UJSONResponse + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.ORJSONResponse + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +## Starlette-Responses + +::: fastapi.responses.FileResponse + options: + members: + - chunk_size + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.HTMLResponse + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.JSONResponse + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.PlainTextResponse + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.RedirectResponse + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.Response + options: + members: + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie + +::: fastapi.responses.StreamingResponse + options: + members: + - body_iterator + - charset + - status_code + - media_type + - body + - background + - raw_headers + - render + - init_headers + - headers + - set_cookie + - delete_cookie From ce1a358cbf2567012c7f85ab8b941752b1f95a39 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 19 Feb 2024 15:53:44 +0000 Subject: [PATCH 50/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 98fea7bb4..833dad61f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/reference/request.md`. PR [#10821](https://github.com/tiangolo/fastapi/pull/10821) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11078](https://github.com/tiangolo/fastapi/pull/11078) by [@emrhnsyts](https://github.com/emrhnsyts). * 🌐 Add German translation for `docs/de/docs/reference/fastapi.md`. PR [#10813](https://github.com/tiangolo/fastapi/pull/10813) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/newsletter.md`. PR [#10853](https://github.com/tiangolo/fastapi/pull/10853) by [@nilslindemann](https://github.com/nilslindemann). From d0b143916ca1bb83e0cff25b7f36e7a0bf003ae3 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 19 Feb 2024 15:54:37 +0000 Subject: [PATCH 51/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 833dad61f..2c25f82ae 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/reference/responses.md`. PR [#10825](https://github.com/tiangolo/fastapi/pull/10825) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/request.md`. PR [#10821](https://github.com/tiangolo/fastapi/pull/10821) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11078](https://github.com/tiangolo/fastapi/pull/11078) by [@emrhnsyts](https://github.com/emrhnsyts). * 🌐 Add German translation for `docs/de/docs/reference/fastapi.md`. PR [#10813](https://github.com/tiangolo/fastapi/pull/10813) by [@nilslindemann](https://github.com/nilslindemann). From 073a05ebdd395bea1317c3a52e9a40c7fd45df64 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Mon, 19 Feb 2024 16:54:52 +0100 Subject: [PATCH 52/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/reference/encoders.md`=20(#10840)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/reference/encoders.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/de/docs/reference/encoders.md diff --git a/docs/de/docs/reference/encoders.md b/docs/de/docs/reference/encoders.md new file mode 100644 index 000000000..2489b8c60 --- /dev/null +++ b/docs/de/docs/reference/encoders.md @@ -0,0 +1,3 @@ +# Encoder – `jsonable_encoder` + +::: fastapi.encoders.jsonable_encoder From e76977bb3575547f1229a8b319724593302cefb5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 19 Feb 2024 15:57:07 +0000 Subject: [PATCH 53/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 2c25f82ae..a02bf2a1d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/reference/encoders.md`. PR [#10840](https://github.com/tiangolo/fastapi/pull/10840) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/responses.md`. PR [#10825](https://github.com/tiangolo/fastapi/pull/10825) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/request.md`. PR [#10821](https://github.com/tiangolo/fastapi/pull/10821) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11078](https://github.com/tiangolo/fastapi/pull/11078) by [@emrhnsyts](https://github.com/emrhnsyts). From e52bf9628f270a7e7c6fba2a99925d6e53cb30b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hasan=20Sezer=20Ta=C5=9Fan?= <13135006+hasansezertasan@users.noreply.github.com> Date: Mon, 19 Feb 2024 21:46:02 +0300 Subject: [PATCH 54/70] =?UTF-8?q?=F0=9F=8C=90=20Update=20Turkish=20transla?= =?UTF-8?q?tion=20for=20`docs/tr/docs/tutorial/query-params.md`=20(#11162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tr/docs/tutorial/query-params.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tr/docs/tutorial/query-params.md b/docs/tr/docs/tutorial/query-params.md index 61232d5b3..aa3915557 100644 --- a/docs/tr/docs/tutorial/query-params.md +++ b/docs/tr/docs/tutorial/query-params.md @@ -224,4 +224,4 @@ Bu durumda, 3 tane sorgu parametresi var olacaktır: * `limit`, isteğe bağlı bir `int`. !!! tip "İpucu" - Ayrıca, [Yol Parametreleri](path-params.md#predefined-values){.internal-link target=_blank}nde de kullanıldığı şekilde `Enum` sınıfından faydalanabilirsiniz. + Ayrıca, [Yol Parametrelerinde](path-params.md#predefined-values){.internal-link target=_blank} de kullanıldığı şekilde `Enum` sınıfından faydalanabilirsiniz. From a6bc32a61a2f57645d5535d076e38b0b3eb4138d Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 19 Feb 2024 18:46:23 +0000 Subject: [PATCH 55/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index a02bf2a1d..d98faea4d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Update Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11162](https://github.com/tiangolo/fastapi/pull/11162) by [@hasansezertasan](https://github.com/hasansezertasan). * 🌐 Add German translation for `docs/de/docs/reference/encoders.md`. PR [#10840](https://github.com/tiangolo/fastapi/pull/10840) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/responses.md`. PR [#10825](https://github.com/tiangolo/fastapi/pull/10825) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/request.md`. PR [#10821](https://github.com/tiangolo/fastapi/pull/10821) by [@nilslindemann](https://github.com/nilslindemann). From 626b066e56e39162f328431395856c959d150bc4 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Wed, 21 Feb 2024 23:23:00 +0100 Subject: [PATCH 56/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/external-links.md`=20(#10852)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/external-links.md | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/de/docs/external-links.md diff --git a/docs/de/docs/external-links.md b/docs/de/docs/external-links.md new file mode 100644 index 000000000..d97f4d39c --- /dev/null +++ b/docs/de/docs/external-links.md @@ -0,0 +1,36 @@ +# Externe Links und Artikel + +**FastAPI** hat eine großartige Community, die ständig wächst. + +Es gibt viele Beiträge, Artikel, Tools und Projekte zum Thema **FastAPI**. + +Hier ist eine unvollständige Liste einiger davon. + +!!! tip "Tipp" + Wenn Sie einen Artikel, ein Projekt, ein Tool oder irgendetwas im Zusammenhang mit **FastAPI** haben, was hier noch nicht aufgeführt ist, erstellen Sie einen Pull Request und fügen Sie es hinzu. + +!!! note "Hinweis Deutsche Übersetzung" + Die folgenden Überschriften und Links werden aus einer anderen Datei gelesen und sind daher nicht ins Deutsche übersetzt. + +{% for section_name, section_content in external_links.items() %} + +## {{ section_name }} + +{% for lang_name, lang_content in section_content.items() %} + +### {{ lang_name }} + +{% for item in lang_content %} + +* {{ item.title }} by {{ item.author }}. + +{% endfor %} +{% endfor %} +{% endfor %} + +## Projekte + +Die neuesten GitHub-Projekte zum Thema `fastapi`: + +
+
From 5da35ff980a9477675929ddc0643e7eb27ea6208 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 21 Feb 2024 22:23:21 +0000 Subject: [PATCH 57/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index d98faea4d..d8d87ca46 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/external-links.md`. PR [#10852](https://github.com/tiangolo/fastapi/pull/10852) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Update Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11162](https://github.com/tiangolo/fastapi/pull/11162) by [@hasansezertasan](https://github.com/hasansezertasan). * 🌐 Add German translation for `docs/de/docs/reference/encoders.md`. PR [#10840](https://github.com/tiangolo/fastapi/pull/10840) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/responses.md`. PR [#10825](https://github.com/tiangolo/fastapi/pull/10825) by [@nilslindemann](https://github.com/nilslindemann). From dec45c534f97bb5635492cba78a93f1409ec6b2a Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Wed, 21 Feb 2024 23:26:02 +0100 Subject: [PATCH 58/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/reference/templating.md`=20(#10842)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/reference/templating.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/de/docs/reference/templating.md diff --git a/docs/de/docs/reference/templating.md b/docs/de/docs/reference/templating.md new file mode 100644 index 000000000..c367a0179 --- /dev/null +++ b/docs/de/docs/reference/templating.md @@ -0,0 +1,13 @@ +# Templating – `Jinja2Templates` + +Sie können die `Jinja2Templates`-Klasse verwenden, um Jinja-Templates zu rendern. + +Lesen Sie mehr darüber in der [FastAPI-Dokumentation zu Templates](../advanced/templates.md). + +Sie können die Klasse direkt von `fastapi.templating` importieren: + +```python +from fastapi.templating import Jinja2Templates +``` + +::: fastapi.templating.Jinja2Templates From 9210e6a330bc9639fcb3315a493e39aa2119d142 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Wed, 21 Feb 2024 23:26:48 +0100 Subject: [PATCH 59/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation?= =?UTF-8?q?=20for=20`docs/de/docs/reference/background.md`=20(#10820)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/reference/background.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/de/docs/reference/background.md diff --git a/docs/de/docs/reference/background.md b/docs/de/docs/reference/background.md new file mode 100644 index 000000000..0fd389325 --- /dev/null +++ b/docs/de/docs/reference/background.md @@ -0,0 +1,11 @@ +# Hintergrundtasks – `BackgroundTasks` + +Sie können einen Parameter in einer *Pfadoperation-Funktion* oder einer Abhängigkeitsfunktion mit dem Typ `BackgroundTasks` deklarieren und diesen danach verwenden, um die Ausführung von Hintergrundtasks nach dem Senden der Response zu definieren. + +Sie können `BackgroundTasks` direkt von `fastapi` importieren: + +```python +from fastapi import BackgroundTasks +``` + +::: fastapi.BackgroundTasks From cb938740145c5d0cea78a26bc0a7215aae4506b9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 21 Feb 2024 22:27:17 +0000 Subject: [PATCH 60/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index d8d87ca46..7251a4f91 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/reference/templating.md`. PR [#10842](https://github.com/tiangolo/fastapi/pull/10842) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/external-links.md`. PR [#10852](https://github.com/tiangolo/fastapi/pull/10852) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Update Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11162](https://github.com/tiangolo/fastapi/pull/11162) by [@hasansezertasan](https://github.com/hasansezertasan). * 🌐 Add German translation for `docs/de/docs/reference/encoders.md`. PR [#10840](https://github.com/tiangolo/fastapi/pull/10840) by [@nilslindemann](https://github.com/nilslindemann). From 6336604906d50e0aca978d15ef82236bac23fb15 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 21 Feb 2024 22:27:53 +0000 Subject: [PATCH 61/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 7251a4f91..e595ed927 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Translations +* 🌐 Add German translation for `docs/de/docs/reference/background.md`. PR [#10820](https://github.com/tiangolo/fastapi/pull/10820) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/reference/templating.md`. PR [#10842](https://github.com/tiangolo/fastapi/pull/10842) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Add German translation for `docs/de/docs/external-links.md`. PR [#10852](https://github.com/tiangolo/fastapi/pull/10852) by [@nilslindemann](https://github.com/nilslindemann). * 🌐 Update Turkish translation for `docs/tr/docs/tutorial/query-params.md`. PR [#11162](https://github.com/tiangolo/fastapi/pull/11162) by [@hasansezertasan](https://github.com/hasansezertasan). From bf771bd7817f8e8348f85836a21d1e96c0b4f7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 00:06:37 +0100 Subject: [PATCH 62/70] =?UTF-8?q?=F0=9F=90=9B=20Fix=20unhandled=20growing?= =?UTF-8?q?=20memory=20for=20internal=20server=20errors,=20refactor=20depe?= =?UTF-8?q?ndencies=20with=20`yield`=20and=20`except`=20to=20require=20rai?= =?UTF-8?q?sing=20again=20as=20in=20regular=20Python=20(#11191)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../dependencies/dependencies-with-yield.md | 70 +++++++++++- docs_src/dependencies/tutorial008c.py | 27 +++++ docs_src/dependencies/tutorial008c_an.py | 28 +++++ docs_src/dependencies/tutorial008c_an_py39.py | 29 +++++ docs_src/dependencies/tutorial008d.py | 28 +++++ docs_src/dependencies/tutorial008d_an.py | 29 +++++ docs_src/dependencies/tutorial008d_an_py39.py | 30 +++++ fastapi/routing.py | 108 ++++++++---------- tests/test_dependency_contextmanager.py | 2 + tests/test_dependency_normal_exceptions.py | 1 + .../test_tutorial008b_an_py39.py | 22 +++- .../test_dependencies/test_tutorial008c.py | 38 ++++++ .../test_dependencies/test_tutorial008c_an.py | 38 ++++++ .../test_tutorial008c_an_py39.py | 44 +++++++ .../test_dependencies/test_tutorial008d.py | 41 +++++++ .../test_dependencies/test_tutorial008d_an.py | 41 +++++++ .../test_tutorial008d_an_py39.py | 47 ++++++++ 17 files changed, 554 insertions(+), 69 deletions(-) create mode 100644 docs_src/dependencies/tutorial008c.py create mode 100644 docs_src/dependencies/tutorial008c_an.py create mode 100644 docs_src/dependencies/tutorial008c_an_py39.py create mode 100644 docs_src/dependencies/tutorial008d.py create mode 100644 docs_src/dependencies/tutorial008d_an.py create mode 100644 docs_src/dependencies/tutorial008d_an_py39.py create mode 100644 tests/test_tutorial/test_dependencies/test_tutorial008c.py create mode 100644 tests/test_tutorial/test_dependencies/test_tutorial008c_an.py create mode 100644 tests/test_tutorial/test_dependencies/test_tutorial008c_an_py39.py create mode 100644 tests/test_tutorial/test_dependencies/test_tutorial008d.py create mode 100644 tests/test_tutorial/test_dependencies/test_tutorial008d_an.py create mode 100644 tests/test_tutorial/test_dependencies/test_tutorial008d_an_py39.py diff --git a/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md index de87ba315..ad5aed932 100644 --- a/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md @@ -162,6 +162,63 @@ The same way, you could raise an `HTTPException` or similar in the exit code, af An alternative you could use to catch exceptions (and possibly also raise another `HTTPException`) is to create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}. +## Dependencies with `yield` and `except` + +If you catch an exception using `except` in a dependency with `yield` and you don't raise it again (or raise a new exception), FastAPI won't be able to notice there was an exception, the same way that would happen with regular Python: + +=== "Python 3.9+" + + ```Python hl_lines="15-16" + {!> ../../../docs_src/dependencies/tutorial008c_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="14-15" + {!> ../../../docs_src/dependencies/tutorial008c_an.py!} + ``` + +=== "Python 3.8+ non-Annotated" + + !!! tip + Prefer to use the `Annotated` version if possible. + + ```Python hl_lines="13-14" + {!> ../../../docs_src/dependencies/tutorial008c.py!} + ``` + +In this case, the client will see an *HTTP 500 Internal Server Error* response as it should, given that we are not raising an `HTTPException` or similar, but the server will **not have any logs** or any other indication of what was the error. 😱 + +### Always `raise` in Dependencies with `yield` and `except` + +If you catch an exception in a dependency with `yield`, unless you are raising another `HTTPException` or similar, you should re-raise the original exception. + +You can re-raise the same exception using `raise`: + +=== "Python 3.9+" + + ```Python hl_lines="17" + {!> ../../../docs_src/dependencies/tutorial008d_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="16" + {!> ../../../docs_src/dependencies/tutorial008d_an.py!} + ``` + + +=== "Python 3.8+ non-Annotated" + + !!! tip + Prefer to use the `Annotated` version if possible. + + ```Python hl_lines="15" + {!> ../../../docs_src/dependencies/tutorial008d.py!} + ``` + +Now the client will get the same *HTTP 500 Internal Server Error* response, but the server will have our custom `InternalError` in the logs. 😎 + ## Execution of dependencies with `yield` The sequence of execution is more or less like this diagram. Time flows from top to bottom. And each column is one of the parts interacting or executing code. @@ -187,7 +244,6 @@ participant tasks as Background tasks operation -->> dep: Raise Exception (e.g. HTTPException) opt handle dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception - dep -->> handler: Auto forward exception end handler -->> client: HTTP error response end @@ -210,15 +266,23 @@ participant tasks as Background tasks !!! tip This diagram shows `HTTPException`, but you could also raise any other exception that you catch in a dependency with `yield` or with a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}. - If you raise any exception, it will be passed to the dependencies with yield, including `HTTPException`, and then **again** to the exception handlers. If there's no exception handler for that exception, it will then be handled by the default internal `ServerErrorMiddleware`, returning a 500 HTTP status code, to let the client know that there was an error in the server. + If you raise any exception, it will be passed to the dependencies with yield, including `HTTPException`. In most cases you will want to re-raise that same exception or a new one from the dependency with `yield` to make sure it's properly handled. -## Dependencies with `yield`, `HTTPException` and Background Tasks +## Dependencies with `yield`, `HTTPException`, `except` and Background Tasks !!! warning You most probably don't need these technical details, you can skip this section and continue below. These details are useful mainly if you were using a version of FastAPI prior to 0.106.0 and used resources from dependencies with `yield` in background tasks. +### Dependencies with `yield` and `except`, Technical Details + +Before FastAPI 0.110.0, if you used a dependency with `yield`, and then you captured an exception with `except` in that dependency, and you didn't raise the exception again, the exception would be automatically raised/forwarded to any exception handlers or the internal server error handler. + +This was changed in version 0.110.0 to fix unhandled memory consumption from forwarded exceptions without a handler (internal server errors), and to make it consistent with the behavior of regular Python code. + +### Background Tasks and Dependencies with `yield`, Technical Details + Before FastAPI 0.106.0, raising exceptions after `yield` was not possible, the exit code in dependencies with `yield` was executed *after* the response was sent, so [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} would have already run. This was designed this way mainly to allow using the same objects "yielded" by dependencies inside of background tasks, because the exit code would be executed after the background tasks were finished. diff --git a/docs_src/dependencies/tutorial008c.py b/docs_src/dependencies/tutorial008c.py new file mode 100644 index 000000000..4b99a5a31 --- /dev/null +++ b/docs_src/dependencies/tutorial008c.py @@ -0,0 +1,27 @@ +from fastapi import Depends, FastAPI, HTTPException + +app = FastAPI() + + +class InternalError(Exception): + pass + + +def get_username(): + try: + yield "Rick" + except InternalError: + print("Oops, we didn't raise again, Britney 😱") + + +@app.get("/items/{item_id}") +def get_item(item_id: str, username: str = Depends(get_username)): + if item_id == "portal-gun": + raise InternalError( + f"The portal gun is too dangerous to be owned by {username}" + ) + if item_id != "plumbus": + raise HTTPException( + status_code=404, detail="Item not found, there's only a plumbus here" + ) + return item_id diff --git a/docs_src/dependencies/tutorial008c_an.py b/docs_src/dependencies/tutorial008c_an.py new file mode 100644 index 000000000..94f59f9aa --- /dev/null +++ b/docs_src/dependencies/tutorial008c_an.py @@ -0,0 +1,28 @@ +from fastapi import Depends, FastAPI, HTTPException +from typing_extensions import Annotated + +app = FastAPI() + + +class InternalError(Exception): + pass + + +def get_username(): + try: + yield "Rick" + except InternalError: + print("Oops, we didn't raise again, Britney 😱") + + +@app.get("/items/{item_id}") +def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): + if item_id == "portal-gun": + raise InternalError( + f"The portal gun is too dangerous to be owned by {username}" + ) + if item_id != "plumbus": + raise HTTPException( + status_code=404, detail="Item not found, there's only a plumbus here" + ) + return item_id diff --git a/docs_src/dependencies/tutorial008c_an_py39.py b/docs_src/dependencies/tutorial008c_an_py39.py new file mode 100644 index 000000000..da92efa9c --- /dev/null +++ b/docs_src/dependencies/tutorial008c_an_py39.py @@ -0,0 +1,29 @@ +from typing import Annotated + +from fastapi import Depends, FastAPI, HTTPException + +app = FastAPI() + + +class InternalError(Exception): + pass + + +def get_username(): + try: + yield "Rick" + except InternalError: + print("Oops, we didn't raise again, Britney 😱") + + +@app.get("/items/{item_id}") +def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): + if item_id == "portal-gun": + raise InternalError( + f"The portal gun is too dangerous to be owned by {username}" + ) + if item_id != "plumbus": + raise HTTPException( + status_code=404, detail="Item not found, there's only a plumbus here" + ) + return item_id diff --git a/docs_src/dependencies/tutorial008d.py b/docs_src/dependencies/tutorial008d.py new file mode 100644 index 000000000..93039343d --- /dev/null +++ b/docs_src/dependencies/tutorial008d.py @@ -0,0 +1,28 @@ +from fastapi import Depends, FastAPI, HTTPException + +app = FastAPI() + + +class InternalError(Exception): + pass + + +def get_username(): + try: + yield "Rick" + except InternalError: + print("We don't swallow the internal error here, we raise again 😎") + raise + + +@app.get("/items/{item_id}") +def get_item(item_id: str, username: str = Depends(get_username)): + if item_id == "portal-gun": + raise InternalError( + f"The portal gun is too dangerous to be owned by {username}" + ) + if item_id != "plumbus": + raise HTTPException( + status_code=404, detail="Item not found, there's only a plumbus here" + ) + return item_id diff --git a/docs_src/dependencies/tutorial008d_an.py b/docs_src/dependencies/tutorial008d_an.py new file mode 100644 index 000000000..c35424574 --- /dev/null +++ b/docs_src/dependencies/tutorial008d_an.py @@ -0,0 +1,29 @@ +from fastapi import Depends, FastAPI, HTTPException +from typing_extensions import Annotated + +app = FastAPI() + + +class InternalError(Exception): + pass + + +def get_username(): + try: + yield "Rick" + except InternalError: + print("We don't swallow the internal error here, we raise again 😎") + raise + + +@app.get("/items/{item_id}") +def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): + if item_id == "portal-gun": + raise InternalError( + f"The portal gun is too dangerous to be owned by {username}" + ) + if item_id != "plumbus": + raise HTTPException( + status_code=404, detail="Item not found, there's only a plumbus here" + ) + return item_id diff --git a/docs_src/dependencies/tutorial008d_an_py39.py b/docs_src/dependencies/tutorial008d_an_py39.py new file mode 100644 index 000000000..99bd5cb91 --- /dev/null +++ b/docs_src/dependencies/tutorial008d_an_py39.py @@ -0,0 +1,30 @@ +from typing import Annotated + +from fastapi import Depends, FastAPI, HTTPException + +app = FastAPI() + + +class InternalError(Exception): + pass + + +def get_username(): + try: + yield "Rick" + except InternalError: + print("We don't swallow the internal error here, we raise again 😎") + raise + + +@app.get("/items/{item_id}") +def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): + if item_id == "portal-gun": + raise InternalError( + f"The portal gun is too dangerous to be owned by {username}" + ) + if item_id != "plumbus": + raise HTTPException( + status_code=404, detail="Item not found, there's only a plumbus here" + ) + return item_id diff --git a/fastapi/routing.py b/fastapi/routing.py index acebabfca..23a32d15f 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -216,19 +216,14 @@ def get_request_handler( actual_response_class = response_class async def app(request: Request) -> Response: - exception_to_reraise: Optional[Exception] = None response: Union[Response, None] = None - async with AsyncExitStack() as async_exit_stack: - # TODO: remove this scope later, after a few releases - # This scope fastapi_astack is no longer used by FastAPI, kept for - # compatibility, just in case - request.scope["fastapi_astack"] = async_exit_stack + async with AsyncExitStack() as file_stack: try: body: Any = None if body_field: if is_body_form: body = await request.form() - async_exit_stack.push_async_callback(body.close) + file_stack.push_async_callback(body.close) else: body_bytes = await request.body() if body_bytes: @@ -260,18 +255,17 @@ def get_request_handler( ], body=e.doc, ) - exception_to_reraise = validation_error raise validation_error from e - except HTTPException as e: - exception_to_reraise = e + except HTTPException: + # If a middleware raises an HTTPException, it should be raised again raise except Exception as e: http_error = HTTPException( status_code=400, detail="There was an error parsing the body" ) - exception_to_reraise = http_error raise http_error from e - try: + errors: List[Any] = [] + async with AsyncExitStack() as async_exit_stack: solved_result = await solve_dependencies( request=request, dependant=dependant, @@ -280,59 +274,53 @@ def get_request_handler( async_exit_stack=async_exit_stack, ) values, errors, background_tasks, sub_response, _ = solved_result - except Exception as e: - exception_to_reraise = e - raise e + if not errors: + raw_response = await run_endpoint_function( + dependant=dependant, values=values, is_coroutine=is_coroutine + ) + if isinstance(raw_response, Response): + if raw_response.background is None: + raw_response.background = background_tasks + response = raw_response + else: + response_args: Dict[str, Any] = {"background": background_tasks} + # If status_code was set, use it, otherwise use the default from the + # response class, in the case of redirect it's 307 + current_status_code = ( + status_code if status_code else sub_response.status_code + ) + if current_status_code is not None: + response_args["status_code"] = current_status_code + if sub_response.status_code: + response_args["status_code"] = sub_response.status_code + content = await serialize_response( + field=response_field, + response_content=raw_response, + include=response_model_include, + exclude=response_model_exclude, + by_alias=response_model_by_alias, + exclude_unset=response_model_exclude_unset, + exclude_defaults=response_model_exclude_defaults, + exclude_none=response_model_exclude_none, + is_coroutine=is_coroutine, + ) + response = actual_response_class(content, **response_args) + if not is_body_allowed_for_status_code(response.status_code): + response.body = b"" + response.headers.raw.extend(sub_response.headers.raw) if errors: validation_error = RequestValidationError( _normalize_errors(errors), body=body ) - exception_to_reraise = validation_error raise validation_error - else: - try: - raw_response = await run_endpoint_function( - dependant=dependant, values=values, is_coroutine=is_coroutine - ) - except Exception as e: - exception_to_reraise = e - raise e - if isinstance(raw_response, Response): - if raw_response.background is None: - raw_response.background = background_tasks - response = raw_response - else: - response_args: Dict[str, Any] = {"background": background_tasks} - # If status_code was set, use it, otherwise use the default from the - # response class, in the case of redirect it's 307 - current_status_code = ( - status_code if status_code else sub_response.status_code - ) - if current_status_code is not None: - response_args["status_code"] = current_status_code - if sub_response.status_code: - response_args["status_code"] = sub_response.status_code - content = await serialize_response( - field=response_field, - response_content=raw_response, - include=response_model_include, - exclude=response_model_exclude, - by_alias=response_model_by_alias, - exclude_unset=response_model_exclude_unset, - exclude_defaults=response_model_exclude_defaults, - exclude_none=response_model_exclude_none, - is_coroutine=is_coroutine, - ) - response = actual_response_class(content, **response_args) - if not is_body_allowed_for_status_code(response.status_code): - response.body = b"" - response.headers.raw.extend(sub_response.headers.raw) - # This exception was possibly handled by the dependency but it should - # still bubble up so that the ServerErrorMiddleware can return a 500 - # or the ExceptionMiddleware can catch and handle any other exceptions - if exception_to_reraise: - raise exception_to_reraise - assert response is not None, "An error occurred while generating the request" + if response is None: + raise FastAPIError( + "No response object was returned. There's a high chance that the " + "application code is raising an exception and a dependency with yield " + "has a block with a bare except, or a block with except Exception, " + "and is not raising the exception again. Read more about it in the " + "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except" + ) return response return app diff --git a/tests/test_dependency_contextmanager.py b/tests/test_dependency_contextmanager.py index b07f9aa5b..008dab7bc 100644 --- a/tests/test_dependency_contextmanager.py +++ b/tests/test_dependency_contextmanager.py @@ -55,6 +55,7 @@ async def asyncgen_state_try(state: Dict[str, str] = Depends(get_state)): yield state["/async_raise"] except AsyncDependencyError: errors.append("/async_raise") + raise finally: state["/async_raise"] = "asyncgen raise finalized" @@ -65,6 +66,7 @@ def generator_state_try(state: Dict[str, str] = Depends(get_state)): yield state["/sync_raise"] except SyncDependencyError: errors.append("/sync_raise") + raise finally: state["/sync_raise"] = "generator raise finalized" diff --git a/tests/test_dependency_normal_exceptions.py b/tests/test_dependency_normal_exceptions.py index 23c366d5d..326f8fd88 100644 --- a/tests/test_dependency_normal_exceptions.py +++ b/tests/test_dependency_normal_exceptions.py @@ -20,6 +20,7 @@ async def get_database(): fake_database.update(temp_database) except HTTPException: state["except"] = True + raise finally: state["finally"] = True diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008b_an_py39.py b/tests/test_tutorial/test_dependencies/test_tutorial008b_an_py39.py index 7f51fc52a..7d24809a8 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008b_an_py39.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008b_an_py39.py @@ -1,23 +1,33 @@ +import pytest from fastapi.testclient import TestClient -from docs_src.dependencies.tutorial008b_an import app - -client = TestClient(app) +from ...utils import needs_py39 -def test_get_no_item(): +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008b_an_py39 import app + + client = TestClient(app) + return client + + +@needs_py39 +def test_get_no_item(client: TestClient): response = client.get("/items/foo") assert response.status_code == 404, response.text assert response.json() == {"detail": "Item not found"} -def test_owner_error(): +@needs_py39 +def test_owner_error(client: TestClient): response = client.get("/items/plumbus") assert response.status_code == 400, response.text assert response.json() == {"detail": "Owner error: Rick"} -def test_get_item(): +@needs_py39 +def test_get_item(client: TestClient): response = client.get("/items/portal-gun") assert response.status_code == 200, response.text assert response.json() == {"description": "Gun to create portals", "owner": "Rick"} diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008c.py b/tests/test_tutorial/test_dependencies/test_tutorial008c.py new file mode 100644 index 000000000..27be8895a --- /dev/null +++ b/tests/test_tutorial/test_dependencies/test_tutorial008c.py @@ -0,0 +1,38 @@ +import pytest +from fastapi.exceptions import FastAPIError +from fastapi.testclient import TestClient + + +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008c import app + + client = TestClient(app) + return client + + +def test_get_no_item(client: TestClient): + response = client.get("/items/foo") + assert response.status_code == 404, response.text + assert response.json() == {"detail": "Item not found, there's only a plumbus here"} + + +def test_get(client: TestClient): + response = client.get("/items/plumbus") + assert response.status_code == 200, response.text + assert response.json() == "plumbus" + + +def test_fastapi_error(client: TestClient): + with pytest.raises(FastAPIError) as exc_info: + client.get("/items/portal-gun") + assert "No response object was returned" in exc_info.value.args[0] + + +def test_internal_server_error(): + from docs_src.dependencies.tutorial008c import app + + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/items/portal-gun") + assert response.status_code == 500, response.text + assert response.text == "Internal Server Error" diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008c_an.py b/tests/test_tutorial/test_dependencies/test_tutorial008c_an.py new file mode 100644 index 000000000..10fa1ab50 --- /dev/null +++ b/tests/test_tutorial/test_dependencies/test_tutorial008c_an.py @@ -0,0 +1,38 @@ +import pytest +from fastapi.exceptions import FastAPIError +from fastapi.testclient import TestClient + + +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008c_an import app + + client = TestClient(app) + return client + + +def test_get_no_item(client: TestClient): + response = client.get("/items/foo") + assert response.status_code == 404, response.text + assert response.json() == {"detail": "Item not found, there's only a plumbus here"} + + +def test_get(client: TestClient): + response = client.get("/items/plumbus") + assert response.status_code == 200, response.text + assert response.json() == "plumbus" + + +def test_fastapi_error(client: TestClient): + with pytest.raises(FastAPIError) as exc_info: + client.get("/items/portal-gun") + assert "No response object was returned" in exc_info.value.args[0] + + +def test_internal_server_error(): + from docs_src.dependencies.tutorial008c_an import app + + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/items/portal-gun") + assert response.status_code == 500, response.text + assert response.text == "Internal Server Error" diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008c_an_py39.py b/tests/test_tutorial/test_dependencies/test_tutorial008c_an_py39.py new file mode 100644 index 000000000..6c3acff50 --- /dev/null +++ b/tests/test_tutorial/test_dependencies/test_tutorial008c_an_py39.py @@ -0,0 +1,44 @@ +import pytest +from fastapi.exceptions import FastAPIError +from fastapi.testclient import TestClient + +from ...utils import needs_py39 + + +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008c_an_py39 import app + + client = TestClient(app) + return client + + +@needs_py39 +def test_get_no_item(client: TestClient): + response = client.get("/items/foo") + assert response.status_code == 404, response.text + assert response.json() == {"detail": "Item not found, there's only a plumbus here"} + + +@needs_py39 +def test_get(client: TestClient): + response = client.get("/items/plumbus") + assert response.status_code == 200, response.text + assert response.json() == "plumbus" + + +@needs_py39 +def test_fastapi_error(client: TestClient): + with pytest.raises(FastAPIError) as exc_info: + client.get("/items/portal-gun") + assert "No response object was returned" in exc_info.value.args[0] + + +@needs_py39 +def test_internal_server_error(): + from docs_src.dependencies.tutorial008c_an_py39 import app + + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/items/portal-gun") + assert response.status_code == 500, response.text + assert response.text == "Internal Server Error" diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008d.py b/tests/test_tutorial/test_dependencies/test_tutorial008d.py new file mode 100644 index 000000000..043496112 --- /dev/null +++ b/tests/test_tutorial/test_dependencies/test_tutorial008d.py @@ -0,0 +1,41 @@ +import pytest +from fastapi.testclient import TestClient + + +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008d import app + + client = TestClient(app) + return client + + +def test_get_no_item(client: TestClient): + response = client.get("/items/foo") + assert response.status_code == 404, response.text + assert response.json() == {"detail": "Item not found, there's only a plumbus here"} + + +def test_get(client: TestClient): + response = client.get("/items/plumbus") + assert response.status_code == 200, response.text + assert response.json() == "plumbus" + + +def test_internal_error(client: TestClient): + from docs_src.dependencies.tutorial008d import InternalError + + with pytest.raises(InternalError) as exc_info: + client.get("/items/portal-gun") + assert ( + exc_info.value.args[0] == "The portal gun is too dangerous to be owned by Rick" + ) + + +def test_internal_server_error(): + from docs_src.dependencies.tutorial008d import app + + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/items/portal-gun") + assert response.status_code == 500, response.text + assert response.text == "Internal Server Error" diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008d_an.py b/tests/test_tutorial/test_dependencies/test_tutorial008d_an.py new file mode 100644 index 000000000..f29d8cdbe --- /dev/null +++ b/tests/test_tutorial/test_dependencies/test_tutorial008d_an.py @@ -0,0 +1,41 @@ +import pytest +from fastapi.testclient import TestClient + + +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008d_an import app + + client = TestClient(app) + return client + + +def test_get_no_item(client: TestClient): + response = client.get("/items/foo") + assert response.status_code == 404, response.text + assert response.json() == {"detail": "Item not found, there's only a plumbus here"} + + +def test_get(client: TestClient): + response = client.get("/items/plumbus") + assert response.status_code == 200, response.text + assert response.json() == "plumbus" + + +def test_internal_error(client: TestClient): + from docs_src.dependencies.tutorial008d_an import InternalError + + with pytest.raises(InternalError) as exc_info: + client.get("/items/portal-gun") + assert ( + exc_info.value.args[0] == "The portal gun is too dangerous to be owned by Rick" + ) + + +def test_internal_server_error(): + from docs_src.dependencies.tutorial008d_an import app + + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/items/portal-gun") + assert response.status_code == 500, response.text + assert response.text == "Internal Server Error" diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008d_an_py39.py b/tests/test_tutorial/test_dependencies/test_tutorial008d_an_py39.py new file mode 100644 index 000000000..0a585f4ad --- /dev/null +++ b/tests/test_tutorial/test_dependencies/test_tutorial008d_an_py39.py @@ -0,0 +1,47 @@ +import pytest +from fastapi.testclient import TestClient + +from ...utils import needs_py39 + + +@pytest.fixture(name="client") +def get_client(): + from docs_src.dependencies.tutorial008d_an_py39 import app + + client = TestClient(app) + return client + + +@needs_py39 +def test_get_no_item(client: TestClient): + response = client.get("/items/foo") + assert response.status_code == 404, response.text + assert response.json() == {"detail": "Item not found, there's only a plumbus here"} + + +@needs_py39 +def test_get(client: TestClient): + response = client.get("/items/plumbus") + assert response.status_code == 200, response.text + assert response.json() == "plumbus" + + +@needs_py39 +def test_internal_error(client: TestClient): + from docs_src.dependencies.tutorial008d_an_py39 import InternalError + + with pytest.raises(InternalError) as exc_info: + client.get("/items/portal-gun") + assert ( + exc_info.value.args[0] == "The portal gun is too dangerous to be owned by Rick" + ) + + +@needs_py39 +def test_internal_server_error(): + from docs_src.dependencies.tutorial008d_an_py39 import app + + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/items/portal-gun") + assert response.status_code == 500, response.text + assert response.text == "Internal Server Error" From b6b0f2a7e6690b923957677807c5c6a4ff556422 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 24 Feb 2024 23:06:56 +0000 Subject: [PATCH 63/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index e595ed927..2e8930ea3 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Breaking Changes + +* 🐛 Fix unhandled growing memory for internal server errors, refactor dependencies with `yield` and `except` to require raising again as in regular Python. PR [#11191](https://github.com/tiangolo/fastapi/pull/11191) by [@tiangolo](https://github.com/tiangolo). + ### Docs * ✏️ Fix minor typos in `docs/ko/docs/`. PR [#11126](https://github.com/tiangolo/fastapi/pull/11126) by [@KaniKim](https://github.com/KaniKim). From 32b56a8d08aece04d55331142a18f7b2ce580fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 00:18:13 +0100 Subject: [PATCH 64/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 2e8930ea3..c442f1449 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -10,6 +10,29 @@ hide: ### Breaking Changes * 🐛 Fix unhandled growing memory for internal server errors, refactor dependencies with `yield` and `except` to require raising again as in regular Python. PR [#11191](https://github.com/tiangolo/fastapi/pull/11191) by [@tiangolo](https://github.com/tiangolo). + * This is a breaking change (and only slightly) if you used dependencies with `yield`, used `except` in those dependencies, and didn't raise again. + * This was reported internally by [@rushilsrivastava](https://github.com/rushilsrivastava) as a memory leak when the server had unhandled exceptions that would produce internal server errors, the memory allocated before that point would not be released. + * Read the new docs: [Dependencies with `yield` and `except`](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except). + +In short, if you had dependencies that looked like: + +```Python +def my_dep(): + try: + yield + except SomeException: + pass +``` + +Now you need to make sure you raise again after `except`, just as you would in regular Python: + +```Python +def my_dep(): + try: + yield + except SomeException: + raise +``` ### Docs From e40747f10ae911910e9cb9a9684576f3b21304c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 00:19:38 +0100 Subject: [PATCH 65/70] =?UTF-8?q?=F0=9F=94=96=20Release=20version=200.110.?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 ++ fastapi/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index c442f1449..e01c3544f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,8 @@ hide: ## Latest Changes +## 0.110.0 + ### Breaking Changes * 🐛 Fix unhandled growing memory for internal server errors, refactor dependencies with `yield` and `except` to require raising again as in regular Python. PR [#11191](https://github.com/tiangolo/fastapi/pull/11191) by [@tiangolo](https://github.com/tiangolo). diff --git a/fastapi/__init__.py b/fastapi/__init__.py index 3458b9e5b..234969256 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.109.2" +__version__ = "0.110.0" from starlette import status as status From 937378ff054fb760ace3779134b3d6211b825534 Mon Sep 17 00:00:00 2001 From: Vusal Abdullayev Date: Sun, 25 Feb 2024 18:25:12 +0400 Subject: [PATCH 66/70] =?UTF-8?q?=F0=9F=8C=90=20Add=20Azerbaijani=20transl?= =?UTF-8?q?ation=20for=20`docs/az/learn/index.md`=20(#11192)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/az/learn/index.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/az/learn/index.md diff --git a/docs/az/learn/index.md b/docs/az/learn/index.md new file mode 100644 index 000000000..cc32108bf --- /dev/null +++ b/docs/az/learn/index.md @@ -0,0 +1,5 @@ +# Öyrən + +Burada **FastAPI** öyrənmək üçün giriş bölmələri və dərsliklər yer alır. + +Siz bunu kitab, kurs, FastAPI öyrənmək üçün rəsmi və tövsiyə olunan üsul hesab edə bilərsiniz. 😎 From 7ef0b08897afa0972c7e8418d05a0ad654e45996 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 25 Feb 2024 14:25:31 +0000 Subject: [PATCH 67/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index e01c3544f..2d5ab2d9c 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Translations + +* 🌐 Add Azerbaijani translation for `docs/az/learn/index.md`. PR [#11192](https://github.com/tiangolo/fastapi/pull/11192) by [@vusallyv](https://github.com/vusallyv). + ## 0.110.0 ### Breaking Changes From c4c70fd7927dbd7d23894f1a69d42457fb7cadbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 27 Feb 2024 12:18:27 +0100 Subject: [PATCH 68/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 2d5ab2d9c..12f8ffd8a 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -324,7 +324,7 @@ Read more in the [advisory: Content-Type Header ReDoS](https://github.com/tiango ### Upgrades -* ⬆️ Upgrade Starlette to `>=0.29.0,<0.33.0`, update docs and usage of templates with new Starlette arguments. PR [#10846](https://github.com/tiangolo/fastapi/pull/10846) by [@tiangolo](https://github.com/tiangolo). +* ⬆️ Upgrade Starlette to `>=0.29.0,<0.33.0`, update docs and usage of templates with new Starlette arguments. Remove pin of AnyIO `>=3.7.1,<4.0.0`, add support for AnyIO 4.x.x. PR [#10846](https://github.com/tiangolo/fastapi/pull/10846) by [@tiangolo](https://github.com/tiangolo). ## 0.107.0 From c0ad1ebabdb9e26b94c0e574c41bd6869e124bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 28 Feb 2024 15:04:08 +0100 Subject: [PATCH 69/70] =?UTF-8?q?=F0=9F=94=A7=20Update=20sponsors,=20remov?= =?UTF-8?q?e=20Jina,=20remove=20Powens,=20move=20TestDriven.io=20(#11213)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 -- docs/en/data/sponsors.yml | 12 +++--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 874abf8c6..8d3e4c68d 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,7 @@ The key features are: - - diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml index fd8518ce3..8401fd33e 100644 --- a/docs/en/data/sponsors.yml +++ b/docs/en/data/sponsors.yml @@ -27,15 +27,9 @@ silver: - url: https://training.talkpython.fm/fastapi-courses title: FastAPI video courses on demand from people you trust img: https://fastapi.tiangolo.com/img/sponsors/talkpython-v2.jpg - - url: https://testdriven.io/courses/tdd-fastapi/ - title: Learn to build high-quality web apps with best practices - img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg - url: https://github.com/deepset-ai/haystack/ title: Build powerful search from composable, open source building blocks img: https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg - - url: https://careers.powens.com/ - title: Powens is hiring! - img: https://fastapi.tiangolo.com/img/sponsors/powens.png - url: https://databento.com/ title: Pay as you go for market data img: https://fastapi.tiangolo.com/img/sponsors/databento.svg @@ -52,6 +46,6 @@ bronze: - url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source title: Biosecurity risk assessments made easy. img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png - - url: https://bit.ly/3JJ7y5C - title: Build cross-modal and multimodal applications on the cloud - img: https://fastapi.tiangolo.com/img/sponsors/jina2.svg + - url: https://testdriven.io/courses/tdd-fastapi/ + title: Learn to build high-quality web apps with best practices + img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg From eef1b7d51530be64ddd48e02b5ca46f28a0ebfc1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 28 Feb 2024 14:04:27 +0000 Subject: [PATCH 70/70] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 12f8ffd8a..ad548327d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -11,6 +11,10 @@ hide: * 🌐 Add Azerbaijani translation for `docs/az/learn/index.md`. PR [#11192](https://github.com/tiangolo/fastapi/pull/11192) by [@vusallyv](https://github.com/vusallyv). +### Internal + +* 🔧 Update sponsors, remove Jina, remove Powens, move TestDriven.io. PR [#11213](https://github.com/tiangolo/fastapi/pull/11213) by [@tiangolo](https://github.com/tiangolo). + ## 0.110.0 ### Breaking Changes