🔧 Update config with new pymdown extensions (#712)

* 🔧 Update config with new pymdown extensions

* 📝 Update admonition blocks syntax

* 📝 Update syntax for tabs with new pymdown extensions
This commit is contained in:
Sebastián Ramírez
2023-11-28 21:50:33 +01:00
committed by GitHub
parent 71baff6015
commit a95bd3873d
39 changed files with 702 additions and 353 deletions

View File

@ -8,8 +8,11 @@ So, we probably want to limit it.
Let's use the same **offset** and **limit** we learned about in the previous tutorial chapters for the API.
!!! info
In many cases, this is also called **pagination**.
/// info
In many cases, this is also called **pagination**.
///
## Add a Limit and Offset to the Query Parameters
@ -46,12 +49,15 @@ So, to prevent it, we add additional validation to the `limit` query parameter,
This way, a client can decide to take fewer heroes if they want, but not more.
!!! info
If you need to refresh how query parameters and their validation work, check out the docs in FastAPI:
/// info
* <a href="https://fastapi.tiangolo.com/tutorial/query-params/" class="external-link" target="_blank">Query Parameters</a>
* <a href="https://fastapi.tiangolo.com/tutorial/query-params-str-validations/" class="external-link" target="_blank">Query Parameters and String Validations</a>
* <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/" class="external-link" target="_blank">Path Parameters and Numeric Validations</a>
If you need to refresh how query parameters and their validation work, check out the docs in FastAPI:
* <a href="https://fastapi.tiangolo.com/tutorial/query-params/" class="external-link" target="_blank">Query Parameters</a>
* <a href="https://fastapi.tiangolo.com/tutorial/query-params-str-validations/" class="external-link" target="_blank">Query Parameters and String Validations</a>
* <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/" class="external-link" target="_blank">Path Parameters and Numeric Validations</a>
///
## Check the Docs UI

View File

@ -136,8 +136,11 @@ But `HeroCreate` and `HeroRead` don't have `table = True`. They are only **data
This also means that `SQLModel.metadata.create_all()` won't create tables in the database for `HeroCreate` and `HeroRead`, because they don't have `table = True`, which is exactly what we want. 🚀
!!! tip
We will improve this code to avoid duplicating the fields, but for now we can continue learning with these models.
/// tip
We will improve this code to avoid duplicating the fields, but for now we can continue learning with these models.
///
## Use Multiple Models to Create a Hero
@ -208,10 +211,13 @@ And now that we return it, FastAPI will validate the data with the `response_mod
This will validate that all the data that we promised is there and will remove any data we didn't declare.
!!! tip
This filtering could be very important and could be a very good security feature, for example, to make sure you filter private data, hashed passwords, etc.
/// tip
You can read more about it in the <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">FastAPI docs about Response Model</a>.
This filtering could be very important and could be a very good security feature, for example, to make sure you filter private data, hashed passwords, etc.
You can read more about it in the <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">FastAPI docs about Response Model</a>.
///
In particular, it will make sure that the `id` is there and that it is indeed an integer (and not `None`).

View File

@ -8,8 +8,11 @@ Let's add a new *path operation* to read one single hero.
We want to get the hero based on the `id`, so we will use a **path parameter** `hero_id`.
!!! info
If you need to refresh how *path parameters* work, including their data validation, check the <a href="https://fastapi.tiangolo.com/tutorial/path-params/" class="external-link" target="_blank">FastAPI docs about Path Parameters</a>.
/// info
If you need to refresh how *path parameters* work, including their data validation, check the <a href="https://fastapi.tiangolo.com/tutorial/path-params/" class="external-link" target="_blank">FastAPI docs about Path Parameters</a>.
///
```Python hl_lines="8"
{!./docs_src/tutorial/fastapi/read_one/tutorial001.py[ln:1-4]!}

View File

@ -100,10 +100,13 @@ Additionally, because the schemas are defined in using a standard, there are man
For example, client generators, that can automatically create the code necessary to talk to your API in many languages.
!!! info
If you are curious about the standards, FastAPI generates OpenAPI, that internally uses JSON Schema.
/// info
You can read about all that in the <a href="https://fastapi.tiangolo.com/tutorial/first-steps/#openapi" class="external-link" target="_blank">FastAPI docs - First Steps</a>.
If you are curious about the standards, FastAPI generates OpenAPI, that internally uses JSON Schema.
You can read about all that in the <a href="https://fastapi.tiangolo.com/tutorial/first-steps/#openapi" class="external-link" target="_blank">FastAPI docs - First Steps</a>.
///
## Recap

View File

@ -81,14 +81,17 @@ We import `Depends()` from `fastapi`. Then we use it in the *path operation func
</details>
!!! tip
Here's a tip about that `*,` thing in the parameters.
/// tip
Here we are passing the parameter `session` that has a "default value" of `Depends(get_session)` before the parameter `hero`, that doesn't have any default value.
Here's a tip about that `*,` thing in the parameters.
Python would normally complain about that, but we can use the initial "parameter" `*,` to mark all the rest of the parameters as "keyword only", which solves the problem.
Here we are passing the parameter `session` that has a "default value" of `Depends(get_session)` before the parameter `hero`, that doesn't have any default value.
You can read more about it in the FastAPI documentation <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks" class="external-link" target="_blank">Path Parameters and Numeric Validations - Order the parameters as you need, tricks</a>
Python would normally complain about that, but we can use the initial "parameter" `*,` to mark all the rest of the parameters as "keyword only", which solves the problem.
You can read more about it in the FastAPI documentation <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks" class="external-link" target="_blank">Path Parameters and Numeric Validations - Order the parameters as you need, tricks</a>
///
The value of a dependency will **only be used for one request**, FastAPI will call it right before calling your code and will give you the value from that dependency.

View File

@ -62,10 +62,13 @@ But here we will make sure we don't share the same **session** in more than one
And we also need to disable it because in **FastAPI** each request could be handled by multiple interacting threads.
!!! info
That's enough information for now, you can read more about it in the <a href="https://fastapi.tiangolo.com/async/" class="external-link" target="_blank">FastAPI docs for `async` and `await`</a>.
/// info
The main point is, by ensuring you **don't share** the same **session** with more than one request, the code is already safe.
That's enough information for now, you can read more about it in the <a href="https://fastapi.tiangolo.com/async/" class="external-link" target="_blank">FastAPI docs for `async` and `await`</a>.
The main point is, by ensuring you **don't share** the same **session** with more than one request, the code is already safe.
///
## **FastAPI** App
@ -119,8 +122,11 @@ This should be called only once at startup, not before every request, so we put
## Create Heroes *Path Operation*
!!! info
If you need a refresher on what a **Path Operation** is (an endpoint with a specific HTTP Operation) and how to work with it in FastAPI, check out the <a href="https://fastapi.tiangolo.com/tutorial/first-steps/" class="external-link" target="_blank">FastAPI First Steps docs</a>.
/// info
If you need a refresher on what a **Path Operation** is (an endpoint with a specific HTTP Operation) and how to work with it in FastAPI, check out the <a href="https://fastapi.tiangolo.com/tutorial/first-steps/" class="external-link" target="_blank">FastAPI First Steps docs</a>.
///
Let's create the **path operation** code to create a new hero.
@ -143,12 +149,15 @@ It will be called when a user sends a request with a `POST` **operation** to the
</details>
!!! info
If you need a refresher on some of those concepts, checkout the FastAPI documentation:
/// info
* <a href="https://fastapi.tiangolo.com/tutorial/first-steps/" class="external-link" target="_blank">First Steps</a>
* <a href="https://fastapi.tiangolo.com/tutorial/path-params/" class="external-link" target="_blank">Path Parameters - Data Validation and Data Conversion</a>
* <a href="https://fastapi.tiangolo.com/tutorial/body/" class="external-link" target="_blank">Request Body</a>
If you need a refresher on some of those concepts, checkout the FastAPI documentation:
* <a href="https://fastapi.tiangolo.com/tutorial/first-steps/" class="external-link" target="_blank">First Steps</a>
* <a href="https://fastapi.tiangolo.com/tutorial/path-params/" class="external-link" target="_blank">Path Parameters - Data Validation and Data Conversion</a>
* <a href="https://fastapi.tiangolo.com/tutorial/body/" class="external-link" target="_blank">Request Body</a>
///
## The **SQLModel** Advantage
@ -162,8 +171,11 @@ And then, because this same **SQLModel** object is not only a **Pydantic** model
So we can use intuitive standard Python **type annotations**, and we don't have to duplicate a lot of the code for the database models and the API data models. 🎉
!!! tip
We will improve this further later, but for now, it already shows the power of having **SQLModel** classes be both **SQLAlchemy** models and **Pydantic** models at the same time.
/// tip
We will improve this further later, but for now, it already shows the power of having **SQLModel** classes be both **SQLAlchemy** models and **Pydantic** models at the same time.
///
## Read Heroes *Path Operation*
@ -226,11 +238,14 @@ $ uvicorn main:app
</div>
!!! info
The command `uvicorn main:app` refers to:
/// info
* `main`: the file `main.py` (the Python "module").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
The command `uvicorn main:app` refers to:
* `main`: the file `main.py` (the Python "module").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
///
### Uvicorn `--reload`

View File

@ -71,8 +71,11 @@ Let's start with a simple test, with just the basic test code we need the check
{!./docs_src/tutorial/fastapi/app_testing/tutorial001/annotations/en/test_main_001.md!}
!!! tip
Check out the number bubbles to see what is done by each line of code.
/// tip
Check out the number bubbles to see what is done by each line of code.
///
That's the **core** of the code we need for all the tests later.
@ -116,8 +119,11 @@ That way we protect the production database and we have better control of the da
{!./docs_src/tutorial/fastapi/app_testing/tutorial001/annotations/en/test_main_002.md!}
!!! tip
Check out the number bubbles to see what is done by each line of code.
/// tip
Check out the number bubbles to see what is done by each line of code.
///
## Create the Engine and Session for Testing
@ -197,8 +203,11 @@ We just have to change a couple of parameters in the **engine**.
{!./docs_src/tutorial/fastapi/app_testing/tutorial001/annotations/en/test_main_004.md!}
!!! tip
Check out the number bubbles to see what is done by each line of code.
/// tip
Check out the number bubbles to see what is done by each line of code.
///
That's it, now the test will run using the **in-memory database**, which will be faster and probably safer.
@ -214,8 +223,11 @@ Do we really have to duplicate all that for **each test**? No, we can do better!
We are using **pytest** to run the tests. And pytest also has a very similar concept to the **dependencies in FastAPI**.
!!! info
In fact, pytest was one of the things that inspired the design of the dependencies in FastAPI.
/// info
In fact, pytest was one of the things that inspired the design of the dependencies in FastAPI.
///
It's a way for us to declare some **code that should be run before** each test and **provide a value** for the test function (that's pretty much the same as FastAPI dependencies).
@ -237,8 +249,11 @@ Let's see the first code example with a fixture:
{!./docs_src/tutorial/fastapi/app_testing/tutorial001/annotations/en/test_main_005.md!}
!!! tip
Check out the number bubbles to see what is done by each line of code.
/// tip
Check out the number bubbles to see what is done by each line of code.
///
**pytest** fixtures work in a very similar way to FastAPI dependencies, but have some minor differences:
@ -274,8 +289,11 @@ So, we can create a **client fixture** that will be used in all the tests, and i
{!./docs_src/tutorial/fastapi/app_testing/tutorial001/annotations/en/test_main_006.md!}
!!! tip
Check out the number bubbles to see what is done by each line of code.
/// tip
Check out the number bubbles to see what is done by each line of code.
///
Now we have a **client fixture** that, in turn, uses the **session fixture**.
@ -306,10 +324,13 @@ Let's add some more tests:
</details>
!!! tip
It's always **good idea** to not only test the normal case, but also that **invalid data**, **errors**, and **corner cases** are handled correctly.
/// tip
That's why we add these two extra tests here.
It's always **good idea** to not only test the normal case, but also that **invalid data**, **errors**, and **corner cases** are handled correctly.
That's why we add these two extra tests here.
///
Now, any additional test functions can be as **simple** as the first one, they just have to **declare the `client` parameter** to get the `TestClient` **fixture** with all the database stuff setup. Nice! 😎

View File

@ -12,10 +12,13 @@ So, we need to have all those fields **marked as optional**.
And because the `HeroBase` has some of them as *required* and not optional, we will need to **create a new model**.
!!! tip
Here is one of those cases where it probably makes sense to use an **independent model** instead of trying to come up with a complex tree of models inheriting from each other.
/// tip
Because each field is **actually different** (we just change it to `Optional`, but that's already making it different), it makes sense to have them in their own model.
Here is one of those cases where it probably makes sense to use an **independent model** instead of trying to come up with a complex tree of models inheriting from each other.
Because each field is **actually different** (we just change it to `Optional`, but that's already making it different), it makes sense to have them in their own model.
///
So, let's create this new `HeroUpdate` model: