mirror of
https://github.com/fastapi/sqlmodel.git
synced 2025-08-15 02:07:54 +08:00
🔧 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:

committed by
GitHub

parent
71baff6015
commit
a95bd3873d
@ -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
|
||||
|
||||
|
@ -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`).
|
||||
|
||||
|
@ -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]!}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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`
|
||||
|
||||
|
@ -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! 😎
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
Reference in New Issue
Block a user