mirror of
https://github.com/fastapi/sqlmodel.git
synced 2026-03-13 09:29:54 +08:00
📝 Update link syntax to minimal Markdown
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
One of the use cases where **SQLModel** shines the most, and the main one why it was built, was to be combined with **FastAPI**. ✨
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/" class="external-link" target="_blank">FastAPI</a> is a Python web framework for building web APIs created by the same <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">author</a> of SQLModel. FastAPI is also built on top of **Pydantic**.
|
||||
[FastAPI](https://fastapi.tiangolo.com/) is a Python web framework for building web APIs created by the same [author](https://twitter.com/tiangolo) of SQLModel. FastAPI is also built on top of **Pydantic**.
|
||||
|
||||
In this group of chapters we will see how to combine SQLModel **table models** representing tables in the SQL database as all the ones we have seen up to now, with **data models** that only represent data (which are actually just Pydantic models behind the scenes).
|
||||
|
||||
@@ -14,4 +14,4 @@ By the end we will have a **simple** but **complete** web **API** to interact wi
|
||||
|
||||
If you have never used FastAPI, maybe a good idea would be to go and study it a bit before continuing.
|
||||
|
||||
Just reading and trying the examples on the <a href="https://fastapi.tiangolo.com/" class="external-link" target="_blank">FastAPI main page</a> should be enough, and it shouldn't take you more than **10 minutes**.
|
||||
Just reading and trying the examples on the [FastAPI main page](https://fastapi.tiangolo.com/) should be enough, and it shouldn't take you more than **10 minutes**.
|
||||
|
||||
@@ -36,9 +36,9 @@ This way, a client can decide to take fewer heroes if they want, but not more.
|
||||
|
||||
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>
|
||||
* [Query Parameters](https://fastapi.tiangolo.com/tutorial/query-params/)
|
||||
* [Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/)
|
||||
* [Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/)
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ This will validate that all the data that we promised is there and will remove 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>.
|
||||
You can read more about it in the [FastAPI docs about Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ We want to get the hero based on the `id`, so we will use a **path parameter** `
|
||||
|
||||
/// 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>.
|
||||
If you need to refresh how *path parameters* work, including their data validation, check the [FastAPI docs about Path Parameters](https://fastapi.tiangolo.com/tutorial/path-params/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ And the same way, we declared the `TeamPublic` with only the same base fields of
|
||||
|
||||
{* ./docs_src/tutorial/fastapi/teams/tutorial001_py310.py ln[5:7,20:21,29:34,43:44] hl[5:7,20:21,29:34,43:44] *}
|
||||
|
||||
Now, remember that <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">FastAPI uses the `response_model` to validate and **filter** the response data</a>?
|
||||
Now, remember that [FastAPI uses the `response_model` to validate and **filter** the response data](https://fastapi.tiangolo.com/tutorial/response-model/)?
|
||||
|
||||
In this case, we used `response_model=TeamPublic` and `response_model=HeroPublic`, so FastAPI will use them to filter the response data, even if we return a **table model** that includes **relationship attributes**:
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Up to now, with the code we have used, the API docs know the data the clients ha
|
||||
|
||||
<img class="shadow" alt="Interactive API docs UI" src="/img/tutorial/fastapi/simple-hero-api/image01.png">
|
||||
|
||||
This interactive docs UI is powered by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>, and what Swagger UI does is to read a big JSON content that defines the API with all the data schemas (data shapes) using the standard <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md" class="external-link" target="_blank">OpenAPI</a>, and showing it in that nice <abbr title="User Interface">UI</abbr>.
|
||||
This interactive docs UI is powered by [Swagger UI](https://github.com/swagger-api/swagger-ui), and what Swagger UI does is to read a big JSON content that defines the API with all the data schemas (data shapes) using the standard [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md), and showing it in that nice <abbr title="User Interface">UI</abbr>.
|
||||
|
||||
FastAPI automatically **generates that OpenAPI** for Swagger UI to read it.
|
||||
|
||||
@@ -48,7 +48,7 @@ FastAPI will do data validation and filtering of the response with this `respons
|
||||
|
||||
So this works like a contract between our application and the client.
|
||||
|
||||
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>.
|
||||
You can read more about it in the [FastAPI docs about `response_model`](https://fastapi.tiangolo.com/tutorial/response-model/).
|
||||
|
||||
## New API Docs UI
|
||||
|
||||
@@ -62,7 +62,7 @@ The clients will know what data they should expect.
|
||||
|
||||
The most visible advantage of using the `response_model` is that it shows up in the API docs UI.
|
||||
|
||||
But there are other advantages, like that FastAPI will do automatic <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">data validation and filtering</a> of the response data using this model.
|
||||
But there are other advantages, like that FastAPI will do automatic [data validation and filtering](https://fastapi.tiangolo.com/tutorial/response-model/) of the response data using this model.
|
||||
|
||||
Additionally, because the schemas are defined in using a standard, there are many tools that can take advantage of this.
|
||||
|
||||
@@ -72,7 +72,7 @@ For example, client generators, that can automatically create the code necessary
|
||||
|
||||
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>.
|
||||
You can read about all that in the [FastAPI docs - First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/#openapi).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Up to now, we have been creating a session in each *path operation*, in a `with`
|
||||
|
||||
{* ./docs_src/tutorial/fastapi/delete/tutorial001_py310.py ln[48:55] hl[50] *}
|
||||
|
||||
That's perfectly fine, but in many use cases we would want to use <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI Dependencies</a>, for example to **verify** that the client is **logged in** and get the **current user** before executing any other code in the *path operation*.
|
||||
That's perfectly fine, but in many use cases we would want to use [FastAPI Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/), for example to **verify** that the client is **logged in** and get the **current user** before executing any other code in the *path operation*.
|
||||
|
||||
These dependencies are also very useful during **testing**, because we can **easily replace them**, and then, for example, use a new database for our tests, or put some data before the tests, etc.
|
||||
|
||||
@@ -38,7 +38,7 @@ Here we are passing the parameter `session` that has a "default value" of `Depen
|
||||
|
||||
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>
|
||||
You can read more about it in the FastAPI documentation [Path Parameters and Numeric Validations - Order the parameters as you need, tricks](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks)
|
||||
|
||||
///
|
||||
|
||||
@@ -86,4 +86,4 @@ You just learned how to use **FastAPI dependencies** to handle the database sess
|
||||
|
||||
And you will see how much these dependencies can help the more you work with FastAPI, to handle **permissions**, **authentication**, resources like database **sessions**, etc. 🚀
|
||||
|
||||
If you want to learn more about dependencies, checkout the <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI docs about Dependencies</a>.
|
||||
If you want to learn more about dependencies, checkout the [FastAPI docs about Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/).
|
||||
|
||||
@@ -8,7 +8,7 @@ The first step is to install FastAPI.
|
||||
|
||||
FastAPI is the framework to create the **web API**.
|
||||
|
||||
Make sure you create a [virtual environment](../../virtual-environments.md){.internal-link target=_blank}, activate it, and then install them, for example with:
|
||||
Make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install them, for example with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -42,7 +42,7 @@ And we also need to disable it because in **FastAPI** each request could be hand
|
||||
|
||||
/// 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>.
|
||||
That's enough information for now, you can read more about it in the [FastAPI docs for `async` and `await`](https://fastapi.tiangolo.com/async/).
|
||||
|
||||
The main point is, by ensuring you **don't share** the same **session** with more than one request, the code is already safe.
|
||||
|
||||
@@ -70,7 +70,7 @@ This should be called only once at startup, not before every request, so we put
|
||||
|
||||
/// 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>.
|
||||
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 [FastAPI First Steps docs](https://fastapi.tiangolo.com/tutorial/first-steps/).
|
||||
|
||||
///
|
||||
|
||||
@@ -84,9 +84,9 @@ It will be called when a user sends a request with a `POST` **operation** to the
|
||||
|
||||
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>
|
||||
* [First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/)
|
||||
* [Path Parameters - Data Validation and Data Conversion](https://fastapi.tiangolo.com/tutorial/path-params/)
|
||||
* [Request Body](https://fastapi.tiangolo.com/tutorial/body/)
|
||||
|
||||
///
|
||||
|
||||
@@ -132,7 +132,7 @@ But we would **never want to *share* the same session** among different requests
|
||||
|
||||
In this simple example, we just create the new sessions manually in the **path operation functions**.
|
||||
|
||||
In future examples later we will use a <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI Dependency</a> to get the **session**, being able to share it with other dependencies and being able to replace it during testing. 🤓
|
||||
In future examples later we will use a [FastAPI Dependency](https://fastapi.tiangolo.com/tutorial/dependencies/) to get the **session**, being able to share it with other dependencies and being able to replace it during testing. 🤓
|
||||
|
||||
## Run the **FastAPI** Server in Development Mode
|
||||
|
||||
@@ -154,7 +154,7 @@ $ fastapi dev main.py
|
||||
|
||||
/// info
|
||||
|
||||
The `fastapi` command uses <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> underneath.
|
||||
The `fastapi` command uses [Uvicorn](https://www.uvicorn.org/) underneath.
|
||||
|
||||
///
|
||||
|
||||
@@ -180,7 +180,7 @@ $ fastapi run main.py
|
||||
|
||||
Now you can go to that URL in your browser `http://127.0.0.1:8000`. We didn't create a *path operation* for the root path `/`, so that URL alone will only show a "Not Found" error... that "Not Found" error is produced by your FastAPI application.
|
||||
|
||||
But you can go to the **automatically generated interactive API documentation** at the path `/docs`: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. ✨
|
||||
But you can go to the **automatically generated interactive API documentation** at the path `/docs`: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs). ✨
|
||||
|
||||
You will see that this **automatic API docs <abbr title="user interface">UI</abbr>** has the *paths* that we defined above with their *operations*, and that it already knows the shape of the data that the **path operations** will receive:
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Now we will see how useful it is to have this session dependency. ✨
|
||||
|
||||
## File Structure
|
||||
|
||||
Now we will have a Python project with multiple files, one file `main.py` with all the application, and one file `test_main.py` with the tests, with the same ideas from [Code Structure and Multiple Files](../code-structure.md){.internal-link target=_blank}.
|
||||
Now we will have a Python project with multiple files, one file `main.py` with all the application, and one file `test_main.py` with the tests, with the same ideas from [Code Structure and Multiple Files](../code-structure.md).
|
||||
|
||||
The file structure is:
|
||||
|
||||
@@ -32,11 +32,11 @@ The file structure is:
|
||||
|
||||
## Testing FastAPI Applications
|
||||
|
||||
If you haven't done testing in FastAPI applications, first check the <a href="https://fastapi.tiangolo.com/tutorial/testing/" class="external-link" target="_blank">FastAPI docs about Testing</a>.
|
||||
If you haven't done testing in FastAPI applications, first check the [FastAPI docs about Testing](https://fastapi.tiangolo.com/tutorial/testing/).
|
||||
|
||||
Then, we can continue here, the first step is to install the dependencies, `requests` and `pytest`.
|
||||
|
||||
Make sure you create a [virtual environment](../../virtual-environments.md){.internal-link target=_blank}, activate it, and then install them, for example with:
|
||||
Make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install them, for example with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -144,7 +144,7 @@ Here we create all the tables in the testing database with:
|
||||
SQLModel.metadata.create_all(engine)
|
||||
```
|
||||
|
||||
But remember that [Order Matters](../create-db-and-table.md#sqlmodel-metadata-order-matters){.internal-link target=_blank} and we need to make sure all the **SQLModel** models are already defined and **imported** before calling `.create_all()`.
|
||||
But remember that [Order Matters](../create-db-and-table.md#sqlmodel-metadata-order-matters) and we need to make sure all the **SQLModel** models are already defined and **imported** before calling `.create_all()`.
|
||||
|
||||
In this case, it all works for a little subtlety that deserves some attention.
|
||||
|
||||
@@ -230,7 +230,7 @@ Let's use these **fixtures** to improve our code and reduce de duplicated boiler
|
||||
|
||||
## Pytest Fixtures
|
||||
|
||||
You can read more about them in the <a href="https://docs.pytest.org/en/6.2.x/fixture.html" class="external-link" target="_blank">pytest docs for fixtures</a>, but I'll give you a short example for what we need here.
|
||||
You can read more about them in the [pytest docs for fixtures](https://docs.pytest.org/en/6.2.x/fixture.html), but I'll give you a short example for what we need here.
|
||||
|
||||
Let's see the first code example with a fixture:
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ So, the thief won't be able to try to use that password in another system (as ma
|
||||
|
||||
/// tip
|
||||
|
||||
You could use <a href="https://passlib.readthedocs.io/en/stable/" class="external-link" target="_blank">passlib</a> to hash passwords.
|
||||
You could use [passlib](https://passlib.readthedocs.io/en/stable/) to hash passwords.
|
||||
|
||||
In this example we will use a fake hashing function to focus on the data changes. 🤡
|
||||
|
||||
|
||||
Reference in New Issue
Block a user