+
-Then it's your turn, you place your order of 2 very fancy burgers 🍔 for your crush 😍 and you.
+Then it's your turn, you place your order of 2 very fancy burgers for your crush and you. 🍔🍔
-You pay 💸.
+
-The cashier 💁 says something to the cook in the kitchen 👨🍳 so they know they have to prepare your burgers 🍔 (even though they are currently preparing the ones for the previous clients).
+The cashier says something to the cook in the kitchen so they know they have to prepare your burgers (even though they are currently preparing the ones for the previous clients).
-The cashier 💁 gives you the number of your turn.
+
-While you are waiting, you go with your crush 😍 and pick a table, you sit and talk with your crush 😍 for a long time (as your burgers are very fancy and take some time to prepare ✨🍔✨).
+You pay. 💸
-As you are sitting at the table with your crush 😍, while you wait for the burgers 🍔, you can spend that time admiring how awesome, cute and smart your crush is ✨😍✨.
+The cashier gives you the number of your turn.
-While waiting and talking to your crush 😍, from time to time, you check the number displayed on the counter to see if it's your turn already.
+
-Then at some point, it finally is your turn. You go to the counter, get your burgers 🍔 and come back to the table.
+While you are waiting, you go with your crush and pick a table, you sit and talk with your crush for a long time (as your burgers are very fancy and take some time to prepare).
-You and your crush 😍 eat the burgers 🍔 and have a nice time ✨.
+As you are sitting at the table with your crush, while you wait for the burgers, you can spend that time admiring how awesome, cute and smart your crush is ✨😍✨.
+
+
+
+While waiting and talking to your crush, from time to time, you check the number displayed on the counter to see if it's your turn already.
+
+Then at some point, it finally is your turn. You go to the counter, get your burgers and come back to the table.
+
+
+
+You and your crush eat the burgers and have a nice time. ✨
+
+
+
+!!! info
+ Beautiful illustrations by Ketrina Thompson. 🎨
---
Imagine you are the computer / program 🤖 in that story.
-While you are at the line, you are just idle 😴, waiting for your turn, not doing anything very "productive". But the line is fast because the cashier 💁 is only taking the orders (not preparing them), so that's fine.
+While you are at the line, you are just idle 😴, waiting for your turn, not doing anything very "productive". But the line is fast because the cashier is only taking the orders (not preparing them), so that's fine.
-Then, when it's your turn, you do actual "productive" work 🤓, you process the menu, decide what you want, get your crush's 😍 choice, pay 💸, check that you give the correct bill or card, check that you are charged correctly, check that the order has the correct items, etc.
+Then, when it's your turn, you do actual "productive" work, you process the menu, decide what you want, get your crush's choice, pay, check that you give the correct bill or card, check that you are charged correctly, check that the order has the correct items, etc.
-But then, even though you still don't have your burgers 🍔, your work with the cashier 💁 is "on pause" ⏸, because you have to wait 🕙 for your burgers to be ready.
+But then, even though you still don't have your burgers, your work with the cashier is "on pause" ⏸, because you have to wait 🕙 for your burgers to be ready.
-But as you go away from the counter and sit at the table with a number for your turn, you can switch 🔀 your attention to your crush 😍, and "work" ⏯ 🤓 on that. Then you are again doing something very "productive" 🤓, as is flirting with your crush 😍.
+But as you go away from the counter and sit at the table with a number for your turn, you can switch 🔀 your attention to your crush, and "work" ⏯ 🤓 on that. Then you are again doing something very "productive" as is flirting with your crush 😍.
-Then the cashier 💁 says "I'm finished with doing the burgers" 🍔 by putting your number on the counter's display, but you don't jump like crazy immediately when the displayed number changes to your turn number. You know no one will steal your burgers 🍔 because you have the number of your turn, and they have theirs.
+Then the cashier 💁 says "I'm finished with doing the burgers" by putting your number on the counter's display, but you don't jump like crazy immediately when the displayed number changes to your turn number. You know no one will steal your burgers because you have the number of your turn, and they have theirs.
-So you wait for your crush 😍 to finish the story (finish the current work ⏯ / task being processed 🤓), smile gently and say that you are going for the burgers ⏸.
+So you wait for your crush to finish the story (finish the current work ⏯ / task being processed 🤓), smile gently and say that you are going for the burgers ⏸.
-Then you go to the counter 🔀, to the initial task that is now finished ⏯, pick the burgers 🍔, say thanks and take them to the table. That finishes that step / task of interaction with the counter ⏹. That in turn, creates a new task, of "eating burgers" 🔀 ⏯, but the previous one of "getting burgers" is finished ⏹.
+Then you go to the counter 🔀, to the initial task that is now finished ⏯, pick the burgers, say thanks and take them to the table. That finishes that step / task of interaction with the counter ⏹. That in turn, creates a new task, of "eating burgers" 🔀 ⏯, but the previous one of "getting burgers" is finished ⏹.
### Parallel Burgers
Now let's imagine these aren't "Concurrent Burgers", but "Parallel Burgers".
-You go with your crush 😍 to get parallel fast food 🍔.
+You go with your crush to get parallel fast food.
-You stand in line while several (let's say 8) cashiers that at the same time are cooks 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 take the orders from the people in front of you.
+You stand in line while several (let's say 8) cashiers that at the same time are cooks take the orders from the people in front of you.
-Everyone before you is waiting 🕙 for their burgers 🍔 to be ready before leaving the counter because each of the 8 cashiers goes and prepares the burger right away before getting the next order.
+Everyone before you is waiting for their burgers to be ready before leaving the counter because each of the 8 cashiers goes and prepares the burger right away before getting the next order.
-Then it's finally your turn, you place your order of 2 very fancy burgers 🍔 for your crush 😍 and you.
+
+
+Then it's finally your turn, you place your order of 2 very fancy burgers for your crush and you.
You pay 💸.
-The cashier goes to the kitchen 👨🍳.
+
-You wait, standing in front of the counter 🕙, so that no one else takes your burgers 🍔 before you do, as there are no numbers for turns.
+The cashier goes to the kitchen.
-As you and your crush 😍 are busy not letting anyone get in front of you and take your burgers whenever they arrive 🕙, you cannot pay attention to your crush 😞.
+You wait, standing in front of the counter 🕙, so that no one else takes your burgers before you do, as there are no numbers for turns.
-This is "synchronous" work, you are "synchronized" with the cashier/cook 👨🍳. You have to wait 🕙 and be there at the exact moment that the cashier/cook 👨🍳 finishes the burgers 🍔 and gives them to you, or otherwise, someone else might take them.
+
-Then your cashier/cook 👨🍳 finally comes back with your burgers 🍔, after a long time waiting 🕙 there in front of the counter.
+As you and your crush are busy not letting anyone get in front of you and take your burgers whenever they arrive, you cannot pay attention to your crush. 😞
-You take your burgers 🍔 and go to the table with your crush 😍.
+This is "synchronous" work, you are "synchronized" with the cashier/cook 👨🍳. You have to wait 🕙 and be there at the exact moment that the cashier/cook 👨🍳 finishes the burgers and gives them to you, or otherwise, someone else might take them.
-You just eat them, and you are done 🍔 ⏹.
+
-There was not much talk or flirting as most of the time was spent waiting 🕙 in front of the counter 😞.
+Then your cashier/cook 👨🍳 finally comes back with your burgers, after a long time waiting 🕙 there in front of the counter.
+
+
+
+You take your burgers and go to the table with your crush.
+
+You just eat them, and you are done. ⏹
+
+
+
+There was not much talk or flirting as most of the time was spent waiting 🕙 in front of the counter. 😞
+
+!!! info
+ Beautiful illustrations by Ketrina Thompson. 🎨
---
-In this scenario of the parallel burgers, you are a computer / program 🤖 with two processors (you and your crush 😍), both waiting 🕙 and dedicating their attention ⏯ to be "waiting on the counter" 🕙 for a long time.
+In this scenario of the parallel burgers, you are a computer / program 🤖 with two processors (you and your crush), both waiting 🕙 and dedicating their attention ⏯ to be "waiting on the counter" 🕙 for a long time.
-The fast food store has 8 processors (cashiers/cooks) 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳. While the concurrent burgers store might have had only 2 (one cashier and one cook) 💁 👨🍳.
+The fast food store has 8 processors (cashiers/cooks). While the concurrent burgers store might have had only 2 (one cashier and one cook).
-But still, the final experience is not the best 😞.
+But still, the final experience is not the best. 😞
---
-This would be the parallel equivalent story for burgers 🍔.
+This would be the parallel equivalent story for burgers. 🍔
For a more "real life" example of this, imagine a bank.
@@ -208,11 +238,7 @@ This "waiting" 🕙 is measured in microseconds, but still, summing it all, it's
That's why it makes a lot of sense to use asynchronous ⏸🔀⏯ code for web APIs.
-Most of the existing popular Python frameworks (including Flask and Django) were created before the new asynchronous features in Python existed. So, the ways they can be deployed support parallel execution and an older form of asynchronous execution that is not as powerful as the new capabilities.
-
-Even though the main specification for asynchronous web Python (ASGI) was developed at Django, to add support for WebSockets.
-
-That kind of asynchronicity is what made NodeJS popular (even though NodeJS is not parallel) and that's the strength of Go as a programming language.
+This kind of asynchronicity is what made NodeJS popular (even though NodeJS is not parallel) and that's the strength of Go as a programming language.
And that's the same level of performance you get with **FastAPI**.
@@ -238,7 +264,7 @@ You could have turns as in the burgers example, first the living room, then the
It would take the same amount of time to finish with or without turns (concurrency) and you would have done the same amount of work.
-But in this case, if you could bring the 8 ex-cashier/cooks/now-cleaners 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳, and each one of them (plus you) could take a zone of the house to clean it, you could do all the work in **parallel**, with the extra help, and finish much sooner.
+But in this case, if you could bring the 8 ex-cashier/cooks/now-cleaners, and each one of them (plus you) could take a zone of the house to clean it, you could do all the work in **parallel**, with the extra help, and finish much sooner.
In this scenario, each one of the cleaners (including you) would be a processor, doing their part of the job.
diff --git a/docs/en/docs/css/custom.css b/docs/en/docs/css/custom.css
index 42b752bcf..066b51725 100644
--- a/docs/en/docs/css/custom.css
+++ b/docs/en/docs/css/custom.css
@@ -4,10 +4,21 @@
display: block;
}
+.termy {
+ /* For right to left languages */
+ direction: ltr;
+}
+
.termy [data-termynal] {
white-space: pre-wrap;
}
+a.external-link {
+ /* For right to left languages */
+ direction: ltr;
+ display: inline-block;
+}
+
a.external-link::after {
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
@@ -118,3 +129,18 @@ a.announce-link:hover {
.twitter {
color: #00acee;
}
+
+/* Right to left languages */
+code {
+ direction: ltr;
+ display: inline-block;
+}
+
+.md-content__inner h1 {
+ direction: ltr !important;
+}
+
+.illustration {
+ margin-top: 2em;
+ margin-bottom: 2em;
+}
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-01.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-01.png
new file mode 100644
index 000000000..e0e77d3fc
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-01.png differ
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-02.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-02.png
new file mode 100644
index 000000000..27f6e1271
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-02.png differ
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-03.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-03.png
new file mode 100644
index 000000000..27472a8e0
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-03.png differ
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-04.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-04.png
new file mode 100644
index 000000000..cf1d8dd45
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-04.png differ
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-05.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-05.png
new file mode 100644
index 000000000..ab6e03669
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-05.png differ
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-06.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-06.png
new file mode 100644
index 000000000..4bbf247c0
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-06.png differ
diff --git a/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-07.png b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-07.png
new file mode 100644
index 000000000..7a0f4092d
Binary files /dev/null and b/docs/en/docs/img/async/concurrent-burgers/concurrent-burgers-07.png differ
diff --git a/docs/en/docs/img/async/parallel-burgers/parallel-burgers-01.png b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-01.png
new file mode 100644
index 000000000..92fc1a8a0
Binary files /dev/null and b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-01.png differ
diff --git a/docs/en/docs/img/async/parallel-burgers/parallel-burgers-02.png b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-02.png
new file mode 100644
index 000000000..9583b84dc
Binary files /dev/null and b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-02.png differ
diff --git a/docs/en/docs/img/async/parallel-burgers/parallel-burgers-03.png b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-03.png
new file mode 100644
index 000000000..bea9ff0d8
Binary files /dev/null and b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-03.png differ
diff --git a/docs/en/docs/img/async/parallel-burgers/parallel-burgers-04.png b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-04.png
new file mode 100644
index 000000000..b5c8a60bb
Binary files /dev/null and b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-04.png differ
diff --git a/docs/en/docs/img/async/parallel-burgers/parallel-burgers-05.png b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-05.png
new file mode 100644
index 000000000..45aca8e21
Binary files /dev/null and b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-05.png differ
diff --git a/docs/en/docs/img/async/parallel-burgers/parallel-burgers-06.png b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-06.png
new file mode 100644
index 000000000..c91c4b472
Binary files /dev/null and b/docs/en/docs/img/async/parallel-burgers/parallel-burgers-06.png differ
diff --git a/docs/en/docs/img/sponsors/docarray-top-banner.svg b/docs/en/docs/img/sponsors/docarray-top-banner.svg
new file mode 100644
index 000000000..b2eca3544
--- /dev/null
+++ b/docs/en/docs/img/sponsors/docarray-top-banner.svg
@@ -0,0 +1 @@
+
diff --git a/docs/en/docs/img/sponsors/docarray.svg b/docs/en/docs/img/sponsors/docarray.svg
new file mode 100644
index 000000000..f18df247e
--- /dev/null
+++ b/docs/en/docs/img/sponsors/docarray.svg
@@ -0,0 +1 @@
+
diff --git a/docs/en/docs/img/sponsors/jina-top-banner.svg b/docs/en/docs/img/sponsors/jina-top-banner.svg
new file mode 100644
index 000000000..8b62cd619
--- /dev/null
+++ b/docs/en/docs/img/sponsors/jina-top-banner.svg
@@ -0,0 +1 @@
+
diff --git a/docs/en/docs/img/sponsors/jina2.svg b/docs/en/docs/img/sponsors/jina2.svg
new file mode 100644
index 000000000..6a48677ba
--- /dev/null
+++ b/docs/en/docs/img/sponsors/jina2.svg
@@ -0,0 +1 @@
+
diff --git a/docs/en/docs/img/sponsors/striveworks2.png b/docs/en/docs/img/sponsors/striveworks2.png
new file mode 100644
index 000000000..bed9cb0a7
Binary files /dev/null and b/docs/en/docs/img/sponsors/striveworks2.png differ
diff --git a/docs/en/docs/python-types.md b/docs/en/docs/python-types.md
index 963fcaf1c..3b0ee4cf6 100644
--- a/docs/en/docs/python-types.md
+++ b/docs/en/docs/python-types.md
@@ -267,7 +267,7 @@ You can declare that a variable can be any of **several types**, for example, an
In Python 3.6 and above (including Python 3.10) you can use the `Union` type from `typing` and put inside the square brackets the possible types to accept.
-In Python 3.10 there's also an **alternative syntax** were you can put the possible types separated by a vertical bar (`|`).
+In Python 3.10 there's also an **alternative syntax** where you can put the possible types separated by a vertical bar (`|`).
=== "Python 3.6 and above"
@@ -326,7 +326,7 @@ If you are using a Python version below 3.10, here's a tip from my very **subjec
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
-I think `Union[str, SomeType]` is more explicit about what it means.
+I think `Union[SomeType, None]` is more explicit about what it means.
It's just about the words and names. But those words can affect how you and your teammates think about the code.
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 55df22c06..806127162 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -2,6 +2,128 @@
## Latest Changes
+* 📝 Update docs for handling HTTP Basic Auth with `secrets.compare_digest()` to account for non-ASCII characters. PR [#3536](https://github.com/tiangolo/fastapi/pull/3536) by [@lewoudar](https://github.com/lewoudar).
+* 📝 Update docs for testing, fix examples with relative imports. PR [#5302](https://github.com/tiangolo/fastapi/pull/5302) by [@tiangolo](https://github.com/tiangolo).
+* 🍱 Update Jina banner, fix typo. PR [#5301](https://github.com/tiangolo/fastapi/pull/5301) by [@tiangolo](https://github.com/tiangolo).
+
+## 0.80.0
+
+### Breaking Changes - Fixes
+
+* 🐛 Fix `response_model` not invalidating `None`. PR [#2725](https://github.com/tiangolo/fastapi/pull/2725) by [@hukkin](https://github.com/hukkin).
+
+If you are using `response_model` with some type that doesn't include `None` but the function is returning `None`, it will now raise an internal server error, because you are returning invalid data that violates the contract in `response_model`. Before this release it would allow breaking that contract returning `None`.
+
+For example, if you have an app like this:
+
+```Python
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+ name: str
+ price: Optional[float] = None
+ owner_ids: Optional[List[int]] = None
+
+app = FastAPI()
+
+@app.get("/items/invalidnone", response_model=Item)
+def get_invalid_none():
+ return None
+```
+
+...calling the path `/items/invalidnone` will raise an error, because `None` is not a valid type for the `response_model` declared with `Item`.
+
+You could also be implicitly returning `None` without realizing, for example:
+
+```Python
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+ name: str
+ price: Optional[float] = None
+ owner_ids: Optional[List[int]] = None
+
+app = FastAPI()
+
+@app.get("/items/invalidnone", response_model=Item)
+def get_invalid_none():
+ if flag:
+ return {"name": "foo"}
+ # if flag is False, at this point the function will implicitly return None
+```
+
+If you have *path operations* using `response_model` that need to be allowed to return `None`, make it explicit in `response_model` using `Union[Something, None]`:
+
+```Python
+from typing import Union
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+ name: str
+ price: Optional[float] = None
+ owner_ids: Optional[List[int]] = None
+
+app = FastAPI()
+
+@app.get("/items/invalidnone", response_model=Union[Item, None])
+def get_invalid_none():
+ return None
+```
+
+This way the data will be correctly validated, you won't have an internal server error, and the documentation will also reflect that this *path operation* could return `None` (or `null` in JSON).
+
+### Fixes
+
+* ⬆ Upgrade Swagger UI copy of `oauth2-redirect.html` to include fixes for flavors of authorization code flows in Swagger UI. PR [#3439](https://github.com/tiangolo/fastapi/pull/3439) initial PR by [@koonpeng](https://github.com/koonpeng).
+* ♻ Strip empty whitespace from description extracted from docstrings. PR [#2821](https://github.com/tiangolo/fastapi/pull/2821) by [@and-semakin](https://github.com/and-semakin).
+* 🐛 Fix cached dependencies when using a dependency in `Security()` and other places (e.g. `Depends()`) with different OAuth2 scopes. PR [#2945](https://github.com/tiangolo/fastapi/pull/2945) by [@laggardkernel](https://github.com/laggardkernel).
+* 🎨 Update type annotations for `response_model`, allow things like `Union[str, None]`. PR [#5294](https://github.com/tiangolo/fastapi/pull/5294) by [@tiangolo](https://github.com/tiangolo).
+
+### Translations
+
+* 🌐 Fix typos in German translation for `docs/de/docs/features.md`. PR [#4533](https://github.com/tiangolo/fastapi/pull/4533) by [@0xflotus](https://github.com/0xflotus).
+* 🌐 Add missing navigator for `encoder.md` in Korean translation. PR [#5238](https://github.com/tiangolo/fastapi/pull/5238) by [@joonas-yoon](https://github.com/joonas-yoon).
+* (Empty PR merge by accident) [#4913](https://github.com/tiangolo/fastapi/pull/4913).
+
+## 0.79.1
+
+### Fixes
+
+* 🐛 Fix `jsonable_encoder` using `include` and `exclude` parameters for non-Pydantic objects. PR [#2606](https://github.com/tiangolo/fastapi/pull/2606) by [@xaviml](https://github.com/xaviml).
+* 🐛 Fix edge case with repeated aliases names not shown in OpenAPI. PR [#2351](https://github.com/tiangolo/fastapi/pull/2351) by [@klaa97](https://github.com/klaa97).
+* 📝 Add misc dependency installs to tutorial docs. PR [#2126](https://github.com/tiangolo/fastapi/pull/2126) by [@TeoZosa](https://github.com/TeoZosa).
+
+### Docs
+
+* 📝 Add note giving credit for illustrations to [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot/). PR [#5284](https://github.com/tiangolo/fastapi/pull/5284) by [@tiangolo](https://github.com/tiangolo).
+* ✏ Fix typo in `python-types.md`. PR [#5116](https://github.com/tiangolo/fastapi/pull/5116) by [@Kludex](https://github.com/Kludex).
+* ✏ Fix typo in `docs/en/docs/python-types.md`. PR [#5007](https://github.com/tiangolo/fastapi/pull/5007) by [@atiabbz](https://github.com/atiabbz).
+* 📝 Remove unneeded Django/Flask references from async topic intro. PR [#5280](https://github.com/tiangolo/fastapi/pull/5280) by [@carltongibson](https://github.com/carltongibson).
+* ✨ Add illustrations for Concurrent burgers and Parallel burgers. PR [#5277](https://github.com/tiangolo/fastapi/pull/5277) by [@tiangolo](https://github.com/tiangolo). Updated docs at: [Concurrency and Burgers](https://fastapi.tiangolo.com/async/#concurrency-and-burgers).
+
+### Translations
+
+* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/query-params.md`. PR [#4775](https://github.com/tiangolo/fastapi/pull/4775) by [@batlopes](https://github.com/batlopes).
+* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/security/first-steps.md`. PR [#4954](https://github.com/tiangolo/fastapi/pull/4954) by [@FLAIR7](https://github.com/FLAIR7).
+* 🌐 Add translation for `docs/zh/docs/advanced/response-cookies.md`. PR [#4638](https://github.com/tiangolo/fastapi/pull/4638) by [@zhangbo2012](https://github.com/zhangbo2012).
+* 🌐 Add French translation for `docs/fr/docs/deployment/index.md`. PR [#3689](https://github.com/tiangolo/fastapi/pull/3689) by [@rjNemo](https://github.com/rjNemo).
+* 🌐 Add Portuguese translation for `tutorial/handling-errors.md`. PR [#4769](https://github.com/tiangolo/fastapi/pull/4769) by [@frnsimoes](https://github.com/frnsimoes).
+* 🌐 Add French translation for `docs/fr/docs/history-design-future.md`. PR [#3451](https://github.com/tiangolo/fastapi/pull/3451) by [@rjNemo](https://github.com/rjNemo).
+* 🌐 Add Russian translation for `docs/ru/docs/tutorial/background-tasks.md`. PR [#4854](https://github.com/tiangolo/fastapi/pull/4854) by [@AdmiralDesu](https://github.com/AdmiralDesu).
+* 🌐 Add Chinese translation for `docs/tutorial/security/first-steps.md`. PR [#3841](https://github.com/tiangolo/fastapi/pull/3841) by [@jaystone776](https://github.com/jaystone776).
+* 🌐 Add Japanese translation for `docs/ja/docs/advanced/nosql-databases.md`. PR [#4205](https://github.com/tiangolo/fastapi/pull/4205) by [@sUeharaE4](https://github.com/sUeharaE4).
+* 🌐 Add Indonesian translation for `docs/id/docs/tutorial/index.md`. PR [#4705](https://github.com/tiangolo/fastapi/pull/4705) by [@bas-baskara](https://github.com/bas-baskara).
+* 🌐 Add Persian translation for `docs/fa/docs/index.md` and tweak right-to-left CSS. PR [#2395](https://github.com/tiangolo/fastapi/pull/2395) by [@mohsen-mahmoodi](https://github.com/mohsen-mahmoodi).
+
+### Internal
+
+* 🔧 Update Jina sponsorship. PR [#5283](https://github.com/tiangolo/fastapi/pull/5283) by [@tiangolo](https://github.com/tiangolo).
+* 🔧 Update Jina sponsorship. PR [#5272](https://github.com/tiangolo/fastapi/pull/5272) by [@tiangolo](https://github.com/tiangolo).
+* 🔧 Update sponsors, Striveworks badge. PR [#5179](https://github.com/tiangolo/fastapi/pull/5179) by [@tiangolo](https://github.com/tiangolo).
## 0.79.0
diff --git a/docs/en/docs/tutorial/response-model.md b/docs/en/docs/tutorial/response-model.md
index e371e86e4..2bbd4d4fd 100644
--- a/docs/en/docs/tutorial/response-model.md
+++ b/docs/en/docs/tutorial/response-model.md
@@ -61,6 +61,12 @@ Here we are declaring a `UserIn` model, it will contain a plaintext password:
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
```
+!!! info
+ To use `EmailStr`, first install `email_validator`.
+
+ E.g. `pip install email-validator`
+ or `pip install pydantic[email]`.
+
And we are using this model to declare our input and the same model to declare our output:
=== "Python 3.6 and above"
diff --git a/docs/en/docs/tutorial/sql-databases.md b/docs/en/docs/tutorial/sql-databases.md
index 3436543a5..5ccaf05ec 100644
--- a/docs/en/docs/tutorial/sql-databases.md
+++ b/docs/en/docs/tutorial/sql-databases.md
@@ -80,6 +80,20 @@ The file `__init__.py` is just an empty file, but it tells Python that `sql_app`
Now let's see what each file/module does.
+## Install `SQLAlchemy`
+
+First you need to install `SQLAlchemy`:
+
+
+ - FastAPI framework, high performance, easy to learn, fast to code, ready for production + فریمورک FastAPI، کارایی بالا، یادگیری آسان، کدنویسی سریع، آماده برای استفاده در محیط پروداکشن
-
-
+
+
@@ -25,103 +21,99 @@
---
-**Documentation**: https://fastapi.tiangolo.com
+**مستندات**: https://fastapi.tiangolo.com
-**Source Code**: https://github.com/tiangolo/fastapi
+**کد منبع**: https://github.com/tiangolo/fastapi
---
+FastAPI یک وب فریمورک مدرن و سریع (با کارایی بالا) برای ایجاد APIهای متنوع (وب، وبسوکت و غبره) با زبان پایتون نسخه +۳.۶ است. این فریمورک با رعایت کامل راهنمای نوع داده (Type Hint) ایجاد شده است.
-FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
+ویژگیهای کلیدی این فریمورک عبارتند از:
-The key features are:
+* **سرعت**: کارایی بسیار بالا و قابل مقایسه با **NodeJS** و **Go** (با تشکر از Starlette و Pydantic). [یکی از سریعترین فریمورکهای پایتونی موجود](#performance).
-* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
+* **کدنویسی سریع**: افزایش ۲۰۰ تا ۳۰۰ درصدی سرعت توسعه فابلیتهای جدید. *
+* **باگ کمتر**: کاهش ۴۰ درصدی خطاهای انسانی (برنامهنویسی). *
+* **غریزی**: پشتیبانی فوقالعاده در محیطهای توسعه یکپارچه (IDE). تکمیل در همه بخشهای کد. کاهش زمان رفع باگ.
+* **آسان**: طراحی شده برای یادگیری و استفاده آسان. کاهش زمان مورد نیاز برای مراجعه به مستندات.
+* **کوچک**: کاهش تکرار در کد. چندین قابلیت برای هر پارامتر (منظور پارامترهای ورودی تابع هندلر میباشد، به بخش خلاصه در همین صفحه مراجعه شود). باگ کمتر.
+* **استوار**: ایجاد کدی آماده برای استفاده در محیط پروداکشن و تولید خودکار مستندات تعاملی
+* **مبتنی بر استانداردها**: مبتنی بر (و منطبق با) استانداردهای متن باز مربوط به API: OpenAPI (سوگر سابق) و JSON Schema.
-* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
-* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
-* **Intuitive**: Great editor support. Completion everywhere. Less time debugging.
-* **Easy**: Designed to be easy to use and learn. Less time reading docs.
-* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
-* **Robust**: Get production-ready code. With automatic interactive documentation.
-* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.
+* تخمینها بر اساس تستهای انجام شده در یک تیم توسعه داخلی که مشغول ایجاد برنامههای کاربردی واقعی بودند صورت گرفته است.
-* estimation based on tests on an internal development team, building production applications.
-
-## Sponsors
+## اسپانسرهای طلایی
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
-
-{% endfor -%}
-{%- for sponsor in sponsors.silver -%}
-
+
{% endfor %}
{% endif %}
-Other sponsors
+دیگر اسپانسرها
-## Opinions
+## نظر دیگران در مورد FastAPI
-"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
+
async def...async def... نیز استفاده کنیدuvicorn main:app --reload...uvicorn main:app --reload...ujson - for faster JSON "parsing".
-* email_validator - for email validation.
+* ujson - برای "تجزیه (parse)" سریعتر JSON .
+* email_validator - برای اعتبارسنجی آدرسهای ایمیل.
-Used by Starlette:
+استفاده شده توسط Starlette:
-* requests - Required if you want to use the `TestClient`.
-* jinja2 - Required if you want to use the default template configuration.
-* python-multipart - Required if you want to support form "parsing", with `request.form()`.
-* itsdangerous - Required for `SessionMiddleware` support.
-* pyyaml - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
-* ujson - Required if you want to use `UJSONResponse`.
+* requests - در صورتی که میخواهید از `TestClient` استفاده کنید.
+* aiofiles - در صورتی که میخواهید از `FileResponse` و `StaticFiles` استفاده کنید.
+* jinja2 - در صورتی که بخواهید از پیکربندی پیشفرض برای قالبها استفاده کنید.
+* python-multipart - در صورتی که بخواهید با استفاده از `request.form()` از قابلیت "تجزیه (parse)" فرم استفاده کنید.
+* itsdangerous - در صورتی که بخواید از `SessionMiddleware` پشتیبانی کنید.
+* pyyaml - برای پشتیبانی `SchemaGenerator` در Starlet (به احتمال زیاد برای کار کردن با FastAPI به آن نیازی پیدا نمیکنید.).
+* graphene - در صورتی که از `GraphQLApp` پشتیبانی میکنید.
+* ujson - در صورتی که بخواهید از `UJSONResponse` استفاده کنید.
-Used by FastAPI / Starlette:
+استفاده شده توسط FastAPI / Starlette:
-* uvicorn - for the server that loads and serves your application.
-* orjson - Required if you want to use `ORJSONResponse`.
+* uvicorn - برای سرور اجرا کننده برنامه وب.
+* orjson - در صورتی که بخواهید از `ORJSONResponse` استفاده کنید.
-You can install all of these with `pip install "fastapi[all]"`.
+میتوان همه این موارد را با استفاده از دستور `pip install fastapi[all]`. به صورت یکجا نصب کرد.
-## License
+## لایسنس
-This project is licensed under the terms of the MIT license.
+این پروژه مشمول قوانین و مقررات لایسنس MIT است.
diff --git a/docs/fa/mkdocs.yml b/docs/fa/mkdocs.yml
index 7d74e0407..7c2fe5eab 100644
--- a/docs/fa/mkdocs.yml
+++ b/docs/fa/mkdocs.yml
@@ -75,6 +75,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs/fr/docs/async.md b/docs/fr/docs/async.md
index 71c28b703..db88c4663 100644
--- a/docs/fr/docs/async.md
+++ b/docs/fr/docs/async.md
@@ -205,10 +205,6 @@ Cette "attente" 🕙 se mesure en microsecondes, mais tout de même, en cumulé
C'est pourquoi il est logique d'utiliser du code asynchrone ⏸🔀⏯ pour des APIs web.
-La plupart des frameworks Python existants (y compris Flask et Django) ont été créés avant que les nouvelles fonctionnalités asynchrones de Python n'existent. Donc, les façons dont ils peuvent être déployés supportent l'exécution parallèle et une ancienne forme d'exécution asynchrone qui n'est pas aussi puissante que les nouvelles fonctionnalités de Python.
-
-Et cela, bien que les spécifications principales du web asynchrone en Python (ou ASGI) ont été développées chez Django, pour ajouter le support des WebSockets.
-
Ce type d'asynchronicité est ce qui a rendu NodeJS populaire (bien que NodeJS ne soit pas parallèle) et c'est la force du Go en tant que langage de programmation.
Et c'est le même niveau de performance que celui obtenu avec **FastAPI**.
diff --git a/docs/fr/docs/deployment/index.md b/docs/fr/docs/deployment/index.md
new file mode 100644
index 000000000..e855adfa3
--- /dev/null
+++ b/docs/fr/docs/deployment/index.md
@@ -0,0 +1,28 @@
+# Déploiement - Intro
+
+Le déploiement d'une application **FastAPI** est relativement simple.
+
+## Que signifie le déploiement
+
+**Déployer** une application signifie effectuer les étapes nécessaires pour la rendre **disponible pour les
+utilisateurs**.
+
+Pour une **API Web**, cela implique normalement de la placer sur une **machine distante**, avec un **programme serveur**
+qui offre de bonnes performances, une bonne stabilité, _etc._, afin que vos **utilisateurs** puissent **accéder** à
+l'application efficacement et sans interruption ni problème.
+
+Ceci contraste avec les étapes de **développement**, où vous êtes constamment en train de modifier le code, de le casser
+et de le réparer, d'arrêter et de redémarrer le serveur de développement, _etc._
+
+## Stratégies de déploiement
+
+Il existe plusieurs façons de procéder, en fonction de votre cas d'utilisation spécifique et des outils que vous
+utilisez.
+
+Vous pouvez **déployer un serveur** vous-même en utilisant une combinaison d'outils, vous pouvez utiliser un **service
+cloud** qui fait une partie du travail pour vous, ou encore d'autres options possibles.
+
+Je vais vous montrer certains des principaux concepts que vous devriez probablement avoir à l'esprit lors du déploiement
+d'une application **FastAPI** (bien que la plupart de ces concepts s'appliquent à tout autre type d'application web).
+
+Vous verrez plus de détails à avoir en tête et certaines des techniques pour le faire dans les sections suivantes. ✨
diff --git a/docs/fr/docs/history-design-future.md b/docs/fr/docs/history-design-future.md
new file mode 100644
index 000000000..b77664be6
--- /dev/null
+++ b/docs/fr/docs/history-design-future.md
@@ -0,0 +1,79 @@
+# Histoire, conception et avenir
+
+Il y a quelque temps, un utilisateur de **FastAPI** a demandé :
+
+> Quelle est l'histoire de ce projet ? Il semble être sorti de nulle part et est devenu génial en quelques semaines [...].
+
+Voici un petit bout de cette histoire.
+
+## Alternatives
+
+Je crée des API avec des exigences complexes depuis plusieurs années (Machine Learning, systèmes distribués, jobs asynchrones, bases de données NoSQL, etc), en dirigeant plusieurs équipes de développeurs.
+
+Dans ce cadre, j'ai dû étudier, tester et utiliser de nombreuses alternatives.
+
+L'histoire de **FastAPI** est en grande partie l'histoire de ses prédécesseurs.
+
+Comme dit dans la section [Alternatives](alternatives.md){.internal-link target=\_blank} :
+
++ +**FastAPI** n'existerait pas sans le travail antérieur d'autres personnes. + +Il y a eu de nombreux outils créés auparavant qui ont contribué à inspirer sa création. + +J'ai évité la création d'un nouveau framework pendant plusieurs années. J'ai d'abord essayé de résoudre toutes les fonctionnalités couvertes par **FastAPI** en utilisant de nombreux frameworks, plug-ins et outils différents. + +Mais à un moment donné, il n'y avait pas d'autre option que de créer quelque chose qui offre toutes ces fonctionnalités, en prenant les meilleures idées des outils précédents, et en les combinant de la meilleure façon possible, en utilisant des fonctionnalités du langage qui n'étaient même pas disponibles auparavant (annotations de type pour Python 3.6+). + ++ +## Recherche + +En utilisant toutes les alternatives précédentes, j'ai eu la chance d'apprendre de toutes, de prendre des idées, et de les combiner de la meilleure façon que j'ai pu trouver pour moi-même et les équipes de développeurs avec lesquelles j'ai travaillé. + +Par exemple, il était clair que l'idéal était de se baser sur les annotations de type Python standard. + +De plus, la meilleure approche était d'utiliser des normes déjà existantes. + +Ainsi, avant même de commencer à coder **FastAPI**, j'ai passé plusieurs mois à étudier les spécifications d'OpenAPI, JSON Schema, OAuth2, etc. Comprendre leurs relations, leurs similarités et leurs différences. + +## Conception + +Ensuite, j'ai passé du temps à concevoir l'"API" de développeur que je voulais avoir en tant qu'utilisateur (en tant que développeur utilisant FastAPI). + +J'ai testé plusieurs idées dans les éditeurs Python les plus populaires : PyCharm, VS Code, les éditeurs basés sur Jedi. + +D'après la dernière Enquête Développeurs Python, cela couvre environ 80% des utilisateurs. + +Cela signifie que **FastAPI** a été spécifiquement testé avec les éditeurs utilisés par 80% des développeurs Python. Et comme la plupart des autres éditeurs ont tendance à fonctionner de façon similaire, tous ses avantages devraient fonctionner pour pratiquement tous les éditeurs. + +Ainsi, j'ai pu trouver les meilleurs moyens de réduire autant que possible la duplication du code, d'avoir la complétion partout, les contrôles de type et d'erreur, etc. + +Le tout de manière à offrir la meilleure expérience de développement à tous les développeurs. + +## Exigences + +Après avoir testé plusieurs alternatives, j'ai décidé que j'allais utiliser **Pydantic** pour ses avantages. + +J'y ai ensuite contribué, pour le rendre entièrement compatible avec JSON Schema, pour supporter différentes manières de définir les déclarations de contraintes, et pour améliorer le support des éditeurs (vérifications de type, autocomplétion) sur la base des tests effectués dans plusieurs éditeurs. + +Pendant le développement, j'ai également contribué à **Starlette**, l'autre exigence clé. + +## Développement + +Au moment où j'ai commencé à créer **FastAPI** lui-même, la plupart des pièces étaient déjà en place, la conception était définie, les exigences et les outils étaient prêts, et la connaissance des normes et des spécifications était claire et fraîche. + +## Futur + +À ce stade, il est déjà clair que **FastAPI** et ses idées sont utiles pour de nombreuses personnes. + +Elle a été préférée aux solutions précédentes parce qu'elle convient mieux à de nombreux cas d'utilisation. + +De nombreux développeurs et équipes dépendent déjà de **FastAPI** pour leurs projets (y compris moi et mon équipe). + +Mais il y a encore de nombreuses améliorations et fonctionnalités à venir. + +**FastAPI** a un grand avenir devant lui. + +Et [votre aide](help-fastapi.md){.internal-link target=\_blank} est grandement appréciée. diff --git a/docs/fr/docs/index.md b/docs/fr/docs/index.md index f713ee96b..1307c063b 100644 --- a/docs/fr/docs/index.md +++ b/docs/fr/docs/index.md @@ -135,7 +135,7 @@ You will also need an ASGI server, for production such as ```console -$ pip install uvicorn[standard] +$ pip install "uvicorn[standard]" ---> 100% ``` diff --git a/docs/fr/mkdocs.yml b/docs/fr/mkdocs.yml index f790c0299..6bed7be73 100644 --- a/docs/fr/mkdocs.yml +++ b/docs/fr/mkdocs.yml @@ -69,9 +69,11 @@ nav: - tutorial/background-tasks.md - async.md - Déploiement: + - deployment/index.md - deployment/docker.md - project-generation.md - alternatives.md +- history-design-future.md - external-links.md markdown_extensions: - toc: @@ -90,6 +92,8 @@ markdown_extensions: format: !!python/name:pymdownx.superfences.fence_code_format '' - pymdownx.tabbed: alternate_style: true +- attr_list +- md_in_html extra: analytics: provider: google diff --git a/docs/he/mkdocs.yml b/docs/he/mkdocs.yml index 34a3b0e6a..3279099b5 100644 --- a/docs/he/mkdocs.yml +++ b/docs/he/mkdocs.yml @@ -54,6 +54,7 @@ nav: - pt: /pt/ - ru: /ru/ - sq: /sq/ + - sv: /sv/ - tr: /tr/ - uk: /uk/ - zh: /zh/ @@ -74,6 +75,8 @@ markdown_extensions: format: !!python/name:pymdownx.superfences.fence_code_format '' - pymdownx.tabbed: alternate_style: true +- attr_list +- md_in_html extra: analytics: provider: google @@ -126,6 +129,8 @@ extra: name: ru - русский язык - link: /sq/ name: sq - shqip + - link: /sv/ + name: sv - svenska - link: /tr/ name: tr - Türkçe - link: /uk/ diff --git a/docs/id/docs/index.md b/docs/id/docs/index.md index 0bb7b55e3..041e0b754 100644 --- a/docs/id/docs/index.md +++ b/docs/id/docs/index.md @@ -135,7 +135,7 @@ You will also need an ASGI server, for production such as ```console -$ pip install uvicorn[standard] +$ pip install "uvicorn[standard]" ---> 100% ``` diff --git a/docs/id/docs/tutorial/index.md b/docs/id/docs/tutorial/index.md new file mode 100644 index 000000000..8fec3c087 --- /dev/null +++ b/docs/id/docs/tutorial/index.md @@ -0,0 +1,80 @@ +# Tutorial - Pedoman Pengguna - Pengenalan + +Tutorial ini menunjukan cara menggunakan ***FastAPI*** dengan semua fitur-fiturnya, tahap demi tahap. + +Setiap bagian dibangun secara bertahap dari bagian sebelumnya, tetapi terstruktur untuk memisahkan banyak topik, sehingga kamu bisa secara langsung menuju ke topik spesifik untuk menyelesaikan kebutuhan API tertentu. + +Ini juga dibangun untuk digunakan sebagai referensi yang akan datang. + +Sehingga kamu dapat kembali lagi dan mencari apa yang kamu butuhkan dengan tepat. + +## Jalankan kode + +Semua blok-blok kode dapat dicopy dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji). + +Untuk menjalankan setiap contoh, copy kode ke file `main.py`, dan jalankan `uvicorn` dengan: + +
awaitを使用していないので、私たちは`async def`ではなく通常の`def`で関数を宣言する必要があります。
+
+また、Couchbaseは単一の`Bucket`オブジェクトを複数のスレッドで使用しないことを推奨していますので、単に直接Bucketを取得して関数に渡すことが出来ます。
+
+```Python hl_lines="49-53"
+{!../../../docs_src/nosql_databases/tutorial001.py!}
+```
+
+## まとめ
+
+他のサードパーティ製のNoSQLデータベースを利用する場合でも、そのデータベースの標準ライブラリを利用するだけで利用できます。
+
+他の外部ツール、システム、APIについても同じことが言えます。
diff --git a/docs/ja/docs/deployment/manually.md b/docs/ja/docs/deployment/manually.md
index dd4b568bd..67010a66f 100644
--- a/docs/ja/docs/deployment/manually.md
+++ b/docs/ja/docs/deployment/manually.md
@@ -11,7 +11,7 @@
+
+!!! marque o "botão de Autorizar!"
+ Você já tem um novo "botão de autorizar!".
+
+ E seu *path operation* tem um pequeno cadeado no canto superior direito que você pode clicar.
+
+E se você clicar, você terá um pequeno formulário de autorização para digitar o `username` e `senha` (e outros campos opcionais):
+
+
+
+!!! nota
+ Não importa o que você digita no formulário, não vai funcionar ainda. Mas nós vamos chegar lá.
+
+Claro que este não é o frontend para os usuários finais, mas é uma ótima ferramenta automática para documentar interativamente toda sua API.
+
+Pode ser usado pelo time de frontend (que pode ser você no caso).
+
+Pode ser usado por aplicações e sistemas third party (de terceiros).
+
+E também pode ser usada por você mesmo, para debugar, checar e testar a mesma aplicação.
+
+## O Fluxo da `senha`
+
+Agora vamos voltar um pouco e entender o que é isso tudo.
+
+O "fluxo" da `senha` é um dos caminhos ("fluxos") definidos no OAuth2, para lidar com a segurança e autenticação.
+
+OAuth2 foi projetado para que o backend ou a API pudesse ser independente do servidor que autentica o usuário.
+
+Mas nesse caso, a mesma aplicação **FastAPI** irá lidar com a API e a autenticação.
+
+Então, vamos rever de um ponto de vista simplificado:
+
+* O usuário digita o `username` e a `senha` no frontend e aperta `Enter`.
+* O frontend (rodando no browser do usuário) manda o `username` e a `senha` para uma URL específica na sua API (declarada com `tokenUrl="token"`).
+* A API checa aquele `username` e `senha`, e responde com um "token" (nós não implementamos nada disso ainda).
+ * Um "token" é apenas uma string com algum conteúdo que nós podemos utilizar mais tarde para verificar o usuário.
+ * Normalmente, um token é definido para expirar depois de um tempo.
+ * Então, o usuário terá que se logar de novo depois de um tempo.
+ * E se o token for roubado, o risco é menor. Não é como se fosse uma chave permanente que vai funcionar para sempre (na maioria dos casos).
+ * O frontend armazena aquele token temporariamente em algum lugar.
+ * O usuário clica no frontend para ir à outra seção daquele frontend do aplicativo web.
+ * O frontend precisa buscar mais dados daquela API.
+ * Mas precisa de autenticação para aquele endpoint em específico.
+ * Então, para autenticar com nossa API, ele manda um header de `Autorização` com o valor `Bearer` mais o token.
+ * Se o token contém `foobar`, o conteúdo do header de `Autorização` será: `Bearer foobar`.
+
+## **FastAPI**'s `OAuth2PasswordBearer`
+
+**FastAPI** fornece várias ferramentas, em diferentes níveis de abstração, para implementar esses recursos de segurança.
+
+Neste exemplo, nós vamos usar o **OAuth2** com o fluxo de **Senha**, usando um token **Bearer**. Fazemos isso usando a classe `OAuth2PasswordBearer`.
+
+!!! informação
+ Um token "bearer" não é a única opção.
+
+ Mas é a melhor no nosso caso.
+
+ E talvez seja a melhor para a maioria dos casos, a não ser que você seja um especialista em OAuth2 e saiba exatamente o porquê de existir outras opções que se adequam melhor às suas necessidades.
+
+ Nesse caso, **FastAPI** também fornece as ferramentas para construir.
+
+Quando nós criamos uma instância da classe `OAuth2PasswordBearer`, nós passamos pelo parâmetro `tokenUrl` Esse parâmetro contém a URL que o client (o frontend rodando no browser do usuário) vai usar para mandar o `username` e `senha` para obter um token.
+
+```Python hl_lines="6"
+{!../../../docs_src/security/tutorial001.py!}
+```
+
+!!! dica
+ Esse `tokenUrl="token"` se refere a uma URL relativa que nós não criamos ainda. Como é uma URL relativa, é equivalente a `./token`.
+
+ Porque estamos usando uma URL relativa, se sua API estava localizada em `https://example.com/`, então irá referir-se à `https://example.com/token`. Mas se sua API estava localizada em `https://example.com/api/v1/`, então irá referir-se à `https://example.com/api/v1/token`.
+
+ Usar uma URL relativa é importante para garantir que sua aplicação continue funcionando, mesmo em um uso avançado tipo [Atrás de um Proxy](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+
+Esse parâmetro não cria um endpoint / *path operation*, mas declara que a URL `/token` vai ser aquela que o client deve usar para obter o token. Essa informação é usada no OpenAPI, e depois na API Interativa de documentação de sistemas.
+
+Em breve também criaremos o atual path operation.
+
+!!! informação
+ Se você é um "Pythonista" muito rigoroso, você pode não gostar do estilo do nome do parâmetro `tokenUrl` em vez de `token_url`.
+
+ Isso ocorre porque está utilizando o mesmo nome que está nas especificações do OpenAPI. Então, se você precisa investigar mais sobre qualquer um desses esquemas de segurança, você pode simplesmente copiar e colar para encontrar mais informações sobre isso.
+
+A variável `oauth2_scheme` é um instância de `OAuth2PasswordBearer`, mas também é um "callable".
+
+Pode ser chamada de:
+
+```Python
+oauth2_scheme(some, parameters)
+```
+
+Então, pode ser usado com `Depends`.
+
+## Use-o
+
+Agora você pode passar aquele `oauth2_scheme` em uma dependência com `Depends`.
+
+```Python hl_lines="10"
+{!../../../docs_src/security/tutorial001.py!}
+```
+
+Esse dependência vai fornecer uma `str` que é atribuído ao parâmetro `token da *função do path operation*
+
+A **FastAPI** saberá que pode usar essa dependência para definir um "esquema de segurança" no esquema da OpenAPI (e na documentação da API automática).
+
+!!! informação "Detalhes técnicos"
+ **FastAPI** saberá que pode usar a classe `OAuth2PasswordBearer` (declarada na dependência) para definir o esquema de segurança na OpenAPI porque herda de `fastapi.security.oauth2.OAuth2`, que por sua vez herda de `fastapi.security.base.Securitybase`.
+
+ Todos os utilitários de segurança que se integram com OpenAPI (e na documentação da API automática) herdam de `SecurityBase`, é assim que **FastAPI** pode saber como integrá-los no OpenAPI.
+
+## O que ele faz
+
+Ele irá e olhará na requisição para aquele header de `Autorização`, verificará se o valor é `Bearer` mais algum token, e vai retornar o token como uma `str`
+
+Se ele não ver o header de `Autorização` ou o valor não tem um token `Bearer`, vai responder com um código de erro 401 (`UNAUTHORIZED`) diretamente.
+
+Você nem precisa verificar se o token existe para retornar um erro. Você pode ter certeza de que se a sua função for executada, ela terá um `str` nesse token.
+
+Você já pode experimentar na documentação interativa:
+
+
+
+Não estamos verificando a validade do token ainda, mas isso já é um começo
+
+## Recapitulando
+
+Então, em apenas 3 ou 4 linhas extras, você já tem alguma forma primitiva de segurança.
diff --git a/docs/pt/mkdocs.yml b/docs/pt/mkdocs.yml
index fb95bfe29..c37b855d8 100644
--- a/docs/pt/mkdocs.yml
+++ b/docs/pt/mkdocs.yml
@@ -64,11 +64,13 @@ nav:
- tutorial/index.md
- tutorial/first-steps.md
- tutorial/path-params.md
+ - tutorial/query-params.md
- tutorial/body.md
- tutorial/body-fields.md
- tutorial/extra-data-types.md
- tutorial/query-params-str-validations.md
- tutorial/cookie-params.md
+ - tutorial/handling-errors.md
- Segurança:
- tutorial/security/index.md
- Guia de Usuário Avançado:
@@ -100,6 +102,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs/ru/docs/index.md b/docs/ru/docs/index.md
index 9a3957d5f..932bb2139 100644
--- a/docs/ru/docs/index.md
+++ b/docs/ru/docs/index.md
@@ -135,7 +135,7 @@ You will also need an ASGI server, for production such as
```console
-$ pip install uvicorn[standard]
+$ pip install "uvicorn[standard]"
---> 100%
```
diff --git a/docs/ru/docs/tutorial/background-tasks.md b/docs/ru/docs/tutorial/background-tasks.md
new file mode 100644
index 000000000..e608f6c8f
--- /dev/null
+++ b/docs/ru/docs/tutorial/background-tasks.md
@@ -0,0 +1,102 @@
+# Фоновые задачи
+
+Вы можете создавать фоновые задачи, которые будут выполнятся *после* возвращения ответа сервером.
+
+Это может быть полезно для функций, которые должны выполниться после получения запроса, но ожидание их выполнения необязательно для пользователя.
+
+К примеру:
+
+* Отправка писем на почту после выполнения каких-либо действий:
+ * Т.к. соединение с почтовым сервером и отправка письма идут достаточно "долго" (несколько секунд), вы можете отправить ответ пользователю, а отправку письма выполнить в фоне.
+* Обработка данных:
+ * К примеру, если вы получаете файл, который должен пройти через медленный процесс, вы можете отправить ответ "Accepted" (HTTP 202) и отправить работу с файлом в фон.
+
+## Использование класса `BackgroundTasks`
+
+Сначала импортируйте `BackgroundTasks`, потом добавьте в функцию параметр с типом `BackgroundTasks`:
+
+```Python hl_lines="1 13"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+**FastAPI** создаст объект класса `BackgroundTasks` для вас и запишет его в параметр.
+
+## Создание функции для фоновой задачи
+
+Создайте функцию, которую хотите запустить в фоне.
+
+Это совершенно обычная функция, которая может принимать параметры.
+
+Она может быть как асинхронной `async def`, так и обычной `def` функцией, **FastAPI** знает, как правильно ее выполнить.
+
+В нашем примере фоновая задача будет вести запись в файл (симулируя отправку письма).
+
+Так как операция записи не использует `async` и `await`, мы определим ее как обычную `def`:
+
+```Python hl_lines="6-9"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+## Добавление фоновой задачи
+
+Внутри функции вызовите метод `.add_task()` у объекта *background tasks* и передайте ему функцию, которую хотите выполнить в фоне:
+
+```Python hl_lines="14"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+`.add_task()` принимает следующие аргументы:
+
+* Функцию, которая будет выполнена в фоне (`write_notification`). Обратите внимание, что передается объект функции, без скобок.
+* Любое упорядоченное количество аргументов, которые принимает функция (`email`).
+* Любое количество именованных аргументов, которые принимает функция (`message="some notification"`).
+
+## Встраивание зависимостей
+
+Класс `BackgroundTasks` также работает с системой встраивания зависимостей, вы можете определить `BackgroundTasks` на разных уровнях: как параметр функции, как завимость, как подзависимость и так далее.
+
+**FastAPI** знает, что нужно сделать в каждом случае и как переиспользовать тот же объект `BackgroundTasks`, так чтобы все фоновые задачи собрались и запустились вместе в фоне:
+
+=== "Python 3.6 и выше"
+
+ ```Python hl_lines="13 15 22 25"
+ {!> ../../../docs_src/background_tasks/tutorial002.py!}
+ ```
+
+=== "Python 3.10 и выше"
+
+ ```Python hl_lines="11 13 20 23"
+ {!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
+ ```
+
+В этом примере сообщения будут записаны в `log.txt` *после* того, как ответ сервера был отправлен.
+
+Если бы в запросе была очередь `q`, она бы первой записалась в `log.txt` фоновой задачей (потому что вызывается в зависимости `get_query`).
+
+После другая фоновая задача, которая была сгенерирована в функции, запишет сообщение из параметра `email`.
+
+## Технические детали
+
+Класс `BackgroundTasks` основан на `starlette.background`.
+
+Он интегрирован в FastAPI, так что вы можете импортировать его прямо из `fastapi` и избежать случайного импорта `BackgroundTask` (без `s` на конце) из `starlette.background`.
+
+При использовании `BackgroundTasks` (а не `BackgroundTask`), вам достаточно только определить параметр функции с типом `BackgroundTasks` и **FastAPI** сделает все за вас, также как при использовании объекта `Request`.
+
+Вы все равно можете использовать `BackgroundTask` из `starlette` в FastAPI, но вам придется самостоятельно создавать объект фоновой задачи и вручную обработать `Response` внутри него.
+
+Вы можете подробнее изучить его в Официальной документации Starlette для BackgroundTasks.
+
+## Предостережение
+
+Если вам нужно выполнить тяжелые вычисления в фоне, которым необязательно быть запущенными в одном процессе с приложением **FastAPI** (к примеру, вам не нужны обрабатываемые переменные или вы не хотите делиться памятью процесса и т.д.), вы можете использовать более серьезные инструменты, такие как Celery.
+
+Их тяжелее настраивать, также им нужен брокер сообщений наподобие RabbitMQ или Redis, но зато они позволяют вам запускать фоновые задачи в нескольких процессах и даже на нескольких серверах.
+
+Для примера, посмотрите [Project Generators](../project-generation.md){.internal-link target=_blank}, там есть проект с уже настроенным Celery.
+
+Но если вам нужен доступ к общим переменным и объектам вашего **FastAPI** приложения или вам нужно выполнять простые фоновые задачи (наподобие отправки письма из примера) вы можете просто использовать `BackgroundTasks`.
+
+## Резюме
+
+Для создания фоновых задач вам необходимо импортировать `BackgroundTasks` и добавить его в функцию, как параметр с типом `BackgroundTasks`.
diff --git a/docs/ru/mkdocs.yml b/docs/ru/mkdocs.yml
index 2eb8eb935..f70b436d2 100644
--- a/docs/ru/mkdocs.yml
+++ b/docs/ru/mkdocs.yml
@@ -58,6 +58,10 @@ nav:
- tr: /tr/
- uk: /uk/
- zh: /zh/
+- python-types.md
+- Учебник - руководство пользователя:
+ - tutorial/background-tasks.md
+- external-links.md
- async.md
markdown_extensions:
- toc:
@@ -76,6 +80,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs/sq/docs/index.md b/docs/sq/docs/index.md
index 29f92e020..2b64003fe 100644
--- a/docs/sq/docs/index.md
+++ b/docs/sq/docs/index.md
@@ -135,7 +135,7 @@ You will also need an ASGI server, for production such as
```console
-$ pip install uvicorn[standard]
+$ pip install "uvicorn[standard]"
---> 100%
```
diff --git a/docs/sq/mkdocs.yml b/docs/sq/mkdocs.yml
index 1d8d9d04e..b07f3bc63 100644
--- a/docs/sq/mkdocs.yml
+++ b/docs/sq/mkdocs.yml
@@ -75,6 +75,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs/sv/mkdocs.yml b/docs/sv/mkdocs.yml
index fa0296d5c..3332d232d 100644
--- a/docs/sv/mkdocs.yml
+++ b/docs/sv/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- es: /es/
- fa: /fa/
- fr: /fr/
+ - he: /he/
- id: /id/
- it: /it/
- ja: /ja/
@@ -74,6 +75,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
@@ -106,6 +109,8 @@ extra:
name: fa
- link: /fr/
name: fr - français
+ - link: /he/
+ name: he
- link: /id/
name: id
- link: /it/
diff --git a/docs/tr/docs/index.md b/docs/tr/docs/index.md
index 5693029b5..0d5337c87 100644
--- a/docs/tr/docs/index.md
+++ b/docs/tr/docs/index.md
@@ -143,7 +143,7 @@ Uygulamanı kullanılabilir hale getirmek için
```console
-$ pip install uvicorn[standard]
+$ pip install "uvicorn[standard]"
---> 100%
```
diff --git a/docs/tr/mkdocs.yml b/docs/tr/mkdocs.yml
index bf66edd68..e29d25936 100644
--- a/docs/tr/mkdocs.yml
+++ b/docs/tr/mkdocs.yml
@@ -78,6 +78,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs/uk/docs/index.md b/docs/uk/docs/index.md
index 29f92e020..2b64003fe 100644
--- a/docs/uk/docs/index.md
+++ b/docs/uk/docs/index.md
@@ -135,7 +135,7 @@ You will also need an ASGI server, for production such as
```console
-$ pip install uvicorn[standard]
+$ pip install "uvicorn[standard]"
---> 100%
```
diff --git a/docs/uk/mkdocs.yml b/docs/uk/mkdocs.yml
index 3b8475907..711328771 100644
--- a/docs/uk/mkdocs.yml
+++ b/docs/uk/mkdocs.yml
@@ -75,6 +75,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs/zh/docs/advanced/response-cookies.md b/docs/zh/docs/advanced/response-cookies.md
new file mode 100644
index 000000000..3e53c5319
--- /dev/null
+++ b/docs/zh/docs/advanced/response-cookies.md
@@ -0,0 +1,47 @@
+# 响应Cookies
+
+## 使用 `Response` 参数
+
+你可以在 *路径函数* 中定义一个类型为 `Response`的参数,这样你就可以在这个临时响应对象中设置cookie了。
+
+```Python hl_lines="1 8-9"
+{!../../../docs_src/response_cookies/tutorial002.py!}
+```
+
+而且你还可以根据你的需要响应不同的对象,比如常用的 `dict`,数据库model等。
+
+如果你定义了 `response_model`,程序会自动根据`response_model`来过滤和转换你响应的对象。
+
+**FastAPI** 会使用这个 *临时* 响应对象去装在这些cookies信息 (同样还有headers和状态码等信息), 最终会将这些信息和通过`response_model`转化过的数据合并到最终的响应里。
+
+你也可以在depend中定义`Response`参数,并设置cookie和header。
+
+## 直接响应 `Response`
+
+你还可以在直接响应`Response`时直接创建cookies。
+
+你可以参考[Return a Response Directly](response-directly.md){.internal-link target=_blank}来创建response
+
+然后设置Cookies,并返回:
+
+```Python hl_lines="10-12"
+{!../../../docs_src/response_cookies/tutorial001.py!}
+```
+
+!!! tip
+ 需要注意,如果你直接反馈一个response对象,而不是使用`Response`入参,FastAPI则会直接反馈你封装的response对象。
+
+ 所以你需要确保你响应数据类型的正确性,如:你可以使用`JSONResponse`来兼容JSON的场景。
+
+ 同时,你也应当仅反馈通过`response_model`过滤过的数据。
+
+### 更多信息
+
+!!! note "技术细节"
+ 你也可以使用`from starlette.responses import Response` 或者 `from starlette.responses import JSONResponse`。
+
+ 为了方便开发者,**FastAPI** 封装了相同数据类型,如`starlette.responses` 和 `fastapi.responses`。不过大部分response对象都是直接引用自Starlette。
+
+ 因为`Response`对象可以非常便捷的设置headers和cookies,所以 **FastAPI** 同时也封装了`fastapi.Response`。
+
+如果你想查看所有可用的参数和选项,可以参考 Starlette帮助文档
diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md
index 797032c86..3898beaee 100644
--- a/docs/zh/docs/index.md
+++ b/docs/zh/docs/index.md
@@ -131,7 +131,7 @@ $ pip install fastapi
+
+!!! check "Authorize 按钮!"
+
+ 页面右上角出现了一个「**Authorize**」按钮。
+
+ *路径操作*的右上角也出现了一个可以点击的小锁图标。
+
+点击 **Authorize** 按钮,弹出授权表单,输入 `username` 与 `password` 及其它可选字段:
+
+
+
+!!! note "笔记"
+
+ 目前,在表单中输入内容不会有任何反应,后文会介绍相关内容。
+
+虽然此文档不是给前端最终用户使用的,但这个自动工具非常实用,可在文档中与所有 API 交互。
+
+前端团队(可能就是开发者本人)可以使用本工具。
+
+第三方应用与系统也可以调用本工具。
+
+开发者也可以用它来调试、检查、测试应用。
+
+## 密码流
+
+现在,我们回过头来介绍这段代码的原理。
+
+`Password` **流**是 OAuth2 定义的,用于处理安全与身份验证的方式(**流**)。
+
+OAuth2 的设计目标是为了让后端或 API 独立于服务器验证用户身份。
+
+但在本例中,**FastAPI** 应用会处理 API 与身份验证。
+
+下面,我们来看一下简化的运行流程:
+
+- 用户在前端输入 `username` 与`password`,并点击**回车**
+- (用户浏览器中运行的)前端把 `username` 与`password` 发送至 API 中指定的 URL(使用 `tokenUrl="token"` 声明)
+- API 检查 `username` 与`password`,并用令牌(`Token`) 响应(暂未实现此功能):
+ - 令牌只是用于验证用户的字符串
+ - 一般来说,令牌会在一段时间后过期
+ - 过时后,用户要再次登录
+ - 这样一来,就算令牌被人窃取,风险也较低。因为它与永久密钥不同,**在绝大多数情况下**不会长期有效
+- 前端临时将令牌存储在某个位置
+- 用户点击前端,前往前端应用的其它部件
+- 前端需要从 API 中提取更多数据:
+ - 为指定的端点(Endpoint)进行身份验证
+ - 因此,用 API 验证身份时,要发送值为 `Bearer` + 令牌的请求头 `Authorization`
+ - 假如令牌为 `foobar`,`Authorization` 请求头就是: `Bearer foobar`
+
+## **FastAPI** 的 `OAuth2PasswordBearer`
+
+**FastAPI** 提供了不同抽象级别的安全工具。
+
+本例使用 **OAuth2** 的 **Password** 流以及 **Bearer** 令牌(`Token`)。为此要使用 `OAuth2PasswordBearer` 类。
+
+!!! info "说明"
+
+ `Beare` 令牌不是唯一的选择。
+
+ 但它是最适合这个用例的方案。
+
+ 甚至可以说,它是适用于绝大多数用例的最佳方案,除非您是 OAuth2 的专家,知道为什么其它方案更合适。
+
+ 本例中,**FastAPI** 还提供了构建工具。
+
+创建 `OAuth2PasswordBearer` 的类实例时,要传递 `tokenUrl` 参数。该参数包含客户端(用户浏览器中运行的前端) 的 URL,用于发送 `username` 与 `password`,并获取令牌。
+
+```Python hl_lines="6"
+{!../../../docs_src/security/tutorial001.py!}
+```
+
+!!! tip "提示"
+
+ 在此,`tokenUrl="token"` 指向的是暂未创建的相对 URL `token`。这个相对 URL 相当于 `./token`。
+
+ 因为使用的是相对 URL,如果 API 位于 `https://example.com/`,则指向 `https://example.com/token`。但如果 API 位于 `https://example.com/api/v1/`,它指向的就是`https://example.com/api/v1/token`。
+
+ 使用相对 URL 非常重要,可以确保应用在遇到[使用代理](../../advanced/behind-a-proxy.md){.internal-link target=_blank}这样的高级用例时,也能正常运行。
+
+该参数不会创建端点或*路径操作*,但会声明客户端用来获取令牌的 URL `/token` 。此信息用于 OpenAPI 及 API 文档。
+
+接下来,学习如何创建实际的路径操作。
+
+!!! info "说明"
+
+ 严苛的 **Pythonista** 可能不喜欢用 `tokenUrl` 这种命名风格代替 `token_url`。
+
+ 这种命名方式是因为要使用与 OpenAPI 规范中相同的名字。以便在深入校验安全方案时,能通过复制粘贴查找更多相关信息。
+
+`oauth2_scheme` 变量是 `OAuth2PasswordBearer` 的实例,也是**可调用项**。
+
+以如下方式调用:
+
+```Python
+oauth2_scheme(some, parameters)
+```
+
+因此,`Depends` 可以调用 `oauth2_scheme` 变量。
+
+### 使用
+
+接下来,使用 `Depends` 把 `oauth2_scheme` 传入依赖项。
+
+```Python hl_lines="10"
+{!../../../docs_src/security/tutorial001.py!}
+```
+
+该依赖项使用字符串(`str`)接收*路径操作函数*的参数 `token` 。
+
+**FastAPI** 使用依赖项在 OpenAPI 概图(及 API 文档)中定义**安全方案**。
+
+!!! info "技术细节"
+
+ **FastAPI** 使用(在依赖项中声明的)类 `OAuth2PasswordBearer` 在 OpenAPI 中定义安全方案,这是因为它继承自 `fastapi.security.oauth2.OAuth2`,而该类又是继承自`fastapi.security.base.SecurityBase`。
+
+ 所有与 OpenAPI(及 API 文档)集成的安全工具都继承自 `SecurityBase`, 这就是为什么 **FastAPI** 能把它们集成至 OpenAPI 的原因。
+
+## 实现的操作
+
+FastAPI 校验请求中的 `Authorization` 请求头,核对请求头的值是不是由 `Bearer ` + 令牌组成, 并返回令牌字符串(`str`)。
+
+如果没有找到 `Authorization` 请求头,或请求头的值不是 `Bearer ` + 令牌。FastAPI 直接返回 401 错误状态码(`UNAUTHORIZED`)。
+
+开发者不需要检查错误信息,查看令牌是否存在,只要该函数能够执行,函数中就会包含令牌字符串。
+
+正如下图所示,API 文档已经包含了这项功能:
+
+
+
+目前,暂时还没有实现验证令牌是否有效的功能,不过后文很快就会介绍的。
+
+## 小结
+
+看到了吧,只要多写三四行代码,就可以添加基础的安全表单。
diff --git a/docs/zh/mkdocs.yml b/docs/zh/mkdocs.yml
index f9bfd6875..b60a0b7a1 100644
--- a/docs/zh/mkdocs.yml
+++ b/docs/zh/mkdocs.yml
@@ -93,6 +93,7 @@ nav:
- tutorial/dependencies/global-dependencies.md
- 安全性:
- tutorial/security/index.md
+ - tutorial/security/first-steps.md
- tutorial/security/get-current-user.md
- tutorial/security/simple-oauth2.md
- tutorial/security/oauth2-jwt.md
@@ -106,6 +107,7 @@ nav:
- advanced/additional-status-codes.md
- advanced/response-directly.md
- advanced/custom-response.md
+ - advanced/response-cookies.md
- contributing.md
- help-fastapi.md
- benchmarks.md
@@ -126,6 +128,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
+- attr_list
+- md_in_html
extra:
analytics:
provider: google
diff --git a/docs_src/security/tutorial007.py b/docs_src/security/tutorial007.py
index 90b9ac054..790ee10bc 100644
--- a/docs_src/security/tutorial007.py
+++ b/docs_src/security/tutorial007.py
@@ -9,9 +9,17 @@ security = HTTPBasic()
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
- correct_username = secrets.compare_digest(credentials.username, "stanleyjobson")
- correct_password = secrets.compare_digest(credentials.password, "swordfish")
- if not (correct_username and correct_password):
+ current_username_bytes = credentials.username.encode("utf8")
+ correct_username_bytes = b"stanleyjobson"
+ is_correct_username = secrets.compare_digest(
+ current_username_bytes, correct_username_bytes
+ )
+ current_password_bytes = credentials.password.encode("utf8")
+ correct_password_bytes = b"swordfish"
+ is_correct_password = secrets.compare_digest(
+ current_password_bytes, correct_password_bytes
+ )
+ if not (is_correct_username and is_correct_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
diff --git a/fastapi/__init__.py b/fastapi/__init__.py
index e5cdbeb09..3dc86cadf 100644
--- a/fastapi/__init__.py
+++ b/fastapi/__init__.py
@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
-__version__ = "0.79.0"
+__version__ = "0.80.0"
from starlette import status as status
diff --git a/fastapi/applications.py b/fastapi/applications.py
index 19e3215fb..356a43d88 100644
--- a/fastapi/applications.py
+++ b/fastapi/applications.py
@@ -291,7 +291,7 @@ class FastAPI(Starlette):
path: str,
endpoint: Callable[..., Coroutine[Any, Any, Response]],
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -349,7 +349,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -452,7 +452,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -507,7 +507,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -562,7 +562,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -617,7 +617,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -672,7 +672,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -727,7 +727,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -782,7 +782,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
@@ -837,7 +837,7 @@ class FastAPI(Starlette):
self,
path: str,
*,
- response_model: Optional[Type[Any]] = None,
+ response_model: Any = None,
status_code: Optional[int] = None,
tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py
index f397e333c..f6151f6bd 100644
--- a/fastapi/dependencies/utils.py
+++ b/fastapi/dependencies/utils.py
@@ -161,7 +161,6 @@ def get_sub_dependant(
)
if security_requirement:
sub_dependant.security_requirements.append(security_requirement)
- sub_dependant.security_scopes = security_scopes
return sub_dependant
@@ -278,7 +277,13 @@ def get_dependant(
path_param_names = get_path_param_names(path)
endpoint_signature = get_typed_signature(call)
signature_params = endpoint_signature.parameters
- dependant = Dependant(call=call, name=name, path=path, use_cache=use_cache)
+ dependant = Dependant(
+ call=call,
+ name=name,
+ path=path,
+ security_scopes=security_scopes,
+ use_cache=use_cache,
+ )
for param_name, param in signature_params.items():
if isinstance(param.default, params.Depends):
sub_dependant = get_param_sub_dependant(
@@ -495,7 +500,6 @@ async def solve_dependencies(
name=sub_dependant.name,
security_scopes=sub_dependant.security_scopes,
)
- use_sub_dependant.security_scopes = sub_dependant.security_scopes
solved_result = await solve_dependencies(
request=request,
diff --git a/fastapi/encoders.py b/fastapi/encoders.py
index 4b7ffe313..b1fde73ce 100644
--- a/fastapi/encoders.py
+++ b/fastapi/encoders.py
@@ -80,6 +80,11 @@ def jsonable_encoder(
return obj
if isinstance(obj, dict):
encoded_dict = {}
+ allowed_keys = set(obj.keys())
+ if include is not None:
+ allowed_keys &= set(include)
+ if exclude is not None:
+ allowed_keys -= set(exclude)
for key, value in obj.items():
if (
(
@@ -88,7 +93,7 @@ def jsonable_encoder(
or (not key.startswith("_sa"))
)
and (value is not None or not exclude_none)
- and ((include and key in include) or not exclude or key not in exclude)
+ and key in allowed_keys
):
encoded_key = jsonable_encoder(
key,
@@ -144,6 +149,8 @@ def jsonable_encoder(
raise ValueError(errors)
return jsonable_encoder(
data,
+ include=include,
+ exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
diff --git a/fastapi/openapi/docs.py b/fastapi/openapi/docs.py
index 68d62b020..f8d693727 100644
--- a/fastapi/openapi/docs.py
+++ b/fastapi/openapi/docs.py
@@ -116,12 +116,14 @@ def get_redoc_html(
def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse:
+ # copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html
html = """
-
+
-
-
-
+
+