Compare commits

...

139 Commits

Author SHA1 Message Date
dependabot[bot]
6d9ca6f36a ⬆ Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 17:53:17 +00:00
github-actions[bot]
98bee09a6a 📝 Update release notes
[skip ci]
2025-12-16 17:52:40 +00:00
Sebastián Ramírez
c68dc2d419 👷 Configure coverage, error on main tests, don't wait for Smokeshow (#14536) 2025-12-16 17:52:17 +00:00
github-actions[bot]
ec287a329b 📝 Update release notes
[skip ci]
2025-12-16 17:37:09 +00:00
Sebastián Ramírez
c0e4b9cd67 👷 Run Smokeshow always, even on test failures (#14538) 2025-12-16 17:36:42 +00:00
github-actions[bot]
c98485514c 📝 Update release notes
[skip ci]
2025-12-16 17:00:34 +00:00
Sebastián Ramírez
6281f8721a 👷 Make Pydantic versions customizable in CI (#14535) 2025-12-16 18:00:12 +01:00
github-actions[bot]
75ad0a0f8c 📝 Update release notes
[skip ci]
2025-12-16 16:34:08 +00:00
Sebastián Ramírez
da83d79546 🌐 Update translations for es (update-outdated) (#14532)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-16 17:33:45 +01:00
github-actions[bot]
f43cba7e78 📝 Update release notes
[skip ci]
2025-12-16 16:16:56 +00:00
Sebastián Ramírez
cbbb11f4df 🌐 Update translations for es (add-missing) (#14533)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-16 16:16:35 +00:00
github-actions[bot]
532ba725a5 📝 Update release notes
[skip ci]
2025-12-16 15:35:03 +00:00
Sebastián Ramírez
886b367a8c 👷 Fix checkout GitHub Action fetch-depth for LLM translations, enable cron monthly (#14531) 2025-12-16 15:34:37 +00:00
github-actions[bot]
41d1b84bd5 📝 Update release notes
[skip ci]
2025-12-16 12:53:54 +00:00
Sebastián Ramírez
5da1cb0792 👷 Fix Typer command for CI LLM translations (#14530) 2025-12-16 12:53:28 +00:00
github-actions[bot]
f9397e93b5 📝 Update release notes
[skip ci]
2025-12-16 12:41:12 +00:00
Sebastián Ramírez
2e7aaea524 👷 Update LLM translation CI, add language matrix and extra commands, prepare for scheduled run (#14529) 2025-12-16 12:40:50 +00:00
github-actions[bot]
4414cd849d 📝 Update release notes
[skip ci]
2025-12-16 12:34:25 +00:00
Sebastián Ramírez
c548348386 👷 Update github-actions user for GitHub Actions workflows (#14528) 2025-12-16 12:34:01 +00:00
github-actions[bot]
61ffa3eb82 📝 Update release notes
[skip ci]
2025-12-12 16:57:03 +00:00
Sebastián Ramírez
59917ab679 🌐 Remove translations for removed docs (#14516) 2025-12-12 16:56:39 +00:00
github-actions[bot]
1163dbd17f 📝 Update release notes
[skip ci]
2025-12-12 16:54:50 +00:00
Sebastián Ramírez
435d839c72 Add requirements for translations (#14515) 2025-12-12 16:54:13 +00:00
Sebastián Ramírez
b1d9769f97 🔖 Release version 0.124.4 2025-12-12 15:59:12 +01:00
github-actions[bot]
89157a803c 📝 Update release notes
[skip ci]
2025-12-12 14:57:20 +00:00
Motov Yurii
d86c47477e 🐛 Fix parameter aliases (#14371)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-12 15:56:57 +01:00
Sebastián Ramírez
3fe6522aae 🔖 Release version 0.124.3 2025-12-12 15:32:58 +01:00
github-actions[bot]
80d1f732e5 📝 Update release notes
[skip ci]
2025-12-12 14:31:45 +00:00
Sebastián Ramírez
c0556ac3a5 🐛 Fix support for tagged union with discriminator inside of Annotated with Body() (#14512) 2025-12-12 15:31:21 +01:00
github-actions[bot]
1fcec88ad2 📝 Update release notes
[skip ci]
2025-12-11 21:25:27 +00:00
Motov Yurii
f8b216df30 🌐 Sync Russian docs (#14509)
* Translate missing pages

* Update outdated translations
2025-12-11 22:25:03 +01:00
github-actions[bot]
4b905b614c 📝 Update release notes
[skip ci]
2025-12-11 16:16:13 +00:00
Motov Yurii
6c54bcefd3 Add set of tests for request parameters and alias (#14358)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-11 17:15:36 +01:00
github-actions[bot]
475ce41268 📝 Update release notes
[skip ci]
2025-12-11 16:02:50 +00:00
Sebastián Ramírez
564a4ac1b8 👷 Tweak coverage to not pass Smokeshow max file size limit (#14507) 2025-12-11 16:02:26 +00:00
github-actions[bot]
931e80f20c 📝 Update release notes
[skip ci]
2025-12-11 15:28:47 +00:00
Sofie Van Landeghem
a7ba9932ba Expand test matrix to include Windows and MacOS (#14171)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-11 16:28:21 +01:00
github-actions[bot]
009c8af7fe 📝 Update release notes
[skip ci]
2025-12-11 14:49:09 +00:00
Sebastián Ramírez
4c4d520198 📝 Tweak links format (#14505) 2025-12-11 14:48:47 +00:00
github-actions[bot]
1cf7cd8af0 📝 Update release notes
[skip ci]
2025-12-10 13:54:57 +00:00
Nils-Hero Lindemann
4a9f13763d 🌐 Sync German docs (#14488)
* Sync with #14472

* Sync with #14413

* Sync with #14486

* Sync with #14487
2025-12-10 14:54:34 +01:00
github-actions[bot]
30747a69c8 📝 Update release notes
[skip ci]
2025-12-10 12:57:18 +00:00
Sebastián Ramírez
cd9d093f60 📝 Update docs about re-raising validation errors, do not include string as is to not leak information (#14487) 2025-12-10 12:56:50 +00:00
github-actions[bot]
4a98a66778 📝 Update release notes
[skip ci]
2025-12-10 12:29:04 +00:00
Sebastián Ramírez
442cb306f6 🔥 Remove external links section (#14486) 2025-12-10 12:28:40 +00:00
Sebastián Ramírez
7b0b915749 🔖 Release version 0.124.2 2025-12-10 13:07:53 +01:00
github-actions[bot]
96bdde376f 📝 Update release notes
[skip ci]
2025-12-10 12:06:32 +00:00
Sebastián Ramírez
7ba042e069 🐛 Fix support for if TYPE_CHECKING, non-evaluated stringified annotations (#14485) 2025-12-10 13:06:05 +01:00
Sebastián Ramírez
60699f306b 🔖 Release version 0.124.1 2025-12-10 11:38:41 +01:00
github-actions[bot]
ae7af59c6d 📝 Update release notes
[skip ci]
2025-12-10 10:36:56 +00:00
Sebastián Ramírez
42b250d14d 🐛 Fix handling arbitrary types when using arbitrary_types_allowed=True (#14482) 2025-12-10 11:36:29 +01:00
github-actions[bot]
71a17b5932 📝 Update release notes
[skip ci]
2025-12-10 08:55:57 +00:00
Motov Yurii
9475024640 📝 Add variants for code examples in "Advanced User Guide" (#14413) 2025-12-10 09:55:32 +01:00
github-actions[bot]
5b28a04d55 📝 Update release notes
[skip ci]
2025-12-09 11:12:49 +00:00
Sebastián Ramírez
8cedb742cb Add test for Pydantic v2, dataclasses, UUID, and __annotations__ (#14477) 2025-12-09 12:12:24 +01:00
github-actions[bot]
320e7ce8fd 📝 Update release notes
[skip ci]
2025-12-08 13:05:20 +00:00
Alejandra
81517f66cc 📝 Update tech stack in project generation docs (#14472) 2025-12-08 13:04:54 +00:00
Sebastián Ramírez
b5ca13249e 🔖 Release version 0.124.0 2025-12-06 14:09:51 +01:00
github-actions[bot]
a2cef707e3 📝 Update release notes
[skip ci]
2025-12-06 12:23:23 +00:00
Yuji Teshima
5b6245666b ✏️ Fix typo in scripts/mkdocs_hooks.py (#14457) 2025-12-06 13:23:01 +01:00
github-actions[bot]
dbd34f1578 📝 Update release notes
[skip ci]
2025-12-06 12:22:24 +00:00
Savannah Ostrowski
e1117f7550 🚸 Improve tracebacks by adding endpoint metadata (#14306)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-06 12:21:57 +00:00
Sebastián Ramírez
08b09e5236 🔖 Release version 0.123.10 2025-12-05 22:26:36 +01:00
github-actions[bot]
e7d7038dfa 📝 Update release notes
[skip ci]
2025-12-05 21:21:29 +00:00
Motov Yurii
da0ffab0b2 🐛 Fix using class (not instance) dependency that has __call__ method (#14458)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-05 21:21:05 +00:00
github-actions[bot]
516169428d 📝 Update release notes
[skip ci]
2025-12-05 20:19:54 +00:00
Motov Yurii
812a1926f0 🐛 Fix separate_input_output_schemas=False with computed_field (#14453) 2025-12-05 21:19:30 +01:00
Sebastián Ramírez
f0dd1046a6 🔖 Release version 0.123.9 2025-12-04 23:23:21 +01:00
github-actions[bot]
188d631011 📝 Update release notes
[skip ci]
2025-12-04 22:22:25 +00:00
Sebastián Ramírez
0b5fa563cd 🐛 Fix OAuth2 scopes in OpenAPI in extra corner cases, parent dependency with scopes, sub-dependency security scheme without scopes (#14459) 2025-12-04 23:22:01 +01:00
Sebastián Ramírez
eb1d50479b 🔖 Release version 0.123.8 2025-12-04 14:01:00 +01:00
github-actions[bot]
e248a4d22b 📝 Update release notes
[skip ci]
2025-12-04 12:59:45 +00:00
Sebastián Ramírez
0ec4bafca2 🐛 Fix OpenAPI security scheme OAuth2 scopes declaration, deduplicate security schemes with different scopes (#14455) 2025-12-04 13:59:24 +01:00
Sebastián Ramírez
603df6e36f 🔖 Release version 0.123.7 2025-12-04 09:27:38 +01:00
github-actions[bot]
6c565482cf 📝 Update release notes
[skip ci]
2025-12-04 08:18:55 +00:00
chaen
861598b4e3 🐛 Fix evaluating stringified annotations in Python 3.10 (#11355)
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
Co-authored-by: svlandeg <svlandeg@github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-04 09:18:32 +01:00
Sebastián Ramírez
811fa89875 🔖 Release version 0.123.6 2025-12-04 08:33:11 +01:00
github-actions[bot]
6c6b9d7a2b 📝 Update release notes
[skip ci]
2025-12-04 07:29:53 +00:00
Sebastián Ramírez
bba4d4c95e 🐛 Fix support for functools wraps and partial combined, for async and regular functions and classes in path operations and dependencies (#14448)
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2025-12-04 08:29:28 +01:00
Sebastián Ramírez
c57ac7bdf3 🔖 Release version 0.123.5 2025-12-02 22:06:25 +01:00
github-actions[bot]
3c440c762a 📝 Update release notes
[skip ci]
2025-12-02 20:58:53 +00:00
Lie Ryan
9824486616 Allow using dependables with functools.partial() (#9753)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 20:58:30 +00:00
github-actions[bot]
aee8e78078 📝 Update release notes
[skip ci]
2025-12-02 17:33:22 +00:00
Nils-Hero Lindemann
f4a17b7568 🌐 Sync German docs (#14367)
* Sync with #14217

* Sync with #14359

* Sync with #13786

* Sync with #14070

* Sync with #14120

* Sync with #14211

* Sync with #14405

* "to deploy" -> "deployen"

The LLM used that translation a lot ithis convinced me that "deployen" it is the better word. "bereitstellen" (or "ausliefern") is still used for "to serve".

---------

Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2025-12-02 18:32:56 +01:00
github-actions[bot]
4ade6d62e2 📝 Update release notes
[skip ci]
2025-12-02 17:23:36 +00:00
[object Object]
1c1e584abd Add support for wrapped functions (e.g. @functools.wraps()) used with forward references (#5077)
Co-authored-by: Yurii Karabas <1998uriyyo@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 18:23:14 +01:00
github-actions[bot]
930b27e5fa 📝 Update release notes
[skip ci]
2025-12-02 17:00:02 +00:00
Victorien
80d69ae0bb 🐛 Fix optional sequence handling with new union syntax from Python 3.10 (#14430)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 16:59:38 +00:00
github-actions[bot]
cff2236dac 📝 Update release notes
[skip ci]
2025-12-02 16:49:12 +00:00
Sebastián Ramírez
a79ae3d66f 🔥 Remove dangling extra condiitonal no longer needed (#14435) 2025-12-02 16:48:46 +00:00
github-actions[bot]
f636513390 📝 Update release notes
[skip ci]
2025-12-02 13:43:52 +00:00
Sebastián Ramírez
247ef32e79 ♻️ Refactor internals, update is_coroutine check to reuse internal supported variants (unwrap, check class) (#14434) 2025-12-02 13:43:31 +00:00
github-actions[bot]
13a98c9988 📝 Update release notes
[skip ci]
2025-12-02 13:34:45 +00:00
Matthew Martin
73c411e1b9 Handle wrapped dependencies (#9555)
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 14:34:19 +01:00
Sebastián Ramírez
4976568fc7 🔖 Release version 0.123.4 2025-12-02 11:47:05 +01:00
github-actions[bot]
fb30cc2f50 📝 Update release notes
[skip ci]
2025-12-02 09:22:35 +00:00
Vincent Grafé
f95a174288 🐛 Fix OpenAPI schema support for computed fields when using separate_input_output_schemas=False (#13207)
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
Co-authored-by: svlandeg <svlandeg@github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: svlandeg <sofie.vanlandeghem@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 09:22:08 +00:00
github-actions[bot]
5126e099bd 📝 Update release notes
[skip ci]
2025-12-02 09:11:52 +00:00
Motov Yurii
dcf0299195 📝 Fix docstring of servers parameter (#14405)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 09:11:29 +00:00
Sebastián Ramírez
c516c9904b 🔖 Release version 0.123.3 2025-12-02 08:42:22 +01:00
github-actions[bot]
b49c05ec22 📝 Update release notes
[skip ci]
2025-12-02 07:24:31 +00:00
Motov Yurii
015b4fae9c 🐛 Fix Query\Header\Cookie parameter model alias (#14360)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 07:24:09 +00:00
github-actions[bot]
eead41bf4c 📝 Update release notes
[skip ci]
2025-12-02 07:10:50 +00:00
Motov Yurii
0f613d9051 🐛 Fix optional sequence handling in serialize sequence value with Pydantic V2 (#14297)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 08:10:27 +01:00
Sebastián Ramírez
3c54a8f07b 🔖 Release version 0.123.2 2025-12-02 06:31:27 +01:00
github-actions[bot]
e1a2933739 📝 Update release notes
[skip ci]
2025-12-02 05:09:48 +00:00
zadevhub
00b97526e7 📝 Add tip on how to install pip in case of No module named pip error in virtual-environments.md (#14211) 2025-12-02 06:09:25 +01:00
github-actions[bot]
2ca7709c24 📝 Update release notes
[skip ci]
2025-12-02 05:07:29 +00:00
Flavius
bb05007f55 📝 Update Primary Key notes for the SQL databases tutorial to avoid confusion (#14120) 2025-12-02 06:06:56 +01:00
github-actions[bot]
0f7ce0b78a 📝 Update release notes
[skip ci]
2025-12-02 05:04:09 +00:00
SaisakthiM
cdafd64c15 📝 Clarify estimation note in documentation (#14070) 2025-12-02 06:03:46 +01:00
github-actions[bot]
c6c7b72096 📝 Update release notes
[skip ci]
2025-12-02 05:01:37 +00:00
Alex Colby
cb3792d39e 🐛 Fix unformatted {type_} in FastAPIError (#14416)
Co-authored-by: Alex Colby <alex.colby@intellisense.io>
2025-12-02 06:01:11 +01:00
github-actions[bot]
10eed3806a 📝 Update release notes
[skip ci]
2025-12-02 04:57:45 +00:00
Motov Yurii
de5bec637c 🐛 Fix parsing extra non-body parameter list (#14356)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 05:57:19 +01:00
github-actions[bot]
2330e2de75 📝 Update release notes
[skip ci]
2025-12-02 04:49:52 +00:00
Motov Yurii
6cf40df24d 🐛 Fix parsing extra Form parameter list (#14303)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 05:49:32 +01:00
github-actions[bot]
740ec2787b 📝 Update release notes
[skip ci]
2025-12-02 04:40:16 +00:00
ad hoc
d68c066246 🐛 Fix support for form values with empty strings interpreted as missing (None if that's the default), for compatibility with HTML forms (#13537)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 05:39:55 +01:00
Sebastián Ramírez
c3373205d0 🔖 Release version 0.123.1 2025-12-02 05:30:18 +01:00
github-actions[bot]
3b4b5ab8c8 📝 Update release notes
[skip ci]
2025-12-02 04:04:37 +00:00
Sofie Van Landeghem
8f99a2b734 🐛 Avoid accessing non-existing "$ref" key for Pydantic v2 compat remapping (#14361)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-12-02 05:04:13 +01:00
github-actions[bot]
74b4c3c9a1 📝 Update release notes
[skip ci]
2025-12-02 04:03:00 +00:00
Hemanth U
bf322d0e94 🐛 Fix Windows UnicodeEncodeError in CLI test (#14295)
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2025-12-02 04:02:38 +00:00
github-actions[bot]
327bad18aa 📝 Update release notes
[skip ci]
2025-12-02 03:32:40 +00:00
Kent Huang
20f40b29c0 🐛 Fix TypeError when encoding a decimal with a NaN or Infinity value (#12935)
Signed-off-by: Kent Huang <kent@infuseai.io>
2025-12-02 04:31:59 +01:00
github-actions[bot]
ee490906d8 📝 Update release notes
[skip ci]
2025-12-01 20:07:18 +00:00
Sebastián Ramírez
6e82df816d 🔧 Update sponsors: add Greptile (#14429) 2025-12-01 21:06:57 +01:00
github-actions[bot]
e752224bce 📝 Update release notes
[skip ci]
2025-12-01 13:17:51 +00:00
Sebastián Ramírez
0dee714026 👥 Update FastAPI GitHub topic repositories (#14426)
Co-authored-by: github-actions <github-actions@github.com>
2025-12-01 14:17:29 +01:00
github-actions[bot]
938f471079 📝 Update release notes
[skip ci]
2025-12-01 06:33:00 +00:00
Motov Yurii
6400d8a623 ⬆ Bump markdown-include-variants from 0.0.6 to 0.0.7 (#14423) 2025-12-01 07:32:32 +01:00
github-actions[bot]
f8e46d98a0 📝 Update release notes
[skip ci]
2025-12-01 06:31:20 +00:00
Sebastián Ramírez
8a7ad3d255 👥 Update FastAPI People - Sponsors (#14422)
Co-authored-by: github-actions <github-actions@github.com>
2025-12-01 07:30:56 +01:00
github-actions[bot]
d661bb1324 📝 Update release notes
[skip ci]
2025-12-01 06:28:06 +00:00
Sebastián Ramírez
32aba57b49 👥 Update FastAPI People - Contributors and Translators (#14420)
Co-authored-by: github-actions <github-actions@github.com>
2025-12-01 07:27:43 +01:00
Sebastián Ramírez
f2bab95267 🔖 Release version 0.123.0 2025-11-30 15:47:35 +01:00
github-actions[bot]
c38e3e0108 📝 Update release notes
[skip ci]
2025-11-30 14:46:13 +00:00
Sebastián Ramírez
7fbd30460f 🐛 Cache dependencies that don't use scopes and don't have sub-dependencies with scopes (#14419)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-30 15:45:49 +01:00
330 changed files with 18483 additions and 3389 deletions

View File

@@ -104,7 +104,7 @@ jobs:
path: docs/${{ matrix.lang }}/.cache
- name: Build Docs
run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v6
with:
name: docs-site-${{ matrix.lang }}
path: ./site/**

View File

@@ -13,7 +13,6 @@ env:
jobs:
smokeshow:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
@@ -24,12 +23,10 @@ jobs:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.9'
python-version: '3.13'
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml

View File

@@ -31,35 +31,58 @@ jobs:
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
- name: Install Dependencies
run: uv pip install -r requirements-tests.txt
- name: Install Pydantic v2
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
- name: Lint
run: bash scripts/lint.sh
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.14"
- "3.13"
- "3.12"
- "3.11"
- "3.10"
- "3.9"
- "3.8"
pydantic-version: ["pydantic-v1", "pydantic-v2"]
exclude:
- python-version: "3.14"
pydantic-version: "pydantic-v1"
os: [ windows-latest, macos-latest ]
python-version: [ "3.14" ]
pydantic-version: [ "pydantic>=2.0.2,<3.0.0" ]
include:
- os: macos-latest
python-version: "3.8"
pydantic-version: "pydantic>=1.10.0,<2.0.0"
- os: windows-latest
python-version: "3.8"
pydantic-version: "pydantic>=2.0.2,<3.0.0"
coverage: coverage
- os: ubuntu-latest
python-version: "3.9"
pydantic-version: "pydantic>=1.10.0,<2.0.0"
coverage: coverage
- os: macos-latest
python-version: "3.10"
pydantic-version: "pydantic>=2.0.2,<3.0.0"
- os: windows-latest
python-version: "3.11"
pydantic-version: "pydantic>=1.10.0,<2.0.0"
- os: ubuntu-latest
python-version: "3.12"
pydantic-version: "pydantic>=2.0.2,<3.0.0"
- os: macos-latest
python-version: "3.13"
pydantic-version: "pydantic>=1.10.0,<2.0.0"
- os: windows-latest
python-version: "3.13"
pydantic-version: "pydantic>=2.0.2,<3.0.0"
coverage: coverage
# - os: ubuntu-latest
# python-version: "3.13"
# pydantic-version: "pydantic>=2.0.2,<2.7.0"
# coverage: coverage
- os: ubuntu-latest
python-version: "3.14"
pydantic-version: "pydantic>=2.0.2,<3.0.0"
coverage: coverage
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- name: Dump GitHub context
env:
@@ -80,12 +103,8 @@ jobs:
pyproject.toml
- name: Install Dependencies
run: uv pip install -r requirements-tests.txt
- name: Install Pydantic v1
if: matrix.pydantic-version == 'pydantic-v1'
run: uv pip install "pydantic>=1.10.0,<2.0.0"
- name: Install Pydantic v2
if: matrix.pydantic-version == 'pydantic-v2'
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
- name: Install Pydantic
run: uv pip install "${{ matrix.pydantic-version }}"
# TODO: Remove this once Python 3.8 is no longer supported
- name: Install older AnyIO in Python 3.8
if: matrix.python-version == '3.8'
@@ -96,10 +115,12 @@ jobs:
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
# Do not store coverage for all possible combinations to avoid file size max errors in Smokeshow
- name: Store coverage files
uses: actions/upload-artifact@v5
if: matrix.coverage == 'coverage'
uses: actions/upload-artifact@v6
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.pydantic-version }}
name: coverage-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/coverage/.coverage.*') }}
path: coverage
include-hidden-files: true
@@ -133,14 +154,14 @@ jobs:
merge-multiple: true
- run: ls -la coverage
- run: coverage combine coverage
- run: coverage report
- run: coverage html --title "Coverage for ${{ github.sha }}"
- name: Store coverage HTML
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: coverage-html
path: htmlcov
include-hidden-files: true
- run: coverage report --fail-under=100
# https://github.com/marketplace/actions/alls-green#why
check: # This job does nothing and is only used for the branch protection

View File

@@ -1,6 +1,9 @@
name: Translate
on:
schedule:
- cron: "0 5 15 * *" # Run at 05:00 on the 15 of every month
workflow_dispatch:
inputs:
debug_enabled:
@@ -16,7 +19,7 @@ on:
- update-outdated
- add-missing
- update-and-add
- remove-all-removable
- remove-removable
language:
description: Language to translate to as a letter code (e.g. "es" for Spanish)
type: string
@@ -32,16 +35,12 @@ env:
UV_SYSTEM_PYTHON: 1
jobs:
job:
if: github.repository_owner == 'fastapi'
langs:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
langs: ${{ steps.show-langs.outputs.langs }}
commands: ${{ steps.show-langs.outputs.commands }}
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
@@ -50,8 +49,45 @@ jobs:
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
- name: Export Language Codes
id: show-langs
run: |
echo "langs=$(python ./scripts/translate.py llm-translatable-json)" >> $GITHUB_OUTPUT
echo "commands=$(python ./scripts/translate.py commands-json)" >> $GITHUB_OUTPUT
env:
LANGUAGE: ${{ github.event.inputs.language }}
COMMAND: ${{ github.event.inputs.command }}
translate:
if: github.repository_owner == 'fastapi'
needs: langs
runs-on: ubuntu-latest
strategy:
matrix:
lang: ${{ fromJson(needs.langs.outputs.langs) }}
command: ${{ fromJson(needs.langs.outputs.commands) }}
permissions:
contents: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
requirements**.txt
pyproject.toml
@@ -68,10 +104,11 @@ jobs:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: FastAPI Translate
run: |
python ./scripts/translate.py ${{ github.event.inputs.command }}
python ./scripts/translate.py ${{ matrix.command }}
python ./scripts/translate.py make-pr
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LANGUAGE: ${{ github.event.inputs.language }}
LANGUAGE: ${{ matrix.lang }}
EN_PATH: ${{ github.event.inputs.en_path }}
COMMAND: ${{ matrix.command }}

View File

@@ -40,7 +40,7 @@ The key features are:
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* estimation based on tests on an internal development team, building production applications.</small>
<small>* estimation based on tests conducted by an internal development team, building production applications.</small>
## Sponsors
@@ -61,6 +61,7 @@ The key features are:
<a href="https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source" target="_blank" title="The Gold Standard in Retail Account Linking"><img src="https://fastapi.tiangolo.com/img/sponsors/subtotal.svg"></a>
<a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" target="_blank" title="Deploy enterprise applications at startup speed"><img src="https://fastapi.tiangolo.com/img/sponsors/railway.png"></a>
<a href="https://serpapi.com/?utm_source=fastapi_website" target="_blank" title="SerpApi: Web Search API"><img src="https://fastapi.tiangolo.com/img/sponsors/serpapi.png"></a>
<a href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank" title="Greptile: The AI Code Reviewer"><img src="https://fastapi.tiangolo.com/img/sponsors/greptile.png"></a>
<a href="https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
<a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" target="_blank" title="SDKs for your API | Speakeasy"><img src="https://fastapi.tiangolo.com/img/sponsors/speakeasy.png"></a>
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>

View File

@@ -443,7 +443,7 @@ Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headin
* die Workload
* das Deployment
* bereitstellen
* deployen
* das SDK
* das Software Development Kit

View File

@@ -175,7 +175,7 @@ Sie können denselben `responses`-Parameter verwenden, um verschiedene Medientyp
Sie können beispielsweise einen zusätzlichen Medientyp `image/png` hinzufügen und damit deklarieren, dass Ihre *Pfadoperation* ein JSON-Objekt (mit dem Medientyp `application/json`) oder ein PNG-Bild zurückgeben kann:
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
/// note | Hinweis
@@ -237,7 +237,7 @@ Mit dieser Technik können Sie einige vordefinierte Responses in Ihren *Pfadoper
Zum Beispiel:
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
## Weitere Informationen zu OpenAPI-Responses { #more-information-about-openapi-responses }

View File

@@ -144,7 +144,7 @@ Dies wurde in Version 0.110.0 geändert, um unbehandelten Speicherverbrauch durc
### Hintergrundtasks und Abhängigkeiten mit `yield`, Technische Details { #background-tasks-and-dependencies-with-yield-technical-details }
Vor FastAPI 0.106.0 war das Werfen von Exceptions nach `yield` nicht möglich, der Exit-Code in Abhängigkeiten mit `yield` wurde ausgeführt, nachdem die Response gesendet wurde, sodass [Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} bereits ausgeführt worden wären.
Vor FastAPI 0.106.0 war das Werfen von Exceptions nach `yield` nicht möglich, der Exit-Code in Abhängigkeiten mit `yield` wurde ausgeführt, nachdem die Response gesendet wurde, sodass [Exceptionhandler](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} bereits ausgeführt worden wären.
Dies war so designt, hauptsächlich um die Verwendung derselben von Abhängigkeiten „geyieldeten“ Objekte in Hintergrundtasks zu ermöglichen, da der Exit-Code erst ausgeführt wurde, nachdem die Hintergrundtasks abgeschlossen waren.

View File

@@ -64,7 +64,7 @@ Wenn Sie mehr über HTTPS erfahren möchten, lesen Sie den Leitfaden [Über HTTP
///
### Wie Proxy-Forwarded-Header funktionieren
### Wie Proxy-Forwarded-Header funktionieren { #how-proxy-forwarded-headers-work }
Hier ist eine visuelle Darstellung, wie der **Proxy** weitergeleitete Header zwischen dem Client und dem **Anwendungsserver** hinzufügt:
@@ -228,7 +228,7 @@ Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe d
Beachten Sie, dass der Server (Uvicorn) diesen `root_path` für nichts anderes verwendet als für die Weitergabe an die Anwendung.
Aber wenn Sie mit Ihrem Browser auf <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> gehen, sehen Sie die normale Response:
Aber wenn Sie mit Ihrem Browser auf <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> gehen, sehen Sie die normale Response:
```JSON
{
@@ -443,6 +443,14 @@ Die Dokumentationsoberfläche interagiert mit dem von Ihnen ausgewählten Server
///
/// note | Technische Details
Die Eigenschaft `servers` in der OpenAPI-Spezifikation ist optional.
Wenn Sie den Parameter `servers` nicht angeben und `root_path` den Wert `/` hat, wird die Eigenschaft `servers` im generierten OpenAPI-Schema standardmäßig vollständig weggelassen, was dem Äquivalent eines einzelnen Servers mit einem `url`-Wert von `/` entspricht.
///
### Den automatischen Server von `root_path` deaktivieren { #disable-automatic-server-from-root-path }
Wenn Sie nicht möchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, können Sie den Parameter `root_path_in_servers=False` verwenden:

View File

@@ -4,7 +4,7 @@ FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-M
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>:
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
Das ist dank **Pydantic** ebenfalls möglich, da es <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses` intern unterstützt</a>.
@@ -32,7 +32,7 @@ Wenn Sie jedoch eine Menge Datenklassen herumliegen haben, ist dies ein guter Tr
Sie können `dataclasses` auch im Parameter `response_model` verwenden:
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
Die Datenklasse wird automatisch in eine Pydantic-Datenklasse konvertiert.
@@ -48,7 +48,7 @@ In einigen Fällen müssen Sie möglicherweise immer noch Pydantics Version von
In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.dataclasses` ersetzen, was einen direkten Ersatz darstellt:
{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. Wir importieren `field` weiterhin von Standard-`dataclasses`.

View File

@@ -31,7 +31,7 @@ Sie verfügt über eine *Pfadoperation*, die einen `Invoice`-Body empfängt, und
Dieser Teil ist ziemlich normal, der größte Teil des Codes ist Ihnen wahrscheinlich bereits bekannt:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
/// tip | Tipp
@@ -90,7 +90,7 @@ Wenn Sie diese Sichtweise (des *externen Entwicklers*) vorübergehend übernehme
Erstellen Sie zunächst einen neuen `APIRouter`, der einen oder mehrere Callbacks enthält.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
### Die Callback-*Pfadoperation* erstellen { #create-the-callback-path-operation }
@@ -101,7 +101,7 @@ Sie sollte wie eine normale FastAPI-*Pfadoperation* aussehen:
* Sie sollte wahrscheinlich eine Deklaration des Bodys enthalten, die sie erhalten soll, z. B. `body: InvoiceEvent`.
* Und sie könnte auch eine Deklaration der Response enthalten, die zurückgegeben werden soll, z. B. `response_model=InvoiceEventReceived`.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
@@ -169,7 +169,7 @@ An diesem Punkt haben Sie die benötigte(n) *Callback-Pfadoperation(en)* (diejen
Verwenden Sie nun den Parameter `callbacks` im *Pfadoperation-Dekorator Ihrer API*, um das Attribut `.routes` (das ist eigentlich nur eine `list`e von Routen/*Pfadoperationen*) dieses Callback-Routers zu übergeben:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
/// tip | Tipp

View File

@@ -50,7 +50,7 @@ Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu,
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) können den Rest verwenden.
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
## Zusätzliche Responses { #additional-responses }
@@ -155,13 +155,13 @@ In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Fu
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
////
@@ -179,13 +179,13 @@ Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
////

View File

@@ -34,7 +34,7 @@ Sie können beispielsweise kein Pydantic-Modell in eine `JSONResponse` einfügen
In diesen Fällen können Sie den `jsonable_encoder` verwenden, um Ihre Daten zu konvertieren, bevor Sie sie an eine Response übergeben:
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | Technische Details

View File

@@ -148,7 +148,7 @@ Dies könnte besonders beim Testen nützlich sein, da es sehr einfach ist, eine
Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
{* ../../docs_src/settings/app02/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
@@ -174,7 +174,7 @@ Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einf
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_email` fest, wenn wir das neue `Settings`-Objekt erstellen, und geben dann dieses neue Objekt zurück.
@@ -217,7 +217,7 @@ Und dann aktualisieren Sie Ihre `config.py` mit:
//// tab | Pydantic v2
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip | Tipp
@@ -229,7 +229,7 @@ Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet.
//// tab | Pydantic v1
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
/// tip | Tipp

View File

@@ -1,16 +1,24 @@
# FastAPI bei Cloudanbietern bereitstellen { #deploy-fastapi-on-cloud-providers }
# FastAPI bei Cloudanbietern deployen { #deploy-fastapi-on-cloud-providers }
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung bereitzustellen.
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Bereitstellen von FastAPI an.
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Deployment von FastAPI an.
## FastAPI Cloud { #fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wurde vom selben Autor und Team hinter **FastAPI** entwickelt.
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Zugreifens** auf eine API mit minimalem Aufwand.
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
FastAPI Cloud ist der Hauptsponsor und Finanzierungsgeber für die *FastAPI and friends* Open-Source-Projekte. ✨
## Cloudanbieter Sponsoren { #cloud-providers-sponsors }
Einige Cloudanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, dies stellt die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem** sicher.
Einige andere Cloudanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ ebenfalls. 🙇
Und es zeigt ihr wahres Engagement für FastAPI und seine **Community** (Sie), da sie Ihnen nicht nur einen **guten Service** bieten möchten, sondern auch sicherstellen möchten, dass Sie ein **gutes und gesundes Framework**, FastAPI, haben. 🙇
Vielleicht möchten Sie deren Dienste ausprobieren und deren Anleitungen folgen:
Sie könnten diese ebenfalls in Betracht ziehen, deren Anleitungen folgen und ihre Dienste ausprobieren:
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>

View File

@@ -1,6 +1,6 @@
# Deployment-Konzepte { #deployments-concepts }
Bei dem Deployment der Bereitstellung einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe der Sie die **am besten geeignete** Methode zur **Bereitstellung Ihrer Anwendung** finden können.
Bei dem Deployment der Bereitstellung einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe der Sie die **am besten geeignete** Methode zum **Deployment Ihrer Anwendung** finden können.
Einige wichtige Konzepte sind:
@@ -15,11 +15,11 @@ Wir werden sehen, wie diese sich auf das **Deployment** auswirken.
Letztendlich besteht das ultimative Ziel darin, **Ihre API-Clients** auf **sichere** Weise zu versorgen, um **Unterbrechungen** zu vermeiden und die **Rechenressourcen** (z. B. entfernte Server/virtuelle Maschinen) so effizient wie möglich zu nutzen. 🚀
Ich erzähle Ihnen hier etwas mehr über diese **Konzepte**, was Ihnen hoffentlich die **Intuition** gibt, die Sie benötigen, um zu entscheiden, wie Sie Ihre API in sehr unterschiedlichen Umgebungen bereitstellen, möglicherweise sogar in **zukünftigen**, die jetzt noch nicht existieren.
Ich erzähle Ihnen hier etwas mehr über diese **Konzepte**, was Ihnen hoffentlich die **Intuition** gibt, die Sie benötigen, um zu entscheiden, wie Sie Ihre API in sehr unterschiedlichen Umgebungen deployen, möglicherweise sogar in **zukünftigen**, die jetzt noch nicht existieren.
Durch die Berücksichtigung dieser Konzepte können Sie die beste Variante der Bereitstellung **Ihrer eigenen APIs** **evaluieren und konzipieren**.
Durch die Berücksichtigung dieser Konzepte können Sie die beste Variante des Deployments **Ihrer eigenen APIs** **evaluieren und konzipieren**.
In den nächsten Kapiteln werde ich Ihnen mehr **konkrete Rezepte** für die Bereitstellung von FastAPI-Anwendungen geben.
In den nächsten Kapiteln werde ich Ihnen mehr **konkrete Rezepte** für das Deployment von FastAPI-Anwendungen geben.
Aber schauen wir uns zunächst einmal diese grundlegenden **konzeptionellen Ideen** an. Diese Konzepte gelten auch für jede andere Art von Web-API. 💡
@@ -271,7 +271,7 @@ In diesem Fall müssen Sie sich darüber keine Sorgen machen. 🤷
### Beispiele für Strategien für Vorab-Schritte { #examples-of-previous-steps-strategies }
Es hängt **stark** davon ab, wie Sie **Ihr System bereitstellen**, und hängt wahrscheinlich mit der Art und Weise zusammen, wie Sie Programme starten, Neustarts durchführen, usw.
Es hängt **stark** davon ab, wie Sie **Ihr System deployen**, und hängt wahrscheinlich mit der Art und Weise zusammen, wie Sie Programme starten, Neustarts durchführen, usw.
Hier sind einige mögliche Ideen:
@@ -307,7 +307,7 @@ Sie können einfache Tools wie `htop` verwenden, um die in Ihrem Server verwende
## Zusammenfassung { #recap }
Sie haben hier einige der wichtigsten Konzepte gelesen, die Sie wahrscheinlich berücksichtigen müssen, wenn Sie entscheiden, wie Sie Ihre Anwendung bereitstellen:
Sie haben hier einige der wichtigsten Konzepte gelesen, die Sie wahrscheinlich berücksichtigen müssen, wenn Sie entscheiden, wie Sie Ihre Anwendung deployen:
* Sicherheit HTTPS
* Beim Hochfahren ausführen

View File

@@ -1,6 +1,6 @@
# FastAPI in Containern Docker { #fastapi-in-containers-docker }
Beim Deployment von FastAPI-Anwendungen besteht ein gängiger Ansatz darin, ein **Linux-Containerimage** zu erstellen. Normalerweise erfolgt dies mit <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Sie können dieses Containerimage dann auf eine von mehreren möglichen Arten bereitstellen.
Beim Deployment von FastAPI-Anwendungen besteht ein gängiger Ansatz darin, ein **Linux-Containerimage** zu erstellen. Normalerweise erfolgt dies mit <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Sie können dieses Containerimage dann auf eine von mehreren möglichen Arten deployen.
Die Verwendung von Linux-Containern bietet mehrere Vorteile, darunter **Sicherheit**, **Replizierbarkeit**, **Einfachheit** und andere.
@@ -40,7 +40,7 @@ Linux-Container werden mit demselben Linux-Kernel des Hosts (Maschine, virtuelle
Auf diese Weise verbrauchen Container **wenig Ressourcen**, eine Menge vergleichbar mit der direkten Ausführung der Prozesse (eine virtuelle Maschine würde viel mehr verbrauchen).
Container verfügen außerdem über ihre eigenen **isoliert** laufenden Prozesse (üblicherweise nur einen Prozess), über ihr eigenes Dateisystem und ihr eigenes Netzwerk, was die Bereitstellung, Sicherheit, Entwicklung usw. vereinfacht.
Container verfügen außerdem über ihre eigenen **isoliert** laufenden Prozesse (üblicherweise nur einen Prozess), über ihr eigenes Dateisystem und ihr eigenes Netzwerk, was Deployment, Sicherheit, Entwicklung usw. vereinfacht.
## Was ist ein Containerimage { #what-is-a-container-image }
@@ -598,7 +598,7 @@ Zum Beispiel:
* Mit einem **Kubernetes**-Cluster
* Mit einem Docker Swarm Mode-Cluster
* Mit einem anderen Tool wie Nomad
* Mit einem Cloud-Dienst, der Ihr Containerimage nimmt und es bereitstellt
* Mit einem Cloud-Dienst, der Ihr Containerimage nimmt und es deployt
## Docker-Image mit `uv` { #docker-image-with-uv }

View File

@@ -0,0 +1,65 @@
# FastAPI Cloud { #fastapi-cloud }
Sie können Ihre FastAPI-App in der <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> mit **einem einzigen Befehl** deployen tragen Sie sich in die Warteliste ein, falls noch nicht geschehen. 🚀
## Anmelden { #login }
Stellen Sie sicher, dass Sie bereits ein **FastAPI-Cloud-Konto** haben (wir haben Sie von der Warteliste eingeladen 😉).
Melden Sie sich dann an:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
## Deployen { #deploy }
Stellen Sie Ihre App jetzt mit **einem einzigen Befehl** bereit:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
Das wars! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
## Über FastAPI Cloud { #about-fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wird vom gleichen Autor und Team hinter **FastAPI** entwickelt.
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Nutzens** einer API mit minimalem Aufwand.
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
Es kümmert sich außerdem um das meiste, was beim Deployen einer App nötig ist, zum Beispiel:
* HTTPS
* Replikation, mit Autoscaling basierend auf Requests
* usw.
FastAPI Cloud ist Hauptsponsor und Finanzierer der Open-Source-Projekte *FastAPI and friends*. ✨
## Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
FastAPI ist Open Source und basiert auf Standards. Sie können FastAPI-Apps bei jedem Cloudanbieter Ihrer Wahl deployen.
Folgen Sie den Anleitungen Ihres Cloudanbieters, um dort FastAPI-Apps zu deployen. 🤓
## Auf den eigenen Server deployen { #deploy-your-own-server }
Ich werde Ihnen später in diesem **Deployment-Leitfaden** auch alle Details zeigen, sodass Sie verstehen, was passiert, was geschehen muss und wie Sie FastAPI-Apps selbst deployen können, auch auf Ihre eigenen Server. 🤓

View File

@@ -14,7 +14,9 @@ Das steht im Gegensatz zu den **Entwicklungsphasen**, in denen Sie ständig den
Es gibt mehrere Möglichkeiten, dies zu tun, abhängig von Ihrem spezifischen Anwendungsfall und den von Ihnen verwendeten Tools.
Sie könnten mithilfe einer Kombination von Tools selbst **einen Server bereitstellen**, Sie könnten einen **Cloud-Dienst** nutzen, der einen Teil der Arbeit für Sie erledigt, oder andere mögliche Optionen.
Sie könnten mithilfe einer Kombination von Tools selbst **einen Server deployen**, Sie könnten einen **Cloud-Dienst** nutzen, der einen Teil der Arbeit für Sie erledigt, oder andere mögliche Optionen.
Zum Beispiel haben wir, das Team hinter FastAPI, <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a> entwickelt, um das Deployment von FastAPI-Apps in der Cloud so reibungslos wie möglich zu gestalten, mit derselben Developer-Experience wie beim Arbeiten mit FastAPI.
Ich zeige Ihnen einige der wichtigsten Konzepte, die Sie beim Deployment einer **FastAPI**-Anwendung wahrscheinlich berücksichtigen sollten (obwohl das meiste davon auch für jede andere Art von Webanwendung gilt).

View File

@@ -11,7 +11,7 @@ Schauen wir uns die Deployment-Konzepte von früher noch einmal an:
Bis zu diesem Punkt, in allen Tutorials in der Dokumentation, haben Sie wahrscheinlich ein **Serverprogramm** ausgeführt, zum Beispiel mit dem `fastapi`-Befehl, der Uvicorn startet, und einen **einzelnen Prozess** ausführt.
Wenn Sie Anwendungen bereitstellen, möchten Sie wahrscheinlich eine gewisse **Replikation von Prozessen**, um **mehrere Kerne** zu nutzen und mehr <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> bearbeiten zu können.
Wenn Sie Anwendungen deployen, möchten Sie wahrscheinlich eine gewisse **Replikation von Prozessen**, um **mehrere Kerne** zu nutzen und mehr <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> bearbeiten zu können.
Wie Sie im vorherigen Kapitel über [Deployment-Konzepte](concepts.md){.internal-link target=_blank} gesehen haben, gibt es mehrere Strategien, die Sie anwenden können.

View File

@@ -66,7 +66,7 @@ Das Ausführen von `fastapi run` startet FastAPI standardmäßig im Produktionsm
Standardmäßig ist **Autoreload** deaktiviert. Es horcht auch auf der IP-Adresse `0.0.0.0`, was alle verfügbaren IP-Adressen bedeutet, so wird es öffentlich zugänglich für jeden, der mit der Maschine kommunizieren kann. So würden Sie es normalerweise in der Produktion ausführen, beispielsweise in einem Container.
In den meisten Fällen würden (und sollten) Sie einen „Terminierungsproxy“ haben, der HTTPS für Sie verwaltet. Dies hängt davon ab, wie Sie Ihre Anwendung bereitstellen. Ihr Anbieter könnte dies für Sie erledigen, oder Sie müssen es selbst einrichten.
In den meisten Fällen würden (und sollten) Sie einen „Terminierungsproxy“ haben, der HTTPS für Sie verwaltet. Dies hängt davon ab, wie Sie Ihre Anwendung deployen. Ihr Anbieter könnte dies für Sie erledigen, oder Sie müssen es selbst einrichten.
/// tip | Tipp

View File

@@ -0,0 +1,17 @@
# Alte 403-Authentifizierungsfehler-Statuscodes verwenden { #use-old-403-authentication-error-status-codes }
Vor FastAPI-Version `0.122.0` verwendeten die integrierten Sicherheits-Utilities den HTTP-Statuscode `403 Forbidden`, wenn sie dem Client nach einer fehlgeschlagenen Authentifizierung einen Fehler zurückgaben.
Ab FastAPI-Version `0.122.0` verwenden sie den passenderen HTTP-Statuscode `401 Unauthorized` und geben in der Response einen sinnvollen `WWW-Authenticate`-Header zurück, gemäß den HTTP-Spezifikationen, <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>, <a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>.
Aber falls Ihre Clients aus irgendeinem Grund vom alten Verhalten abhängen, können Sie darauf zurückgreifen, indem Sie in Ihren Sicherheitsklassen die Methode `make_not_authenticated_error` überschreiben.
Sie können beispielsweise eine Unterklasse von `HTTPBearer` erstellen, die einen Fehler `403 Forbidden` zurückgibt, statt des Default-`401 Unauthorized`-Fehlers:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
/// tip | Tipp
Beachten Sie, dass die Funktion die Exception-Instanz zurückgibt; sie wirft sie nicht. Das Werfen erfolgt im restlichen internen Code.
///

View File

@@ -40,7 +40,7 @@ FastAPI enthält einige Defaultkonfigurationsparameter, die für die meisten Anw
Es umfasst die folgenden Defaultkonfigurationen:
{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_parameters` einen anderen Wert festlegen.

View File

@@ -42,7 +42,7 @@ Wenn der Header kein `gzip` enthält, wird nicht versucht, den Body zu dekomprim
Auf diese Weise kann dieselbe Routenklasse gzip-komprimierte oder unkomprimierte Requests verarbeiten.
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen { #create-a-custom-gziproute-class }
@@ -54,7 +54,7 @@ Diese Methode gibt eine Funktion zurück. Und diese Funktion empfängt einen <ab
Hier verwenden wir sie, um aus dem ursprünglichen Request einen `GzipRequest` zu erstellen.
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
/// note | Technische Details
@@ -92,18 +92,18 @@ Wir können denselben Ansatz auch verwenden, um in einem Exceptionhandler auf de
Alles, was wir tun müssen, ist, den Request innerhalb eines `try`/`except`-Blocks zu handhaben:
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
Wenn eine Exception auftritt, befindet sich die `Request`-Instanz weiterhin im Gültigkeitsbereich, sodass wir den Requestbody lesen und bei der Fehlerbehandlung verwenden können:
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
## Benutzerdefinierte `APIRoute`-Klasse in einem Router { #custom-apiroute-class-in-a-router }
Sie können auch den Parameter `route_class` eines `APIRouter` festlegen:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
In diesem Beispiel verwenden die *Pfadoperationen* unter dem `router` die benutzerdefinierte `TimedRoute`-Klasse und haben in der Response einen zusätzlichen `X-Response-Time`-Header mit der Zeit, die zum Generieren der Response benötigt wurde:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}

View File

@@ -46,20 +46,26 @@ Seine Schlüssel-Merkmale sind:
* **Robust**: Erhalten Sie produktionsreifen Code. Mit automatischer, interaktiver Dokumentation.
* **Standards-basiert**: Basierend auf (und vollständig kompatibel mit) den offenen Standards für APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (früher bekannt als Swagger) und <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* Schätzung basierend auf Tests in einem internen Entwicklungsteam, das Produktionsanwendungen erstellt.</small>
<small>* Schätzung basierend auf Tests, die von einem internen Entwicklungsteam durchgeführt wurden, das Produktionsanwendungen erstellt.</small>
## Sponsoren { #sponsors }
<!-- sponsors -->
{% if sponsors %}
### Keystone-Sponsor
{% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
### Gold- und Silber-Sponsoren
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
<!-- /sponsors -->
@@ -444,6 +450,58 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
* **Cookie-Sessions**
* ... und mehr.
### Ihre App deployen (optional) { #deploy-your-app-optional }
Optional können Sie Ihre FastAPI-App in die <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem einzigen Befehl deployen.
Stellen Sie vor dem Deployen sicher, dass Sie eingeloggt sind:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
Stellen Sie dann Ihre App bereit:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
Das wars! Jetzt können Sie unter dieser URL auf Ihre App zugreifen. ✨
#### Über FastAPI Cloud { #about-fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wird vom selben Autor und Team hinter **FastAPI** entwickelt.
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Zugreifens** auf eine API mit minimalem Aufwand.
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
FastAPI Cloud ist der Hauptsponsor und Finanzierer der „FastAPI and friends“ Open-Source-Projekte. ✨
#### Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
FastAPI ist Open Source und basiert auf Standards. Sie können FastAPI-Apps bei jedem Cloudanbieter Ihrer Wahl deployen.
Folgen Sie den Anleitungen Ihres Cloudanbieters, um FastAPI-Apps dort bereitzustellen. 🤓
## Performanz { #performance }
Unabhängige TechEmpower-Benchmarks zeigen **FastAPI**-Anwendungen, die unter Uvicorn laufen, als <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">eines der schnellsten verfügbaren Python-Frameworks</a>, nur hinter Starlette und Uvicorn selbst (intern von FastAPI verwendet). (*)

View File

@@ -9,20 +9,20 @@ GitHub-Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-templ
## Full Stack FastAPI Template Technologiestack und Funktionen { #full-stack-fastapi-template-technology-stack-and-features }
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/de) für die Python-Backend-API.
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
- 🚀 [React](https://react.dev) für das Frontend.
- 💃 Verwendung von TypeScript, Hooks, [Vite](https://vitejs.dev) und anderen Teilen eines modernen Frontend-Stacks.
- 🎨 [Chakra UI](https://chakra-ui.com) für die Frontend-Komponenten.
- 🤖 Ein automatisch generierter Frontend-Client.
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
- 🦇 Unterstützung des Dunkelmodus.
- 💃 Verwendung von TypeScript, Hooks, [Vite](https://vitejs.dev) und anderen Teilen eines modernen Frontend-Stacks.
- 🎨 [Tailwind CSS](https://tailwindcss.com) und [shadcn/ui](https://ui.shadcn.com) für die Frontend-Komponenten.
- 🤖 Ein automatisch generierter Frontend-Client.
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
- 🦇 „Dark-Mode“-Unterstützung.
- 🐋 [Docker Compose](https://www.docker.com) für Entwicklung und Produktion.
- 🔒 Sicheres Passwort-Hashing standardmäßig.
- 🔑 JWT-Token-Authentifizierung.
- 🔑 JWT (JSON Web Token)-Token-Authentifizierung.
- 📫 E-Mail-basierte Passwortwiederherstellung.
- ✅ Tests mit [Pytest](https://pytest.org).
- 📞 [Traefik](https://traefik.io) als Reverse-Proxy / Load Balancer.
- 🚢 Deployment-Anleitungen unter Verwendung von Docker Compose, einschließlich der Einrichtung eines Frontend-Traefik-Proxys zur Handhabung automatischer HTTPS-Zertifikate.
- 🏭 CI (kontinuierliche Integration) und CD (kontinuierliche Bereitstellung) basierend auf GitHub Actions.
- 🏭 CI (kontinuierliche Integration) und CD (kontinuierliches Deployment) basierend auf GitHub Actions.

View File

@@ -1,3 +1,3 @@
# Ressourcen { #resources }
Zusätzliche Ressourcen, externe Links, Artikel und mehr. ✈️
Zusätzliche Ressourcen, externe Links und mehr. ✈️

View File

@@ -85,9 +85,7 @@ Sie können die *Pfadoperationen* für dieses Modul mit `APIRouter` erstellen.
Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie mit der Klasse `FastAPI`:
```Python hl_lines="1 3" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### *Pfadoperationen* mit `APIRouter` { #path-operations-with-apirouter }
@@ -95,9 +93,7 @@ Und dann verwenden Sie ihn, um Ihre *Pfadoperationen* zu deklarieren.
Verwenden Sie ihn auf die gleiche Weise wie die Klasse `FastAPI`:
```Python hl_lines="6 11 16" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
Sie können sich `APIRouter` als eine „Mini-`FastAPI`“-Klasse vorstellen.
@@ -121,35 +117,7 @@ Also fügen wir sie in ihr eigenes `dependencies`-Modul (`app/dependencies.py`)
Wir werden nun eine einfache Abhängigkeit verwenden, um einen benutzerdefinierten `X-Token`-Header zu lesen:
//// tab | Python 3.9+
```Python hl_lines="3 6-8" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="1 5-7" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1 4-6" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app/dependencies.py!}
```
////
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | Tipp
@@ -181,9 +149,7 @@ Wir wissen, dass alle *Pfadoperationen* in diesem Modul folgendes haben:
Anstatt also alles zu jeder *Pfadoperation* hinzuzufügen, können wir es dem `APIRouter` hinzufügen.
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
Da der Pfad jeder *Pfadoperation* mit `/` beginnen muss, wie in:
@@ -242,9 +208,7 @@ Und wir müssen die Abhängigkeitsfunktion aus dem Modul `app.dependencies` impo
Daher verwenden wir einen relativen Import mit `..` für die Abhängigkeiten:
```Python hl_lines="3" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
#### Wie relative Importe funktionieren { #how-relative-imports-work }
@@ -315,9 +279,7 @@ Wir fügen weder das Präfix `/items` noch `tags=["items"]` zu jeder *Pfadoperat
Aber wir können immer noch _mehr_ `tags` hinzufügen, die auf eine bestimmte *Pfadoperation* angewendet werden, sowie einige zusätzliche `responses`, die speziell für diese *Pfadoperation* gelten:
```Python hl_lines="30-31" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | Tipp
@@ -343,17 +305,13 @@ Sie importieren und erstellen wie gewohnt eine `FastAPI`-Klasse.
Und wir können sogar [globale Abhängigkeiten](dependencies/global-dependencies.md){.internal-link target=_blank} deklarieren, die mit den Abhängigkeiten für jeden `APIRouter` kombiniert werden:
```Python hl_lines="1 3 7" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
### Den `APIRouter` importieren { #import-the-apirouter }
Jetzt importieren wir die anderen Submodule, die `APIRouter` haben:
```Python hl_lines="4-5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
Da es sich bei den Dateien `app/routers/users.py` und `app/routers/items.py` um Submodule handelt, die Teil desselben Python-Packages `app` sind, können wir einen einzelnen Punkt `.` verwenden, um sie mit „relativen Imports“ zu importieren.
@@ -416,17 +374,13 @@ würde der `router` von `users` den von `items` überschreiben und wir könnten
Um also beide in derselben Datei verwenden zu können, importieren wir die Submodule direkt:
```Python hl_lines="5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
### Die `APIRouter` für `users` und `items` inkludieren { #include-the-apirouters-for-users-and-items }
Inkludieren wir nun die `router` aus diesen Submodulen `users` und `items`:
```Python hl_lines="10-11" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
/// info | Info
@@ -466,17 +420,13 @@ Sie enthält einen `APIRouter` mit einigen administrativen *Pfadoperationen*, di
In diesem Beispiel wird es ganz einfach sein. Nehmen wir jedoch an, dass wir, da sie mit anderen Projekten in der Organisation geteilt wird, sie nicht ändern und kein `prefix`, `dependencies`, `tags`, usw. direkt zum `APIRouter` hinzufügen können:
```Python hl_lines="3" title="app/internal/admin.py"
{!../../docs_src/bigger_applications/app/internal/admin.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
Aber wir möchten immer noch ein benutzerdefiniertes `prefix` festlegen, wenn wir den `APIRouter` einbinden, sodass alle seine *Pfadoperationen* mit `/admin` beginnen, wir möchten es mit den `dependencies` sichern, die wir bereits für dieses Projekt haben, und wir möchten `tags` und `responses` hinzufügen.
Wir können das alles deklarieren, ohne den ursprünglichen `APIRouter` ändern zu müssen, indem wir diese Parameter an `app.include_router()` übergeben:
```Python hl_lines="14-17" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
Auf diese Weise bleibt der ursprüngliche `APIRouter` unverändert, sodass wir dieselbe `app/internal/admin.py`-Datei weiterhin mit anderen Projekten in der Organisation teilen können.
@@ -497,9 +447,7 @@ Wir können *Pfadoperationen* auch direkt zur `FastAPI`-App hinzufügen.
Hier machen wir es ... nur um zu zeigen, dass wir es können 🤷:
```Python hl_lines="21-23" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
und es wird korrekt funktionieren, zusammen mit allen anderen *Pfadoperationen*, die mit `app.include_router()` hinzugefügt wurden.

View File

@@ -50,7 +50,7 @@ Ihre API hat jetzt die Macht, ihre eigene <abbr title="Das ist ein Scherz, nur f
Sie können die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu verbieten (`forbid`):
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
Wenn ein Client versucht, einige **zusätzliche Cookies** zu senden, erhält er eine **Error-<abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**.

View File

@@ -143,6 +143,42 @@ Es gibt dutzende Alternativen, die alle auf OpenAPI basieren. Sie können jede d
Ebenfalls können Sie es verwenden, um automatisch Code für Clients zu generieren, die mit Ihrer API kommunizieren. Zum Beispiel für Frontend-, Mobile- oder IoT-Anwendungen.
### Ihre App deployen (optional) { #deploy-your-app-optional }
Sie können optional Ihre FastAPI-App in der <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, treten Sie der Warteliste bei, falls Sie es noch nicht getan haben. 🚀
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem Befehl deployen.
Vor dem Deployen, stellen Sie sicher, dass Sie eingeloggt sind:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
Dann stellen Sie Ihre App bereit:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
Das war's! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
## Zusammenfassung, Schritt für Schritt { #recap-step-by-step }
### Schritt 1: `FastAPI` importieren { #step-1-import-fastapi }
@@ -314,6 +350,26 @@ Sie können auch Pydantic-Modelle zurückgeben (dazu später mehr).
Es gibt viele andere Objekte und Modelle, die automatisch zu JSON konvertiert werden (einschließlich ORMs, usw.). Versuchen Sie, Ihre Lieblingsobjekte zu verwenden. Es ist sehr wahrscheinlich, dass sie bereits unterstützt werden.
### Schritt 6: Deployen { #step-6-deploy-it }
Stellen Sie Ihre App in der **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** mit einem Befehl bereit: `fastapi deploy`. 🎉
#### Über FastAPI Cloud { #about-fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wird vom selben Autor und Team hinter **FastAPI** entwickelt.
Es vereinfacht den Prozess des Erstellens, Deployens und des Zugriffs auf eine API mit minimalem Aufwand.
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
FastAPI Cloud ist der Hauptsponsor und Finanzierer der „FastAPI and friends“ Open-Source-Projekte. ✨
#### Zu anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
FastAPI ist Open Source und basiert auf Standards. Sie können FastAPI-Apps bei jedem Cloudanbieter Ihrer Wahl deployen.
Folgen Sie den Anleitungen Ihres Cloudanbieters, um dort FastAPI-Apps bereitzustellen. 🤓
## Zusammenfassung { #recap }
* Importieren Sie `FastAPI`.
@@ -321,3 +377,4 @@ Es gibt viele andere Objekte und Modelle, die automatisch zu JSON konvertiert we
* Schreiben Sie einen **Pfadoperation-Dekorator** unter Verwendung von Dekoratoren wie `@app.get("/")`.
* Definieren Sie eine **Pfadoperation-Funktion**, zum Beispiel `def root(): ...`.
* Starten Sie den Entwicklungsserver mit dem Befehl `fastapi dev`.
* Optional: Ihre App mit `fastapi deploy` deployen.

View File

@@ -127,7 +127,7 @@ Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und ve
Der Exceptionhandler erhält einen `Request` und die Exception.
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen JSON-Fehlers mit:
@@ -149,36 +149,17 @@ Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen
eine Textversion mit:
```
1 validation error
path -> item_id
value is not a valid integer (type=type_error.integer)
Validation errors:
Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
```
#### `RequestValidationError` vs. `ValidationError` { #requestvalidationerror-vs-validationerror }
/// warning | Achtung
Dies sind technische Details, die Sie überspringen können, wenn sie für Sie jetzt nicht wichtig sind.
///
`RequestValidationError` ist eine Unterklasse von Pydantics <a href="https://docs.pydantic.dev/latest/concepts/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a>.
**FastAPI** verwendet diesen so, dass, wenn Sie ein Pydantic-Modell in `response_model` verwenden und Ihre Daten einen Fehler haben, Sie den Fehler in Ihrem Log sehen.
Aber der Client/Benutzer wird ihn nicht sehen. Stattdessen erhält der Client einen „Internal Server Error“ mit einem HTTP-Statuscode `500`.
Es sollte so sein, denn wenn Sie einen Pydantic `ValidationError` in Ihrer *Response* oder irgendwo anders in Ihrem Code haben (nicht im *Request* des Clients), ist es tatsächlich ein Fehler in Ihrem Code.
Und während Sie den Fehler beheben, sollten Ihre Clients/Benutzer keinen Zugriff auf interne Informationen über den Fehler haben, da das eine Sicherheitslücke aufdecken könnte.
### Überschreiben des `HTTPException`-Fehlerhandlers { #override-the-httpexception-error-handler }
Auf die gleiche Weise können Sie den `HTTPException`-Handler überschreiben.
Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
/// note | Technische Details
@@ -188,6 +169,14 @@ Sie könnten auch `from starlette.responses import PlainTextResponse` verwenden.
///
/// warning | Achtung
Beachten Sie, dass der `RequestValidationError` Informationen über den Dateinamen und die Zeile enthält, in der der Validierungsfehler auftritt, sodass Sie ihn bei Bedarf mit den relevanten Informationen in Ihren Logs anzeigen können.
Das bedeutet aber auch, dass, wenn Sie ihn einfach in einen String umwandeln und diese Informationen direkt zurückgeben, Sie möglicherweise ein paar Informationen über Ihr System preisgeben. Daher extrahiert und zeigt der Code hier jeden Fehler getrennt.
///
### Verwenden des `RequestValidationError`-Bodys { #use-the-requestvalidationerror-body }
Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen Daten.

View File

@@ -65,7 +65,7 @@ Es gibt ein paar Unterschiede:
* `Field(primary_key=True)` sagt SQLModel, dass die `id` der **Primärschlüssel** in der SQL-Datenbank ist (Sie können mehr über SQL-Primärschlüssel in der SQLModel-Dokumentation erfahren).
Durch das Festlegen des Typs als `int | None` wird SQLModel wissen, dass diese Spalte ein `INTEGER` in der SQL-Datenbank sein sollte und dass sie `NULLABLE` sein sollte.
**Hinweis:** Wir verwenden für das Primärschlüsselfeld `int | None`, damit wir im Python-Code *ein Objekt ohne `id` erstellen* können (`id=None`), in der Annahme, dass die Datenbank sie *beim Speichern generiert*. SQLModel versteht, dass die Datenbank die `id` bereitstellt, und *definiert die Spalte im Datenbankschema als ein Nicht-Null-`INTEGER`*. Siehe die <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">SQLModel-Dokumentation zu Primärschlüsseln</a> für Details.
* `Field(index=True)` sagt SQLModel, dass es einen **SQL-Index** für diese Spalte erstellen soll, was schnelleres Suchen in der Datenbank ermöglicht, wenn Daten mittels dieser Spalte gefiltert werden.

View File

@@ -122,63 +122,13 @@ Sie verfügt über eine `POST`-Operation, die mehrere Fehler zurückgeben könnt
Beide *Pfadoperationen* erfordern einen `X-Token`-Header.
//// tab | Python 3.10+
```Python
{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
```
////
//// tab | Python 3.9+
```Python
{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
```
////
//// tab | Python 3.8+
```Python
{!> ../../docs_src/app_testing/app_b_an/main.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python
{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python
{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
### Erweiterte Testdatei { #extended-testing-file }
Anschließend könnten Sie `test_main.py` mit den erweiterten Tests aktualisieren:
{* ../../docs_src/app_testing/app_b/test_main.py *}
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
Wenn Sie möchten, dass der Client Informationen im Request übergibt und Sie nicht wissen, wie das geht, können Sie suchen (googeln), wie es mit `httpx` gemacht wird, oder sogar, wie es mit `requests` gemacht wird, da das Design von HTTPX auf dem Design von Requests basiert.

View File

@@ -242,6 +242,26 @@ $ python -m pip install --upgrade pip
</div>
/// tip | Tipp
Manchmal kann beim Versuch, `pip` zu aktualisieren, der Fehler **`No module named pip`** auftreten.
Wenn das passiert, installieren und aktualisieren Sie `pip` mit dem folgenden Befehl:
<div class="termy">
```console
$ python -m ensurepip --upgrade
---> 100%
```
</div>
Dieser Befehl installiert `pip`, falls es noch nicht installiert ist, und stellt außerdem sicher, dass die installierte Version von `pip` mindestens so aktuell ist wie die in `ensurepip` verfügbare.
///
## `.gitignore` hinzufügen { #add-gitignore }
Wenn Sie **Git** verwenden (was Sie sollten), fügen Sie eine `.gitignore`-Datei hinzu, um alles in Ihrem `.venv` von Git auszuschließen.

View File

@@ -255,6 +255,7 @@ Below is a list of English terms and their preferred German translations, separa
* «the default value»: «der Defaultwert»
* «the default value»: NOT «der Standardwert»
* «the default declaration»: «die Default-Deklaration»
* «the deployment»: «das Deployment»
* «the dict»: «das Dict»
* «the dictionary»: «das Dictionary»
* «the enumeration»: «die Enumeration»
@@ -316,6 +317,7 @@ Below is a list of English terms and their preferred German translations, separa
* «the worker process»: «der Workerprozess»
* «the worker process»: NOT «der Arbeiterprozess»
* «to commit»: «committen»
* «to deploy» (in the cloud): «deployen»
* «to modify»: «ändern»
* «to serve» (an application): «bereitstellen»
* «to serve» (a response): «ausliefern»

View File

@@ -1,21 +1,21 @@
tiangolo:
login: tiangolo
count: 794
count: 808
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
dependabot:
login: dependabot
count: 126
count: 130
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
url: https://github.com/apps/dependabot
alejsdev:
login: alejsdev
count: 52
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=447d12a1b347f466b35378bee4c7104cc9b2c571&v=4
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4
url: https://github.com/alejsdev
pre-commit-ci:
login: pre-commit-ci
count: 49
count: 50
avatarUrl: https://avatars.githubusercontent.com/in/68672?v=4
url: https://github.com/apps/pre-commit-ci
github-actions:
@@ -28,31 +28,31 @@ Kludex:
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
YuriiMotov:
login: YuriiMotov
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov
dmontagu:
login: dmontagu
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
YuriiMotov:
login: YuriiMotov
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov
nilslindemann:
login: nilslindemann
count: 14
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
svlandeg:
login: svlandeg
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
euri10:
login: euri10
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
svlandeg:
login: svlandeg
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
kantandane:
login: kantandane
count: 13
@@ -103,6 +103,11 @@ waynerv:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
musicinmybrain:
login: musicinmybrain
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
url: https://github.com/musicinmybrain
krishnamadhavan:
login: krishnamadhavan
count: 5
@@ -133,11 +138,6 @@ iudeen:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
url: https://github.com/iudeen
musicinmybrain:
login: musicinmybrain
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
url: https://github.com/musicinmybrain
philipokiokio:
login: philipokiokio
count: 4
@@ -483,6 +483,11 @@ nzig:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/7372858?u=e769add36ed73c778cdb136eb10bf96b1e119671&v=4
url: https://github.com/nzig
kristjanvalur:
login: kristjanvalur
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6009543?u=1419f20bbfff8f031be8cb470962e7e62de2595e&v=4
url: https://github.com/kristjanvalur
yezz123:
login: yezz123
count: 2

View File

@@ -1,430 +0,0 @@
Articles:
English:
- author: Apitally
author_link: https://apitally.io
link: https://apitally.io/blog/getting-started-with-logging-in-fastapi
title: Getting started with logging in FastAPI
- author: Balthazar Rouberol
author_link: https://balthazar-rouberol.com
link: https://blog.balthazar-rouberol.com/how-to-profile-a-fastapi-asynchronous-request
title: How to profile a FastAPI asynchronous request
- author: Stephen Siegert - Neon
link: https://neon.tech/blog/deploy-a-serverless-fastapi-app-with-neon-postgres-and-aws-app-runner-at-any-scale
title: Deploy a Serverless FastAPI App with Neon Postgres and AWS App Runner at any scale
- author: Kurtis Pykes - NVIDIA
link: https://developer.nvidia.com/blog/building-a-machine-learning-microservice-with-fastapi/
title: Building a Machine Learning Microservice with FastAPI
- author: Ravgeet Dhillon - Twilio
link: https://www.twilio.com/en-us/blog/booking-appointments-twilio-notion-fastapi
title: Booking Appointments with Twilio, Notion, and FastAPI
- author: Abhinav Tripathi - Microsoft Blogs
link: https://devblogs.microsoft.com/cosmosdb/azure-cosmos-db-python-and-fastapi/
title: Write a Python data layer with Azure Cosmos DB and FastAPI
- author: Donny Peeters
author_link: https://github.com/Donnype
link: https://bitestreams.com/blog/fastapi-sqlalchemy/
title: 10 Tips for adding SQLAlchemy to FastAPI
- author: Jessica Temporal
author_link: https://jtemporal.com/socials
link: https://jtemporal.com/tips-on-migrating-from-flask-to-fastapi-and-vice-versa/
title: Tips on migrating from Flask to FastAPI and vice-versa
- author: Ankit Anchlia
author_link: https://linkedin.com/in/aanchlia21
link: https://hackernoon.com/explore-how-to-effectively-use-jwt-with-fastapi
title: Explore How to Effectively Use JWT With FastAPI
- author: Nicoló Lino
author_link: https://www.nlino.com
link: https://github.com/softwarebloat/python-tracing-demo
title: Instrument FastAPI with OpenTelemetry tracing and visualize traces in Grafana Tempo.
- author: Mikhail Rozhkov, Elena Samuylova
author_link: https://www.linkedin.com/in/mnrozhkov/
link: https://www.evidentlyai.com/blog/fastapi-tutorial
title: ML serving and monitoring with FastAPI and Evidently
- author: Visual Studio Code Team
author_link: https://code.visualstudio.com/
link: https://code.visualstudio.com/docs/python/tutorial-fastapi
title: FastAPI Tutorial in Visual Studio Code
- author: Apitally
author_link: https://apitally.io
link: https://blog.apitally.io/fastapi-application-monitoring-made-easy
title: FastAPI application monitoring made easy
- author: John Philip
author_link: https://medium.com/@amjohnphilip
link: https://python.plainenglish.io/building-a-restful-api-with-fastapi-secure-signup-and-login-functionality-included-45cdbcb36106
title: "Building a RESTful API with FastAPI: Secure Signup and Login Functionality Included"
- author: Keshav Malik
author_link: https://theinfosecguy.xyz/
link: https://blog.theinfosecguy.xyz/building-a-crud-api-with-fastapi-and-supabase-a-step-by-step-guide
title: Building a CRUD API with FastAPI and Supabase
- author: Adejumo Ridwan Suleiman
author_link: https://www.linkedin.com/in/adejumoridwan/
link: https://medium.com/python-in-plain-english/build-an-sms-spam-classifier-serverless-database-with-faunadb-and-fastapi-23dbb275bc5b
title: Build an SMS Spam Classifier Serverless Database with FaunaDB and FastAPI
- author: Raf Rasenberg
author_link: https://rafrasenberg.com/about/
link: https://rafrasenberg.com/fastapi-lambda/
title: 'FastAPI lambda container: serverless simplified'
- author: Teresa N. Fontanella De Santis
author_link: https://dev.to/
link: https://dev.to/teresafds/authorization-on-fastapi-with-casbin-41og
title: Authorization on FastAPI with Casbin
- author: New Relic
author_link: https://newrelic.com
link: https://newrelic.com/instant-observability/fastapi/e559ec64-f765-4470-a15f-1901fcebb468
title: How to monitor FastAPI application performance using Python agent
- author: Jean-Baptiste Rocher
author_link: https://hashnode.com/@jibrocher
link: https://dev.indooroutdoor.io/series/fastapi-react-poll-app
title: Building the Poll App From Django Tutorial With FastAPI And React
- author: Silvan Melchior
author_link: https://github.com/silvanmelchior
link: https://blog.devgenius.io/seamless-fastapi-configuration-with-confz-90949c14ea12
title: Seamless FastAPI Configuration with ConfZ
- author: Kaustubh Gupta
author_link: https://medium.com/@kaustubhgupta1828/
link: https://levelup.gitconnected.com/5-advance-features-of-fastapi-you-should-try-7c0ac7eebb3e
title: 5 Advanced Features of FastAPI You Should Try
- author: Kaustubh Gupta
author_link: https://medium.com/@kaustubhgupta1828/
link: https://www.analyticsvidhya.com/blog/2021/06/deploying-ml-models-as-api-using-fastapi-and-heroku/
title: Deploying ML Models as API Using FastAPI and Heroku
- link: https://jarmos.netlify.app/posts/using-github-actions-to-deploy-a-fastapi-project-to-heroku/
title: Using GitHub Actions to Deploy a FastAPI Project to Heroku
author_link: https://jarmos.netlify.app/
author: Somraj Saha
- author: "@pystar"
author_link: https://pystar.substack.com/
link: https://pystar.substack.com/p/how-to-create-a-fake-certificate
title: How to Create A Fake Certificate Authority And Generate TLS Certs for FastAPI
- author: Ben Gamble
author_link: https://uk.linkedin.com/in/bengamble7
link: https://ably.com/blog/realtime-ticket-booking-solution-kafka-fastapi-ably
title: Building a realtime ticket booking solution with Kafka, FastAPI, and Ably
- author: Shahriyar(Shako) Rzayev
author_link: https://www.linkedin.com/in/shahriyar-rzayev/
link: https://www.azepug.az/posts/fastapi/#building-simple-e-commerce-with-nuxtjs-and-fastapi-series
title: Building simple E-Commerce with NuxtJS and FastAPI
- author: Rodrigo Arenas
author_link: https://rodrigo-arenas.medium.com/
link: https://medium.com/analytics-vidhya/serve-a-machine-learning-model-using-sklearn-fastapi-and-docker-85aabf96729b
title: "Serve a machine learning model using Sklearn, FastAPI and Docker"
- author: Yashasvi Singh
author_link: https://hashnode.com/@aUnicornDev
link: https://aunicorndev.hashnode.dev/series/supafast-api
title: "Building an API with FastAPI and Supabase and Deploying on Deta"
- author: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/deploy-fastapi-on-ubuntu-gunicorn-caddy-2/
title: Deploy FastAPI on Ubuntu and Serve using Caddy 2 Web Server
- author: Patrick Ladon
author_link: https://dev.to/factorlive
link: https://dev.to/factorlive/python-facebook-messenger-webhook-with-fastapi-on-glitch-4n90
title: Python Facebook messenger webhook with FastAPI on Glitch
- author: Valon Januzaj
author_link: https://www.linkedin.com/in/valon-januzaj-b02692187/
link: https://valonjanuzaj.medium.com/deploy-a-dockerized-fastapi-application-to-aws-cc757830ba1b
title: Deploy a dockerized FastAPI application to AWS
- author: Amit Chaudhary
author_link: https://x.com/amitness
link: https://amitness.com/2020/06/fastapi-vs-flask/
title: FastAPI for Flask Users
- author: Louis Guitton
author_link: https://x.com/louis_guitton
link: https://guitton.co/posts/fastapi-monitoring/
title: How to monitor your FastAPI service
- author: Precious Ndubueze
author_link: https://medium.com/@gabbyprecious2000
link: https://medium.com/@gabbyprecious2000/creating-a-crud-app-with-fastapi-part-one-7c049292ad37
title: Creating a CRUD App with FastAPI (Part one)
- author: Farhad Malik
author_link: https://medium.com/@farhadmalik
link: https://towardsdatascience.com/build-and-host-fast-data-science-applications-using-fastapi-823be8a1d6a0
title: Build And Host Fast Data Science Applications Using FastAPI
- author: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/deploy-fastapi-on-azure/
title: Deploy FastAPI on Azure App Service
- author: Davide Fiocco
author_link: https://github.com/davidefiocco
link: https://davidefiocco.github.io/streamlit-fastapi-ml-serving/
title: Machine learning model serving in Python using FastAPI and streamlit
- author: Netflix
author_link: https://netflixtechblog.com/
link: https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072
title: Introducing Dispatch
- author: Stavros Korokithakis
author_link: https://x.com/Stavros
link: https://www.stavros.io/posts/fastapi-with-django/
title: Using FastAPI with Django
- author: Twilio
author_link: https://www.twilio.com
link: https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi
title: Build a Secure Twilio Webhook with Python and FastAPI
- author: Sebastián Ramírez (tiangolo)
author_link: https://x.com/tiangolo
link: https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe
title: Build a web API from scratch with FastAPI - the workshop
- author: Paul Sec
author_link: https://x.com/PaulWebSec
link: https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/
title: FastAPI + Zeit.co = 🚀
- author: cuongld2
author_link: https://dev.to/cuongld2
link: https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o
title: Build simple API service with Python FastAPI — Part 1
- author: Paurakh Sharma Humagain
author_link: https://x.com/PaurakhSharma
link: https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc
title: Microservice in Python using FastAPI
- author: Guillermo Cruz
author_link: https://wuilly.com/
link: https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/
title: Real-time Notifications with Python and Postgres
- author: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/
title: Create and Deploy FastAPI app to Heroku without using Docker
- author: Arthur Henrique
author_link: https://x.com/arthurheinrique
link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb
title: 'Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest'
- author: Shane Soh
author_link: https://medium.com/@shane.soh
link: https://medium.com/analytics-vidhya/deploy-machine-learning-models-with-keras-fastapi-redis-and-docker-4940df614ece
title: Deploy Machine Learning Models with Keras, FastAPI, Redis and Docker
- author: Mandy Gu
author_link: https://towardsdatascience.com/@mandygu
link: https://towardsdatascience.com/deploying-iris-classifications-with-fastapi-and-docker-7c9b83fdec3a
title: 'Towards Data Science: Deploying Iris Classifications with FastAPI and Docker'
- author: Michael Herman
author_link: https://testdriven.io/authors/herman
link: https://testdriven.io/blog/fastapi-crud/
title: 'TestDriven.io: Developing and Testing an Asynchronous API with FastAPI and Pytest'
- author: Bernard Brenyah
author_link: https://medium.com/@bbrenyah
link: https://medium.com/python-data/how-to-deploy-tensorflow-2-0-models-as-an-api-service-with-fastapi-docker-128b177e81f3
title: How To Deploy Tensorflow 2.0 Models As An API Service With FastAPI & Docker
- author: Dylan Anthony
author_link: https://dev.to/dbanty
link: https://dev.to/dbanty/why-i-m-leaving-flask-3ki6
title: Why I'm Leaving Flask
- author: Mike Moritz
author_link: https://medium.com/@mike.p.moritz
link: https://medium.com/@mike.p.moritz/using-docker-compose-to-deploy-a-lightweight-python-rest-api-with-a-job-queue-37e6072a209b
title: Using Docker Compose to deploy a lightweight Python REST API with a job queue
- author: '@euri10'
author_link: https://gitlab.com/euri10
link: https://gitlab.com/euri10/fastapi_cheatsheet
title: A FastAPI and Swagger UI visual cheatsheet
- author: Uber Engineering
author_link: https://eng.uber.com
link: https://eng.uber.com/ludwig-v0-2/
title: 'Uber: Ludwig v0.2 Adds New Features and Other Improvements to its Deep Learning Toolbox [including a FastAPI server]'
- author: Maarten Grootendorst
author_link: https://www.linkedin.com/in/mgrootendorst/
link: https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf
title: How to Deploy a Machine Learning Model
- author: Johannes Gontrum
author_link: https://x.com/gntrm
link: https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e
title: JWT Authentication with FastAPI and AWS Cognito
- author: Ankush Thakur
author_link: https://geekflare.com/author/ankush/
link: https://geekflare.com/python-asynchronous-web-frameworks/
title: Top 5 Asynchronous Web Frameworks for Python
- author: Nico Axtmann
author_link: https://www.linkedin.com/in/nico-axtmann
link: https://medium.com/@nico.axtmann95/deploying-a-scikit-learn-model-with-onnx-und-fastapi-1af398268915
title: Deploying a scikit-learn model with ONNX and FastAPI
- author: Nils de Bruin
author_link: https://medium.com/@nilsdebruin
link: https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680
title: 'FastAPI authentication revisited: Enabling API key authentication'
- author: Nick Cortale
author_link: https://nickc1.github.io/
link: https://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
title: 'FastAPI and Scikit-Learn: Easily Deploy Models'
- author: Errieta Kostala
author_link: https://dev.to/errietta
link: https://dev.to/errietta/introduction-to-the-fastapi-python-framework-2n10
title: Introduction to the fastapi python framework
- author: Nils de Bruin
author_link: https://medium.com/@nilsdebruin
link: https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3
title: FastAPIHow to add basic and cookie authentication
- author: Nils de Bruin
author_link: https://medium.com/@nilsdebruin
link: https://medium.com/data-rebels/fastapi-google-as-an-external-authentication-provider-3a527672cf33
title: FastAPIGoogle as an external authentication provider
- author: William Hayes
author_link: https://medium.com/@williamhayes
link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59
title: FastAPI/Starlette debug vs prod
- author: Mukul Mantosh
author_link: https://x.com/MantoshMukul
link: https://www.jetbrains.com/pycharm/guide/tutorials/fastapi-aws-kubernetes/
title: Developing FastAPI Application using K8s & AWS
- author: KrishNa
author_link: https://medium.com/@krishnardt365
link: https://medium.com/@krishnardt365/fastapi-docker-and-postgres-91943e71be92
title: Fastapi, Docker(Docker compose) and Postgres
- author: Devon Ray
author_link: https://devonray.com
link: https://devonray.com/blog/deploying-a-fastapi-project-using-aws-lambda-aurora-cdk
title: Deployment using Docker, Lambda, Aurora, CDK & GH Actions
- author: Shubhendra Kushwaha
author_link: https://www.linkedin.com/in/theshubhendra/
link: https://theshubhendra.medium.com/mastering-soft-delete-advanced-sqlalchemy-techniques-4678f4738947
title: 'Mastering Soft Delete: Advanced SQLAlchemy Techniques'
- author: Shubhendra Kushwaha
author_link: https://www.linkedin.com/in/theshubhendra/
link: https://theshubhendra.medium.com/role-based-row-filtering-advanced-sqlalchemy-techniques-733e6b1328f6
title: 'Role based row filtering: Advanced SQLAlchemy Techniques'
German:
- author: Marcel Sander (actidoo)
author_link: https://www.actidoo.com
link: https://www.actidoo.com/de/blog/python-fastapi-domain-driven-design
title: Domain-driven Design mit Python und FastAPI
- author: Nico Axtmann
author_link: https://x.com/_nicoax
link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI
- author: Felix Schürmeyer
author_link: https://hellocoding.de/autor/felix-schuermeyer/
link: https://hellocoding.de/blog/coding-language/python/fastapi
title: REST-API Programmieren mittels Python und dem FastAPI Modul
Japanese:
- author: '@bee2'
author_link: https://qiita.com/bee2
link: https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9
title: '[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する'
- author: '@bee2'
author_link: https://qiita.com/bee2
link: https://qiita.com/bee2/items/0ad260ab9835a2087dae
title: PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-admin-page-improvement
title: '【第4回】FastAPIチュートリアル: toDoアプリを作ってみよう【管理者ページ改良編】'
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-authentication-user-registration
title: '【第3回】FastAPIチュートリアル: toDoアプリを作ってみよう【認証・ユーザ登録編】'
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-model-building
title: '【第2回】FastAPIチュートリアル: ToDoアプリを作ってみよう【モデル構築編】'
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment
title: '【第1回】FastAPIチュートリアル: ToDoアプリを作ってみよう【環境構築編】'
- author: Hikaru Takahashi
author_link: https://qiita.com/hikarut
link: https://qiita.com/hikarut/items/b178af2e2440c67c6ac4
title: フロントエンド開発者向けのDockerによるPython開発環境構築
- author: '@angel_katayoku'
author_link: https://qiita.com/angel_katayoku
link: https://qiita.com/angel_katayoku/items/8a458a8952f50b73f420
title: FastAPIでPOSTされたJSONのレスポンスbodyを受け取る
- author: '@angel_katayoku'
author_link: https://qiita.com/angel_katayoku
link: https://qiita.com/angel_katayoku/items/4fbc1a4e2b33fa2237d2
title: FastAPIをMySQLと接続してDockerで管理してみる
- author: '@angel_katayoku'
author_link: https://qiita.com/angel_katayoku
link: https://qiita.com/angel_katayoku/items/0e1f5dbbe62efc612a78
title: FastAPIでCORSを回避
- author: '@ryoryomaru'
author_link: https://qiita.com/ryoryomaru
link: https://qiita.com/ryoryomaru/items/59958ed385b3571d50de
title: python製の最新APIフレームワーク FastAPI を触ってみた
- author: '@mtitg'
author_link: https://qiita.com/mtitg
link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPIDB接続してCRUDするPython製APIサーバーを構築
Portuguese:
- author: Eduardo Mendes
author_link: https://bolha.us/@dunossauro
link: https://fastapidozero.dunossauro.com/
title: FastAPI do ZERO
- author: Jessica Temporal
author_link: https://jtemporal.com/socials
link: https://jtemporal.com/dicas-para-migrar-de-flask-para-fastapi-e-vice-versa/
title: Dicas para migrar uma aplicação de Flask para FastAPI e vice-versa
Russian:
- author: Troy Köhler
author_link: https://www.linkedin.com/in/trkohler/
link: https://trkohler.com/fast-api-introduction-to-framework
title: 'FastAPI: знакомимся с фреймворком'
- author: prostomarkeloff
author_link: https://github.com/prostomarkeloff
link: https://habr.com/ru/post/478620/
title: Почему Вы должны попробовать FastAPI?
- author: Andrey Korchak
author_link: https://habr.com/ru/users/57uff3r/
link: https://habr.com/ru/post/454440/
title: 'Мелкая питонячая радость #2: Starlette - Солидная примочка FastAPI'
Vietnamese:
- author: Nguyễn Nhân
author_link: https://fullstackstation.com/author/figonking/
link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
title: 'FASTAPI: TRIỂN KHAI BẰNG DOCKER'
Taiwanese:
- author: Leon
author_link: http://editor.leonh.space/
link: https://editor.leonh.space/2022/tortoise/
title: 'Tortoise ORM / FastAPI 整合快速筆記'
Spanish:
- author: Eduardo Zepeda
author_link: https://coffeebytes.dev/en/authors/eduardo-zepeda/
link: https://coffeebytes.dev/es/python-fastapi-el-mejor-framework-de-python/
title: 'Tutorial de FastAPI, ¿el mejor framework de Python?'
Podcasts:
English:
- author: Behind the Commit
author_link: https://www.youtube.com/@BehindtheCommit
link: https://youtu.be/iaDRYUQ0OMM
title: Why FastAPI Became Pythons FastestGrowing Framework Chat with Sebastián Ramírez
- author: Real Python
author_link: https://realpython.com/
link: https://realpython.com/podcasts/rpp/72/
title: Starting With FastAPI and Examining Python's Import System - Episode 72
- author: Python Bytes FM
author_link: https://pythonbytes.fm/
link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
title: 'Do you dare to press "."? - Episode 247 - Dan #6: SQLModel - use the same models for SQL and FastAPI'
- author: Podcast.`__init__`
author_link: https://www.pythonpodcast.com/
link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
title: Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)
- author: Python Bytes FM
author_link: https://pythonbytes.fm/
link: https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855
title: FastAPI on PythonBytes
Talks:
English:
- author: Sebastián Ramírez (tiangolo)
author_link: https://x.com/tiangolo
link: https://www.youtube.com/watch?v=mwvmfl8nN_U
title: 'Keynote: Behind the scenes of FastAPI and friends for developers and builders — Sebastián Ramírez'
- author: Jeny Sadadia
author_link: https://github.com/JenySadadia
link: https://www.youtube.com/watch?v=uZdTe8_Z6BQ
title: 'PyCon AU 2023: Testing asynchronous applications with FastAPI and pytest'
- author: Sebastián Ramírez (tiangolo)
author_link: https://x.com/tiangolo
link: https://www.youtube.com/watch?v=PnpTY1f4k2U
title: '[VIRTUAL] Py.Amsterdam''s flying Software Circus: Intro to FastAPI'
- author: Sebastián Ramírez (tiangolo)
author_link: https://x.com/tiangolo
link: https://www.youtube.com/watch?v=z9K5pwb0rt8
title: 'PyConBY 2020: Serve ML models easily with FastAPI'
- author: Chris Withers
author_link: https://x.com/chriswithers13
link: https://www.youtube.com/watch?v=3DLwPcrE5mA
title: 'PyCon UK 2019: FastAPI from the ground up'
Taiwanese:
- author: Blueswen
author_link: https://github.com/blueswen
link: https://www.youtube.com/watch?v=y3sumuoDq4w
title: 'PyCon TW 2024: 全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例'

View File

@@ -23,9 +23,6 @@ sponsors:
- login: railwayapp
avatarUrl: https://avatars.githubusercontent.com/u/66716858?v=4
url: https://github.com/railwayapp
- login: scalar
avatarUrl: https://avatars.githubusercontent.com/u/301879?v=4
url: https://github.com/scalar
- - login: dribia
avatarUrl: https://avatars.githubusercontent.com/u/41189616?v=4
url: https://github.com/dribia
@@ -44,25 +41,25 @@ sponsors:
- login: permitio
avatarUrl: https://avatars.githubusercontent.com/u/71775833?v=4
url: https://github.com/permitio
- - login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
- login: mercedes-benz
avatarUrl: https://avatars.githubusercontent.com/u/34240465?v=4
url: https://github.com/mercedes-benz
- login: Ponte-Energy-Partners
- - login: Ponte-Energy-Partners
avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
url: https://github.com/Ponte-Energy-Partners
- login: LambdaTest-Inc
avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4
url: https://github.com/LambdaTest-Inc
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
- login: requestly
avatarUrl: https://avatars.githubusercontent.com/u/12287519?v=4
url: https://github.com/requestly
- login: acsone
avatarUrl: https://avatars.githubusercontent.com/u/7601056?v=4
url: https://github.com/acsone
- - login: Trivie
- - login: scalar
avatarUrl: https://avatars.githubusercontent.com/u/301879?v=4
url: https://github.com/scalar
- login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie
- - login: takashi-yoneya
@@ -71,42 +68,30 @@ sponsors:
- login: Doist
avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4
url: https://github.com/Doist
- login: bholagabbar
avatarUrl: https://avatars.githubusercontent.com/u/11693595?v=4
url: https://github.com/bholagabbar
- - login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
- - login: alixlahuec
avatarUrl: https://avatars.githubusercontent.com/u/29543316?u=44357eb2a93bccf30fb9d389b8befe94a3d00985&v=4
url: https://github.com/alixlahuec
- login: Partho
avatarUrl: https://avatars.githubusercontent.com/u/2034301?u=ce195ac36835cca0cdfe6dd6e897bd38873a1524&v=4
url: https://github.com/Partho
- - login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
- login: xsalagarcia
avatarUrl: https://avatars.githubusercontent.com/u/66035908?v=4
url: https://github.com/xsalagarcia
- - login: upciti
avatarUrl: https://avatars.githubusercontent.com/u/43346262?v=4
url: https://github.com/upciti
- login: GonnaFlyMethod
avatarUrl: https://avatars.githubusercontent.com/u/60840539?u=edf70b373fd4f1a83d3eb7c6802f4b6addb572cf&v=4
url: https://github.com/GonnaFlyMethod
- login: ChargeStorm
avatarUrl: https://avatars.githubusercontent.com/u/26000165?v=4
url: https://github.com/ChargeStorm
- login: DanielYang59
avatarUrl: https://avatars.githubusercontent.com/u/80093591?u=63873f701c7c74aac83c906800a1dddc0bc8c92f&v=4
url: https://github.com/DanielYang59
- login: nilslindemann
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
- - login: samuelcolvin
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
url: https://github.com/samuelcolvin
- login: vincentkoc
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
url: https://github.com/vincentkoc
- login: otosky
avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
url: https://github.com/otosky
@@ -137,9 +122,6 @@ sponsors:
- login: jugeeem
avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4
url: https://github.com/jugeeem
- login: connorpark24
avatarUrl: https://avatars.githubusercontent.com/u/142128990?u=09b84a4beb1f629b77287a837bcf3729785cdd89&v=4
url: https://github.com/connorpark24
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
url: https://github.com/patsatsia
@@ -155,9 +137,9 @@ sponsors:
- login: kaoru0310
avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4
url: https://github.com/kaoru0310
- login: DelfinaCare
avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
url: https://github.com/DelfinaCare
- login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden
- login: knallgelb
avatarUrl: https://avatars.githubusercontent.com/u/2358812?u=c48cb6362b309d74cbf144bd6ad3aed3eb443e82&v=4
url: https://github.com/knallgelb
@@ -191,9 +173,6 @@ sponsors:
- login: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen
- login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden
- login: paulcwatts
avatarUrl: https://avatars.githubusercontent.com/u/150269?u=1819e145d573b44f0ad74b87206d21cd60331d4e&v=4
url: https://github.com/paulcwatts
@@ -233,9 +212,6 @@ sponsors:
- login: mjohnsey
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
url: https://github.com/mjohnsey
- login: enguy-hub
avatarUrl: https://avatars.githubusercontent.com/u/16822912?u=2c45f9e7f427b2f2f3b023d7fdb0d44764c92ae8&v=4
url: https://github.com/enguy-hub
- login: ashi-agrawal
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
url: https://github.com/ashi-agrawal
@@ -260,10 +236,7 @@ sponsors:
- - login: manoelpqueiroz
avatarUrl: https://avatars.githubusercontent.com/u/23669137?u=b12e84b28a84369ab5b30bd5a79e5788df5a0756&v=4
url: https://github.com/manoelpqueiroz
- - login: ceb10n
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: pawamoy
- - login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
- login: siavashyj
@@ -281,9 +254,9 @@ sponsors:
- login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=6cc9028f3db63f8f60ad21c17b1ce4b88c4e2e60&v=4
url: https://github.com/hgalytoby
- login: johnl28
avatarUrl: https://avatars.githubusercontent.com/u/54412955?u=47dd06082d1c39caa90c752eb55566e4f3813957&v=4
url: https://github.com/johnl28
- login: nisutec
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
url: https://github.com/nisutec
- login: hoenie-ams
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
url: https://github.com/hoenie-ams
@@ -299,21 +272,24 @@ sponsors:
- login: petercool
avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=75aa8c6729e6e8f85a300561c4dbeef9d65c8797&v=4
url: https://github.com/petercool
- login: johnl28
avatarUrl: https://avatars.githubusercontent.com/u/54412955?u=47dd06082d1c39caa90c752eb55566e4f3813957&v=4
url: https://github.com/johnl28
- login: PunRabbit
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
url: https://github.com/PunRabbit
- login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/PelicanQ
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=8a80356e3e7d5a417157aba7ea565dabc8678327&v=4
url: https://github.com/WillHogan
- login: my3
avatarUrl: https://avatars.githubusercontent.com/u/1825270?v=4
url: https://github.com/my3
- login: danielunderwood
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
url: https://github.com/danielunderwood
- login: rangulvers
avatarUrl: https://avatars.githubusercontent.com/u/5235430?u=e254d4af4ace5a05fa58372ae677c7d26f0d5a53&v=4
url: https://github.com/rangulvers
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
@@ -323,15 +299,21 @@ sponsors:
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: ceb10n
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: miguelgr
avatarUrl: https://avatars.githubusercontent.com/u/1484589?u=54556072b8136efa12ae3b6902032ea2a39ace4b&v=4
url: https://github.com/miguelgr
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=8a80356e3e7d5a417157aba7ea565dabc8678327&v=4
url: https://github.com/WillHogan
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
url: https://github.com/xncbf
- login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
url: https://github.com/DMantis
- login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
@@ -347,9 +329,9 @@ sponsors:
- login: joshuatz
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
url: https://github.com/joshuatz
- login: nisutec
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
url: https://github.com/nisutec
- login: rangulvers
avatarUrl: https://avatars.githubusercontent.com/u/5235430?u=e254d4af4ace5a05fa58372ae677c7d26f0d5a53&v=4
url: https://github.com/rangulvers
- login: sdevkota
avatarUrl: https://avatars.githubusercontent.com/u/5250987?u=4ed9a120c89805a8aefda1cbdc0cf6512e64d1b4&v=4
url: https://github.com/sdevkota
@@ -368,19 +350,7 @@ sponsors:
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
url: https://github.com/xncbf
- login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
url: https://github.com/DMantis
- - login: morzan1001
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
url: https://github.com/morzan1001
- login: larsyngvelundin
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
url: https://github.com/larsyngvelundin
- login: andrecorumba
- - login: andrecorumba
avatarUrl: https://avatars.githubusercontent.com/u/37807517?u=9b9be3b41da9bda60957da9ef37b50dbf65baa61&v=4
url: https://github.com/andrecorumba
- login: KOZ39
@@ -389,21 +359,30 @@ sponsors:
- login: rwxd
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd
- login: morzan1001
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
url: https://github.com/morzan1001
- login: Olegt0rr
avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4
url: https://github.com/Olegt0rr
- login: dinoz0rg
avatarUrl: https://avatars.githubusercontent.com/u/32940067?u=739cda1eb123a2dd5e1db45c361396f239e23f8b&v=4
url: https://github.com/dinoz0rg
- login: larsyngvelundin
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
url: https://github.com/larsyngvelundin
- login: hippoley
avatarUrl: https://avatars.githubusercontent.com/u/135493401?u=1164ef48a645a7c12664fabc1638fbb7e1c459b0&v=4
url: https://github.com/hippoley
- login: 4anklee
avatarUrl: https://avatars.githubusercontent.com/u/144109238?u=a79c0d581b2a3d8f3897e7ef4c012640a6c1eb3a&v=4
url: https://github.com/4anklee
- login: CoderDeltaLAN
avatarUrl: https://avatars.githubusercontent.com/u/152043745?u=4ff541efffb7d134e60c5fcf2dd1e343f90bb782&v=4
url: https://github.com/CoderDeltaLAN
- login: chris1ding1
avatarUrl: https://avatars.githubusercontent.com/u/194386334?u=5500604b50e35ed8a5aeb82ce34aa5d3ee3f88c7&v=4
url: https://github.com/chris1ding1
- login: onestn
avatarUrl: https://avatars.githubusercontent.com/u/62360849?u=746dd21c34e7e06eefb11b03e8bb01aaae3c2a4f&v=4
url: https://github.com/onestn
- login: Rubinskiy
avatarUrl: https://avatars.githubusercontent.com/u/62457878?u=f2e35ed3d196a99cfadb5a29a91950342af07e34&v=4
url: https://github.com/Rubinskiy
- login: nayasinghania
avatarUrl: https://avatars.githubusercontent.com/u/74111380?u=752e99a5e139389fdc0a0677122adc08438eb076&v=4
url: https://github.com/nayasinghania
@@ -413,9 +392,6 @@ sponsors:
- login: andreagrandi
avatarUrl: https://avatars.githubusercontent.com/u/636391?u=13d90cb8ec313593a5b71fbd4e33b78d6da736f5&v=4
url: https://github.com/andreagrandi
- login: Olegt0rr
avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4
url: https://github.com/Olegt0rr
- login: msserpa
avatarUrl: https://avatars.githubusercontent.com/u/6334934?u=82c4489eb1559d88d2990d60001901b14f722bbb&v=4
url: https://github.com/msserpa

View File

@@ -33,6 +33,9 @@ gold:
- url: https://serpapi.com/?utm_source=fastapi_website
title: "SerpApi: Web Search API"
img: https://fastapi.tiangolo.com/img/sponsors/serpapi.png
- url: https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page
title: "Greptile: The AI Code Reviewer"
img: https://fastapi.tiangolo.com/img/sponsors/greptile.png
silver:
- url: https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display
title: Pay as you go for market data

View File

@@ -47,3 +47,4 @@ logins:
- railwayapp
- subtotal
- requestly
- greptileai

View File

@@ -1,368 +1,388 @@
- name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 38779
stars: 39475
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python
stars: 32726
stars: 33090
owner_login: mouredev
owner_html_url: https://github.com/mouredev
- name: serve
html_url: https://github.com/jina-ai/serve
stars: 21779
stars: 21798
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: HivisionIDPhotos
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
stars: 20028
stars: 20258
owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin
- name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel
stars: 17038
stars: 17212
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Douyin_TikTok_Download_API
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
stars: 14786
stars: 15145
owner_login: Evil0ctal
owner_html_url: https://github.com/Evil0ctal
- name: fastapi-best-practices
html_url: https://github.com/zhanymkanov/fastapi-best-practices
stars: 13968
stars: 14644
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: machine-learning-zoomcamp
html_url: https://github.com/DataTalksClub/machine-learning-zoomcamp
stars: 12171
stars: 12320
owner_login: DataTalksClub
owner_html_url: https://github.com/DataTalksClub
- name: fastapi_mcp
html_url: https://github.com/tadata-org/fastapi_mcp
stars: 10976
stars: 11174
owner_login: tadata-org
owner_html_url: https://github.com/tadata-org
- name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi
stars: 10618
owner_login: mjhea0
owner_html_url: https://github.com/mjhea0
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 10243
stars: 10858
owner_login: MODSetter
owner_html_url: https://github.com/MODSetter
- name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi
stars: 10758
owner_login: mjhea0
owner_html_url: https://github.com/mjhea0
- name: XHS-Downloader
html_url: https://github.com/JoeanAmier/XHS-Downloader
stars: 9062
stars: 9313
owner_login: JoeanAmier
owner_html_url: https://github.com/JoeanAmier
- name: FastUI
html_url: https://github.com/pydantic/FastUI
stars: 8892
stars: 8915
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: polar
html_url: https://github.com/polarsource/polar
stars: 8084
stars: 8339
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox
stars: 7494
stars: 7721
owner_login: vastsa
owner_html_url: https://github.com/vastsa
- name: nonebot2
html_url: https://github.com/nonebot/nonebot2
stars: 7128
stars: 7170
owner_login: nonebot
owner_html_url: https://github.com/nonebot
- name: hatchet
html_url: https://github.com/hatchet-dev/hatchet
stars: 6155
stars: 6253
owner_login: hatchet-dev
owner_html_url: https://github.com/hatchet-dev
- name: serge
html_url: https://github.com/serge-chat/serge
stars: 5754
owner_login: serge-chat
owner_html_url: https://github.com/serge-chat
- name: fastapi-users
html_url: https://github.com/fastapi-users/fastapi-users
stars: 5683
stars: 5849
owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users
- name: serge
html_url: https://github.com/serge-chat/serge
stars: 5756
owner_login: serge-chat
owner_html_url: https://github.com/serge-chat
- name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry
stars: 4452
stars: 4569
owner_login: strawberry-graphql
owner_html_url: https://github.com/strawberry-graphql
- name: chatgpt-web-share
html_url: https://github.com/chatpire/chatgpt-web-share
stars: 4296
stars: 4294
owner_login: chatpire
owner_html_url: https://github.com/chatpire
- name: poem
html_url: https://github.com/poem-web/poem
stars: 4235
stars: 4276
owner_login: poem-web
owner_html_url: https://github.com/poem-web
- name: dynaconf
html_url: https://github.com/dynaconf/dynaconf
stars: 4174
stars: 4202
owner_login: dynaconf
owner_html_url: https://github.com/dynaconf
- name: atrilabs-engine
html_url: https://github.com/Atri-Labs/atrilabs-engine
stars: 4094
stars: 4093
owner_login: Atri-Labs
owner_html_url: https://github.com/Atri-Labs
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 3875
stars: 4019
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: logfire
html_url: https://github.com/pydantic/logfire
stars: 3717
stars: 3805
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: LitServe
html_url: https://github.com/Lightning-AI/LitServe
stars: 3615
stars: 3719
owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI
- name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3632
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 3554
stars: 3609
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: huma
html_url: https://github.com/danielgtaylor/huma
stars: 3521
stars: 3603
owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor
- name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3497
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: farfalle
html_url: https://github.com/rashadphz/farfalle
stars: 3476
stars: 3490
owner_login: rashadphz
owner_html_url: https://github.com/rashadphz
- name: tracecat
html_url: https://github.com/TracecatHQ/tracecat
stars: 3310
stars: 3379
owner_login: TracecatHQ
owner_html_url: https://github.com/TracecatHQ
- name: opyrator
html_url: https://github.com/ml-tooling/opyrator
stars: 3134
stars: 3135
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: docarray
html_url: https://github.com/docarray/docarray
stars: 3108
stars: 3114
owner_login: docarray
owner_html_url: https://github.com/docarray
- name: devpush
html_url: https://github.com/hunvreus/devpush
stars: 3097
owner_login: hunvreus
owner_html_url: https://github.com/hunvreus
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 2945
stars: 3050
owner_login: nsidnev
owner_html_url: https://github.com/nsidnev
- name: uvicorn-gunicorn-fastapi-docker
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
stars: 2809
stars: 2911
owner_login: tiangolo
owner_html_url: https://github.com/tiangolo
- name: devpush
html_url: https://github.com/hunvreus/devpush
stars: 2784
owner_login: hunvreus
owner_html_url: https://github.com/hunvreus
- name: mcp-context-forge
html_url: https://github.com/IBM/mcp-context-forge
stars: 2763
stars: 2899
owner_login: IBM
owner_html_url: https://github.com/IBM
- name: best-of-web-python
html_url: https://github.com/ml-tooling/best-of-web-python
stars: 2630
stars: 2648
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2464
owner_login: Buuntu
owner_html_url: https://github.com/Buuntu
- name: FastAPI-template
html_url: https://github.com/s3rius/FastAPI-template
stars: 2453
stars: 2637
owner_login: s3rius
owner_html_url: https://github.com/s3rius
- name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT
stars: 2444
owner_login: paulpierre
owner_html_url: https://github.com/paulpierre
- name: sqladmin
html_url: https://github.com/aminalaee/sqladmin
stars: 2423
owner_login: aminalaee
owner_html_url: https://github.com/aminalaee
- name: nextpy
html_url: https://github.com/dot-agent/nextpy
stars: 2325
owner_login: dot-agent
owner_html_url: https://github.com/dot-agent
- name: supabase-py
html_url: https://github.com/supabase/supabase-py
stars: 2292
owner_login: supabase
owner_html_url: https://github.com/supabase
- name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2214
owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs
- name: YC-Killer
html_url: https://github.com/sahibzada-allahyar/YC-Killer
stars: 2599
owner_login: sahibzada-allahyar
owner_html_url: https://github.com/sahibzada-allahyar
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2569
owner_login: Buuntu
owner_html_url: https://github.com/Buuntu
- name: Yuxi-Know
html_url: https://github.com/xerrors/Yuxi-Know
stars: 2212
stars: 2563
owner_login: xerrors
owner_html_url: https://github.com/xerrors
- name: langserve
html_url: https://github.com/langchain-ai/langserve
stars: 2191
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: sqladmin
html_url: https://github.com/aminalaee/sqladmin
stars: 2558
owner_login: aminalaee
owner_html_url: https://github.com/aminalaee
- name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT
stars: 2451
owner_login: paulpierre
owner_html_url: https://github.com/paulpierre
- name: supabase-py
html_url: https://github.com/supabase/supabase-py
stars: 2344
owner_login: supabase
owner_html_url: https://github.com/supabase
- name: nextpy
html_url: https://github.com/dot-agent/nextpy
stars: 2335
owner_login: dot-agent
owner_html_url: https://github.com/dot-agent
- name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2185
stars: 2291
owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils
- name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2220
owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs
- name: langserve
html_url: https://github.com/langchain-ai/langserve
stars: 2215
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: solara
html_url: https://github.com/widgetti/solara
stars: 2111
stars: 2122
owner_login: widgetti
owner_html_url: https://github.com/widgetti
- name: mangum
html_url: https://github.com/Kludex/mangum
stars: 2011
stars: 2029
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: agentkit
html_url: https://github.com/BCG-X-Official/agentkit
stars: 1826
stars: 1912
owner_login: BCG-X-Official
owner_html_url: https://github.com/BCG-X-Official
- name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022
stars: 1815
owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno
- name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi
stars: 1787
stars: 1885
owner_login: ycd
owner_html_url: https://github.com/ycd
- name: ormar
html_url: https://github.com/collerek/ormar
stars: 1780
owner_login: collerek
owner_html_url: https://github.com/collerek
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 1758
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client
stars: 1731
stars: 1862
owner_login: openapi-generators
owner_html_url: https://github.com/openapi-generators
- name: piccolo
html_url: https://github.com/piccolo-orm/piccolo
stars: 1711
stars: 1836
owner_login: piccolo-orm
owner_html_url: https://github.com/piccolo-orm
- name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache
stars: 1677
owner_login: long2ice
owner_html_url: https://github.com/long2ice
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 1831
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022
stars: 1817
owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1669
stars: 1798
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve
stars: 1632
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache
stars: 1789
owner_login: long2ice
owner_html_url: https://github.com/long2ice
- name: ormar
html_url: https://github.com/collerek/ormar
stars: 1783
owner_login: collerek
owner_html_url: https://github.com/collerek
- name: termpair
html_url: https://github.com/cs01/termpair
stars: 1621
stars: 1716
owner_login: cs01
owner_html_url: https://github.com/cs01
- name: FastAPI-boilerplate
html_url: https://github.com/benavlabs/FastAPI-boilerplate
stars: 1596
stars: 1660
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1573
owner_login: ExpDev07
owner_html_url: https://github.com/ExpDev07
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1553
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: fastapi-langgraph-agent-production-ready-template
html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template
stars: 1638
owner_login: wassim249
owner_html_url: https://github.com/wassim249
- name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve
stars: 1635
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: awesome-fastapi-projects
html_url: https://github.com/Kludex/awesome-fastapi-projects
stars: 1485
stars: 1589
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: fastapi-pagination
html_url: https://github.com/uriyyo/fastapi-pagination
stars: 1473
stars: 1585
owner_login: uriyyo
owner_html_url: https://github.com/uriyyo
- name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1574
owner_login: ExpDev07
owner_html_url: https://github.com/ExpDev07
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1559
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: bracket
html_url: https://github.com/evroon/bracket
stars: 1470
stars: 1489
owner_login: evroon
owner_html_url: https://github.com/evroon
- name: fastapi-langgraph-agent-production-ready-template
html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template
stars: 1456
owner_login: wassim249
owner_html_url: https://github.com/wassim249
- name: fastapi-amis-admin
html_url: https://github.com/amisadmin/fastapi-amis-admin
stars: 1475
owner_login: amisadmin
owner_html_url: https://github.com/amisadmin
- name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1424
stars: 1436
owner_login: teamhide
owner_html_url: https://github.com/teamhide
- name: awesome-python-resources
html_url: https://github.com/DjangoEx/awesome-python-resources
stars: 1420
stars: 1426
owner_login: DjangoEx
owner_html_url: https://github.com/DjangoEx
- name: fastapi-amis-admin
html_url: https://github.com/amisadmin/fastapi-amis-admin
stars: 1363
owner_login: amisadmin
owner_html_url: https://github.com/amisadmin
- name: fastcrud
html_url: https://github.com/benavlabs/fastcrud
stars: 1362
stars: 1414
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1388
owner_login: trallnag
owner_html_url: https://github.com/trallnag
- name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 1378
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1375
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: budgetml
html_url: https://github.com/ebhy/budgetml
stars: 1345
@@ -370,126 +390,106 @@
owner_html_url: https://github.com/ebhy
- name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1315
stars: 1327
owner_login: liaogx
owner_html_url: https://github.com/liaogx
- name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 1311
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1270
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1264
owner_login: trallnag
owner_html_url: https://github.com/trallnag
- name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
stars: 1259
owner_login: jonra1993
owner_html_url: https://github.com/jonra1993
- name: fastapi-scaff
html_url: https://github.com/atpuxiner/fastapi-scaff
stars: 1255
owner_login: atpuxiner
owner_html_url: https://github.com/atpuxiner
- name: bedrock-chat
html_url: https://github.com/aws-samples/bedrock-chat
stars: 1243
stars: 1254
owner_login: aws-samples
owner_html_url: https://github.com/aws-samples
- name: bolt-python
html_url: https://github.com/slackapi/bolt-python
stars: 1238
stars: 1253
owner_login: slackapi
owner_html_url: https://github.com/slackapi
- name: fastapi_production_template
html_url: https://github.com/zhanymkanov/fastapi_production_template
stars: 1209
stars: 1217
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: fastapi-scaff
html_url: https://github.com/atpuxiner/fastapi-scaff
stars: 1200
owner_login: atpuxiner
owner_html_url: https://github.com/atpuxiner
- name: langchain-extract
html_url: https://github.com/langchain-ai/langchain-extract
stars: 1173
stars: 1176
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
stars: 1162
owner_login: jonra1993
owner_html_url: https://github.com/jonra1993
- name: odmantic
html_url: https://github.com/art049/odmantic
stars: 1137
owner_login: art049
owner_html_url: https://github.com/art049
- name: restish
html_url: https://github.com/rest-sh/restish
stars: 1129
stars: 1140
owner_login: rest-sh
owner_html_url: https://github.com/rest-sh
- name: kubetorch
html_url: https://github.com/run-house/kubetorch
stars: 1065
owner_login: run-house
owner_html_url: https://github.com/run-house
- name: flock
html_url: https://github.com/Onelevenvy/flock
stars: 1039
owner_login: Onelevenvy
owner_html_url: https://github.com/Onelevenvy
- name: odmantic
html_url: https://github.com/art049/odmantic
stars: 1138
owner_login: art049
owner_html_url: https://github.com/art049
- name: authx
html_url: https://github.com/yezz123/authx
stars: 1017
stars: 1119
owner_login: yezz123
owner_html_url: https://github.com/yezz123
- name: autollm
html_url: https://github.com/viddexa/autollm
stars: 997
owner_login: viddexa
owner_html_url: https://github.com/viddexa
- name: lanarky
html_url: https://github.com/ajndkr/lanarky
stars: 993
owner_login: ajndkr
owner_html_url: https://github.com/ajndkr
- name: RuoYi-Vue3-FastAPI
html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI
stars: 974
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: aktools
html_url: https://github.com/akfamily/aktools
stars: 972
owner_login: akfamily
owner_html_url: https://github.com/akfamily
- name: titiler
html_url: https://github.com/developmentseed/titiler
stars: 965
owner_login: developmentseed
owner_html_url: https://github.com/developmentseed
- name: secure
html_url: https://github.com/TypeError/secure
stars: 953
owner_login: TypeError
owner_html_url: https://github.com/TypeError
- name: energy-forecasting
html_url: https://github.com/iusztinpaul/energy-forecasting
stars: 949
owner_login: iusztinpaul
owner_html_url: https://github.com/iusztinpaul
- name: every-pdf
html_url: https://github.com/DDULDDUCK/every-pdf
stars: 942
owner_login: DDULDDUCK
owner_html_url: https://github.com/DDULDDUCK
- name: langcorn
html_url: https://github.com/msoedov/langcorn
stars: 933
owner_login: msoedov
owner_html_url: https://github.com/msoedov
- name: NoteDiscovery
html_url: https://github.com/gamosoft/NoteDiscovery
stars: 1107
owner_login: gamosoft
owner_html_url: https://github.com/gamosoft
- name: flock
html_url: https://github.com/Onelevenvy/flock
stars: 1055
owner_login: Onelevenvy
owner_html_url: https://github.com/Onelevenvy
- name: fastapi-observability
html_url: https://github.com/blueswen/fastapi-observability
stars: 923
stars: 1038
owner_login: blueswen
owner_html_url: https://github.com/blueswen
- name: aktools
html_url: https://github.com/akfamily/aktools
stars: 1027
owner_login: akfamily
owner_html_url: https://github.com/akfamily
- name: RuoYi-Vue3-FastAPI
html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI
stars: 1016
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: autollm
html_url: https://github.com/viddexa/autollm
stars: 1002
owner_login: viddexa
owner_html_url: https://github.com/viddexa
- name: titiler
html_url: https://github.com/developmentseed/titiler
stars: 999
owner_login: developmentseed
owner_html_url: https://github.com/developmentseed
- name: lanarky
html_url: https://github.com/ajndkr/lanarky
stars: 994
owner_login: ajndkr
owner_html_url: https://github.com/ajndkr
- name: every-pdf
html_url: https://github.com/DDULDDUCK/every-pdf
stars: 985
owner_login: DDULDDUCK
owner_html_url: https://github.com/DDULDDUCK
- name: enterprise-deep-research
html_url: https://github.com/SalesforceAIResearch/enterprise-deep-research
stars: 973
owner_login: SalesforceAIResearch
owner_html_url: https://github.com/SalesforceAIResearch
- name: fastapi-mail
html_url: https://github.com/sabuhish/fastapi-mail
stars: 964
owner_login: sabuhish
owner_html_url: https://github.com/sabuhish

View File

@@ -75,7 +75,7 @@ mattwang44:
url: https://github.com/mattwang44
tiangolo:
login: tiangolo
count: 55
count: 56
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
Laineyzhang55:
@@ -136,7 +136,7 @@ JavierSanchezCastro:
alejsdev:
login: alejsdev
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=447d12a1b347f466b35378bee4c7104cc9b2c571&v=4
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4
url: https://github.com/alejsdev
stlucasgarcia:
login: stlucasgarcia
@@ -436,7 +436,7 @@ jburckel:
peidrao:
login: peidrao
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=64c634bb10381905038ff7faf3c8c3df47fb799a&v=4
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=979c62398e16ff000cc0faa028e028efd679887c&v=4
url: https://github.com/peidrao
impocode:
login: impocode
@@ -1006,7 +1006,7 @@ takacs:
anton2yakovlev:
login: anton2yakovlev
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/44229180?u=bdd445ba99074b378e7298d23c4bf6d707d2c282&v=4
avatarUrl: https://avatars.githubusercontent.com/u/44229180?u=ac245e57bc834ff80f08ca8128000bb650a77a3d&v=4
url: https://github.com/anton2yakovlev
ILoveSorasakiHina:
login: ILoveSorasakiHina
@@ -1161,7 +1161,7 @@ cookie-byte217:
AbolfazlKameli:
login: AbolfazlKameli
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/120686133?u=e41743da3c1820efafc59c5870cacd4f4425334c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/120686133?u=af8f025278cce0d489007071254e4055df60b78c&v=4
url: https://github.com/AbolfazlKameli
tyronedamasceno:
login: tyronedamasceno
@@ -1196,7 +1196,7 @@ Xaraxx:
Suyoung789:
login: Suyoung789
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/31277231?u=744bd3e641413e19bfad6b06a90bb0887c3f9332&v=4
avatarUrl: https://avatars.githubusercontent.com/u/31277231?u=1591aaf651eb860017231a36590050e154c026b6&v=4
url: https://github.com/Suyoung789
akagaeng:
login: akagaeng
@@ -1806,7 +1806,7 @@ MrL8199:
ivintoiu:
login: ivintoiu
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1853336?u=b537c905ad08b69993de8796fb235c8d4d47f039&v=4
avatarUrl: https://avatars.githubusercontent.com/u/1853336?u=e3de5fd0ab17efc12256b4295285b504ca281440&v=4
url: https://github.com/ivintoiu
TechnoService2:
login: TechnoService2
@@ -1841,7 +1841,7 @@ NavesSapnis:
eqsdxr:
login: eqsdxr
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=d7aaffb29f542b647cf0f6b0e05722490863658a&v=4
avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=7927dc0366995334f9a18c3204a41d3a34d6d96f&v=4
url: https://github.com/eqsdxr
syedasamina56:
login: syedasamina56

View File

@@ -1,6 +1,6 @@
nilslindemann:
login: nilslindemann
count: 124
count: 125
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
jaystone776:
@@ -8,16 +8,16 @@ jaystone776:
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
ceb10n:
login: ceb10n
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
valentinDruzhinin:
login: valentinDruzhinin
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
url: https://github.com/valentinDruzhinin
ceb10n:
login: ceb10n
count: 27
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
tokusumi:
login: tokusumi
count: 23
@@ -286,7 +286,7 @@ hsuanchi:
alejsdev:
login: alejsdev
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=447d12a1b347f466b35378bee4c7104cc9b2c571&v=4
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4
url: https://github.com/alejsdev
riroan:
login: riroan
@@ -358,6 +358,11 @@ ruzia:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/24503?v=4
url: https://github.com/ruzia
YuriiMotov:
login: YuriiMotov
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov
izaguerreiro:
login: izaguerreiro
count: 2
@@ -543,8 +548,3 @@ EdmilsonRodrigues:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/62777025?u=217d6f3cd6cc750bb8818a3af7726c8d74eb7c2d&v=4
url: https://github.com/EdmilsonRodrigues
YuriiMotov:
login: YuriiMotov
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov

View File

@@ -15,7 +15,7 @@ Use as follows:
The tests:
## Code snippets { #code-snippets}
## Code snippets { #code-snippets }
//// tab | Test
@@ -53,7 +53,7 @@ See for example section `### Quotes` in `docs/de/llm-prompt.md`.
////
## Quotes in code snippets { #quotes-in-code-snippets}
## Quotes in code snippets { #quotes-in-code-snippets }
//// tab | Test

View File

@@ -175,7 +175,7 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
/// note
@@ -237,7 +237,7 @@ You can use that technique to reuse some predefined responses in your *path oper
For example:
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
## More information about OpenAPI responses { #more-information-about-openapi-responses }

View File

@@ -443,6 +443,14 @@ The docs UI will interact with the server that you select.
///
/// note | Technical Details
The `servers` property in the OpenAPI specification is optional.
If you don't specify the `servers` parameter and `root_path` is equal to `/`, the `servers` property in the generated OpenAPI schema will be omitted entirely by default, which is the equivalent of a single server with a `url` value of `/`.
///
### Disable automatic server from `root_path` { #disable-automatic-server-from-root-path }
If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`:

View File

@@ -4,7 +4,7 @@ FastAPI is built on top of **Pydantic**, and I have been showing you how to use
But FastAPI also supports using <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> the same way:
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
This is still supported thanks to **Pydantic**, as it has <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.
@@ -32,7 +32,7 @@ But if you have a bunch of dataclasses laying around, this is a nice trick to us
You can also use `dataclasses` in the `response_model` parameter:
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
The dataclass will be automatically converted to a Pydantic dataclass.
@@ -48,7 +48,7 @@ In some cases, you might still have to use Pydantic's version of `dataclasses`.
In that case, you can simply swap the standard `dataclasses` with `pydantic.dataclasses`, which is a drop-in replacement:
{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. We still import `field` from standard `dataclasses`.

View File

@@ -31,7 +31,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query
This part is pretty normal, most of the code is probably already familiar to you:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
/// tip
@@ -90,7 +90,7 @@ Temporarily adopting this point of view (of the *external developer*) can help y
First create a new `APIRouter` that will contain one or more callbacks.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
### Create the callback *path operation* { #create-the-callback-path-operation }
@@ -101,7 +101,7 @@ It should look just like a normal FastAPI *path operation*:
* It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`.
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
There are 2 main differences from a normal *path operation*:
@@ -169,7 +169,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that
Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
/// tip

View File

@@ -50,7 +50,7 @@ Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate
It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
## Additional Responses { #additional-responses }
@@ -155,13 +155,13 @@ For example, in this application we don't use FastAPI's integrated functionality
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
////
@@ -179,13 +179,13 @@ And then in our code, we parse that YAML content directly, and then we are again
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
////

View File

@@ -34,7 +34,7 @@ For example, you cannot put a Pydantic model in a `JSONResponse` without first c
For those cases, you can use the `jsonable_encoder` to convert your data before passing it to a response:
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | Technical Details

View File

@@ -148,7 +148,7 @@ This could be especially useful during testing, as it's very easy to override a
Coming from the previous example, your `config.py` file could look like:
{* ../../docs_src/settings/app02/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
Notice that now we don't create a default instance `settings = Settings()`.
@@ -174,7 +174,7 @@ And then we can require it from the *path operation function* as a dependency an
Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
In the dependency override we set a new value for the `admin_email` when creating the new `Settings` object, and then we return that new object.
@@ -217,7 +217,7 @@ And then update your `config.py` with:
//// tab | Pydantic v2
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip
@@ -229,7 +229,7 @@ The `model_config` attribute is used just for Pydantic configuration. You can re
//// tab | Pydantic v1
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
/// tip

View File

@@ -1,36 +1,22 @@
# External Links and Articles
# External Links
**FastAPI** has a great community constantly growing.
There are many posts, articles, tools, and projects, related to **FastAPI**.
Here's an incomplete list of some of them.
You could easily use a search engine or video platform to find many resources related to FastAPI.
/// tip
/// info
If you have an article, project, tool, or anything related to **FastAPI** that is not yet listed here, create a <a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">Pull Request adding it</a>.
Before, this page used to list links to external articles.
But now that FastAPI is the backend framework with the most GitHub stars across languages, and the most starred and used framework in Python, it no longer makes sense to attempt to list all articles written about it.
///
{% 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 %}
* <a href="{{ item.link }}" class="external-link" target="_blank">{{ item.title }}</a> by <a href="{{ item.author_link }}" class="external-link" target="_blank">{{ item.author }}</a>.
{% endfor %}
{% endfor %}
{% endfor %}
## GitHub Repositories
Most starred GitHub repositories with the topic `fastapi`:
Most starred <a href="https://github.com/topics/fastapi" class="external-link" target="_blank">GitHub repositories with the topic `fastapi`</a>:
{% for repo in topic_repos %}

View File

@@ -40,7 +40,7 @@ FastAPI includes some default configuration parameters appropriate for most of t
It includes these default configurations:
{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
You can override any of them by setting a different value in the argument `swagger_ui_parameters`.

View File

@@ -42,7 +42,7 @@ If there's no `gzip` in the header, it will not try to decompress the body.
That way, the same route class can handle gzip compressed or uncompressed requests.
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
### Create a custom `GzipRoute` class { #create-a-custom-gziproute-class }
@@ -54,7 +54,7 @@ This method returns a function. And that function is what will receive a request
Here we use it to create a `GzipRequest` from the original request.
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
/// note | Technical Details
@@ -92,18 +92,18 @@ We can also use this same approach to access the request body in an exception ha
All we need to do is handle the request inside a `try`/`except` block:
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
If an exception occurs, the`Request` instance will still be in scope, so we can read and make use of the request body when handling the error:
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
## Custom `APIRoute` class in a router { #custom-apiroute-class-in-a-router }
You can also set the `route_class` parameter of an `APIRouter`:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -46,19 +46,19 @@ The key features are:
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* estimation based on tests on an internal development team, building production applications.</small>
<small>* estimation based on tests conducted by an internal development team, building production applications.</small>
## Sponsors { #sponsors }
<!-- sponsors -->
### Keystone Sponsor
### Keystone Sponsor { #keystone-sponsor }
{% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
### Gold and Silver Sponsors
### Gold and Silver Sponsors { #gold-and-silver-sponsors }
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>

View File

@@ -9,18 +9,18 @@ GitHub Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-templ
## Full Stack FastAPI Template - Technology Stack and Features { #full-stack-fastapi-template-technology-stack-and-features }
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API.
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM).
- 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
- 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database.
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM).
- 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
- 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database.
- 🚀 [React](https://react.dev) for the frontend.
- 💃 Using TypeScript, hooks, [Vite](https://vitejs.dev), and other parts of a modern frontend stack.
- 🎨 [Chakra UI](https://chakra-ui.com) for the frontend components.
- 🤖 An automatically generated frontend client.
- 🧪 [Playwright](https://playwright.dev) for End-to-End testing.
- 🦇 Dark mode support.
- 💃 Using TypeScript, hooks, Vite, and other parts of a modern frontend stack.
- 🎨 [Tailwind CSS](https://tailwindcss.com) and [shadcn/ui](https://ui.shadcn.com) for the frontend components.
- 🤖 An automatically generated frontend client.
- 🧪 [Playwright](https://playwright.dev) for End-to-End testing.
- 🦇 Dark mode support.
- 🐋 [Docker Compose](https://www.docker.com) for development and production.
- 🔒 Secure password hashing by default.
- 🔑 JWT token authentication.
- 🔑 JWT (JSON Web Token) authentication.
- 📫 Email based password recovery.
- ✅ Tests with [Pytest](https://pytest.org).
- 📞 [Traefik](https://traefik.io) as a reverse proxy / load balancer.

View File

@@ -7,6 +7,192 @@ hide:
## Latest Changes
### Translations
* 🌐 Update translations for es (update-outdated). PR [#14532](https://github.com/fastapi/fastapi/pull/14532) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (add-missing). PR [#14533](https://github.com/fastapi/fastapi/pull/14533) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Remove translations for removed docs. PR [#14516](https://github.com/fastapi/fastapi/pull/14516) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 👷 Configure coverage, error on main tests, don't wait for Smokeshow. PR [#14536](https://github.com/fastapi/fastapi/pull/14536) by [@tiangolo](https://github.com/tiangolo).
* 👷 Run Smokeshow always, even on test failures. PR [#14538](https://github.com/fastapi/fastapi/pull/14538) by [@tiangolo](https://github.com/tiangolo).
* 👷 Make Pydantic versions customizable in CI. PR [#14535](https://github.com/fastapi/fastapi/pull/14535) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix checkout GitHub Action fetch-depth for LLM translations, enable cron monthly. PR [#14531](https://github.com/fastapi/fastapi/pull/14531) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix Typer command for CI LLM translations. PR [#14530](https://github.com/fastapi/fastapi/pull/14530) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update LLM translation CI, add language matrix and extra commands, prepare for scheduled run. PR [#14529](https://github.com/fastapi/fastapi/pull/14529) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update github-actions user for GitHub Actions workflows. PR [#14528](https://github.com/fastapi/fastapi/pull/14528) by [@tiangolo](https://github.com/tiangolo).
* Add requirements for translations. PR [#14515](https://github.com/fastapi/fastapi/pull/14515) by [@tiangolo](https://github.com/tiangolo).
## 0.124.4
### Fixes
* 🐛 Fix parameter aliases. PR [#14371](https://github.com/fastapi/fastapi/pull/14371) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.124.3
### Fixes
* 🐛 Fix support for tagged union with discriminator inside of `Annotated` with `Body()`. PR [#14512](https://github.com/fastapi/fastapi/pull/14512) by [@tiangolo](https://github.com/tiangolo).
### Refactors
* ✅ Add set of tests for request parameters and alias. PR [#14358](https://github.com/fastapi/fastapi/pull/14358) by [@YuriiMotov](https://github.com/YuriiMotov).
### Docs
* 📝 Tweak links format. PR [#14505](https://github.com/fastapi/fastapi/pull/14505) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs about re-raising validation errors, do not include string as is to not leak information. PR [#14487](https://github.com/fastapi/fastapi/pull/14487) by [@tiangolo](https://github.com/tiangolo).
* 🔥 Remove external links section. PR [#14486](https://github.com/fastapi/fastapi/pull/14486) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Sync Russian docs. PR [#14509](https://github.com/fastapi/fastapi/pull/14509) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Sync German docs. PR [#14488](https://github.com/fastapi/fastapi/pull/14488) by [@nilslindemann](https://github.com/nilslindemann).
### Internal
* 👷 Tweak coverage to not pass Smokeshow max file size limit. PR [#14507](https://github.com/fastapi/fastapi/pull/14507) by [@tiangolo](https://github.com/tiangolo).
* ✅ Expand test matrix to include Windows and MacOS. PR [#14171](https://github.com/fastapi/fastapi/pull/14171) by [@svlandeg](https://github.com/svlandeg).
## 0.124.2
### Fixes
* 🐛 Fix support for `if TYPE_CHECKING`, non-evaluated stringified annotations. PR [#14485](https://github.com/fastapi/fastapi/pull/14485) by [@tiangolo](https://github.com/tiangolo).
## 0.124.1
### Fixes
* 🐛 Fix handling arbitrary types when using `arbitrary_types_allowed=True`. PR [#14482](https://github.com/fastapi/fastapi/pull/14482) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Add variants for code examples in "Advanced User Guide". PR [#14413](https://github.com/fastapi/fastapi/pull/14413) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Update tech stack in project generation docs. PR [#14472](https://github.com/fastapi/fastapi/pull/14472) by [@alejsdev](https://github.com/alejsdev).
### Internal
* ✅ Add test for Pydantic v2, dataclasses, UUID, and `__annotations__`. PR [#14477](https://github.com/fastapi/fastapi/pull/14477) by [@tiangolo](https://github.com/tiangolo).
## 0.124.0
### Features
* 🚸 Improve tracebacks by adding endpoint metadata. PR [#14306](https://github.com/fastapi/fastapi/pull/14306) by [@savannahostrowski](https://github.com/savannahostrowski).
### Internal
* ✏️ Fix typo in `scripts/mkdocs_hooks.py`. PR [#14457](https://github.com/fastapi/fastapi/pull/14457) by [@yujiteshima](https://github.com/yujiteshima).
## 0.123.10
### Fixes
* 🐛 Fix using class (not instance) dependency that has `__call__` method. PR [#14458](https://github.com/fastapi/fastapi/pull/14458) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🐛 Fix `separate_input_output_schemas=False` with `computed_field`. PR [#14453](https://github.com/fastapi/fastapi/pull/14453) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.123.9
### Fixes
* 🐛 Fix OAuth2 scopes in OpenAPI in extra corner cases, parent dependency with scopes, sub-dependency security scheme without scopes. PR [#14459](https://github.com/fastapi/fastapi/pull/14459) by [@tiangolo](https://github.com/tiangolo).
## 0.123.8
### Fixes
* 🐛 Fix OpenAPI security scheme OAuth2 scopes declaration, deduplicate security schemes with different scopes. PR [#14455](https://github.com/fastapi/fastapi/pull/14455) by [@tiangolo](https://github.com/tiangolo).
## 0.123.7
### Fixes
* 🐛 Fix evaluating stringified annotations in Python 3.10. PR [#11355](https://github.com/fastapi/fastapi/pull/11355) by [@chaen](https://github.com/chaen).
## 0.123.6
### Fixes
* 🐛 Fix support for functools wraps and partial combined, for async and regular functions and classes in path operations and dependencies. PR [#14448](https://github.com/fastapi/fastapi/pull/14448) by [@tiangolo](https://github.com/tiangolo).
## 0.123.5
### Features
* ✨ Allow using dependables with `functools.partial()`. PR [#9753](https://github.com/fastapi/fastapi/pull/9753) by [@lieryan](https://github.com/lieryan).
* ✨ Add support for wrapped functions (e.g. `@functools.wraps()`) used with forward references. PR [#5077](https://github.com/fastapi/fastapi/pull/5077) by [@lucaswiman](https://github.com/lucaswiman).
* ✨ Handle wrapped dependencies. PR [#9555](https://github.com/fastapi/fastapi/pull/9555) by [@phy1729](https://github.com/phy1729).
### Fixes
* 🐛 Fix optional sequence handling with new union syntax from Python 3.10. PR [#14430](https://github.com/fastapi/fastapi/pull/14430) by [@Viicos](https://github.com/Viicos).
### Refactors
* 🔥 Remove dangling extra condiitonal no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor internals, update `is_coroutine` check to reuse internal supported variants (unwrap, check class). PR [#14434](https://github.com/fastapi/fastapi/pull/14434) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Sync German docs. PR [#14367](https://github.com/fastapi/fastapi/pull/14367) by [@nilslindemann](https://github.com/nilslindemann).
## 0.123.4
### Fixes
* 🐛 Fix OpenAPI schema support for computed fields when using `separate_input_output_schemas=False`. PR [#13207](https://github.com/fastapi/fastapi/pull/13207) by [@vgrafe](https://github.com/vgrafe).
### Docs
* 📝 Fix docstring of `servers` parameter. PR [#14405](https://github.com/fastapi/fastapi/pull/14405) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.123.3
### Fixes
* 🐛 Fix Query\Header\Cookie parameter model alias. PR [#14360](https://github.com/fastapi/fastapi/pull/14360) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🐛 Fix optional sequence handling in `serialize sequence value` with Pydantic V2. PR [#14297](https://github.com/fastapi/fastapi/pull/14297) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.123.2
### Fixes
* 🐛 Fix unformatted `{type_}` in FastAPIError. PR [#14416](https://github.com/fastapi/fastapi/pull/14416) by [@Just-Helpful](https://github.com/Just-Helpful).
* 🐛 Fix parsing extra non-body parameter list. PR [#14356](https://github.com/fastapi/fastapi/pull/14356) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🐛 Fix parsing extra `Form` parameter list. PR [#14303](https://github.com/fastapi/fastapi/pull/14303) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🐛 Fix support for form values with empty strings interpreted as missing (`None` if that's the default), for compatibility with HTML forms. PR [#13537](https://github.com/fastapi/fastapi/pull/13537) by [@MarinPostma](https://github.com/MarinPostma).
### Docs
* 📝 Add tip on how to install `pip` in case of `No module named pip` error in `virtual-environments.md`. PR [#14211](https://github.com/fastapi/fastapi/pull/14211) by [@zadevhub](https://github.com/zadevhub).
* 📝 Update Primary Key notes for the SQL databases tutorial to avoid confusion. PR [#14120](https://github.com/fastapi/fastapi/pull/14120) by [@FlaviusRaducu](https://github.com/FlaviusRaducu).
* 📝 Clarify estimation note in documentation. PR [#14070](https://github.com/fastapi/fastapi/pull/14070) by [@SaisakthiM](https://github.com/SaisakthiM).
## 0.123.1
### Fixes
* 🐛 Avoid accessing non-existing "$ref" key for Pydantic v2 compat remapping. PR [#14361](https://github.com/fastapi/fastapi/pull/14361) by [@svlandeg](https://github.com/svlandeg).
* 🐛 Fix `TypeError` when encoding a decimal with a `NaN` or `Infinity` value. PR [#12935](https://github.com/fastapi/fastapi/pull/12935) by [@kentwelcome](https://github.com/kentwelcome).
### Internal
* 🐛 Fix Windows UnicodeEncodeError in CLI test. PR [#14295](https://github.com/fastapi/fastapi/pull/14295) by [@hemanth-thirthahalli](https://github.com/hemanth-thirthahalli).
* 🔧 Update sponsors: add Greptile. PR [#14429](https://github.com/fastapi/fastapi/pull/14429) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI GitHub topic repositories. PR [#14426](https://github.com/fastapi/fastapi/pull/14426) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump markdown-include-variants from 0.0.6 to 0.0.7. PR [#14423](https://github.com/fastapi/fastapi/pull/14423) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👥 Update FastAPI People - Sponsors. PR [#14422](https://github.com/fastapi/fastapi/pull/14422) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Contributors and Translators. PR [#14420](https://github.com/fastapi/fastapi/pull/14420) by [@tiangolo](https://github.com/tiangolo).
## 0.123.0
### Fixes
* 🐛 Cache dependencies that don't use scopes and don't have sub-dependencies with scopes. PR [#14419](https://github.com/fastapi/fastapi/pull/14419) by [@tiangolo](https://github.com/tiangolo).
## 0.122.1
### Fixes

View File

@@ -1,3 +1,3 @@
# Resources { #resources }
Additional resources, external links, articles and more. ✈️
Additional resources, external links, and more. ✈️

View File

@@ -85,9 +85,7 @@ You can create the *path operations* for that module using `APIRouter`.
You import it and create an "instance" the same way you would with the class `FastAPI`:
```Python hl_lines="1 3" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### *Path operations* with `APIRouter` { #path-operations-with-apirouter }
@@ -95,9 +93,7 @@ And then you use it to declare your *path operations*.
Use it the same way you would use the `FastAPI` class:
```Python hl_lines="6 11 16" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
You can think of `APIRouter` as a "mini `FastAPI`" class.
@@ -121,35 +117,7 @@ So we put them in their own `dependencies` module (`app/dependencies.py`).
We will now use a simple dependency to read a custom `X-Token` header:
//// tab | Python 3.9+
```Python hl_lines="3 6-8" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="1 5-7" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip
Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="1 4-6" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app/dependencies.py!}
```
////
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip
@@ -181,9 +149,7 @@ We know all the *path operations* in this module have the same:
So, instead of adding all that to each *path operation*, we can add it to the `APIRouter`.
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
As the path of each *path operation* has to start with `/`, like in:
@@ -242,9 +208,7 @@ And we need to get the dependency function from the module `app.dependencies`, t
So we use a relative import with `..` for the dependencies:
```Python hl_lines="3" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
#### How relative imports work { #how-relative-imports-work }
@@ -315,9 +279,7 @@ We are not adding the prefix `/items` nor the `tags=["items"]` to each *path ope
But we can still add _more_ `tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:
```Python hl_lines="30-31" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip
@@ -343,17 +305,13 @@ You import and create a `FastAPI` class as normally.
And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:
```Python hl_lines="1 3 7" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
### Import the `APIRouter` { #import-the-apirouter }
Now we import the other submodules that have `APIRouter`s:
```Python hl_lines="4-5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".
@@ -416,17 +374,13 @@ the `router` from `users` would overwrite the one from `items` and we wouldn't b
So, to be able to use both of them in the same file, we import the submodules directly:
```Python hl_lines="5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
### Include the `APIRouter`s for `users` and `items` { #include-the-apirouters-for-users-and-items }
Now, let's include the `router`s from the submodules `users` and `items`:
```Python hl_lines="10-11" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
/// info
@@ -466,17 +420,13 @@ It contains an `APIRouter` with some admin *path operations* that your organizat
For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:
```Python hl_lines="3" title="app/internal/admin.py"
{!../../docs_src/bigger_applications/app/internal/admin.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.
We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:
```Python hl_lines="14-17" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
That way, the original `APIRouter` will stay unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.
@@ -497,9 +447,7 @@ We can also add *path operations* directly to the `FastAPI` app.
Here we do it... just to show that we can 🤷:
```Python hl_lines="21-23" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
and it will work correctly, together with all the other *path operations* added with `app.include_router()`.

View File

@@ -50,7 +50,7 @@ Your API now has the power to control its own <abbr title="This is a joke, just
You can use Pydantic's model configuration to `forbid` any `extra` fields:
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
If a client tries to send some **extra cookies**, they will receive an **error** response.

View File

@@ -127,7 +127,7 @@ To override it, import the `RequestValidationError` and use it with `@app.except
The exception handler will receive a `Request` and the exception.
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
Now, if you go to `/items/foo`, instead of getting the default JSON error with:
@@ -149,36 +149,17 @@ Now, if you go to `/items/foo`, instead of getting the default JSON error with:
you will get a text version, with:
```
1 validation error
path -> item_id
value is not a valid integer (type=type_error.integer)
Validation errors:
Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
```
#### `RequestValidationError` vs `ValidationError` { #requestvalidationerror-vs-validationerror }
/// warning
These are technical details that you might skip if it's not important for you now.
///
`RequestValidationError` is a sub-class of Pydantic's <a href="https://docs.pydantic.dev/latest/concepts/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a>.
**FastAPI** uses it so that, if you use a Pydantic model in `response_model`, and your data has an error, you will see the error in your log.
But the client/user will not see it. Instead, the client will receive an "Internal Server Error" with an HTTP status code `500`.
It should be this way because if you have a Pydantic `ValidationError` in your *response* or anywhere in your code (not in the client's *request*), it's actually a bug in your code.
And while you fix it, your clients/users shouldn't have access to internal information about the error, as that could expose a security vulnerability.
### Override the `HTTPException` error handler { #override-the-httpexception-error-handler }
The same way, you can override the `HTTPException` handler.
For example, you could want to return a plain text response instead of JSON for these errors:
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
/// note | Technical Details
@@ -188,6 +169,14 @@ You could also use `from starlette.responses import PlainTextResponse`.
///
/// warning
Have in mind that the `RequestValidationError` contains the information of the file name and line where the validation error happens so that you can show it in your logs with the relevant information if you want to.
But that means that if you just convert it to a string and return that information directly, you could be leaking a bit of information about your system, that's why here the code extracts and shows each error independently.
///
### Use the `RequestValidationError` body { #use-the-requestvalidationerror-body }
The `RequestValidationError` contains the `body` it received with invalid data.

View File

@@ -65,7 +65,7 @@ There are a few differences:
* `Field(primary_key=True)` tells SQLModel that the `id` is the **primary key** in the SQL database (you can learn more about SQL primary keys in the SQLModel docs).
By having the type as `int | None`, SQLModel will know that this column should be an `INTEGER` in the SQL database and that it should be `NULLABLE`.
**Note:** We use `int | None` for the primary key field so that in Python code we can *create an object without an `id`* (`id=None`), assuming the database will *generate it when saving*. SQLModel understands that the database will provide the `id` and *defines the column as a non-null `INTEGER`* in the database schema. See <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">SQLModel docs on primary keys</a> for details.
* `Field(index=True)` tells SQLModel that it should create a **SQL index** for this column, that would allow faster lookups in the database when reading data filtered by this column.

View File

@@ -121,63 +121,13 @@ It has a `POST` operation that could return several errors.
Both *path operations* require an `X-Token` header.
//// tab | Python 3.10+
```Python
{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
```
////
//// tab | Python 3.9+
```Python
{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
```
////
//// tab | Python 3.8+
```Python
{!> ../../docs_src/app_testing/app_b_an/main.py!}
```
////
//// tab | Python 3.10+ non-Annotated
/// tip
Prefer to use the `Annotated` version if possible.
///
```Python
{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip
Prefer to use the `Annotated` version if possible.
///
```Python
{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
### Extended testing file { #extended-testing-file }
You could then update `test_main.py` with the extended tests:
{* ../../docs_src/app_testing/app_b/test_main.py *}
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
Whenever you need the client to pass information in the request and you don't know how to, you can search (Google) how to do it in `httpx`, or even how to do it with `requests`, as HTTPX's design is based on Requests' design.

View File

@@ -242,6 +242,26 @@ $ python -m pip install --upgrade pip
</div>
/// tip
Sometimes, you might get a **`No module named pip`** error when trying to upgrade pip.
If this happens, install and upgrade pip using the command below:
<div class="termy">
```console
$ python -m ensurepip --upgrade
---> 100%
```
</div>
This command will install pip if it is not already installed and also ensures that the installed version of pip is at least as recent as the one available in `ensurepip`.
///
## Add `.gitignore` { #add-gitignore }
If you are using **Git** (you should), add a `.gitignore` file to exclude everything in your `.venv` from Git.

View File

@@ -59,7 +59,6 @@ plugins:
search: null
macros:
include_yaml:
- external_links: ../en/data/external_links.yml
- github_sponsors: ../en/data/github_sponsors.yml
- people: ../en/data/people.yml
- contributors: ../en/data/contributors.yml

View File

@@ -93,6 +93,12 @@
<img class="sponsor-image" src="/img/sponsors/serpapi-banner.png" />
</a>
</div>
<div class="item">
<a title="Greptile: The AI Code Reviewer" style="display: block; position: relative;" href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/greptile-banner.png" />
</a>
</div>
</div>
</div>
{% endblock %}

503
docs/es/docs/_llm-test.md Normal file
View File

@@ -0,0 +1,503 @@
# Archivo de prueba de LLM { #llm-test-file }
Este documento prueba si el <abbr title="Large Language Model Modelo de lenguaje grande">LLM</abbr>, que traduce la documentación, entiende el `general_prompt` en `scripts/translate.py` y el prompt específico del idioma en `docs/{language code}/llm-prompt.md`. El prompt específico del idioma se agrega al final de `general_prompt`.
Las pruebas añadidas aquí serán vistas por todas las personas que diseñan prompts específicos del idioma.
Úsalo de la siguiente manera:
* Ten un prompt específico del idioma `docs/{language code}/llm-prompt.md`.
* Haz una traducción fresca de este documento a tu idioma destino (mira, por ejemplo, el comando `translate-page` de `translate.py`). Esto creará la traducción en `docs/{language code}/docs/_llm-test.md`.
* Comprueba si todo está bien en la traducción.
* Si es necesario, mejora tu prompt específico del idioma, el prompt general, o el documento en inglés.
* Luego corrige manualmente los problemas restantes en la traducción para que sea una buena traducción.
* Vuelve a traducir, teniendo la buena traducción en su lugar. El resultado ideal sería que el LLM ya no hiciera cambios a la traducción. Eso significa que el prompt general y tu prompt específico del idioma están tan bien como pueden estar (a veces hará algunos cambios aparentemente aleatorios; la razón es que <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">los LLMs no son algoritmos deterministas</a>).
Las pruebas:
## Fragmentos de código { #code-snippets }
//// tab | Prueba
Este es un fragmento de código: `foo`. Y este es otro fragmento de código: `bar`. Y otro más: `baz quux`.
////
//// tab | Información
El contenido de los fragmentos de código debe dejarse tal cual.
Consulta la sección `### Content of code snippets` en el prompt general en `scripts/translate.py`.
////
## Comillas { #quotes }
//// tab | Prueba
Ayer, mi amigo escribió: "Si escribes 'incorrectly' correctamente, lo habrás escrito incorrectamente". A lo que respondí: "Correcto, pero 'incorrectly' está incorrecto, no '"incorrectly"'".
/// note | Nota
El LLM probablemente traducirá esto mal. Lo interesante es si mantiene la traducción corregida al volver a traducir.
///
////
//// tab | Información
La persona que diseña el prompt puede elegir si quiere convertir comillas neutras a comillas tipográficas. También está bien dejarlas como están.
Consulta por ejemplo la sección `### Quotes` en `docs/de/llm-prompt.md`.
////
## Comillas en fragmentos de código { #quotes-in-code-snippets }
//// tab | Prueba
`pip install "foo[bar]"`
Ejemplos de literales de string en fragmentos de código: `"this"`, `'that'`.
Un ejemplo difícil de literales de string en fragmentos de código: `f"I like {'oranges' if orange else "apples"}"`
Hardcore: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"`
////
//// tab | Información
... Sin embargo, las comillas dentro de fragmentos de código deben quedarse tal cual.
////
## bloques de código { #code-blocks }
//// tab | Prueba
Un ejemplo de código Bash...
```bash
# Imprime un saludo al universo
echo "Hello universe"
```
...y un ejemplo de código de consola...
```console
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting server
Searching for package file structure
```
...y otro ejemplo de código de consola...
```console
// Crea un directorio "Code"
$ mkdir code
// Cambia a ese directorio
$ cd code
```
...y un ejemplo de código Python...
```Python
wont_work() # Esto no va a funcionar 😱
works(foo="bar") # Esto funciona 🎉
```
...y eso es todo.
////
//// tab | Información
El código en bloques de código no debe modificarse, con la excepción de los comentarios.
Consulta la sección `### Content of code blocks` en el prompt general en `scripts/translate.py`.
////
## Pestañas y cajas coloreadas { #tabs-and-colored-boxes }
//// tab | Prueba
/// info | Información
Algo de texto
///
/// note | Nota
Algo de texto
///
/// note | Detalles técnicos
Algo de texto
///
/// check | Revisa
Algo de texto
///
/// tip | Consejo
Algo de texto
///
/// warning | Advertencia
Algo de texto
///
/// danger | Peligro
Algo de texto
///
////
//// tab | Información
Las pestañas y los bloques `Info`/`Note`/`Warning`/etc. deben tener la traducción de su título añadida después de una barra vertical (`|`).
Consulta las secciones `### Special blocks` y `### Tab blocks` en el prompt general en `scripts/translate.py`.
////
## Enlaces web e internos { #web-and-internal-links }
//// tab | Prueba
El texto del enlace debe traducirse, la dirección del enlace debe permanecer sin cambios:
* [Enlace al encabezado de arriba](#code-snippets)
* [Enlace interno](index.md#installation){.internal-link target=_blank}
* <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">Enlace externo</a>
* <a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">Enlace a un estilo</a>
* <a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">Enlace a un script</a>
* <a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">Enlace a una imagen</a>
El texto del enlace debe traducirse, la dirección del enlace debe apuntar a la traducción:
* <a href="https://fastapi.tiangolo.com/es/" class="external-link" target="_blank">Enlace a FastAPI</a>
////
//// tab | Información
Los enlaces deben traducirse, pero su dirección debe permanecer sin cambios. Una excepción son los enlaces absolutos a páginas de la documentación de FastAPI. En ese caso deben enlazar a la traducción.
Consulta la sección `### Links` en el prompt general en `scripts/translate.py`.
////
## Elementos HTML "abbr" { #html-abbr-elements }
//// tab | Prueba
Aquí algunas cosas envueltas en elementos HTML "abbr" (algunas son inventadas):
### El abbr da una frase completa { #the-abbr-gives-a-full-phrase }
* <abbr title="Getting Things Done Hacer las cosas">GTD</abbr>
* <abbr title="less than menor que"><code>lt</code></abbr>
* <abbr title="XML Web Token Token web XML">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface Interfaz de pasarela de servidor paralela">PSGI</abbr>
### El abbr da una explicación { #the-abbr-gives-an-explanation }
* <abbr title="Un grupo de máquinas configuradas para estar conectadas y trabajar juntas de alguna manera.">clúster</abbr>
* <abbr title="Un método de machine learning que usa redes neuronales artificiales con numerosas capas ocultas entre las capas de entrada y salida, desarrollando así una estructura interna completa">Deep Learning</abbr>
### El abbr da una frase completa y una explicación { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbr title="Mozilla Developer Network Red de Desarrolladores de Mozilla: documentación para desarrolladores, escrita por la gente de Firefox">MDN</abbr>
* <abbr title="Input/Output Entrada/Salida: lectura o escritura de disco, comunicaciones de red.">I/O</abbr>.
////
//// tab | Información
Los atributos "title" de los elementos "abbr" se traducen siguiendo instrucciones específicas.
Las traducciones pueden añadir sus propios elementos "abbr" que el LLM no debe eliminar. P. ej., para explicar palabras en inglés.
Consulta la sección `### HTML abbr elements` en el prompt general en `scripts/translate.py`.
////
## Encabezados { #headings }
//// tab | Prueba
### Desarrolla una webapp - un tutorial { #develop-a-webapp-a-tutorial }
Hola.
### Anotaciones de tipos y -anotaciones { #type-hints-and-annotations }
Hola de nuevo.
### Superclases y subclases { #super-and-subclasses }
Hola de nuevo.
////
//// tab | Información
La única regla estricta para los encabezados es que el LLM deje la parte del hash dentro de llaves sin cambios, lo que asegura que los enlaces no se rompan.
Consulta la sección `### Headings` en el prompt general en `scripts/translate.py`.
Para instrucciones específicas del idioma, mira p. ej. la sección `### Headings` en `docs/de/llm-prompt.md`.
////
## Términos usados en la documentación { #terms-used-in-the-docs }
//// tab | Prueba
*
* tu
* p. ej.
* etc.
* `foo` como un `int`
* `bar` como un `str`
* `baz` como una `list`
* el Tutorial - Guía de usuario
* la Guía de usuario avanzada
* la documentación de SQLModel
* la documentación de la API
* la documentación automática
* Ciencia de datos
* Deep Learning
* Machine Learning
* Inyección de dependencias
* autenticación HTTP Basic
* HTTP Digest
* formato ISO
* el estándar JSON Schema
* el JSON Schema
* la definición del esquema
* Flujo de contraseña
* Móvil
* obsoleto
* diseñado
* inválido
* sobre la marcha
* estándar
* por defecto
* sensible a mayúsculas/minúsculas
* insensible a mayúsculas/minúsculas
* servir la aplicación
* servir la página
* la app
* la aplicación
* la request
* la response
* la response de error
* la path operation
* el decorador de path operation
* la path operation function
* el body
* el request body
* el response body
* el body JSON
* el body del formulario
* el body de archivo
* el cuerpo de la función
* el parámetro
* el parámetro del body
* el parámetro del path
* el parámetro de query
* el parámetro de cookie
* el parámetro de header
* el parámetro del formulario
* el parámetro de la función
* el evento
* el evento de inicio
* el inicio del servidor
* el evento de apagado
* el evento de lifespan
* el manejador
* el manejador de eventos
* el manejador de excepciones
* manejar
* el modelo
* el modelo de Pydantic
* el modelo de datos
* el modelo de base de datos
* el modelo de formulario
* el objeto del modelo
* la clase
* la clase base
* la clase padre
* la subclase
* la clase hija
* la clase hermana
* el método de clase
* el header
* los headers
* el header de autorización
* el header `Authorization`
* el header Forwarded
* el sistema de inyección de dependencias
* la dependencia
* el dependable
* el dependiente
* limitado por I/O
* limitado por CPU
* concurrencia
* paralelismo
* multiprocesamiento
* la variable de entorno
* la variable de entorno
* el `PATH`
* la variable `PATH`
* la autenticación
* el proveedor de autenticación
* la autorización
* el formulario de autorización
* el proveedor de autorización
* el usuario se autentica
* el sistema autentica al usuario
* la CLI
* la interfaz de línea de comandos
* el servidor
* el cliente
* el proveedor en la nube
* el servicio en la nube
* el desarrollo
* las etapas de desarrollo
* el dict
* el diccionario
* la enumeración
* el enum
* el miembro del enum
* el codificador
* el decodificador
* codificar
* decodificar
* la excepción
* lanzar
* la expresión
* el statement
* el frontend
* el backend
* la discusión de GitHub
* el issue de GitHub
* el rendimiento
* la optimización de rendimiento
* el tipo de retorno
* el valor de retorno
* la seguridad
* el esquema de seguridad
* la tarea
* la tarea en segundo plano
* la función de tarea
* la plantilla
* el motor de plantillas
* la anotación de tipos
* la anotación de tipos
* el worker del servidor
* el worker de Uvicorn
* el Gunicorn Worker
* el worker process
* la worker class
* la carga de trabajo
* el despliegue
* desplegar
* el SDK
* el kit de desarrollo de software
* el `APIRouter`
* el `requirements.txt`
* el Bearer Token
* el cambio incompatible
* el bug
* el botón
* el invocable
* el código
* el commit
* el context manager
* la corrutina
* la sesión de base de datos
* el disco
* el dominio
* el motor
* el X falso
* el método HTTP GET
* el ítem
* el paquete
* el lifespan
* el bloqueo
* el middleware
* la aplicación móvil
* el módulo
* el montaje
* la red
* el origen
* el override
* el payload
* el procesador
* la propiedad
* el proxy
* el pull request
* la query
* la RAM
* la máquina remota
* el código de estado
* el string
* la etiqueta
* el framework web
* el comodín
* devolver
* validar
////
//// tab | Información
Esta es una lista no completa y no normativa de términos (mayormente) técnicos vistos en la documentación. Puede ayudar a la persona que diseña el prompt a identificar para qué términos el LLM necesita una mano. Por ejemplo cuando sigue revirtiendo una buena traducción a una traducción subóptima. O cuando tiene problemas conjugando/declinando un término en tu idioma.
Mira p. ej. la sección `### List of English terms and their preferred German translations` en `docs/de/llm-prompt.md`.
////

View File

@@ -1,3 +1,3 @@
# Acerca de
# Acerca de { #about }
Acerca de FastAPI, su diseño, inspiración y más. 🤓

View File

@@ -1,4 +1,4 @@
# Responses Adicionales en OpenAPI
# Responses Adicionales en OpenAPI { #additional-responses-in-openapi }
/// warning | Advertencia
@@ -14,7 +14,7 @@ Esos responses adicionales se incluirán en el esquema de OpenAPI, por lo que ta
Pero para esos responses adicionales tienes que asegurarte de devolver un `Response` como `JSONResponse` directamente, con tu código de estado y contenido.
## Response Adicional con `model`
## Response Adicional con `model` { #additional-response-with-model }
Puedes pasar a tus *decoradores de path operation* un parámetro `responses`.
@@ -169,13 +169,13 @@ Los esquemas se referencian a otro lugar dentro del esquema de OpenAPI:
}
```
## Media types adicionales para el response principal
## Media types adicionales para el response principal { #additional-media-types-for-the-main-response }
Puedes usar este mismo parámetro `responses` para agregar diferentes media type para el mismo response principal.
Por ejemplo, puedes agregar un media type adicional de `image/png`, declarando que tu *path operation* puede devolver un objeto JSON (con media type `application/json`) o una imagen PNG:
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
/// note | Nota
@@ -191,13 +191,13 @@ Pero si has especificado una clase de response personalizada con `None` como su
///
## Combinando información
## Combinando información { #combining-information }
También puedes combinar información de response de múltiples lugares, incluyendo los parámetros `response_model`, `status_code`, y `responses`.
Puedes declarar un `response_model`, usando el código de estado predeterminado `200` (o uno personalizado si lo necesitas), y luego declarar información adicional para ese mismo response en `responses`, directamente en el esquema de OpenAPI.
Puedes declarar un `response_model`, usando el código de estado por defecto `200` (o uno personalizado si lo necesitas), y luego declarar información adicional para ese mismo response en `responses`, directamente en el esquema de OpenAPI.
**FastAPI** manterá la información adicional de `responses` y la combinará con el JSON Schema de tu modelo.
**FastAPI** mantendrá la información adicional de `responses` y la combinará con el JSON Schema de tu modelo.
Por ejemplo, puedes declarar un response con un código de estado `404` que usa un modelo Pydantic y tiene una `description` personalizada.
@@ -209,7 +209,7 @@ Todo se combinará e incluirá en tu OpenAPI, y se mostrará en la documentació
<img src="/img/tutorial/additional-responses/image01.png">
## Combina responses predefinidos y personalizados
## Combina responses predefinidos y personalizados { #combine-predefined-responses-and-custom-ones }
Es posible que desees tener algunos responses predefinidos que se apliquen a muchas *path operations*, pero que quieras combinarlos con responses personalizados necesarios por cada *path operation*.
@@ -237,9 +237,9 @@ Puedes usar esa técnica para reutilizar algunos responses predefinidos en tus *
Por ejemplo:
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
## Más información sobre responses OpenAPI
## Más información sobre responses OpenAPI { #more-information-about-openapi-responses }
Para ver exactamente qué puedes incluir en los responses, puedes revisar estas secciones en la especificación OpenAPI:

View File

@@ -1,10 +1,10 @@
# Códigos de Estado Adicionales
# Códigos de Estado Adicionales { #additional-status-codes }
Por defecto, **FastAPI** devolverá los responses usando un `JSONResponse`, colocando el contenido que devuelves desde tu *path operation* dentro de ese `JSONResponse`.
Usará el código de estado por defecto o el que configures en tu *path operation*.
## Códigos de estado adicionales
## Códigos de estado adicionales { #additional-status-codes_1 }
Si quieres devolver códigos de estado adicionales aparte del principal, puedes hacerlo devolviendo un `Response` directamente, como un `JSONResponse`, y configurando el código de estado adicional directamente.
@@ -34,7 +34,7 @@ También podrías usar `from starlette.responses import JSONResponse`.
///
## OpenAPI y documentación de API
## OpenAPI y documentación de API { #openapi-and-api-docs }
Si devuelves códigos de estado adicionales y responses directamente, no se incluirán en el esquema de OpenAPI (la documentación de la API), porque FastAPI no tiene una forma de saber de antemano qué vas a devolver.

View File

@@ -1,6 +1,6 @@
# Dependencias Avanzadas
# Dependencias Avanzadas { #advanced-dependencies }
## Dependencias con parámetros
## Dependencias con parámetros { #parameterized-dependencies }
Todas las dependencias que hemos visto son una función o clase fija.
@@ -10,7 +10,7 @@ Imaginemos que queremos tener una dependencia que revise si el parámetro de que
Pero queremos poder parametrizar ese contenido fijo.
## Una *instance* "callable"
## Una *instance* "callable" { #a-callable-instance }
En Python hay una forma de hacer que una instance de una clase sea un "callable".
@@ -22,7 +22,7 @@ Para hacer eso, declaramos un método `__call__`:
En este caso, este `__call__` es lo que **FastAPI** usará para comprobar parámetros adicionales y sub-dependencias, y es lo que llamará para pasar un valor al parámetro en tu *path operation function* más adelante.
## Parametrizar la instance
## Parametrizar la instance { #parameterize-the-instance }
Y ahora, podemos usar `__init__` para declarar los parámetros de la instance que podemos usar para "parametrizar" la dependencia:
@@ -30,7 +30,7 @@ Y ahora, podemos usar `__init__` para declarar los parámetros de la instance qu
En este caso, **FastAPI** nunca tocará ni se preocupará por `__init__`, lo usaremos directamente en nuestro código.
## Crear una instance
## Crear una instance { #create-an-instance }
Podríamos crear una instance de esta clase con:
@@ -38,7 +38,7 @@ Podríamos crear una instance de esta clase con:
Y de esa manera podemos "parametrizar" nuestra dependencia, que ahora tiene `"bar"` dentro de ella, como el atributo `checker.fixed_content`.
## Usar la instance como una dependencia
## Usar la instance como una dependencia { #use-the-instance-as-a-dependency }
Luego, podríamos usar este `checker` en un `Depends(checker)`, en lugar de `Depends(FixedContentQueryChecker)`, porque la dependencia es la instance, `checker`, no la clase en sí.
@@ -63,3 +63,101 @@ En los capítulos sobre seguridad, hay funciones utilitarias que se implementan
Si entendiste todo esto, ya sabes cómo funcionan por debajo esas herramientas de utilidad para seguridad.
///
## Dependencias con `yield`, `HTTPException`, `except` y Tareas en segundo plano { #dependencies-with-yield-httpexception-except-and-background-tasks }
/// warning | Advertencia
Muy probablemente no necesites estos detalles técnicos.
Estos detalles son útiles principalmente si tenías una aplicación de FastAPI anterior a la 0.121.0 y estás enfrentando problemas con dependencias con `yield`.
///
Las dependencias con `yield` han evolucionado con el tiempo para cubrir diferentes casos de uso y arreglar algunos problemas; aquí tienes un resumen de lo que ha cambiado.
### Dependencias con `yield` y `scope` { #dependencies-with-yield-and-scope }
En la versión 0.121.0, FastAPI agregó soporte para `Depends(scope="function")` para dependencias con `yield`.
Usando `Depends(scope="function")`, el código de salida después de `yield` se ejecuta justo después de que la *path operation function* termina, antes de que la response se envíe de vuelta al cliente.
Y al usar `Depends(scope="request")` (el valor por defecto), el código de salida después de `yield` se ejecuta después de que la response es enviada.
Puedes leer más al respecto en la documentación de [Dependencias con `yield` - Salida temprana y `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope).
### Dependencias con `yield` y `StreamingResponse`, detalles técnicos { #dependencies-with-yield-and-streamingresponse-technical-details }
Antes de FastAPI 0.118.0, si usabas una dependencia con `yield`, ejecutaba el código de salida después de que la *path operation function* retornaba pero justo antes de enviar la response.
La intención era evitar retener recursos por más tiempo del necesario, esperando a que la response viajara por la red.
Este cambio también significaba que si retornabas un `StreamingResponse`, el código de salida de la dependencia con `yield` ya se habría ejecutado.
Por ejemplo, si tenías una sesión de base de datos en una dependencia con `yield`, el `StreamingResponse` no podría usar esa sesión mientras hace streaming de datos porque la sesión ya se habría cerrado en el código de salida después de `yield`.
Este comportamiento se revirtió en la 0.118.0, para hacer que el código de salida después de `yield` se ejecute después de que la response sea enviada.
/// info | Información
Como verás abajo, esto es muy similar al comportamiento anterior a la versión 0.106.0, pero con varias mejoras y arreglos de bugs para casos límite.
///
#### Casos de uso con salida temprana del código { #use-cases-with-early-exit-code }
Hay algunos casos de uso con condiciones específicas que podrían beneficiarse del comportamiento antiguo de ejecutar el código de salida de dependencias con `yield` antes de enviar la response.
Por ejemplo, imagina que tienes código que usa una sesión de base de datos en una dependencia con `yield` solo para verificar un usuario, pero la sesión de base de datos no se vuelve a usar en la *path operation function*, solo en la dependencia, y la response tarda mucho en enviarse, como un `StreamingResponse` que envía datos lentamente, pero que por alguna razón no usa la base de datos.
En este caso, la sesión de base de datos se mantendría hasta que la response termine de enviarse, pero si no la usas, entonces no sería necesario mantenerla.
Así es como se vería:
{* ../../docs_src/dependencies/tutorial013_an_py310.py *}
El código de salida, el cierre automático de la `Session` en:
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}
...se ejecutaría después de que la response termine de enviar los datos lentos:
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}
Pero como `generate_stream()` no usa la sesión de base de datos, no es realmente necesario mantener la sesión abierta mientras se envía la response.
Si tienes este caso de uso específico usando SQLModel (o SQLAlchemy), podrías cerrar explícitamente la sesión después de que ya no la necesites:
{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *}
De esa manera la sesión liberaría la conexión a la base de datos, para que otras requests puedan usarla.
Si tienes un caso de uso diferente que necesite salir temprano desde una dependencia con `yield`, por favor crea una <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">Pregunta de Discusión en GitHub</a> con tu caso de uso específico y por qué te beneficiaría tener cierre temprano para dependencias con `yield`.
Si hay casos de uso convincentes para el cierre temprano en dependencias con `yield`, consideraría agregar una nueva forma de optar por el cierre temprano.
### Dependencias con `yield` y `except`, detalles técnicos { #dependencies-with-yield-and-except-technical-details }
Antes de FastAPI 0.110.0, si usabas una dependencia con `yield`, y luego capturabas una excepción con `except` en esa dependencia, y no volvías a elevar la excepción, la excepción se elevaría/remitiría automáticamente a cualquier manejador de excepciones o al manejador de error interno del servidor.
Esto cambió en la versión 0.110.0 para arreglar consumo de memoria no manejado por excepciones reenviadas sin un manejador (errores internos del servidor), y para hacerlo consistente con el comportamiento del código Python normal.
### Tareas en segundo plano y dependencias con `yield`, detalles técnicos { #background-tasks-and-dependencies-with-yield-technical-details }
Antes de FastAPI 0.106.0, elevar excepciones después de `yield` no era posible, el código de salida en dependencias con `yield` se ejecutaba después de que la response era enviada, por lo que [Manejadores de Excepciones](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} ya habrían corrido.
Esto se diseñó así principalmente para permitir usar los mismos objetos devueltos con `yield` por las dependencias dentro de tareas en segundo plano, porque el código de salida se ejecutaría después de que las tareas en segundo plano terminaran.
Esto cambió en FastAPI 0.106.0 con la intención de no retener recursos mientras se espera a que la response viaje por la red.
/// tip | Consejo
Adicionalmente, una tarea en segundo plano normalmente es un conjunto independiente de lógica que debería manejarse por separado, con sus propios recursos (por ejemplo, su propia conexión a la base de datos).
Así, probablemente tendrás un código más limpio.
///
Si solías depender de este comportamiento, ahora deberías crear los recursos para las tareas en segundo plano dentro de la propia tarea en segundo plano, y usar internamente solo datos que no dependan de los recursos de dependencias con `yield`.
Por ejemplo, en lugar de usar la misma sesión de base de datos, crearías una nueva sesión de base de datos dentro de la tarea en segundo plano, y obtendrías los objetos de la base de datos usando esta nueva sesión. Y entonces, en lugar de pasar el objeto de la base de datos como parámetro a la función de la tarea en segundo plano, pasarías el ID de ese objeto y luego obtendrías el objeto de nuevo dentro de la función de la tarea en segundo plano.

View File

@@ -1,4 +1,4 @@
# Tests Asíncronos
# Tests Asíncronos { #async-tests }
Ya has visto cómo probar tus aplicaciones de **FastAPI** usando el `TestClient` proporcionado. Hasta ahora, solo has visto cómo escribir tests sincrónicos, sin usar funciones `async`.
@@ -6,11 +6,11 @@ Poder usar funciones asíncronas en tus tests puede ser útil, por ejemplo, cuan
Veamos cómo podemos hacer que esto funcione.
## pytest.mark.anyio
## pytest.mark.anyio { #pytest-mark-anyio }
Si queremos llamar funciones asíncronas en nuestros tests, nuestras funciones de test tienen que ser asíncronas. AnyIO proporciona un plugin útil para esto, que nos permite especificar que algunas funciones de test deben ser llamadas de manera asíncrona.
## HTTPX
## HTTPX { #httpx }
Incluso si tu aplicación de **FastAPI** usa funciones `def` normales en lugar de `async def`, sigue siendo una aplicación `async` por debajo.
@@ -18,7 +18,7 @@ El `TestClient` hace algo de magia interna para llamar a la aplicación FastAPI
El `TestClient` está basado en <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>, y afortunadamente, podemos usarlo directamente para probar la API.
## Ejemplo
## Ejemplo { #example }
Para un ejemplo simple, consideremos una estructura de archivos similar a la descrita en [Aplicaciones Más Grandes](../tutorial/bigger-applications.md){.internal-link target=_blank} y [Testing](../tutorial/testing.md){.internal-link target=_blank}:
@@ -38,7 +38,7 @@ El archivo `test_main.py` tendría los tests para `main.py`, podría verse así
{* ../../docs_src/async_tests/test_main.py *}
## Ejecútalo
## Ejecútalo { #run-it }
Puedes ejecutar tus tests como de costumbre vía:
@@ -52,7 +52,7 @@ $ pytest
</div>
## En Detalle
## En Detalle { #in-detail }
El marcador `@pytest.mark.anyio` le dice a pytest que esta función de test debe ser llamada asíncronamente:
@@ -60,7 +60,7 @@ El marcador `@pytest.mark.anyio` le dice a pytest que esta función de test debe
/// tip | Consejo
Note que la función de test ahora es `async def` en lugar de solo `def` como antes al usar el `TestClient`.
Nota que la función de test ahora es `async def` en lugar de solo `def` como antes al usar el `TestClient`.
///
@@ -88,12 +88,12 @@ Si tu aplicación depende de eventos de lifespan, el `AsyncClient` no activará
///
## Otras Llamadas a Funciones Asíncronas
## Otras Llamadas a Funciones Asíncronas { #other-asynchronous-function-calls }
Al ser la función de test asíncrona, ahora también puedes llamar (y `await`) otras funciones `async` además de enviar requests a tu aplicación FastAPI en tus tests, exactamente como las llamarías en cualquier otro lugar de tu código.
/// tip | Consejo
Si encuentras un `RuntimeError: Task attached to a different loop` al integrar llamadas a funciones asíncronas en tus tests (por ejemplo, cuando usas <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MotorClient de MongoDB</a>), recuerda crear instances de objetos que necesiten un loop de eventos solo dentro de funciones async, por ejemplo, en un callback `'@app.on_event("startup")`.
Si encuentras un `RuntimeError: Task attached to a different loop` al integrar llamadas a funciones asíncronas en tus tests (por ejemplo, cuando usas <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MotorClient de MongoDB</a>), recuerda crear instances de objetos que necesiten un loop de eventos solo dentro de funciones async, por ejemplo, en un callback `@app.on_event("startup")`.
///

View File

@@ -1,6 +1,105 @@
# Detrás de un Proxy
# Detrás de un Proxy { #behind-a-proxy }
En algunas situaciones, podrías necesitar usar un **proxy** como Traefik o Nginx con una configuración que añade un prefijo de path extra que no es visto por tu aplicación.
En muchas situaciones, usarías un **proxy** como Traefik o Nginx delante de tu app de FastAPI.
Estos proxies podrían manejar certificados HTTPS y otras cosas.
## Headers reenviados por el Proxy { #proxy-forwarded-headers }
Un **proxy** delante de tu aplicación normalmente establecería algunos headers sobre la marcha antes de enviar los requests a tu **server** para que el servidor sepa que el request fue **reenviado** por el proxy, informándole la URL original (pública), incluyendo el dominio, que está usando HTTPS, etc.
El programa **server** (por ejemplo **Uvicorn** a través de **FastAPI CLI**) es capaz de interpretar esos headers, y luego pasar esa información a tu aplicación.
Pero por seguridad, como el server no sabe que está detrás de un proxy confiable, no interpretará esos headers.
/// note | Detalles Técnicos
Los headers del proxy son:
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
///
### Habilitar headers reenviados por el Proxy { #enable-proxy-forwarded-headers }
Puedes iniciar FastAPI CLI con la *Opción de CLI* `--forwarded-allow-ips` y pasar las direcciones IP que deberían ser confiables para leer esos headers reenviados.
Si lo estableces a `--forwarded-allow-ips="*"`, confiaría en todas las IPs entrantes.
Si tu **server** está detrás de un **proxy** confiable y solo el proxy le habla, esto haría que acepte cualquiera que sea la IP de ese **proxy**.
<div class="termy">
```console
$ fastapi run --forwarded-allow-ips="*"
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Redirecciones con HTTPS { #redirects-with-https }
Por ejemplo, digamos que defines una *path operation* `/items/`:
{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
Si el cliente intenta ir a `/items`, por defecto, sería redirigido a `/items/`.
Pero antes de configurar la *Opción de CLI* `--forwarded-allow-ips` podría redirigir a `http://localhost:8000/items/`.
Pero quizá tu aplicación está alojada en `https://mysuperapp.com`, y la redirección debería ser a `https://mysuperapp.com/items/`.
Al configurar `--proxy-headers` ahora FastAPI podrá redirigir a la ubicación correcta. 😎
```
https://mysuperapp.com/items/
```
/// tip | Consejo
Si quieres aprender más sobre HTTPS, revisa la guía [Acerca de HTTPS](../deployment/https.md){.internal-link target=_blank}.
///
### Cómo funcionan los headers reenviados por el Proxy { #how-proxy-forwarded-headers-work }
Aquí tienes una representación visual de cómo el **proxy** añade headers reenviados entre el cliente y el **application server**:
```mermaid
sequenceDiagram
participant Client as Cliente
participant Proxy as Proxy/Load Balancer
participant Server as Servidor de FastAPI
Client->>Proxy: HTTPS Request<br/>Host: mysuperapp.com<br/>Path: /items
Note over Proxy: El proxy añade headers reenviados
Proxy->>Server: HTTP Request<br/>X-Forwarded-For: [client IP]<br/>X-Forwarded-Proto: https<br/>X-Forwarded-Host: mysuperapp.com<br/>Path: /items
Note over Server: El servidor interpreta los headers<br/>(si --forwarded-allow-ips está configurado)
Server->>Proxy: HTTP Response<br/>con URLs HTTPS correctas
Proxy->>Client: HTTPS Response
```
El **proxy** intercepta el request original del cliente y añade los *headers* especiales de reenvío (`X-Forwarded-*`) antes de pasar el request al **application server**.
Estos headers preservan información sobre el request original que de otro modo se perdería:
* **X-Forwarded-For**: La IP original del cliente
* **X-Forwarded-Proto**: El protocolo original (`https`)
* **X-Forwarded-Host**: El host original (`mysuperapp.com`)
Cuando **FastAPI CLI** está configurado con `--forwarded-allow-ips`, confía en estos headers y los usa, por ejemplo para generar las URLs correctas en redirecciones.
## Proxy con un prefijo de path eliminado { #proxy-with-a-stripped-path-prefix }
Podrías tener un proxy que añada un prefijo de path a tu aplicación.
En estos casos, puedes usar `root_path` para configurar tu aplicación.
@@ -10,8 +109,6 @@ El `root_path` se usa para manejar estos casos específicos.
Y también se usa internamente al montar subaplicaciones.
## Proxy con un prefijo de path eliminado
Tener un proxy con un prefijo de path eliminado, en este caso, significa que podrías declarar un path en `/app` en tu código, pero luego añades una capa encima (el proxy) que situaría tu aplicación **FastAPI** bajo un path como `/api/v1`.
En este caso, el path original `/app` realmente sería servido en `/api/v1/app`.
@@ -66,14 +163,14 @@ La UI de los docs también necesitaría el esquema de OpenAPI para declarar que
En este ejemplo, el "Proxy" podría ser algo como **Traefik**. Y el servidor sería algo como FastAPI CLI con **Uvicorn**, ejecutando tu aplicación de FastAPI.
### Proporcionando el `root_path`
### Proporcionando el `root_path` { #providing-the-root-path }
Para lograr esto, puedes usar la opción de línea de comandos `--root-path` como:
<div class="termy">
```console
$ fastapi run main.py --root-path /api/v1
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -90,7 +187,7 @@ Y la opción de línea de comandos `--root-path` proporciona ese `root_path`.
///
### Revisar el `root_path` actual
### Revisar el `root_path` actual { #checking-the-current-root-path }
Puedes obtener el `root_path` actual utilizado por tu aplicación para cada request, es parte del diccionario `scope` (que es parte de la especificación ASGI).
@@ -103,7 +200,7 @@ Luego, si inicias Uvicorn con:
<div class="termy">
```console
$ fastapi run main.py --root-path /api/v1
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -119,7 +216,7 @@ El response sería algo como:
}
```
### Configurar el `root_path` en la app de FastAPI
### Configurar el `root_path` en la app de FastAPI { #setting-the-root-path-in-the-fastapi-app }
Alternativamente, si no tienes una forma de proporcionar una opción de línea de comandos como `--root-path` o su equivalente, puedes configurar el parámetro `root_path` al crear tu app de FastAPI:
@@ -127,11 +224,11 @@ Alternativamente, si no tienes una forma de proporcionar una opción de línea d
Pasar el `root_path` a `FastAPI` sería el equivalente a pasar la opción de línea de comandos `--root-path` a Uvicorn o Hypercorn.
### Acerca de `root_path`
### Acerca de `root_path` { #about-root-path }
Ten en cuenta que el servidor (Uvicorn) no usará ese `root_path` para nada, a excepción de pasárselo a la app.
Pero si vas con tu navegador a <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> verás el response normal:
Pero si vas con tu navegador a <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> verás el response normal:
```JSON
{
@@ -144,15 +241,15 @@ Así que no se esperará que sea accedido en `http://127.0.0.1:8000/api/v1/app`.
Uvicorn esperará que el proxy acceda a Uvicorn en `http://127.0.0.1:8000/app`, y luego será responsabilidad del proxy añadir el prefijo extra `/api/v1` encima.
## Sobre proxies con un prefijo de path eliminado
## Sobre proxies con un prefijo de path eliminado { #about-proxies-with-a-stripped-path-prefix }
Ten en cuenta que un proxy con prefijo de path eliminado es solo una de las formas de configurarlo.
Probablemente en muchos casos, el valor predeterminado será que el proxy no tenga un prefijo de path eliminado.
Probablemente en muchos casos, el valor por defecto será que el proxy no tenga un prefijo de path eliminado.
En un caso así (sin un prefijo de path eliminado), el proxy escucharía algo como `https://myawesomeapp.com`, y luego si el navegador va a `https://myawesomeapp.com/api/v1/app` y tu servidor (por ejemplo, Uvicorn) escucha en `http://127.0.0.1:8000`, el proxy (sin un prefijo de path eliminado) accedería a Uvicorn en el mismo path: `http://127.0.0.1:8000/api/v1/app`.
## Probando localmente con Traefik
## Probando localmente con Traefik { #testing-locally-with-traefik }
Puedes ejecutar fácilmente el experimento localmente con un prefijo de path eliminado usando <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
@@ -224,14 +321,14 @@ Y ahora inicia tu app, utilizando la opción `--root-path`:
<div class="termy">
```console
$ fastapi run main.py --root-path /api/v1
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Revisa los responses
### Revisa los responses { #check-the-responses }
Ahora, si vas a la URL con el puerto para Uvicorn: <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, verás el response normal:
@@ -267,7 +364,7 @@ Y la versión sin el prefijo de path (`http://127.0.0.1:8000/app`), proporcionad
Eso demuestra cómo el Proxy (Traefik) usa el prefijo de path y cómo el servidor (Uvicorn) usa el `root_path` de la opción `--root-path`.
### Revisa la UI de los docs
### Revisa la UI de los docs { #check-the-docs-ui }
Pero aquí está la parte divertida. ✨
@@ -287,7 +384,7 @@ Justo como queríamos. ✔️
Esto es porque FastAPI usa este `root_path` para crear el `server` por defecto en OpenAPI con la URL proporcionada por `root_path`.
## Servidores adicionales
## Servidores adicionales { #additional-servers }
/// warning | Advertencia
@@ -346,7 +443,15 @@ La UI de los docs interactuará con el server que selecciones.
///
### Desactivar el server automático de `root_path`
/// note | Detalles Técnicos
La propiedad `servers` en la especificación de OpenAPI es opcional.
Si no especificas el parámetro `servers` y `root_path` es igual a `/`, la propiedad `servers` en el esquema de OpenAPI generado se omitirá por completo por defecto, lo cual es equivalente a un único server con un valor `url` de `/`.
///
### Desactivar el server automático de `root_path` { #disable-automatic-server-from-root-path }
Si no quieres que **FastAPI** incluya un server automático usando el `root_path`, puedes usar el parámetro `root_path_in_servers=False`:
@@ -354,7 +459,7 @@ Si no quieres que **FastAPI** incluya un server automático usando el `root_path
y entonces no lo incluirá en el esquema de OpenAPI.
## Montando una sub-aplicación
## Montando una sub-aplicación { #mounting-a-sub-application }
Si necesitas montar una sub-aplicación (como se describe en [Aplicaciones secundarias - Monturas](sub-applications.md){.internal-link target=_blank}) mientras usas un proxy con `root_path`, puedes hacerlo normalmente, como esperarías.

View File

@@ -1,4 +1,4 @@
# Response Personalizado - HTML, Stream, Archivo, otros
# Response Personalizado - HTML, Stream, Archivo, otros { #custom-response-html-stream-file-others }
Por defecto, **FastAPI** devolverá los responses usando `JSONResponse`.
@@ -18,7 +18,7 @@ Si usas una clase de response sin media type, FastAPI esperará que tu response
///
## Usa `ORJSONResponse`
## Usa `ORJSONResponse` { #use-orjsonresponse }
Por ejemplo, si estás exprimendo el rendimiento, puedes instalar y usar <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> y establecer el response como `ORJSONResponse`.
@@ -48,7 +48,7 @@ El `ORJSONResponse` solo está disponible en FastAPI, no en Starlette.
///
## Response HTML
## Response HTML { #html-response }
Para devolver un response con HTML directamente desde **FastAPI**, usa `HTMLResponse`.
@@ -67,7 +67,7 @@ Y se documentará así en OpenAPI.
///
### Devuelve una `Response`
### Devuelve una `Response` { #return-a-response }
Como se ve en [Devolver una Response directamente](response-directly.md){.internal-link target=_blank}, también puedes sobrescribir el response directamente en tu *path operation*, devolviéndolo.
@@ -87,13 +87,13 @@ Por supuesto, el `Content-Type` header real, el código de estado, etc., provend
///
### Documenta en OpenAPI y sobrescribe `Response`
### Documenta en OpenAPI y sobrescribe `Response` { #document-in-openapi-and-override-response }
Si quieres sobrescribir el response desde dentro de la función pero al mismo tiempo documentar el "media type" en OpenAPI, puedes usar el parámetro `response_class` Y devolver un objeto `Response`.
El `response_class` solo se usará para documentar el OpenAPI *path operation*, pero tu `Response` se usará tal cual.
#### Devuelve un `HTMLResponse` directamente
#### Devuelve un `HTMLResponse` directamente { #return-an-htmlresponse-directly }
Por ejemplo, podría ser algo así:
@@ -101,13 +101,13 @@ Por ejemplo, podría ser algo así:
En este ejemplo, la función `generate_html_response()` ya genera y devuelve una `Response` en lugar de devolver el HTML en un `str`.
Al devolver el resultado de llamar a `generate_html_response()`, ya estás devolviendo una `Response` que sobrescribirá el comportamiento predeterminado de **FastAPI**.
Al devolver el resultado de llamar a `generate_html_response()`, ya estás devolviendo una `Response` que sobrescribirá el comportamiento por defecto de **FastAPI**.
Pero como pasaste `HTMLResponse` en el `response_class` también, **FastAPI** sabrá cómo documentarlo en OpenAPI y la documentación interactiva como HTML con `text/html`:
<img src="/img/tutorial/custom-response/image01.png">
## Responses disponibles
## Responses disponibles { #available-responses }
Aquí hay algunos de los responses disponibles.
@@ -121,7 +121,7 @@ También podrías usar `from starlette.responses import HTMLResponse`.
///
### `Response`
### `Response` { #response }
La clase principal `Response`, todos los otros responses heredan de ella.
@@ -138,23 +138,23 @@ FastAPI (de hecho Starlette) incluirá automáticamente un header Content-Length
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
### `HTMLResponse`
### `HTMLResponse` { #htmlresponse }
Toma algún texto o bytes y devuelve un response HTML, como leíste arriba.
### `PlainTextResponse`
### `PlainTextResponse` { #plaintextresponse }
Toma algún texto o bytes y devuelve un response de texto plano.
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
### `JSONResponse`
### `JSONResponse` { #jsonresponse }
Toma algunos datos y devuelve un response codificado como `application/json`.
Este es el response predeterminado usado en **FastAPI**, como leíste arriba.
Este es el response usado por defecto en **FastAPI**, como leíste arriba.
### `ORJSONResponse`
### `ORJSONResponse` { #orjsonresponse }
Un response JSON rápido alternativo usando <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, como leíste arriba.
@@ -164,7 +164,7 @@ Esto requiere instalar `orjson`, por ejemplo, con `pip install orjson`.
///
### `UJSONResponse`
### `UJSONResponse` { #ujsonresponse }
Un response JSON alternativo usando <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>.
@@ -188,7 +188,7 @@ Es posible que `ORJSONResponse` sea una alternativa más rápida.
///
### `RedirectResponse`
### `RedirectResponse` { #redirectresponse }
Devuelve una redirección HTTP. Usa un código de estado 307 (Redirección Temporal) por defecto.
@@ -204,7 +204,7 @@ O puedes usarlo en el parámetro `response_class`:
Si haces eso, entonces puedes devolver la URL directamente desde tu *path operation function*.
En este caso, el `status_code` utilizado será el predeterminado para `RedirectResponse`, que es `307`.
En este caso, el `status_code` utilizado será el por defecto para `RedirectResponse`, que es `307`.
---
@@ -212,13 +212,13 @@ También puedes usar el parámetro `status_code` combinado con el parámetro `re
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
### `StreamingResponse`
### `StreamingResponse` { #streamingresponse }
Toma un generador `async` o un generador/iterador normal y transmite el cuerpo del response.
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
#### Usando `StreamingResponse` con objetos similares a archivos
#### Usando `StreamingResponse` con objetos similares a archivos { #using-streamingresponse-with-file-like-objects }
Si tienes un objeto similar a un archivo (por ejemplo, el objeto devuelto por `open()`), puedes crear una función generadora para iterar sobre ese objeto similar a un archivo.
@@ -242,7 +242,7 @@ Nota que aquí como estamos usando `open()` estándar que no admite `async` y `a
///
### `FileResponse`
### `FileResponse` { #fileresponse }
Transmite un archivo asincrónicamente como response.
@@ -263,7 +263,7 @@ También puedes usar el parámetro `response_class`:
En este caso, puedes devolver la path del archivo directamente desde tu *path operation* function.
## Clase de response personalizada
## Clase de response personalizada { #custom-response-class }
Puedes crear tu propia clase de response personalizada, heredando de `Response` y usándola.
@@ -291,7 +291,7 @@ Ahora en lugar de devolver:
Por supuesto, probablemente encontrarás formas mucho mejores de aprovechar esto que formatear JSON. 😉
## Clase de response predeterminada
## Clase de response por defecto { #default-response-class }
Al crear una instance de la clase **FastAPI** o un `APIRouter`, puedes especificar qué clase de response usar por defecto.
@@ -307,6 +307,6 @@ Todavía puedes sobrescribir `response_class` en *path operations* como antes.
///
## Documentación adicional
## Documentación adicional { #additional-documentation }
También puedes declarar el media type y muchos otros detalles en OpenAPI usando `responses`: [Responses Adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}.

View File

@@ -1,10 +1,10 @@
# Usando Dataclasses
# Usando Dataclasses { #using-dataclasses }
FastAPI está construido sobre **Pydantic**, y te he estado mostrando cómo usar modelos de Pydantic para declarar requests y responses.
Pero FastAPI también soporta el uso de <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> de la misma manera:
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
Esto sigue siendo soportado gracias a **Pydantic**, ya que tiene <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">soporte interno para `dataclasses`</a>.
@@ -28,11 +28,11 @@ Pero si tienes un montón de dataclasses por ahí, este es un buen truco para us
///
## Dataclasses en `response_model`
## Dataclasses en `response_model` { #dataclasses-in-response-model }
También puedes usar `dataclasses` en el parámetro `response_model`:
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
El dataclass será automáticamente convertido a un dataclass de Pydantic.
@@ -40,7 +40,7 @@ De esta manera, su esquema aparecerá en la interfaz de usuario de la documentac
<img src="/img/tutorial/dataclasses/image01.png">
## Dataclasses en Estructuras de Datos Anidadas
## Dataclasses en Estructuras de Datos Anidadas { #dataclasses-in-nested-data-structures }
También puedes combinar `dataclasses` con otras anotaciones de tipos para crear estructuras de datos anidadas.
@@ -48,7 +48,7 @@ En algunos casos, todavía podrías tener que usar la versión de `dataclasses`
En ese caso, simplemente puedes intercambiar los `dataclasses` estándar con `pydantic.dataclasses`, que es un reemplazo directo:
{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. Todavía importamos `field` de los `dataclasses` estándar.
@@ -64,7 +64,7 @@ En ese caso, simplemente puedes intercambiar los `dataclasses` estándar con `py
6. Aquí estamos regresando un diccionario que contiene `items`, que es una lista de dataclasses.
FastAPI todavía es capaz de <abbr title="converting the data to a format that can be transmitted">serializar</abbr> los datos a JSON.
FastAPI todavía es capaz de <abbr title="convertir los datos a un formato que pueda transmitirse">serializar</abbr> los datos a JSON.
7. Aquí el `response_model` está usando una anotación de tipo de una lista de dataclasses `Author`.
@@ -84,12 +84,12 @@ Puedes combinar `dataclasses` con otras anotaciones de tipos en muchas combinaci
Revisa las anotaciones en el código arriba para ver más detalles específicos.
## Aprende Más
## Aprende Más { #learn-more }
También puedes combinar `dataclasses` con otros modelos de Pydantic, heredar de ellos, incluirlos en tus propios modelos, etc.
Para saber más, revisa la <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">documentación de Pydantic sobre dataclasses</a>.
## Versión
## Versión { #version }
Esto está disponible desde la versión `0.67.0` de FastAPI. 🔖

View File

@@ -1,115 +1,76 @@
# Genera Clientes
# Generando SDKs { #generating-sdks }
Como **FastAPI** está basado en la especificación OpenAPI, obtienes compatibilidad automática con muchas herramientas, incluyendo la documentación automática de la API (proporcionada por Swagger UI).
Como **FastAPI** está basado en la especificación **OpenAPI**, sus APIs se pueden describir en un formato estándar que muchas herramientas entienden.
Una ventaja particular que no es necesariamente obvia es que puedes **generar clientes** (a veces llamados <abbr title="Software Development Kits">**SDKs**</abbr> ) para tu API, para muchos **lenguajes de programación** diferentes.
Esto facilita generar **documentación** actualizada, paquetes de cliente (<abbr title="Software Development Kits Kits de Desarrollo de Software">**SDKs**</abbr>) en múltiples lenguajes y **escribir pruebas** o **flujos de automatización** que se mantengan sincronizados con tu código.
## Generadores de Clientes OpenAPI
En esta guía, aprenderás a generar un **SDK de TypeScript** para tu backend con FastAPI.
Hay muchas herramientas para generar clientes desde **OpenAPI**.
## Generadores de SDKs de código abierto { #open-source-sdk-generators }
Una herramienta común es <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>.
Una opción versátil es el <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>, que soporta **muchos lenguajes de programación** y puede generar SDKs a partir de tu especificación OpenAPI.
Si estás construyendo un **frontend**, una alternativa muy interesante es <a href="https://github.com/hey-api/openapi-ts" class="external-link" target="_blank">openapi-ts</a>.
Para **clientes de TypeScript**, <a href="https://heyapi.dev/" class="external-link" target="_blank">Hey API</a> es una solución diseñada específicamente, que ofrece una experiencia optimizada para el ecosistema de TypeScript.
## Generadores de Clientes y SDKs - Sponsor
Puedes descubrir más generadores de SDK en <a href="https://openapi.tools/#sdk" class="external-link" target="_blank">OpenAPI.Tools</a>.
También hay algunos generadores de Clientes y SDKs **respaldados por empresas** basados en OpenAPI (FastAPI), en algunos casos pueden ofrecerte **funcionalidades adicionales** además de SDKs/clientes generados de alta calidad.
/// tip | Consejo
Algunos de ellos también ✨ [**sponsorean FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, esto asegura el **desarrollo** continuo y saludable de FastAPI y su **ecosistema**.
FastAPI genera automáticamente especificaciones **OpenAPI 3.1**, así que cualquier herramienta que uses debe soportar esta versión.
Y muestra su verdadero compromiso con FastAPI y su **comunidad** (tú), ya que no solo quieren proporcionarte un **buen servicio** sino también asegurarse de que tengas un **buen y saludable framework**, FastAPI. 🙇
///
## Generadores de SDKs de sponsors de FastAPI { #sdk-generators-from-fastapi-sponsors }
Esta sección destaca soluciones **respaldadas por empresas** y **venture-backed** de compañías que sponsorean FastAPI. Estos productos ofrecen **funcionalidades adicionales** e **integraciones** además de SDKs generados de alta calidad.
Al ✨ [**sponsorear FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, estas compañías ayudan a asegurar que el framework y su **ecosistema** se mantengan saludables y **sustentables**.
Su sponsorship también demuestra un fuerte compromiso con la **comunidad** de FastAPI (tú), mostrando que no solo les importa ofrecer un **gran servicio**, sino también apoyar un **framework robusto y próspero**, FastAPI. 🙇
Por ejemplo, podrías querer probar:
* <a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>
* <a href="https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>
* <a href="https://developers.liblab.com/tutorials/sdk-for-fastapi/?utm_source=fastapi" class="external-link" target="_blank">liblab</a>
* <a href="https://www.stainless.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>
* <a href="https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi" class="external-link" target="_blank">liblab</a>
También hay varias otras empresas que ofrecen servicios similares que puedes buscar y encontrar en línea. 🤓
Algunas de estas soluciones también pueden ser open source u ofrecer niveles gratuitos, así que puedes probarlas sin un compromiso financiero. Hay otros generadores de SDK comerciales disponibles y se pueden encontrar en línea. 🤓
## Genera un Cliente Frontend en TypeScript
## Crea un SDK de TypeScript { #create-a-typescript-sdk }
Empecemos con una aplicación simple de FastAPI:
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
Nota que las *path operations* definen los modelos que usan para el payload de la petición y el payload del response, usando los modelos `Item` y `ResponseMessage`.
Nota que las *path operations* definen los modelos que usan para el payload del request y el payload del response, usando los modelos `Item` y `ResponseMessage`.
### Documentación de la API
### Documentación de la API { #api-docs }
Si vas a la documentación de la API, verás que tiene los **esquemas** para los datos que se enviarán en las peticiones y se recibirán en los responses:
Si vas a `/docs`, verás que tiene los **esquemas** para los datos a enviar en requests y recibir en responses:
<img src="/img/tutorial/generate-clients/image01.png">
Puedes ver esos esquemas porque fueron declarados con los modelos en la aplicación.
Puedes ver esos esquemas porque fueron declarados con los modelos en la app.
Esa información está disponible en el **JSON Schema** de OpenAPI de la aplicación, y luego se muestra en la documentación de la API (por Swagger UI).
Esa información está disponible en el **OpenAPI schema** de la app, y luego se muestra en la documentación de la API.
Y esa misma información de los modelos que está incluida en OpenAPI es lo que puede usarse para **generar el código del cliente**.
### Genera un Cliente en TypeScript
### Hey API { #hey-api }
Ahora que tenemos la aplicación con los modelos, podemos generar el código del cliente para el frontend.
Una vez que tenemos una app de FastAPI con los modelos, podemos usar Hey API para generar un cliente de TypeScript. La forma más rápida de hacerlo es con npx.
#### Instalar `openapi-ts`
Puedes instalar `openapi-ts` en tu código de frontend con:
<div class="termy">
```console
$ npm install @hey-api/openapi-ts --save-dev
---> 100%
```sh
npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
```
</div>
Esto generará un SDK de TypeScript en `./src/client`.
#### Generar el Código del Cliente
Puedes aprender cómo <a href="https://heyapi.dev/openapi-ts/get-started" class="external-link" target="_blank">instalar `@hey-api/openapi-ts`</a> y leer sobre el <a href="https://heyapi.dev/openapi-ts/output" class="external-link" target="_blank">output generado</a> en su sitio web.
Para generar el código del cliente puedes usar la aplicación de línea de comandos `openapi-ts` que ahora estaría instalada.
### Usar el SDK { #using-the-sdk }
Como está instalada en el proyecto local, probablemente no podrías llamar a ese comando directamente, pero podrías ponerlo en tu archivo `package.json`.
Podría verse como esto:
```JSON hl_lines="7"
{
"name": "frontend-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
"@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
```
Después de tener ese script de NPM `generate-client` allí, puedes ejecutarlo con:
<div class="termy">
```console
$ npm run generate-client
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
</div>
Ese comando generará código en `./src/client` y usará `axios` (el paquete HTTP de frontend) internamente.
### Prueba el Código del Cliente
Ahora puedes importar y usar el código del cliente, podría verse así, nota que tienes autocompletado para los métodos:
Ahora puedes importar y usar el código del cliente. Podría verse así, nota que tienes autocompletado para los métodos:
<img src="/img/tutorial/generate-clients/image02.png">
@@ -131,17 +92,17 @@ El objeto de response también tendrá autocompletado:
<img src="/img/tutorial/generate-clients/image05.png">
## App de FastAPI con Tags
## App de FastAPI con tags { #fastapi-app-with-tags }
En muchos casos tu aplicación de FastAPI será más grande, y probablemente usarás tags para separar diferentes grupos de *path operations*.
En muchos casos tu app de FastAPI será más grande, y probablemente usarás tags para separar diferentes grupos de *path operations*.
Por ejemplo, podrías tener una sección para **items** y otra sección para **usuarios**, y podrían estar separadas por tags:
Por ejemplo, podrías tener una sección para **items** y otra sección para **users**, y podrían estar separadas por tags:
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
### Genera un Cliente TypeScript con Tags
### Genera un Cliente TypeScript con tags { #generate-a-typescript-client-with-tags }
Si generas un cliente para una aplicación de FastAPI usando tags, normalmente también separará el código del cliente basándose en los tags.
Si generas un cliente para una app de FastAPI usando tags, normalmente también separará el código del cliente basándose en los tags.
De esta manera podrás tener las cosas ordenadas y agrupadas correctamente para el código del cliente:
@@ -152,7 +113,7 @@ En este caso tienes:
* `ItemsService`
* `UsersService`
### Nombres de los Métodos del Cliente
### Nombres de los métodos del cliente { #client-method-names }
Ahora mismo los nombres de los métodos generados como `createItemItemsPost` no se ven muy limpios:
@@ -166,15 +127,15 @@ OpenAPI requiere que cada operation ID sea único a través de todas las *path o
Pero te mostraré cómo mejorar eso a continuación. 🤓
## Operation IDs Personalizados y Mejores Nombres de Métodos
## Operation IDs personalizados y mejores nombres de métodos { #custom-operation-ids-and-better-method-names }
Puedes **modificar** la forma en que estos operation IDs son **generados** para hacerlos más simples y tener **nombres de métodos más simples** en los clientes.
En este caso tendrás que asegurarte de que cada operation ID sea **único** de alguna otra manera.
Por ejemplo, podrías asegurarte de que cada *path operation* tenga un tag, y luego generar el operation ID basado en el **tag** y el nombre de la *path operation* **name** (el nombre de la función).
Por ejemplo, podrías asegurarte de que cada *path operation* tenga un tag, y luego generar el operation ID basado en el **tag** y el **name** de la *path operation* (el nombre de la función).
### Función Personalizada para Generar ID Único
### Función personalizada para generar ID único { #custom-generate-unique-id-function }
FastAPI usa un **ID único** para cada *path operation*, se usa para el **operation ID** y también para los nombres de cualquier modelo personalizado necesario, para requests o responses.
@@ -186,15 +147,15 @@ Puedes entonces pasar esa función personalizada a **FastAPI** como el parámetr
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
### Generar un Cliente TypeScript con Operation IDs Personalizados
### Genera un Cliente TypeScript con operation IDs personalizados { #generate-a-typescript-client-with-custom-operation-ids }
Ahora si generas el cliente de nuevo, verás que tiene los nombres de métodos mejorados:
Ahora, si generas el cliente de nuevo, verás que tiene los nombres de métodos mejorados:
<img src="/img/tutorial/generate-clients/image07.png">
Como ves, los nombres de métodos ahora tienen el tag y luego el nombre de la función, ahora no incluyen información del path de la URL y la operación HTTP.
### Preprocesa la Especificación OpenAPI para el Generador de Clientes
### Preprocesa la especificación OpenAPI para el generador de clientes { #preprocess-the-openapi-specification-for-the-client-generator }
El código generado aún tiene algo de **información duplicada**.
@@ -218,44 +179,30 @@ Podríamos descargar el JSON de OpenAPI a un archivo `openapi.json` y luego podr
Con eso, los operation IDs serían renombrados de cosas como `items-get_items` a solo `get_items`, de esa manera el generador del cliente puede generar nombres de métodos más simples.
### Generar un Cliente TypeScript con el OpenAPI Preprocesado
### Genera un Cliente TypeScript con el OpenAPI preprocesado { #generate-a-typescript-client-with-the-preprocessed-openapi }
Ahora como el resultado final está en un archivo `openapi.json`, modificarías el `package.json` para usar ese archivo local, por ejemplo:
Como el resultado final ahora está en un archivo `openapi.json`, necesitas actualizar la ubicación de la entrada:
```JSON hl_lines="7"
{
"name": "frontend-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
"@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
```sh
npx @hey-api/openapi-ts -i ./openapi.json -o src/client
```
Después de generar el nuevo cliente, ahora tendrías nombres de métodos **limpios**, con todo el **autocompletado**, **errores en línea**, etc:
<img src="/img/tutorial/generate-clients/image08.png">
## Beneficios
## Beneficios { #benefits }
Cuando usas los clientes generados automáticamente obtendrás **autocompletado** para:
Cuando uses los clientes generados automáticamente obtendrás **autocompletado** para:
* Métodos.
* Payloads de peticiones en el cuerpo, parámetros de query, etc.
* Payloads de responses.
* Payloads de request en el body, parámetros de query, etc.
* Payloads de response.
También tendrás **errores en línea** para todo.
Y cada vez que actualices el código del backend, y **regeneres** el frontend, tendrás las nuevas *path operations* disponibles como métodos, las antiguas eliminadas, y cualquier otro cambio se reflejará en el código generado. 🤓
Esto también significa que si algo cambió será **reflejado** automáticamente en el código del cliente. Y si haces **build** del cliente, te dará error si tienes algún **desajuste** en los datos utilizados.
Esto también significa que si algo cambió será **reflejado** automáticamente en el código del cliente. Y si haces **build** del cliente, dará error si tienes algún **desajuste** en los datos utilizados.
Así que, **detectarás muchos errores** muy temprano en el ciclo de desarrollo en lugar de tener que esperar a que los errores se muestren a tus usuarios finales en producción para luego intentar depurar dónde está el problema. ✨

View File

@@ -1,6 +1,6 @@
# Guía avanzada del usuario
# Guía avanzada del usuario { #advanced-user-guide }
## Funcionalidades adicionales
## Funcionalidades adicionales { #additional-features }
El [Tutorial - Guía del usuario](../tutorial/index.md){.internal-link target=_blank} principal debería ser suficiente para darte un recorrido por todas las funcionalidades principales de **FastAPI**.
@@ -14,23 +14,8 @@ Y es posible que para tu caso de uso, la solución esté en una de ellas.
///
## Lee primero el Tutorial
## Lee primero el Tutorial { #read-the-tutorial-first }
Aún podrías usar la mayoría de las funcionalidades en **FastAPI** con el conocimiento del [Tutorial - Guía del usuario](../tutorial/index.md){.internal-link target=_blank} principal.
Y las siguientes secciones asumen que ya lo leíste y que conoces esas ideas principales.
## Cursos externos
Aunque el [Tutorial - Guía del usuario](../tutorial/index.md){.internal-link target=_blank} y esta **Guía avanzada del usuario** están escritos como un tutorial guiado (como un libro) y deberían ser suficientes para que **aprendas FastAPI**, podrías querer complementarlo con cursos adicionales.
O podría ser que simplemente prefieras tomar otros cursos porque se adaptan mejor a tu estilo de aprendizaje.
Algunos proveedores de cursos ✨ [**sponsorean FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, esto asegura el desarrollo continuo y saludable de FastAPI y su **ecosistema**.
Y muestra su verdadero compromiso con FastAPI y su **comunidad** (tú), ya que no solo quieren brindarte una **buena experiencia de aprendizaje** sino que también quieren asegurarse de que tengas un **buen y saludable framework**, FastAPI. 🙇
Podrías querer probar sus cursos:
* <a href="https://training.talkpython.fm/fastapi-courses" class="external-link" target="_blank">Talk Python Training</a>
* <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Desarrollo guiado por pruebas</a>

View File

@@ -1,18 +1,18 @@
# OpenAPI Callbacks
# Callbacks de OpenAPI { #openapi-callbacks }
Podrías crear una API con una *path operation* que podría desencadenar un request a una *API externa* creada por alguien más (probablemente el mismo desarrollador que estaría *usando* tu API).
El proceso que ocurre cuando tu aplicación API llama a la *API externa* se llama un "callback". Porque el software que escribió el desarrollador externo envía un request a tu API y luego tu API *responde*, enviando un request a una *API externa* (que probablemente fue creada por el mismo desarrollador).
El proceso que ocurre cuando tu aplicación API llama a la *API externa* se llama un "callback". Porque el software que escribió el desarrollador externo envía un request a tu API y luego tu API hace un *callback*, enviando un request a una *API externa* (que probablemente fue creada por el mismo desarrollador).
En este caso, podrías querer documentar cómo esa API externa *debería* verse. Qué *path operation* debería tener, qué cuerpo debería esperar, qué response debería devolver, etc.
## Una aplicación con callbacks
## Una aplicación con callbacks { #an-app-with-callbacks }
Veamos todo esto con un ejemplo.
Imagina que desarrollas una aplicación que permite crear facturas.
Estas facturas tendrán un `id`, `title` (opcional), `customer`, y `total`.
Estas facturas tendrán un `id`, `title` (opcional), `customer` y `total`.
El usuario de tu API (un desarrollador externo) creará una factura en tu API con un request POST.
@@ -23,15 +23,15 @@ Luego tu API (imaginemos):
* Enviará una notificación de vuelta al usuario de la API (el desarrollador externo).
* Esto se hará enviando un request POST (desde *tu API*) a alguna *API externa* proporcionada por ese desarrollador externo (este es el "callback").
## La aplicación normal de **FastAPI**
## La aplicación normal de **FastAPI** { #the-normal-fastapi-app }
Primero veamos cómo sería la aplicación API normal antes de agregar el callback.
Primero veamos cómo se vería la aplicación API normal antes de agregar el callback.
Tendrá una *path operation* que recibirá un cuerpo `Invoice`, y un parámetro de query `callback_url` que contendrá la URL para el callback.
Esta parte es bastante normal, probablemente ya estés familiarizado con la mayor parte del código:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
/// tip | Consejo
@@ -39,9 +39,9 @@ El parámetro de query `callback_url` utiliza un tipo <a href="https://docs.pyda
///
Lo único nuevo es el `callbacks=invoices_callback_router.routes` como un argumento para el *decorador de path operation*. Veremos qué es eso a continuación.
Lo único nuevo es `callbacks=invoices_callback_router.routes` como un argumento para el *decorador de path operation*. Veremos qué es eso a continuación.
## Documentar el callback
## Documentar el callback { #documenting-the-callback }
El código real del callback dependerá mucho de tu propia aplicación API.
@@ -56,7 +56,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
Pero posiblemente la parte más importante del callback es asegurarse de que el usuario de tu API (el desarrollador externo) implemente la *API externa* correctamente, de acuerdo con los datos que *tu API* va a enviar en el request body del callback, etc.
Entonces, lo que haremos a continuación es agregar el código para documentar cómo debería verse esa *API externa* para recibir el callback de *tu API*.
Así que, lo que haremos a continuación es agregar el código para documentar cómo debería verse esa *API externa* para recibir el callback de *tu API*.
Esa documentación aparecerá en la Swagger UI en `/docs` en tu API, y permitirá a los desarrolladores externos saber cómo construir la *API externa*.
@@ -70,11 +70,11 @@ Cuando implementes el callback tú mismo, podrías usar algo como <a href="https
///
## Escribir el código de documentación del callback
## Escribe el código de documentación del callback { #write-the-callback-documentation-code }
Este código no se ejecutará en tu aplicación, solo lo necesitamos para *documentar* cómo debería verse esa *API externa*.
Pero, ya sabes cómo crear fácilmente documentación automática para una API con **FastAPI**.
Pero ya sabes cómo crear fácilmente documentación automática para una API con **FastAPI**.
Así que vamos a usar ese mismo conocimiento para documentar cómo debería verse la *API externa*... creando la(s) *path operation(s)* que la API externa debería implementar (las que tu API va a llamar).
@@ -86,29 +86,29 @@ Adoptar temporalmente este punto de vista (del *desarrollador externo*) puede ay
///
### Crear un `APIRouter` de callback
### Crea un `APIRouter` de callback { #create-a-callback-apirouter }
Primero crea un nuevo `APIRouter` que contendrá uno o más callbacks.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
### Crear la *path operation* del callback
### Crea la *path operation* del callback { #create-the-callback-path-operation }
Para crear la *path operation* del callback utiliza el mismo `APIRouter` que creaste anteriormente.
Para crear la *path operation* del callback usa el mismo `APIRouter` que creaste arriba.
Debería verse como una *path operation* normal de FastAPI:
* Probablemente debería tener una declaración del body que debería recibir, por ejemplo `body: InvoiceEvent`.
* Y también podría tener una declaración del response que debería devolver, por ejemplo `response_model=InvoiceEventReceived`.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
Hay 2 diferencias principales respecto a una *path operation* normal:
* No necesita tener ningún código real, porque tu aplicación nunca llamará a este código. Solo se usa para documentar la *API externa*. Así que, la función podría simplemente tener `pass`.
* El *path* puede contener una <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">expresión OpenAPI 3</a> (ver más abajo) donde puede usar variables con parámetros y partes del request original enviado a *tu API*.
### La expresión del path del callback
### La expresión del path del callback { #the-callback-path-expression }
El *path* del callback puede tener una <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">expresión OpenAPI 3</a> que puede contener partes del request original enviado a *tu API*.
@@ -134,7 +134,7 @@ con un JSON body de:
}
```
luego *tu API* procesará la factura, y en algún momento después, enviará un request de callback al `callback_url` (la *API externa*):
luego *tu API* procesará la factura y, en algún momento después, enviará un request de callback al `callback_url` (la *API externa*):
```
https://www.external.org/events/invoices/2expen51ve
@@ -163,13 +163,13 @@ Observa cómo la URL del callback utilizada contiene la URL recibida como parám
///
### Agregar el router de callback
### Agrega el router de callback { #add-the-callback-router }
En este punto tienes las *path operation(s)* del callback necesarias (las que el *desarrollador externo* debería implementar en la *API externa*) en el router de callback que creaste antes.
En este punto tienes las *path operation(s)* del callback necesarias (las que el *desarrollador externo* debería implementar en la *API externa*) en el router de callback que creaste arriba.
Ahora usa el parámetro `callbacks` en el *decorador de path operation de tu API* para pasar el atributo `.routes` (que en realidad es solo un `list` de rutas/*path operations*) de ese router de callback:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
/// tip | Consejo
@@ -177,7 +177,7 @@ Observa que no estás pasando el router en sí (`invoices_callback_router`) a `c
///
### Revisa la documentación
### Revisa la documentación { #check-the-docs }
Ahora puedes iniciar tu aplicación e ir a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.

View File

@@ -1,4 +1,4 @@
# Webhooks de OpenAPI
# Webhooks de OpenAPI { #openapi-webhooks }
Hay casos donde quieres decirle a los **usuarios** de tu API que tu aplicación podría llamar a *su* aplicación (enviando una request) con algunos datos, normalmente para **notificar** de algún tipo de **evento**.
@@ -6,7 +6,7 @@ Esto significa que en lugar del proceso normal de tus usuarios enviando requests
Esto normalmente se llama un **webhook**.
## Pasos de los webhooks
## Pasos de los webhooks { #webhooks-steps }
El proceso normalmente es que **tú defines** en tu código cuál es el mensaje que enviarás, el **body de la request**.
@@ -16,7 +16,7 @@ Y **tus usuarios** definen de alguna manera (por ejemplo en un panel web en alg
Toda la **lógica** sobre cómo registrar los URLs para webhooks y el código para realmente enviar esas requests depende de ti. Lo escribes como quieras en **tu propio código**.
## Documentando webhooks con **FastAPI** y OpenAPI
## Documentando webhooks con **FastAPI** y OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
Con **FastAPI**, usando OpenAPI, puedes definir los nombres de estos webhooks, los tipos de operaciones HTTP que tu aplicación puede enviar (por ejemplo, `POST`, `PUT`, etc.) y los **bodies** de las requests que tu aplicación enviaría.
@@ -28,7 +28,7 @@ Los webhooks están disponibles en OpenAPI 3.1.0 y superiores, soportados por Fa
///
## Una aplicación con webhooks
## Una aplicación con webhooks { #an-app-with-webhooks }
Cuando creas una aplicación de **FastAPI**, hay un atributo `webhooks` que puedes usar para definir *webhooks*, de la misma manera que definirías *path operations*, por ejemplo con `@app.webhooks.post()`.
@@ -46,7 +46,7 @@ Nota que con los webhooks en realidad no estás declarando un *path* (como `/ite
Esto es porque se espera que **tus usuarios** definan el actual **URL path** donde quieren recibir la request del webhook de alguna otra manera (por ejemplo, un panel web).
### Revisa la documentación
### Revisa la documentación { #check-the-docs }
Ahora puedes iniciar tu app e ir a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.

View File

@@ -1,6 +1,6 @@
# Configuración Avanzada de Path Operation
# Configuración Avanzada de Path Operation { #path-operation-advanced-configuration }
## operationId de OpenAPI
## operationId de OpenAPI { #openapi-operationid }
/// warning | Advertencia
@@ -14,7 +14,7 @@ Tienes que asegurarte de que sea único para cada operación.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
### Usar el nombre de la *función de path operation* como el operationId
### Usar el nombre de la *path operation function* como el operationId { #using-the-path-operation-function-name-as-the-operationid }
Si quieres usar los nombres de las funciones de tus APIs como `operationId`s, puedes iterar sobre todas ellas y sobrescribir el `operation_id` de cada *path operation* usando su `APIRoute.name`.
@@ -30,29 +30,29 @@ Si llamas manualmente a `app.openapi()`, deberías actualizar los `operationId`s
/// warning | Advertencia
Si haces esto, tienes que asegurarte de que cada una de tus *funciones de path operation* tenga un nombre único.
Si haces esto, tienes que asegurarte de que cada una de tus *path operation functions* tenga un nombre único.
Incluso si están en diferentes módulos (archivos de Python).
///
## Excluir de OpenAPI
## Excluir de OpenAPI { #exclude-from-openapi }
Para excluir una *path operation* del esquema OpenAPI generado (y por lo tanto, de los sistemas de documentación automática), utiliza el parámetro `include_in_schema` y configúralo en `False`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
## Descripción avanzada desde el docstring
## Descripción avanzada desde el docstring { #advanced-description-from-docstring }
Puedes limitar las líneas usadas del docstring de una *función de path operation* para OpenAPI.
Puedes limitar las líneas usadas del docstring de una *path operation function* para OpenAPI.
Añadir un `\f` (un carácter de separación de página escapado) hace que **FastAPI** trunque la salida usada para OpenAPI en este punto.
No aparecerá en la documentación, pero otras herramientas (como Sphinx) podrán usar el resto.
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
## Responses Adicionales
## Responses Adicionales { #additional-responses }
Probablemente has visto cómo declarar el `response_model` y el `status_code` para una *path operation*.
@@ -62,11 +62,11 @@ También puedes declarar responses adicionales con sus modelos, códigos de esta
Hay un capítulo entero en la documentación sobre ello, puedes leerlo en [Responses Adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}.
## OpenAPI Extra
## OpenAPI Extra { #openapi-extra }
Cuando declaras una *path operation* en tu aplicación, **FastAPI** genera automáticamente los metadatos relevantes sobre esa *path operation* para incluirlos en el esquema de OpenAPI.
/// note | Nota
/// note | Detalles técnicos
En la especificación de OpenAPI se llama el <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Objeto de Operación</a>.
@@ -88,7 +88,7 @@ Si solo necesitas declarar responses adicionales, una forma más conveniente de
Puedes extender el esquema de OpenAPI para una *path operation* usando el parámetro `openapi_extra`.
### Extensiones de OpenAPI
### Extensiones de OpenAPI { #openapi-extensions }
Este `openapi_extra` puede ser útil, por ejemplo, para declarar [Extensiones de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
@@ -129,7 +129,7 @@ Y si ves el OpenAPI resultante (en `/openapi.json` en tu API), verás tu extensi
}
```
### Esquema de *path operation* personalizada de OpenAPI
### Esquema de *path operation* personalizada de OpenAPI { #custom-openapi-path-operation-schema }
El diccionario en `openapi_extra` se combinará profundamente con el esquema de OpenAPI generado automáticamente para la *path operation*.
@@ -141,37 +141,37 @@ Podrías hacer eso con `openapi_extra`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el cuerpo del request ni siquiera se <abbr title="converted from some plain format, like bytes, into Python objects">parse</abbr> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el cuerpo del request ni siquiera se <abbr title="convertido de algún formato plano, como bytes, a objetos de Python">parse</abbr> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
Sin embargo, podemos declarar el esquema esperado para el cuerpo del request.
### Tipo de contenido personalizado de OpenAPI
### Tipo de contenido personalizado de OpenAPI { #custom-openapi-content-type }
Usando este mismo truco, podrías usar un modelo Pydantic para definir el esquema JSON que luego se incluye en la sección personalizada del esquema OpenAPI para la *path operation*.
Usando este mismo truco, podrías usar un modelo Pydantic para definir el JSON Schema que luego se incluye en la sección personalizada del esquema OpenAPI para la *path operation*.
Y podrías hacer esto incluso si el tipo de datos en el request no es JSON.
Por ejemplo, en esta aplicación no usamos la funcionalidad integrada de FastAPI para extraer el esquema JSON de los modelos Pydantic ni la validación automática para JSON. De hecho, estamos declarando el tipo de contenido del request como YAML, no JSON:
Por ejemplo, en esta aplicación no usamos la funcionalidad integrada de FastAPI para extraer el JSON Schema de los modelos Pydantic ni la validación automática para JSON. De hecho, estamos declarando el tipo de contenido del request como YAML, no JSON:
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
////
/// info | Información
En la versión 1 de Pydantic el método para obtener el esquema JSON para un modelo se llamaba `Item.schema()`, en la versión 2 de Pydantic, el método se llama `Item.model_json_schema()`.
En la versión 1 de Pydantic el método para obtener el JSON Schema para un modelo se llamaba `Item.schema()`, en la versión 2 de Pydantic, el método se llama `Item.model_json_schema()`.
///
Sin embargo, aunque no estamos usando la funcionalidad integrada por defecto, aún estamos usando un modelo Pydantic para generar manualmente el esquema JSON para los datos que queremos recibir en YAML.
Sin embargo, aunque no estamos usando la funcionalidad integrada por defecto, aún estamos usando un modelo Pydantic para generar manualmente el JSON Schema para los datos que queremos recibir en YAML.
Luego usamos el request directamente, y extraemos el cuerpo como `bytes`. Esto significa que FastAPI ni siquiera intentará parsear la carga útil del request como JSON.
@@ -179,13 +179,13 @@ Y luego en nuestro código, parseamos ese contenido YAML directamente, y nuevame
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
////

View File

@@ -1,10 +1,10 @@
# Response - Cambiar Código de Estado
# Response - Cambiar Código de Estado { #response-change-status-code }
Probablemente leíste antes que puedes establecer un [Código de Estado de Response](../tutorial/response-status-code.md){.internal-link target=_blank} por defecto.
Pero en algunos casos necesitas devolver un código de estado diferente al predeterminado.
## Caso de uso
## Caso de uso { #use-case }
Por ejemplo, imagina que quieres devolver un código de estado HTTP de "OK" `200` por defecto.
@@ -14,9 +14,9 @@ Pero todavía quieres poder filtrar y convertir los datos que devuelves con un `
Para esos casos, puedes usar un parámetro `Response`.
## Usa un parámetro `Response`
## Usa un parámetro `Response` { #use-a-response-parameter }
Puedes declarar un parámetro de tipo `Response` en tu *función de path operation* (como puedes hacer para cookies y headers).
Puedes declarar un parámetro de tipo `Response` en tu *path operation function* (como puedes hacer para cookies y headers).
Y luego puedes establecer el `status_code` en ese objeto de response *temporal*.

View File

@@ -1,4 +1,4 @@
# Devolver una Response Directamente
# Devolver una Response Directamente { #return-a-response-directly }
Cuando creas una *path operation* en **FastAPI**, normalmente puedes devolver cualquier dato desde ella: un `dict`, una `list`, un modelo de Pydantic, un modelo de base de datos, etc.
@@ -10,7 +10,7 @@ Pero puedes devolver un `JSONResponse` directamente desde tus *path operations*.
Esto podría ser útil, por ejemplo, para devolver headers o cookies personalizados.
## Devolver una `Response`
## Devolver una `Response` { #return-a-response }
De hecho, puedes devolver cualquier `Response` o cualquier subclase de ella.
@@ -26,7 +26,7 @@ No hará ninguna conversión de datos con los modelos de Pydantic, no convertir
Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de datos, sobrescribir cualquier declaración o validación de datos, etc.
## Usar el `jsonable_encoder` en una `Response`
## Usar el `jsonable_encoder` en una `Response` { #using-the-jsonable-encoder-in-a-response }
Como **FastAPI** no realiza cambios en una `Response` que devuelves, tienes que asegurarte de que sus contenidos estén listos para ello.
@@ -34,9 +34,9 @@ Por ejemplo, no puedes poner un modelo de Pydantic en un `JSONResponse` sin prim
Para esos casos, puedes usar el `jsonable_encoder` para convertir tus datos antes de pasarlos a un response:
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | Nota
/// note | Detalles técnicos
También podrías usar `from starlette.responses import JSONResponse`.
@@ -44,7 +44,7 @@ También podrías usar `from starlette.responses import JSONResponse`.
///
## Devolver una `Response` personalizada
## Devolver una `Response` personalizada { #returning-a-custom-response }
El ejemplo anterior muestra todas las partes que necesitas, pero aún no es muy útil, ya que podrías haber devuelto el `item` directamente, y **FastAPI** lo colocaría en un `JSONResponse` por ti, convirtiéndolo a un `dict`, etc. Todo eso por defecto.
@@ -56,7 +56,7 @@ Podrías poner tu contenido XML en un string, poner eso en un `Response`, y devo
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
## Notas
## Notas { #notes }
Cuando devuelves una `Response` directamente, sus datos no son validados, convertidos (serializados), ni documentados automáticamente.

View File

@@ -1,4 +1,4 @@
# HTTP Basic Auth
# HTTP Basic Auth { #http-basic-auth }
Para los casos más simples, puedes usar HTTP Basic Auth.
@@ -12,7 +12,7 @@ Eso le dice al navegador que muestre el prompt integrado para un nombre de usuar
Luego, cuando escribes ese nombre de usuario y contraseña, el navegador los envía automáticamente en el header.
## Simple HTTP Basic Auth
## Simple HTTP Basic Auth { #simple-http-basic-auth }
* Importa `HTTPBasic` y `HTTPBasicCredentials`.
* Crea un "esquema de `security`" usando `HTTPBasic`.
@@ -26,7 +26,7 @@ Cuando intentas abrir la URL por primera vez (o haces clic en el botón "Execute
<img src="/img/tutorial/security/image12.png">
## Revisa el nombre de usuario
## Revisa el nombre de usuario { #check-the-username }
Aquí hay un ejemplo más completo.
@@ -46,13 +46,13 @@ Esto sería similar a:
```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# Return some error
# Devuelve algún error
...
```
Pero al usar `secrets.compare_digest()` será seguro contra un tipo de ataques llamados "timing attacks".
### Timing Attacks
### Timing attacks { #timing-attacks }
¿Pero qué es un "timing attack"?
@@ -80,19 +80,19 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
Python tendrá que comparar todo `stanleyjobso` en ambos `stanleyjobsox` y `stanleyjobson` antes de darse cuenta de que ambas strings no son las mismas. Así que tomará algunos microsegundos extra para responder "Nombre de usuario o contraseña incorrectos".
#### El tiempo de respuesta ayuda a los atacantes
#### El tiempo de respuesta ayuda a los atacantes { #the-time-to-answer-helps-the-attackers }
En ese punto, al notar que el servidor tardó algunos microsegundos más en enviar el response "Nombre de usuario o contraseña incorrectos", los atacantes sabrán que acertaron en _algo_, algunas de las letras iniciales eran correctas.
Y luego pueden intentar de nuevo sabiendo que probablemente es algo más similar a `stanleyjobsox` que a `johndoe`.
#### Un ataque "profesional"
#### Un ataque "profesional" { #a-professional-attack }
Por supuesto, los atacantes no intentarían todo esto a mano, escribirían un programa para hacerlo, posiblemente con miles o millones de pruebas por segundo. Y obtendrían solo una letra correcta adicional a la vez.
Pero haciendo eso, en algunos minutos u horas, los atacantes habrían adivinado el nombre de usuario y la contraseña correctos, con la "ayuda" de nuestra aplicación, solo usando el tiempo tomado para responder.
#### Arréglalo con `secrets.compare_digest()`
#### Arréglalo con `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest }
Pero en nuestro código estamos usando realmente `secrets.compare_digest()`.
@@ -100,7 +100,7 @@ En resumen, tomará el mismo tiempo comparar `stanleyjobsox` con `stanleyjobson`
De esa manera, usando `secrets.compare_digest()` en el código de tu aplicación, será seguro contra todo este rango de ataques de seguridad.
### Devuelve el error
### Devuelve el error { #return-the-error }
Después de detectar que las credenciales son incorrectas, regresa un `HTTPException` con un código de estado 401 (el mismo que se devuelve cuando no se proporcionan credenciales) y agrega el header `WWW-Authenticate` para que el navegador muestre el prompt de inicio de sesión nuevamente:

View File

@@ -1,6 +1,6 @@
# Seguridad Avanzada
# Seguridad Avanzada { #advanced-security }
## Funcionalidades Adicionales
## Funcionalidades Adicionales { #additional-features }
Hay algunas funcionalidades extra para manejar la seguridad aparte de las cubiertas en el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank}.
@@ -12,8 +12,8 @@ Y es posible que para tu caso de uso, la solución esté en una de ellas.
///
## Lee primero el Tutorial
## Lee primero el Tutorial { #read-the-tutorial-first }
Las siguientes secciones asumen que ya leíste el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank}.
Las siguientes secciones asumen que ya leíste el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank} principal.
Todas están basadas en los mismos conceptos, pero permiten algunas funcionalidades adicionales.

View File

@@ -1,4 +1,4 @@
# Configuraciones y Variables de Entorno
# Configuraciones y Variables de Entorno { #settings-and-environment-variables }
En muchos casos, tu aplicación podría necesitar algunas configuraciones o ajustes externos, por ejemplo, claves secretas, credenciales de base de datos, credenciales para servicios de correo electrónico, etc.
@@ -12,17 +12,17 @@ Para entender las variables de entorno, puedes leer [Variables de Entorno](../en
///
## Tipos y validación
## Tipos y validación { #types-and-validation }
Estas variables de entorno solo pueden manejar strings de texto, ya que son externas a Python y tienen que ser compatibles con otros programas y el resto del sistema (e incluso con diferentes sistemas operativos, como Linux, Windows, macOS).
Eso significa que cualquier valor leído en Python desde una variable de entorno será un `str`, y cualquier conversión a un tipo diferente o cualquier validación tiene que hacerse en código.
## Pydantic `Settings`
## Pydantic `Settings` { #pydantic-settings }
Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic: Settings management</a>.
### Instalar `pydantic-settings`
### Instalar `pydantic-settings` { #install-pydantic-settings }
Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo y luego instala el paquete `pydantic-settings`:
@@ -52,7 +52,7 @@ En Pydantic v1 venía incluido con el paquete principal. Ahora se distribuye com
///
### Crear el objeto `Settings`
### Crear el objeto `Settings` { #create-the-settings-object }
Importa `BaseSettings` de Pydantic y crea una sub-clase, muy similar a un modelo de Pydantic.
@@ -88,13 +88,13 @@ Luego, cuando creas una instance de esa clase `Settings` (en este caso, en el ob
Luego convertirá y validará los datos. Así que, cuando uses ese objeto `settings`, tendrás datos de los tipos que declaraste (por ejemplo, `items_per_user` será un `int`).
### Usar el `settings`
### Usar el `settings` { #use-the-settings }
Luego puedes usar el nuevo objeto `settings` en tu aplicación:
{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
### Ejecutar el servidor
### Ejecutar el servidor { #run-the-server }
Luego, ejecutarías el servidor pasando las configuraciones como variables de entorno, por ejemplo, podrías establecer un `ADMIN_EMAIL` y `APP_NAME` con:
@@ -120,7 +120,7 @@ El `app_name` sería `"ChimichangApp"`.
Y el `items_per_user` mantendría su valor por defecto de `50`.
## Configuraciones en otro módulo
## Configuraciones en otro módulo { #settings-in-another-module }
Podrías poner esas configuraciones en otro archivo de módulo como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
@@ -138,21 +138,21 @@ También necesitarías un archivo `__init__.py` como viste en [Aplicaciones Más
///
## Configuraciones en una dependencia
## Configuraciones en una dependencia { #settings-in-a-dependency }
En algunas ocasiones podría ser útil proporcionar las configuraciones desde una dependencia, en lugar de tener un objeto global con `settings` que se use en todas partes.
Esto podría ser especialmente útil durante las pruebas, ya que es muy fácil sobrescribir una dependencia con tus propias configuraciones personalizadas.
### El archivo de configuración
### El archivo de configuración { #the-config-file }
Proveniente del ejemplo anterior, tu archivo `config.py` podría verse como:
{* ../../docs_src/settings/app02/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
Nota que ahora no creamos una instance por defecto `settings = Settings()`.
### El archivo principal de la app
### El archivo principal de la app { #the-main-app-file }
Ahora creamos una dependencia que devuelve un nuevo `config.Settings()`.
@@ -170,17 +170,17 @@ Y luego podemos requerirlo desde la *path operation function* como una dependenc
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
### Configuraciones y pruebas
### Configuraciones y pruebas { #settings-and-testing }
Luego sería muy fácil proporcionar un objeto de configuraciones diferente durante las pruebas al sobrescribir una dependencia para `get_settings`:
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
En la dependencia sobreescrita establecemos un nuevo valor para el `admin_email` al crear el nuevo objeto `Settings`, y luego devolvemos ese nuevo objeto.
Luego podemos probar que se está usando.
## Leer un archivo `.env`
## Leer un archivo `.env` { #reading-a-env-file }
Si tienes muchas configuraciones que posiblemente cambien mucho, tal vez en diferentes entornos, podría ser útil ponerlos en un archivo y luego leerlos desde allí como si fueran variables de entorno.
@@ -202,7 +202,7 @@ Para que esto funcione, necesitas `pip install python-dotenv`.
///
### El archivo `.env`
### El archivo `.env` { #the-env-file }
Podrías tener un archivo `.env` con:
@@ -211,13 +211,13 @@ ADMIN_EMAIL="deadpool@example.com"
APP_NAME="ChimichangApp"
```
### Leer configuraciones desde `.env`
### Leer configuraciones desde `.env` { #read-settings-from-env }
Y luego actualizar tu `config.py` con:
//// tab | Pydantic v2
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip | Consejo
@@ -229,7 +229,7 @@ El atributo `model_config` se usa solo para configuración de Pydantic. Puedes l
//// tab | Pydantic v1
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
/// tip | Consejo
@@ -247,7 +247,7 @@ En la versión 1 de Pydantic la configuración se hacía en una clase interna `C
Aquí definimos la configuración `env_file` dentro de tu clase Pydantic `Settings`, y establecemos el valor en el nombre del archivo con el archivo dotenv que queremos usar.
### Creando el `Settings` solo una vez con `lru_cache`
### Creando el `Settings` solo una vez con `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
Leer un archivo desde el disco es normalmente una operación costosa (lenta), por lo que probablemente quieras hacerlo solo una vez y luego reutilizar el mismo objeto de configuraciones, en lugar de leerlo para cada request.
@@ -274,7 +274,7 @@ Pero como estamos usando el decorador `@lru_cache` encima, el objeto `Settings`
Entonces, para cualquier llamada subsiguiente de `get_settings()` en las dependencias de los próximos requests, en lugar de ejecutar el código interno de `get_settings()` y crear un nuevo objeto `Settings`, devolverá el mismo objeto que fue devuelto en la primera llamada, una y otra vez.
#### Detalles Técnicos de `lru_cache`
#### Detalles Técnicos de `lru_cache` { #lru-cache-technical-details }
`@lru_cache` modifica la función que decora para devolver el mismo valor que se devolvió la primera vez, en lugar de calcularlo nuevamente, ejecutando el código de la función cada vez.
@@ -335,9 +335,9 @@ En el caso de nuestra dependencia `get_settings()`, la función ni siquiera toma
De esa manera, se comporta casi como si fuera solo una variable global. Pero como usa una función de dependencia, entonces podemos sobrescribirla fácilmente para las pruebas.
`@lru_cache` es parte de `functools`, que es parte del library estándar de Python, puedes leer más sobre él en las <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">docs de Python para `@lru_cache`</a>.
`@lru_cache` es parte de `functools`, que es parte del paquete estándar de Python, puedes leer más sobre él en las <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">docs de Python para `@lru_cache`</a>.
## Resumen
## Resumen { #recap }
Puedes usar Pydantic Settings para manejar las configuraciones o ajustes de tu aplicación, con todo el poder de los modelos de Pydantic.

View File

@@ -1,18 +1,18 @@
# Sub Aplicaciones - Mounts
# Sub Aplicaciones - Mounts { #sub-applications-mounts }
Si necesitas tener dos aplicaciones de **FastAPI** independientes, cada una con su propio OpenAPI independiente y su propia interfaz de docs, puedes tener una aplicación principal y "montar" una (o más) sub-aplicación(es).
## Montar una aplicación **FastAPI**
## Montar una aplicación **FastAPI** { #mounting-a-fastapi-application }
"Montar" significa añadir una aplicación completamente "independiente" en un path específico, que luego se encarga de manejar todo bajo ese path, con las _path operations_ declaradas en esa sub-aplicación.
### Aplicación de nivel superior
### Aplicación de nivel superior { #top-level-application }
Primero, crea la aplicación principal de nivel superior de **FastAPI**, y sus *path operations*:
{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
### Sub-aplicación
### Sub-aplicación { #sub-application }
Luego, crea tu sub-aplicación, y sus *path operations*.
@@ -20,7 +20,7 @@ Esta sub-aplicación es solo otra aplicación estándar de FastAPI, pero es la q
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
### Montar la sub-aplicación
### Montar la sub-aplicación { #mount-the-sub-application }
En tu aplicación de nivel superior, `app`, monta la sub-aplicación, `subapi`.
@@ -28,7 +28,7 @@ En este caso, se montará en el path `/subapi`:
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
### Revisa la documentación automática de la API
### Revisa la documentación automática de la API { #check-the-automatic-api-docs }
Ahora, ejecuta el comando `fastapi` con tu archivo:
@@ -56,7 +56,7 @@ Verás la documentación automática de la API para la sub-aplicación, incluyen
Si intentas interactuar con cualquiera de las dos interfaces de usuario, funcionarán correctamente, porque el navegador podrá comunicarse con cada aplicación o sub-aplicación específica.
### Detalles Técnicos: `root_path`
### Detalles Técnicos: `root_path` { #technical-details-root-path }
Cuando montas una sub-aplicación como se describe arriba, FastAPI se encargará de comunicar el path de montaje para la sub-aplicación usando un mecanismo de la especificación ASGI llamado `root_path`.

View File

@@ -1,6 +1,6 @@
# Probando Dependencias con Overrides
# Probando Dependencias con Overrides { #testing-dependencies-with-overrides }
## Sobrescribir dependencias durante las pruebas
## Sobrescribir dependencias durante las pruebas { #overriding-dependencies-during-testing }
Hay algunos escenarios donde podrías querer sobrescribir una dependencia durante las pruebas.
@@ -8,7 +8,7 @@ No quieres que la dependencia original se ejecute (ni ninguna de las sub-depende
En cambio, quieres proporcionar una dependencia diferente que se usará solo durante las pruebas (posiblemente solo algunas pruebas específicas), y que proporcionará un valor que pueda ser usado donde se usó el valor de la dependencia original.
### Casos de uso: servicio externo
### Casos de uso: servicio externo { #use-cases-external-service }
Un ejemplo podría ser que tienes un proveedor de autenticación externo al que necesitas llamar.
@@ -20,7 +20,7 @@ Probablemente quieras probar el proveedor externo una vez, pero no necesariament
En este caso, puedes sobrescribir la dependencia que llama a ese proveedor y usar una dependencia personalizada que devuelva un usuario de prueba, solo para tus tests.
### Usa el atributo `app.dependency_overrides`
### Usa el atributo `app.dependency_overrides` { #use-the-app-dependency-overrides-attribute }
Para estos casos, tu aplicación **FastAPI** tiene un atributo `app.dependency_overrides`, es un simple `dict`.

View File

@@ -1,5 +1,12 @@
# Testing Events: startup - shutdown
# Eventos de testing: lifespan y startup - shutdown { #testing-events-lifespan-and-startup-shutdown }
Cuando necesitas que tus manejadores de eventos (`startup` y `shutdown`) se ejecuten en tus tests, puedes usar el `TestClient` con un statement `with`:
Cuando necesitas que `lifespan` se ejecute en tus tests, puedes usar el `TestClient` con un statement `with`:
{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
Puedes leer más detalles sobre ["Ejecutar lifespan en tests en el sitio oficial de documentación de Starlette."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
Para los eventos obsoletos `startup` y `shutdown`, puedes usar el `TestClient` así:
{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}

View File

@@ -1,10 +1,10 @@
# Incluyendo WSGI - Flask, Django, otros
# Incluyendo WSGI - Flask, Django, otros { #including-wsgi-flask-django-others }
Puedes montar aplicaciones WSGI como viste con [Sub Aplicaciones - Mounts](sub-applications.md){.internal-link target=_blank}, [Detrás de un Proxy](behind-a-proxy.md){.internal-link target=_blank}.
Para eso, puedes usar `WSGIMiddleware` y usarlo para envolver tu aplicación WSGI, por ejemplo, Flask, Django, etc.
## Usando `WSGIMiddleware`
## Usando `WSGIMiddleware` { #using-wsgimiddleware }
Necesitas importar `WSGIMiddleware`.
@@ -14,7 +14,7 @@ Y luego móntala bajo un path.
{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
## Revisa
## Revisa { #check-it }
Ahora, cada request bajo el path `/v1/` será manejado por la aplicación Flask.

View File

@@ -1,10 +1,10 @@
# Benchmarks
# Benchmarks { #benchmarks }
Los benchmarks independientes de TechEmpower muestran aplicaciones de **FastAPI** ejecutándose bajo Uvicorn como <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">uno de los frameworks de Python más rápidos disponibles</a>, solo por debajo de Starlette y Uvicorn en sí mismos (utilizados internamente por FastAPI).
Pero al revisar benchmarks y comparaciones, debes tener en cuenta lo siguiente.
## Benchmarks y velocidad
## Benchmarks y velocidad { #benchmarks-and-speed }
Cuando ves los benchmarks, es común ver varias herramientas de diferentes tipos comparadas como equivalentes.

View File

@@ -1,15 +1,24 @@
# Despliega FastAPI en Proveedores de Nube
# Despliega FastAPI en Proveedores de Nube { #deploy-fastapi-on-cloud-providers }
Puedes usar prácticamente **cualquier proveedor de nube** para desplegar tu aplicación FastAPI.
En la mayoría de los casos, los principales proveedores de nube tienen guías para desplegar FastAPI con ellos.
## Proveedores de Nube - Sponsors
## FastAPI Cloud { #fastapi-cloud }
Algunos proveedores de nube ✨ [**son sponsors de FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, esto asegura el desarrollo **continuado** y **saludable** de FastAPI y su **ecosistema**.
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** está construido por el mismo autor y equipo detrás de **FastAPI**.
Y muestra su verdadero compromiso con FastAPI y su **comunidad** (tú), ya que no solo quieren proporcionarte un **buen servicio**, sino también asegurarse de que tengas un **framework bueno y saludable**, FastAPI. 🙇
Simplifica el proceso de **construir**, **desplegar** y **acceder** a una API con un esfuerzo mínimo.
Podrías querer probar sus servicios y seguir sus guías:
Trae la misma experiencia de desarrollador de construir aplicaciones con FastAPI a desplegarlas en la nube. 🎉
FastAPI Cloud es el sponsor principal y proveedor de financiamiento de los proyectos open source *FastAPI and friends*. ✨
## Proveedores de Nube - Sponsors { #cloud-providers-sponsors }
Otros proveedores de nube ✨ [**son sponsors de FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ también. 🙇
También podrías considerarlos para seguir sus guías y probar sus servicios:
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>

View File

@@ -1,4 +1,4 @@
# Conceptos de Implementación
# Conceptos de Implementación { #deployments-concepts }
Cuando implementas una aplicación **FastAPI**, o en realidad, cualquier tipo de API web, hay varios conceptos que probablemente te importen, y al entenderlos, puedes encontrar la **forma más adecuada** de **implementar tu aplicación**.
@@ -23,7 +23,7 @@ En los próximos capítulos, te daré más **recetas concretas** para implementa
Pero por ahora, revisemos estas importantes **ideas conceptuales**. Estos conceptos también se aplican a cualquier otro tipo de API web. 💡
## Seguridad - HTTPS
## Seguridad - HTTPS { #security-https }
En el [capítulo anterior sobre HTTPS](https.md){.internal-link target=_blank} aprendimos sobre cómo HTTPS proporciona cifrado para tu API.
@@ -31,7 +31,7 @@ También vimos que HTTPS es normalmente proporcionado por un componente **extern
Y debe haber algo encargado de **renovar los certificados HTTPS**, podría ser el mismo componente o algo diferente.
### Herramientas de Ejemplo para HTTPS
### Herramientas de Ejemplo para HTTPS { #example-tools-for-https }
Algunas de las herramientas que podrías usar como Proxy de Terminación TLS son:
@@ -55,11 +55,11 @@ Te mostraré algunos ejemplos concretos en los próximos capítulos.
Luego, los siguientes conceptos a considerar son todos acerca del programa que ejecuta tu API real (por ejemplo, Uvicorn).
## Programa y Proceso
## Programa y Proceso { #program-and-process }
Hablaremos mucho sobre el "**proceso**" en ejecución, así que es útil tener claridad sobre lo que significa y cuál es la diferencia con la palabra "**programa**".
### Qué es un Programa
### Qué es un Programa { #what-is-a-program }
La palabra **programa** se usa comúnmente para describir muchas cosas:
@@ -67,7 +67,7 @@ La palabra **programa** se usa comúnmente para describir muchas cosas:
* El **archivo** que puede ser **ejecutado** por el sistema operativo, por ejemplo: `python`, `python.exe` o `uvicorn`.
* Un programa específico mientras está siendo **ejecutado** en el sistema operativo, usando la CPU y almacenando cosas en la memoria. Esto también se llama **proceso**.
### Qué es un Proceso
### Qué es un Proceso { #what-is-a-process }
La palabra **proceso** se usa normalmente de una manera más específica, refiriéndose solo a lo que está ejecutándose en el sistema operativo (como en el último punto anterior):
@@ -88,11 +88,11 @@ Y, por ejemplo, probablemente verás que hay múltiples procesos ejecutando el m
Ahora que conocemos la diferencia entre los términos **proceso** y **programa**, sigamos hablando sobre implementaciones.
## Ejecución al Iniciar
## Ejecución al Iniciar { #running-on-startup }
En la mayoría de los casos, cuando creas una API web, quieres que esté **siempre en ejecución**, ininterrumpida, para que tus clientes puedan acceder a ella en cualquier momento. Esto, por supuesto, a menos que tengas una razón específica para que se ejecute solo en ciertas situaciones, pero la mayoría de las veces quieres que esté constantemente en ejecución y **disponible**.
### En un Servidor Remoto
### En un Servidor Remoto { #in-a-remote-server }
Cuando configuras un servidor remoto (un servidor en la nube, una máquina virtual, etc.) lo más sencillo que puedes hacer es usar `fastapi run` (que utiliza Uvicorn) o algo similar, manualmente, de la misma manera que lo haces al desarrollar localmente.
@@ -102,15 +102,15 @@ Pero si pierdes la conexión con el servidor, el **proceso en ejecución** proba
Y si el servidor se reinicia (por ejemplo, después de actualizaciones o migraciones del proveedor de la nube) probablemente **no lo notarás**. Y debido a eso, ni siquiera sabrás que tienes que reiniciar el proceso manualmente. Así, tu API simplemente quedará muerta. 😱
### Ejecutar Automáticamente al Iniciar
### Ejecutar Automáticamente al Iniciar { #run-automatically-on-startup }
En general, probablemente querrás que el programa del servidor (por ejemplo, Uvicorn) se inicie automáticamente al arrancar el servidor, y sin necesidad de ninguna **intervención humana**, para tener siempre un proceso en ejecución con tu API (por ejemplo, Uvicorn ejecutando tu aplicación FastAPI).
### Programa Separado
### Programa Separado { #separate-program }
Para lograr esto, normalmente tendrás un **programa separado** que se asegurará de que tu aplicación se ejecute al iniciarse. Y en muchos casos, también se asegurará de que otros componentes o aplicaciones se ejecuten, por ejemplo, una base de datos.
### Herramientas de Ejemplo para Ejecutar al Iniciar
### Herramientas de Ejemplo para Ejecutar al Iniciar { #example-tools-to-run-at-startup }
Algunos ejemplos de las herramientas que pueden hacer este trabajo son:
@@ -125,29 +125,29 @@ Algunos ejemplos de las herramientas que pueden hacer este trabajo son:
Te daré más ejemplos concretos en los próximos capítulos.
## Reinicios
## Reinicios { #restarts }
De manera similar a asegurarte de que tu aplicación se ejecute al iniciar, probablemente también quieras asegurarte de que se **reinicie** después de fallos.
### Cometemos Errores
### Cometemos Errores { #we-make-mistakes }
Nosotros, como humanos, cometemos **errores**, todo el tiempo. El software casi *siempre* tiene **bugs** ocultos en diferentes lugares. 🐛
Y nosotros, como desarrolladores, seguimos mejorando el código a medida que encontramos esos bugs y a medida que implementamos nuevas funcionalidades (posiblemente agregando nuevos bugs también 😅).
### Errores Pequeños Manejados Automáticamente
### Errores Pequeños Manejados Automáticamente { #small-errors-automatically-handled }
Al construir APIs web con FastAPI, si hay un error en nuestro código, FastAPI normalmente lo contiene a la solicitud única que desencadenó el error. 🛡
Al construir APIs web con FastAPI, si hay un error en nuestro código, FastAPI normalmente lo contiene al request único que desencadenó el error. 🛡
El cliente obtendrá un **500 Internal Server Error** para esa solicitud, pero la aplicación continuará funcionando para las siguientes solicitudes en lugar de simplemente colapsar por completo.
El cliente obtendrá un **500 Internal Server Error** para ese request, pero la aplicación continuará funcionando para los siguientes requests en lugar de simplemente colapsar por completo.
### Errores Mayores - Colapsos
### Errores Mayores - Colapsos { #bigger-errors-crashes }
Sin embargo, puede haber casos en los que escribamos algún código que **colapse toda la aplicación** haciendo que Uvicorn y Python colapsen. 💥
Y aún así, probablemente no querrías que la aplicación quede muerta porque hubo un error en un lugar, probablemente querrás que **siga ejecutándose** al menos para las *path operations* que no estén rotas.
### Reiniciar Después del Colapso
### Reiniciar Después del Colapso { #restart-after-crash }
Pero en esos casos con errores realmente malos que colapsan el **proceso en ejecución**, querrías un componente externo encargado de **reiniciar** el proceso, al menos un par de veces...
@@ -161,7 +161,7 @@ Así que enfoquémonos en los casos principales, donde podría colapsar por comp
Probablemente querrías que la cosa encargada de reiniciar tu aplicación sea un **componente externo**, porque para ese punto, la misma aplicación con Uvicorn y Python ya colapsó, así que no hay nada en el mismo código de la misma aplicación que pueda hacer algo al respecto.
### Herramientas de Ejemplo para Reiniciar Automáticamente
### Herramientas de Ejemplo para Reiniciar Automáticamente { #example-tools-to-restart-automatically }
En la mayoría de los casos, la misma herramienta que se utiliza para **ejecutar el programa al iniciar** también se utiliza para manejar reinicios automáticos.
@@ -176,19 +176,19 @@ Por ejemplo, esto podría ser manejado por:
* Manejado internamente por un proveedor de nube como parte de sus servicios
* Otros...
## Replicación - Procesos y Memoria
## Replicación - Procesos y Memoria { #replication-processes-and-memory }
Con una aplicación FastAPI, usando un programa servidor como el comando `fastapi` que ejecuta Uvicorn, ejecutarlo una vez en **un proceso** puede servir a múltiples clientes concurrentemente.
Pero en muchos casos, querrás ejecutar varios worker processes al mismo tiempo.
### Múltiples Procesos - Workers
### Múltiples Procesos - Workers { #multiple-processes-workers }
Si tienes más clientes de los que un solo proceso puede manejar (por ejemplo, si la máquina virtual no es muy grande) y tienes **múltiples núcleos** en la CPU del servidor, entonces podrías tener **múltiples procesos** ejecutando la misma aplicación al mismo tiempo, y distribuir todas las requests entre ellos.
Cuando ejecutas **múltiples procesos** del mismo programa de API, comúnmente se les llama **workers**.
### Worker Processes y Puertos
### Worker Processes y Puertos { #worker-processes-and-ports }
Recuerda de la documentación [Sobre HTTPS](https.md){.internal-link target=_blank} que solo un proceso puede estar escuchando en una combinación de puerto y dirección IP en un servidor.
@@ -196,19 +196,19 @@ Esto sigue siendo cierto.
Así que, para poder tener **múltiples procesos** al mismo tiempo, tiene que haber un **solo proceso escuchando en un puerto** que luego transmita la comunicación a cada worker process de alguna forma.
### Memoria por Proceso
### Memoria por Proceso { #memory-per-process }
Ahora, cuando el programa carga cosas en memoria, por ejemplo, un modelo de machine learning en una variable, o el contenido de un archivo grande en una variable, todo eso **consume un poco de la memoria (RAM)** del servidor.
Ahora, cuando el programa carga cosas en memoria, por ejemplo, un modelo de Machine Learning en una variable, o el contenido de un archivo grande en una variable, todo eso **consume un poco de la memoria (RAM)** del servidor.
Y múltiples procesos normalmente **no comparten ninguna memoria**. Esto significa que cada proceso en ejecución tiene sus propias cosas, variables y memoria. Y si estás consumiendo una gran cantidad de memoria en tu código, **cada proceso** consumirá una cantidad equivalente de memoria.
### Memoria del Servidor
### Memoria del Servidor { #server-memory }
Por ejemplo, si tu código carga un modelo de Machine Learning con **1 GB de tamaño**, cuando ejecutas un proceso con tu API, consumirá al menos 1 GB de RAM. Y si inicias **4 procesos** (4 workers), cada uno consumirá 1 GB de RAM. Así que, en total, tu API consumirá **4 GB de RAM**.
Y si tu servidor remoto o máquina virtual solo tiene 3 GB de RAM, intentar cargar más de 4 GB de RAM causará problemas. 🚨
### Múltiples Procesos - Un Ejemplo
### Múltiples Procesos - Un Ejemplo { #multiple-processes-an-example }
En este ejemplo, hay un **Proceso Administrador** que inicia y controla dos **Worker Processes**.
@@ -224,7 +224,7 @@ Un detalle interesante es que el porcentaje de **CPU utilizado** por cada proces
Si tienes una API que hace una cantidad comparable de cálculos cada vez y tienes muchos clientes, entonces la **utilización de CPU** probablemente *también sea estable* (en lugar de constantemente subir y bajar rápidamente).
### Ejemplos de Herramientas y Estrategias de Replicación
### Ejemplos de Herramientas y Estrategias de Replicación { #examples-of-replication-tools-and-strategies }
Puede haber varios enfoques para lograr esto, y te contaré más sobre estrategias específicas en los próximos capítulos, por ejemplo, al hablar sobre Docker y contenedores.
@@ -247,7 +247,7 @@ Te contaré más sobre imágenes de contenedores, Docker, Kubernetes, etc. en un
///
## Pasos Previos Antes de Iniciar
## Pasos Previos Antes de Iniciar { #previous-steps-before-starting }
Hay muchos casos en los que quieres realizar algunos pasos **antes de iniciar** tu aplicación.
@@ -269,7 +269,7 @@ En ese caso, no tendrías que preocuparte por nada de esto. 🤷
///
### Ejemplos de Estrategias para Pasos Previos
### Ejemplos de Estrategias para Pasos Previos { #examples-of-previous-steps-strategies }
Esto **dependerá mucho** de la forma en que **implementarás tu sistema**, y probablemente estará conectado con la forma en que inicias programas, manejas reinicios, etc.
@@ -285,7 +285,7 @@ Te daré más ejemplos concretos para hacer esto con contenedores en un capítul
///
## Utilización de Recursos
## Utilización de Recursos { #resource-utilization }
Tu(s) servidor(es) es(son) un **recurso** que puedes consumir o **utilizar**, con tus programas, el tiempo de cómputo en las CPUs y la memoria RAM disponible.
@@ -305,7 +305,7 @@ Podrías establecer un **número arbitrario** para alcanzar, por ejemplo, algo *
Puedes usar herramientas simples como `htop` para ver la CPU y RAM utilizadas en tu servidor o la cantidad utilizada por cada proceso. O puedes usar herramientas de monitoreo más complejas, que pueden estar distribuidas a través de servidores, etc.
## Resumen
## Resumen { #recap }
Has estado leyendo aquí algunos de los conceptos principales que probablemente necesitarás tener en mente al decidir cómo implementar tu aplicación:

View File

@@ -1,4 +1,4 @@
# FastAPI en Contenedores - Docker
# FastAPI en Contenedores - Docker { #fastapi-in-containers-docker }
Al desplegar aplicaciones de FastAPI, un enfoque común es construir una **imagen de contenedor de Linux**. Normalmente se realiza usando <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Luego puedes desplegar esa imagen de contenedor de varias formas.
@@ -6,7 +6,7 @@ Usar contenedores de Linux tiene varias ventajas, incluyendo **seguridad**, **re
/// tip | Consejo
¿Tienes prisa y ya conoces esto? Salta al [`Dockerfile` más abajo 👇](#construir-una-imagen-de-docker-para-fastapi).
¿Tienes prisa y ya conoces esto? Salta al [`Dockerfile` más abajo 👇](#build-a-docker-image-for-fastapi).
///
@@ -32,7 +32,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
</details>
## Qué es un Contenedor
## Qué es un Contenedor { #what-is-a-container }
Los contenedores (principalmente contenedores de Linux) son una forma muy **ligera** de empaquetar aplicaciones incluyendo todas sus dependencias y archivos necesarios, manteniéndolos aislados de otros contenedores (otras aplicaciones o componentes) en el mismo sistema.
@@ -42,11 +42,11 @@ De esta forma, los contenedores consumen **pocos recursos**, una cantidad compar
Los contenedores también tienen sus propios procesos de ejecución **aislados** (normalmente solo un proceso), sistema de archivos y red, simplificando el despliegue, la seguridad, el desarrollo, etc.
## Qué es una Imagen de Contenedor
## Qué es una Imagen de Contenedor { #what-is-a-container-image }
Un **contenedor** se ejecuta desde una **imagen de contenedor**.
Una imagen de contenedor es una versión **estática** de todos los archivos, variables de entorno y el comando/programa por defecto que debería estar presente en un contenedor. **Estático** aquí significa que la imagen de contenedor **no se está ejecutando**, no está siendo ejecutada, son solo los archivos empaquetados y los metadatos.
Una imagen de contenedor es una versión **estática** de todos los archivos, variables de entorno y el comando/programa por defecto que debería estar presente en un contenedor. **Estático** aquí significa que la **imagen** de contenedor no se está ejecutando, no está siendo ejecutada, son solo los archivos empaquetados y los metadatos.
En contraste con una "**imagen de contenedor**" que son los contenidos estáticos almacenados, un "**contenedor**" normalmente se refiere a la instance en ejecución, lo que está siendo **ejecutado**.
@@ -56,7 +56,7 @@ Una imagen de contenedor es comparable al archivo de **programa** y sus contenid
Y el **contenedor** en sí (en contraste con la **imagen de contenedor**) es la instance real en ejecución de la imagen, comparable a un **proceso**. De hecho, un contenedor solo se está ejecutando cuando tiene un **proceso en ejecución** (y normalmente es solo un proceso). El contenedor se detiene cuando no hay un proceso en ejecución en él.
## Imágenes de Contenedor
## Imágenes de Contenedor { #container-images }
Docker ha sido una de las herramientas principales para crear y gestionar **imágenes de contenedor** y **contenedores**.
@@ -77,9 +77,9 @@ De esta manera, en muchos casos puedes aprender sobre contenedores y Docker y re
Así, ejecutarías **múltiples contenedores** con diferentes cosas, como una base de datos, una aplicación de Python, un servidor web con una aplicación frontend en React, y conectarlos entre sí a través de su red interna.
Todos los sistemas de gestión de contenedores (como Docker o Kubernetes) tienen estas características de redes integradas en ellos.
Todos los sistemas de gestión de contenedores (como Docker o Kubernetes) tienen estas funcionalidades de redes integradas.
## Contenedores y Procesos
## Contenedores y Procesos { #containers-and-processes }
Una **imagen de contenedor** normalmente incluye en sus metadatos el programa o comando por defecto que debería ser ejecutado cuando el **contenedor** se inicie y los parámetros que deben pasar a ese programa. Muy similar a lo que sería si estuviera en la línea de comandos.
@@ -91,7 +91,7 @@ Un contenedor normalmente tiene un **proceso único**, pero también es posible
Pero no es posible tener un contenedor en ejecución sin **al menos un proceso en ejecución**. Si el proceso principal se detiene, el contenedor se detiene.
## Construir una Imagen de Docker para FastAPI
## Construir una Imagen de Docker para FastAPI { #build-a-docker-image-for-fastapi }
¡Bien, construyamos algo ahora! 🚀
@@ -103,7 +103,7 @@ Esto es lo que querrías hacer en **la mayoría de los casos**, por ejemplo:
* Al ejecutar en un **Raspberry Pi**
* Usando un servicio en la nube que ejecutaría una imagen de contenedor por ti, etc.
### Requisitos del Paquete
### Requisitos del Paquete { #package-requirements }
Normalmente tendrías los **requisitos del paquete** para tu aplicación en algún archivo.
@@ -138,7 +138,7 @@ Existen otros formatos y herramientas para definir e instalar dependencias de pa
///
### Crear el Código de **FastAPI**
### Crear el Código de **FastAPI** { #create-the-fastapi-code }
* Crea un directorio `app` y entra en él.
* Crea un archivo vacío `__init__.py`.
@@ -162,7 +162,7 @@ def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
```
### Dockerfile
### Dockerfile { #dockerfile }
Ahora, en el mismo directorio del proyecto, crea un archivo `Dockerfile` con:
@@ -238,7 +238,7 @@ Asegúrate de **siempre** usar la **forma exec** de la instrucción `CMD`, como
///
#### Usar `CMD` - Forma Exec
#### Usar `CMD` - Forma Exec { #use-cmd-exec-form }
La instrucción Docker <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> se puede escribir usando dos formas:
@@ -262,20 +262,20 @@ Puedes leer más sobre esto en las <a href="https://docs.docker.com/reference/do
Esto puede ser bastante notorio al usar `docker compose`. Consulta esta sección de preguntas frecuentes de Docker Compose para más detalles técnicos: <a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">¿Por qué mis servicios tardan 10 segundos en recrearse o detenerse?</a>.
#### Estructura de Directorios
#### Estructura de Directorios { #directory-structure }
Ahora deberías tener una estructura de directorios como:
```
.
├── app
├── __init__.py
   ├── __init__.py
│ └── main.py
├── Dockerfile
└── requirements.txt
```
#### Detrás de un Proxy de Terminación TLS
#### Detrás de un Proxy de Terminación TLS { #behind-a-tls-termination-proxy }
Si estás ejecutando tu contenedor detrás de un Proxy de Terminación TLS (load balancer) como Nginx o Traefik, añade la opción `--proxy-headers`, esto le dirá a Uvicorn (a través de la CLI de FastAPI) que confíe en los headers enviados por ese proxy indicando que la aplicación se está ejecutando detrás de HTTPS, etc.
@@ -283,7 +283,7 @@ Si estás ejecutando tu contenedor detrás de un Proxy de Terminación TLS (load
CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
```
#### Cache de Docker
#### Caché de Docker { #docker-cache }
Hay un truco importante en este `Dockerfile`, primero copiamos **el archivo con las dependencias solo**, no el resto del código. Déjame decirte por qué es así.
@@ -315,7 +315,7 @@ Luego, cerca del final del `Dockerfile`, copiamos todo el código. Como esto es
COPY ./app /code/app
```
### Construir la Imagen de Docker
### Construir la Imagen de Docker { #build-the-docker-image }
Ahora que todos los archivos están en su lugar, vamos a construir la imagen del contenedor.
@@ -340,7 +340,7 @@ En este caso, es el mismo directorio actual (`.`).
///
### Iniciar el Contenedor Docker
### Iniciar el Contenedor Docker { #start-the-docker-container }
* Ejecuta un contenedor basado en tu imagen:
@@ -352,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
</div>
## Revísalo
## Revísalo { #check-it }
Deberías poder revisarlo en la URL de tu contenedor de Docker, por ejemplo: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> o <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (o equivalente, usando tu host de Docker).
@@ -362,7 +362,7 @@ Verás algo como:
{"item_id": 5, "q": "somequery"}
```
## Documentación Interactiva de la API
## Documentación Interactiva de la API { #interactive-api-docs }
Ahora puedes ir a <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> o <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (o equivalente, usando tu host de Docker).
@@ -370,7 +370,7 @@ Verás la documentación interactiva automática de la API (proporcionada por <a
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
## Documentación Alternativa de la API
## Documentación Alternativa de la API { #alternative-api-docs }
Y también puedes ir a <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> o <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (o equivalente, usando tu host de Docker).
@@ -378,7 +378,7 @@ Verás la documentación alternativa automática (proporcionada por <a href="htt
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Construir una Imagen de Docker con un FastAPI de Un Solo Archivo
## Construir una Imagen de Docker con un FastAPI de Un Solo Archivo { #build-a-docker-image-with-a-single-file-fastapi }
Si tu FastAPI es un solo archivo, por ejemplo, `main.py` sin un directorio `./app`, tu estructura de archivos podría verse así:
@@ -413,7 +413,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
Cuando pasas el archivo a `fastapi run`, detectará automáticamente que es un archivo único y no parte de un paquete y sabrá cómo importarlo y servir tu aplicación FastAPI. 😎
## Conceptos de Despliegue
## Conceptos de Despliegue { #deployment-concepts }
Hablemos nuevamente de algunos de los mismos [Conceptos de Despliegue](concepts.md){.internal-link target=_blank} en términos de contenedores.
@@ -430,7 +430,7 @@ Revisemos estos **conceptos de despliegue** en términos de contenedores:
* Memoria
* Pasos previos antes de comenzar
## HTTPS
## HTTPS { #https }
Si nos enfocamos solo en la **imagen de contenedor** para una aplicación FastAPI (y luego el **contenedor** en ejecución), HTTPS normalmente sería manejado **externamente** por otra herramienta.
@@ -444,7 +444,7 @@ Traefik tiene integraciones con Docker, Kubernetes, y otros, por lo que es muy f
Alternativamente, HTTPS podría ser manejado por un proveedor de la nube como uno de sus servicios (mientras que la aplicación aún se ejecuta en un contenedor).
## Ejecutar en el Inicio y Reinicios
## Ejecutar en el Inicio y Reinicios { #running-on-startup-and-restarts }
Normalmente hay otra herramienta encargada de **iniciar y ejecutar** tu contenedor.
@@ -454,7 +454,7 @@ En la mayoría (o todas) de las casos, hay una opción sencilla para habilitar l
Sin usar contenedores, hacer que las aplicaciones se ejecuten al inicio y con reinicios puede ser engorroso y difícil. Pero al **trabajar con contenedores** en la mayoría de los casos, esa funcionalidad se incluye por defecto. ✨
## Replicación - Número de Procesos
## Replicación - Número de Procesos { #replication-number-of-processes }
Si tienes un <abbr title="Un grupo de máquinas que están configuradas para estar conectadas y trabajar juntas de alguna manera.">cluster</abbr> de máquinas con **Kubernetes**, Docker Swarm Mode, Nomad, u otro sistema complejo similar para gestionar contenedores distribuidos en varias máquinas, entonces probablemente querrás manejar la **replicación** a nivel de **cluster** en lugar de usar un **gestor de procesos** (como Uvicorn con workers) en cada contenedor.
@@ -462,7 +462,7 @@ Uno de esos sistemas de gestión de contenedores distribuidos como Kubernetes no
En esos casos, probablemente desearías construir una **imagen de Docker desde cero** como se [explica arriba](#dockerfile), instalando tus dependencias, y ejecutando **un solo proceso de Uvicorn** en lugar de usar múltiples workers de Uvicorn.
### Load Balancer
### Load Balancer { #load-balancer }
Al usar contenedores, normalmente tendrías algún componente **escuchando en el puerto principal**. Podría posiblemente ser otro contenedor que es también un **Proxy de Terminación TLS** para manejar **HTTPS** o alguna herramienta similar.
@@ -476,17 +476,17 @@ El mismo componente **Proxy de Terminación TLS** usado para HTTPS probablemente
Y al trabajar con contenedores, el mismo sistema que usas para iniciarlos y gestionarlos ya tendría herramientas internas para transmitir la **comunicación en red** (e.g., requests HTTP) desde ese **load balancer** (que también podría ser un **Proxy de Terminación TLS**) a los contenedores con tu aplicación.
### Un Load Balancer - Múltiples Contenedores Worker
### Un Load Balancer - Múltiples Contenedores Worker { #one-load-balancer-multiple-worker-containers }
Al trabajar con **Kubernetes** u otros sistemas de gestión de contenedores distribuidos similares, usar sus mecanismos de red internos permitiría que el único **load balancer** que está escuchando en el **puerto** principal transmita la comunicación (requests) a posiblemente **múltiples contenedores** ejecutando tu aplicación.
Cada uno de estos contenedores ejecutando tu aplicación normalmente tendría **solo un proceso** (e.g., un proceso Uvicorn ejecutando tu aplicación FastAPI). Todos serían **contenedores idénticos**, ejecutando lo mismo, pero cada uno con su propio proceso, memoria, etc. De esa forma, aprovecharías la **paralelización** en **diferentes núcleos** de la CPU, o incluso en **diferentes máquinas**.
Y el sistema de contenedores distribuido con el **load balancer** **distribuiría las requests** a cada uno de los contenedores **replicados** que ejecutan tu aplicación **en turnos**. Así, cada request podría ser manejado por uno de los múltiples **contenedores replicados** ejecutando tu aplicación.
Y el sistema de contenedores distribuido con el **load balancer** **distribuiría las requests** a cada uno de los contenedores con tu aplicación **en turnos**. Así, cada request podría ser manejada por uno de los múltiples **contenedores replicados** ejecutando tu aplicación.
Y normalmente este **load balancer** podría manejar requests que vayan a *otras* aplicaciones en tu cluster (p. ej., a un dominio diferente, o bajo un prefijo de ruta de URL diferente), y transmitiría esa comunicación a los contenedores correctos para *esa otra* aplicación ejecutándose en tu cluster.
Y normalmente este **load balancer** podría manejar requests que vayan a *otras* aplicaciones en tu cluster (p. ej., a un dominio diferente, o bajo un prefijo de path de URL diferente), y transmitiría esa comunicación a los contenedores correctos para *esa otra* aplicación ejecutándose en tu cluster.
### Un Proceso por Contenedor
### Un Proceso por Contenedor { #one-process-per-container }
En este tipo de escenario, probablemente querrías tener **un solo proceso (Uvicorn) por contenedor**, ya que ya estarías manejando la replicación a nivel de cluster.
@@ -494,7 +494,7 @@ Así que, en este caso, **no** querrías tener múltiples workers en el contened
Tener otro gestor de procesos dentro del contenedor (como sería con múltiples workers) solo añadiría **complejidad innecesaria** que probablemente ya estés manejando con tu sistema de cluster.
### Contenedores con Múltiples Procesos y Casos Especiales
### Contenedores con Múltiples Procesos y Casos Especiales { #containers-with-multiple-processes-and-special-cases }
Por supuesto, hay **casos especiales** donde podrías querer tener **un contenedor** con varios **worker processes de Uvicorn** dentro.
@@ -519,11 +519,11 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
Aquí hay algunos ejemplos de cuándo eso podría tener sentido:
#### Una Aplicación Simple
#### Una Aplicación Simple { #a-simple-app }
Podrías querer un gestor de procesos en el contenedor si tu aplicación es **lo suficientemente simple** que pueda ejecutarse en un **servidor único**, no un cluster.
#### Docker Compose
#### Docker Compose { #docker-compose }
Podrías estar desplegando en un **servidor único** (no un cluster) con **Docker Compose**, por lo que no tendrías una forma fácil de gestionar la replicación de contenedores (con Docker Compose) mientras se preserva la red compartida y el **load balancing**.
@@ -540,7 +540,7 @@ El punto principal es que, **ninguna** de estas son **reglas escritas en piedra*
* Memoria
* Pasos previos antes de comenzar
## Memoria
## Memoria { #memory }
Si ejecutas **un solo proceso por contenedor**, tendrás una cantidad de memoria más o menos bien definida, estable y limitada consumida por cada uno de esos contenedores (más de uno si están replicados).
@@ -550,11 +550,11 @@ Si tu aplicación es **simple**, probablemente esto **no será un problema**, y
Si ejecutas **múltiples procesos por contenedor**, tendrás que asegurarte de que el número de procesos iniciados no **consuma más memoria** de la que está disponible.
## Pasos Previos Antes de Comenzar y Contenedores
## Pasos Previos Antes de Comenzar y Contenedores { #previous-steps-before-starting-and-containers }
Si estás usando contenedores (por ejemplo, Docker, Kubernetes), entonces hay dos enfoques principales que puedes usar.
### Múltiples Contenedores
### Múltiples Contenedores { #multiple-containers }
Si tienes **múltiples contenedores**, probablemente cada uno ejecutando un **proceso único** (por ejemplo, en un cluster de **Kubernetes**), entonces probablemente querrías tener un **contenedor separado** realizando el trabajo de los **pasos previos** en un solo contenedor, ejecutando un solo proceso, **antes** de ejecutar los contenedores worker replicados.
@@ -566,13 +566,13 @@ Si estás usando Kubernetes, probablemente sería un <a href="https://kubernetes
Si en tu caso de uso no hay problema en ejecutar esos pasos previos **múltiples veces en paralelo** (por ejemplo, si no estás ejecutando migraciones de base de datos, sino simplemente verificando si la base de datos está lista), entonces también podrías simplemente ponerlos en cada contenedor justo antes de iniciar el proceso principal.
### Un Contenedor Único
### Un Contenedor Único { #single-container }
Si tienes una configuración simple, con un **contenedor único** que luego inicia múltiples **worker processes** (o también solo un proceso), entonces podrías ejecutar esos pasos previos en el mismo contenedor, justo antes de iniciar el proceso con la aplicación.
### Imagen Base de Docker
### Imagen Base de Docker { #base-docker-image }
Solía haber una imagen official de Docker de FastAPI: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Pero ahora está obsoleta. ⛔️
Solía haber una imagen official de Docker de FastAPI: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi-docker</a>. Pero ahora está obsoleta. ⛔️
Probablemente **no** deberías usar esta imagen base de Docker (o cualquier otra similar).
@@ -588,7 +588,7 @@ Pero ahora que Uvicorn (y el comando `fastapi`) soportan el uso de `--workers`,
///
## Desplegar la Imagen del Contenedor
## Desplegar la Imagen del Contenedor { #deploy-the-container-image }
Después de tener una Imagen de Contenedor (Docker) hay varias maneras de desplegarla.
@@ -600,11 +600,11 @@ Por ejemplo:
* Con otra herramienta como Nomad
* Con un servicio en la nube que tome tu imagen de contenedor y la despliegue
## Imagen de Docker con `uv`
## Imagen de Docker con `uv` { #docker-image-with-uv }
Si estás usando <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> para instalar y gestionar tu proyecto, puedes seguir su <a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">guía de Docker de uv</a>.
## Resumen
## Resumen { #recap }
Usando sistemas de contenedores (por ejemplo, con **Docker** y **Kubernetes**) se vuelve bastante sencillo manejar todos los **conceptos de despliegue**:

View File

@@ -0,0 +1,65 @@
# FastAPI Cloud { #fastapi-cloud }
Puedes desplegar tu app de FastAPI en <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> con un solo comando; ve y únete a la lista de espera si aún no lo has hecho. 🚀
## Iniciar sesión { #login }
Asegúrate de que ya tienes una cuenta de **FastAPI Cloud** (te invitamos desde la lista de espera 😉).
Luego inicia sesión:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
## Desplegar { #deploy }
Ahora despliega tu app, con un solo comando:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
¡Eso es todo! Ahora puedes acceder a tu app en esa URL. ✨
## Acerca de FastAPI Cloud { #about-fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** está creado por el mismo autor y equipo detrás de **FastAPI**.
Agiliza el proceso de **crear**, **desplegar** y **acceder** a una API con el mínimo esfuerzo.
Aporta la misma **experiencia de desarrollador** de crear apps con FastAPI al **desplegarlas** en la nube. 🎉
También se encargará de la mayoría de las cosas que necesitas al desplegar una app, como:
* HTTPS
* Replicación, con autoescalado basado en requests
* etc.
FastAPI Cloud es el sponsor principal y proveedor de financiación de los proyectos open source de *FastAPI and friends*. ✨
## Desplegar en otros proveedores de la nube { #deploy-to-other-cloud-providers }
FastAPI es open source y está basado en estándares. Puedes desplegar apps de FastAPI en cualquier proveedor de la nube que elijas.
Sigue las guías de tu proveedor de la nube para desplegar apps de FastAPI con ellos. 🤓
## Despliega tu propio servidor { #deploy-your-own-server }
También te enseñaré más adelante en esta guía de **Despliegue** todos los detalles, para que puedas entender qué está pasando, qué tiene que ocurrir o cómo desplegar apps de FastAPI por tu cuenta, también con tus propios servidores. 🤓

View File

@@ -1,4 +1,4 @@
# Sobre HTTPS
# Sobre HTTPS { #about-https }
Es fácil asumir que HTTPS es algo que simplemente está "activado" o no.
@@ -28,7 +28,7 @@ Ahora, desde una **perspectiva de desarrollador**, aquí hay varias cosas a tene
* **Por defecto**, eso significaría que solo puedes tener **un certificado HTTPS por dirección IP**.
* No importa cuán grande sea tu servidor o qué tan pequeña pueda ser cada aplicación que tengas en él.
* Sin embargo, hay una **solución** para esto.
* Hay una **extensión** para el protocolo **TLS** (el que maneja la encriptación a nivel de TCP, antes de HTTP) llamada **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>**.
* Hay una **extensión** para el protocolo **TLS** (el que maneja la encriptación a nivel de TCP, antes de HTTP) llamada **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication Indicación del nombre del servidor">SNI</abbr></a>**.
* Esta extensión SNI permite que un solo servidor (con una **sola dirección IP**) tenga **varios certificados HTTPS** y sirva **múltiples dominios/aplicaciones HTTPS**.
* Para que esto funcione, un componente (programa) **único** que se ejecute en el servidor, escuchando en la **dirección IP pública**, debe tener **todos los certificados HTTPS** en el servidor.
* **Después** de obtener una conexión segura, el protocolo de comunicación sigue siendo **HTTP**.
@@ -43,7 +43,7 @@ Algunas de las opciones que podrías usar como un TLS Termination Proxy son:
* Nginx
* HAProxy
## Let's Encrypt
## Let's Encrypt { #lets-encrypt }
Antes de Let's Encrypt, estos **certificados HTTPS** eran vendidos por terceros.
@@ -51,17 +51,17 @@ El proceso para adquirir uno de estos certificados solía ser complicado, requer
Pero luego se creó **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>**.
Es un proyecto de la Linux Foundation. Proporciona **certificados HTTPS de forma gratuita**, de manera automatizada. Estos certificados usan toda la seguridad criptográfica estándar, y tienen una corta duración (aproximadamente 3 meses), por lo que la **seguridad es en realidad mejor** debido a su corta vida útil.
Es un proyecto de la Linux Foundation. Proporciona **certificados HTTPS de forma gratuita**, de manera automatizada. Estos certificados usan toda la seguridad criptográfica estándar, y tienen una corta duración (aproximadamente 3 meses), por lo que la **seguridad es en realidad mejor** debido a su lifespan reducida.
Los dominios son verificados de manera segura y los certificados se generan automáticamente. Esto también permite automatizar la renovación de estos certificados.
La idea es automatizar la adquisición y renovación de estos certificados para que puedas tener **HTTPS seguro, gratuito, para siempre**.
## HTTPS para Desarrolladores
## HTTPS para Desarrolladores { #https-for-developers }
Aquí tienes un ejemplo de cómo podría ser una API HTTPS, paso a paso, prestando atención principalmente a las ideas importantes para los desarrolladores.
### Nombre de Dominio
### Nombre de Dominio { #domain-name }
Probablemente todo comenzaría adquiriendo un **nombre de dominio**. Luego, lo configurarías en un servidor DNS (posiblemente tu mismo proveedor de la nube).
@@ -77,7 +77,7 @@ Esta parte del Nombre de Dominio es mucho antes de HTTPS, pero como todo depende
///
### DNS
### DNS { #dns }
Ahora centrémonos en todas las partes realmente de HTTPS.
@@ -87,7 +87,7 @@ Los servidores DNS le dirían al navegador que use una **dirección IP** especí
<img src="/img/deployment/https/https01.drawio.svg">
### Inicio del Handshake TLS
### Inicio del Handshake TLS { #tls-handshake-start }
El navegador luego se comunicaría con esa dirección IP en el **puerto 443** (el puerto HTTPS).
@@ -97,7 +97,7 @@ La primera parte de la comunicación es solo para establecer la conexión entre
Esta interacción entre el cliente y el servidor para establecer la conexión TLS se llama **handshake TLS**.
### TLS con Extensión SNI
### TLS con Extensión SNI { #tls-with-sni-extension }
**Solo un proceso** en el servidor puede estar escuchando en un **puerto** específico en una **dirección IP** específica. Podría haber otros procesos escuchando en otros puertos en la misma dirección IP, pero solo uno para cada combinación de dirección IP y puerto.
@@ -127,7 +127,7 @@ Ten en cuenta que la encriptación de la comunicación ocurre a nivel de **TCP**
///
### Request HTTPS
### Request HTTPS { #https-request }
Ahora que el cliente y el servidor (específicamente el navegador y el TLS Termination Proxy) tienen una **conexión TCP encriptada**, pueden iniciar la **comunicación HTTP**.
@@ -135,19 +135,19 @@ Así que, el cliente envía un **request HTTPS**. Esto es simplemente un request
<img src="/img/deployment/https/https04.drawio.svg">
### Desencriptar el Request
### Desencriptar el Request { #decrypt-the-request }
El TLS Termination Proxy usaría la encriptación acordada para **desencriptar el request**, y transmitiría el **request HTTP simple (desencriptado)** al proceso que ejecuta la aplicación (por ejemplo, un proceso con Uvicorn ejecutando la aplicación FastAPI).
<img src="/img/deployment/https/https05.drawio.svg">
### Response HTTP
### Response HTTP { #http-response }
La aplicación procesaría el request y enviaría un **response HTTP simple (sin encriptar)** al TLS Termination Proxy.
<img src="/img/deployment/https/https06.drawio.svg">
### Response HTTPS
### Response HTTPS { #https-response }
El TLS Termination Proxy entonces **encriptaría el response** usando la criptografía acordada antes (que comenzó con el certificado para `someapp.example.com`), y lo enviaría de vuelta al navegador.
@@ -157,7 +157,7 @@ Luego, el navegador verificaría que el response sea válido y encriptado con la
El cliente (navegador) sabrá que el response proviene del servidor correcto porque está utilizando la criptografía que acordaron usando el **certificado HTTPS** anteriormente.
### Múltiples Aplicaciones
### Múltiples Aplicaciones { #multiple-applications }
En el mismo servidor (o servidores), podrían haber **múltiples aplicaciones**, por ejemplo, otros programas API o una base de datos.
@@ -167,7 +167,7 @@ Solo un proceso puede estar gestionando la IP y puerto específica (el TLS Termi
De esa manera, el TLS Termination Proxy podría gestionar HTTPS y certificados para **múltiples dominios**, para múltiples aplicaciones, y luego transmitir los requests a la aplicación correcta en cada caso.
### Renovación de Certificados
### Renovación de Certificados { #certificate-renewal }
En algún momento en el futuro, cada certificado **expiraría** (alrededor de 3 meses después de haberlo adquirido).
@@ -190,7 +190,39 @@ Para hacer eso, y para acomodar diferentes necesidades de aplicaciones, hay vari
Todo este proceso de renovación, mientras aún se sirve la aplicación, es una de las principales razones por las que querrías tener un **sistema separado para gestionar el HTTPS** con un TLS Termination Proxy en lugar de simplemente usar los certificados TLS con el servidor de aplicaciones directamente (por ejemplo, Uvicorn).
## Resumen
## Headers reenviados por el proxy { #proxy-forwarded-headers }
Al usar un proxy para gestionar HTTPS, tu **servidor de aplicaciones** (por ejemplo Uvicorn vía FastAPI CLI) no sabe nada sobre el proceso HTTPS, se comunica con HTTP simple con el **TLS Termination Proxy**.
Este **proxy** normalmente configuraría algunos headers HTTP sobre la marcha antes de transmitir el request al **servidor de aplicaciones**, para hacerle saber al servidor de aplicaciones que el request está siendo **reenviado** por el proxy.
/// note | Detalles técnicos
Los headers del proxy son:
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
///
Aun así, como el **servidor de aplicaciones** no sabe que está detrás de un **proxy** de confianza, por defecto, no confiaría en esos headers.
Pero puedes configurar el **servidor de aplicaciones** para confiar en los headers reenviados enviados por el **proxy**. Si estás usando FastAPI CLI, puedes usar la *Opción de la CLI* `--forwarded-allow-ips` para indicarle desde qué IPs debería confiar en esos headers reenviados.
Por ejemplo, si el **servidor de aplicaciones** solo está recibiendo comunicación del **proxy** de confianza, puedes establecerlo en `--forwarded-allow-ips="*"` para hacer que confíe en todas las IPs entrantes, ya que solo recibirá requests desde la IP que sea utilizada por el **proxy**.
De esta manera la aplicación podrá saber cuál es su propia URL pública, si está usando HTTPS, el dominio, etc.
Esto sería útil, por ejemplo, para manejar correctamente redirecciones.
/// tip | Consejo
Puedes aprender más sobre esto en la documentación de [Detrás de un proxy - Habilitar headers reenviados por el proxy](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
///
## Resumen { #recap }
Tener **HTTPS** es muy importante y bastante **crítico** en la mayoría de los casos. La mayor parte del esfuerzo que como desarrollador tienes que poner en torno a HTTPS es solo sobre **entender estos conceptos** y cómo funcionan.

View File

@@ -1,8 +1,8 @@
# Despliegue
# Despliegue { #deployment }
Desplegar una aplicación **FastAPI** es relativamente fácil.
## Qué Significa Despliegue
## Qué Significa Despliegue { #what-does-deployment-mean }
**Desplegar** una aplicación significa realizar los pasos necesarios para hacerla **disponible para los usuarios**.
@@ -10,12 +10,14 @@ Para una **API web**, normalmente implica ponerla en una **máquina remota**, co
Esto contrasta con las etapas 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
## Estrategias de Despliegue { #deployment-strategies }
Hay varias maneras de hacerlo dependiendo de tu caso de uso específico y las herramientas que utilices.
Podrías **desplegar un servidor** tú mismo utilizando una combinación de herramientas, podrías usar un **servicio en la nube** que hace parte del trabajo por ti, u otras opciones posibles.
Por ejemplo, nosotros, el equipo detrás de FastAPI, construimos <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, para hacer que desplegar aplicaciones de FastAPI en la nube sea lo más ágil posible, con la misma experiencia de desarrollador de trabajar con FastAPI.
Te mostraré algunos de los conceptos principales que probablemente deberías tener en cuenta al desplegar una aplicación **FastAPI** (aunque la mayoría se aplica a cualquier otro tipo de aplicación web).
Verás más detalles a tener en cuenta y algunas de las técnicas para hacerlo en las siguientes secciones. ✨

View File

@@ -1,4 +1,4 @@
# Servidores Workers - Uvicorn con Workers
# Servidores Workers - Uvicorn con Workers { #server-workers-uvicorn-with-workers }
Vamos a revisar esos conceptos de despliegue de antes:
@@ -25,7 +25,7 @@ En particular, cuando corras en **Kubernetes** probablemente **no** querrás usa
///
## Múltiples Workers
## Múltiples Workers { #multiple-workers }
Puedes iniciar múltiples workers con la opción de línea de comando `--workers`:
@@ -36,56 +36,43 @@ Si usas el comando `fastapi`:
<div class="termy">
```console
$ <pre> <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:single">main.py</u>
<font color="#3465A4">INFO </font> Using path <font color="#3465A4">main.py</font>
<font color="#3465A4">INFO </font> Resolved absolute path <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font>
<font color="#3465A4">INFO </font> Searching for package file structure from directories with <font color="#3465A4">__init__.py</font> files
<font color="#3465A4">INFO </font> Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u>
╭─ <font color="#8AE234"><b>Python module file</b></font> ─╮
│ │
│ 🐍 main.py │
│ │
╰──────────────────────╯
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
<font color="#3465A4">INFO </font> Importing module <font color="#4E9A06">main</font>
<font color="#3465A4">INFO </font> Found importable FastAPI app
Searching for package file structure from directories with
<font color="#3465A4">__init__.py</font> files
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
╭─ <font color="#8AE234"><b>Importable FastAPI app</b></font> ─╮
│ │
│ <span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822"> </span> │
│ │
╰──────────────────────────╯
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
<font color="#3465A4">INFO </font> Using import string <font color="#8AE234"><b>main:app</b></font>
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the
following code:
<font color="#4E9A06">╭─────────── FastAPI CLI - Production mode ───────────╮</font>
<font color="#4E9A06">│ │</font>
<font color="#4E9A06">│ Serving at: http://0.0.0.0:8000 │</font>
<font color="#4E9A06">│ │</font>
<font color="#4E9A06">│ API docs: http://0.0.0.0:8000/docs │</font>
<font color="#4E9A06">│ │</font>
<font color="#4E9A06">│ Running in production mode, for development use: │</font>
<font color="#4E9A06">│ │</font>
<font color="#4E9A06">│ </font><font color="#8AE234"><b>fastapi dev</b></font><font color="#4E9A06"> │</font>
<font color="#4E9A06">│ │</font>
<font color="#4E9A06">╰─────────────────────────────────────────────────────╯</font>
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
<font color="#4E9A06">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8000</b> (Press CTRL+C to quit)
<font color="#4E9A06">INFO</font>: Started parent process [<font color="#34E2E2"><b>27365</b></font>]
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">27368</font>]
<font color="#4E9A06">INFO</font>: Waiting for application startup.
<font color="#4E9A06">INFO</font>: Application startup complete.
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">27369</font>]
<font color="#4E9A06">INFO</font>: Waiting for application startup.
<font color="#4E9A06">INFO</font>: Application startup complete.
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">27370</font>]
<font color="#4E9A06">INFO</font>: Waiting for application startup.
<font color="#4E9A06">INFO</font>: Application startup complete.
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">27367</font>]
<font color="#4E9A06">INFO</font>: Waiting for application startup.
<font color="#4E9A06">INFO</font>: Application startup complete.
</pre>
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
Logs:
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to
quit<b>)</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
```
</div>
@@ -124,7 +111,7 @@ La única opción nueva aquí es `--workers` indicando a Uvicorn que inicie 4 wo
También puedes ver que muestra el **PID** de cada proceso, `27365` para el proceso padre (este es el **gestor de procesos**) y uno para cada worker process: `27368`, `27369`, `27370`, y `27367`.
## Conceptos de Despliegue
## Conceptos de Despliegue { #deployment-concepts }
Aquí viste cómo usar múltiples **workers** para **paralelizar** la ejecución de la aplicación, aprovechar los **múltiples núcleos** del CPU, y poder servir **más requests**.
@@ -137,13 +124,13 @@ De la lista de conceptos de despliegue de antes, usar workers ayudaría principa
* **Memoria**
* **Pasos previos antes de empezar**
## Contenedores y Docker
## Contenedores y Docker { #containers-and-docker }
En el próximo capítulo sobre [FastAPI en Contenedores - Docker](docker.md){.internal-link target=_blank} te explicaré algunas estrategias que podrías usar para manejar los otros **conceptos de despliegue**.
Te mostraré cómo **construir tu propia imagen desde cero** para ejecutar un solo proceso de Uvicorn. Es un proceso sencillo y probablemente es lo que querrías hacer al usar un sistema de gestión de contenedores distribuido como **Kubernetes**.
## Resumen
## Resumen { #recap }
Puedes usar múltiples worker processes con la opción CLI `--workers` con los comandos `fastapi` o `uvicorn` para aprovechar los **CPUs de múltiples núcleos**, para ejecutar **múltiples procesos en paralelo**.

View File

@@ -1,4 +1,4 @@
# Sobre las versiones de FastAPI
# Sobre las versiones de FastAPI { #about-fastapi-versions }
**FastAPI** ya se está utilizando en producción en muchas aplicaciones y sistemas. Y la cobertura de tests se mantiene al 100%. Pero su desarrollo sigue avanzando rápidamente.
@@ -8,7 +8,7 @@ Por eso las versiones actuales siguen siendo `0.x.x`, esto refleja que cada vers
Puedes crear aplicaciones de producción con **FastAPI** ahora mismo (y probablemente ya lo has estado haciendo desde hace algún tiempo), solo debes asegurarte de que utilizas una versión que funciona correctamente con el resto de tu código.
## Fijar tu versión de `fastapi`
## Fija tu versión de `fastapi` { #pin-your-fastapi-version }
Lo primero que debes hacer es "fijar" la versión de **FastAPI** que estás usando a la versión específica más reciente que sabes que funciona correctamente para tu aplicación.
@@ -32,11 +32,11 @@ eso significaría que usarías las versiones `0.112.0` o superiores, pero menore
Si utilizas cualquier otra herramienta para gestionar tus instalaciones, como `uv`, Poetry, Pipenv, u otras, todas tienen una forma que puedes usar para definir versiones específicas para tus paquetes.
## Versiones disponibles
## Versiones disponibles { #available-versions }
Puedes ver las versiones disponibles (por ejemplo, para revisar cuál es la más reciente) en las [Release Notes](../release-notes.md){.internal-link target=_blank}.
## Sobre las versiones
## Sobre las versiones { #about-versions }
Siguiendo las convenciones del Semantic Versioning, cualquier versión por debajo de `1.0.0` podría potencialmente añadir cambios incompatibles.
@@ -62,7 +62,7 @@ El "MINOR" es el número en el medio, por ejemplo, en `0.2.3`, la versión MINOR
///
## Actualizando las versiones de FastAPI
## Actualizando las versiones de FastAPI { #upgrading-the-fastapi-versions }
Deberías añadir tests para tu aplicación.
@@ -72,7 +72,7 @@ Después de tener tests, puedes actualizar la versión de **FastAPI** a una más
Si todo está funcionando, o después de hacer los cambios necesarios, y todos tus tests pasan, entonces puedes fijar tu `fastapi` a esa nueva versión más reciente.
## Sobre Starlette
## Sobre Starlette { #about-starlette }
No deberías fijar la versión de `starlette`.
@@ -80,7 +80,7 @@ Diferentes versiones de **FastAPI** utilizarán una versión más reciente espec
Así que, puedes simplemente dejar que **FastAPI** use la versión correcta de Starlette.
## Sobre Pydantic
## Sobre Pydantic { #about-pydantic }
Pydantic incluye los tests para **FastAPI** con sus propios tests, así que nuevas versiones de Pydantic (por encima de `1.0.0`) siempre son compatibles con FastAPI.

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