]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:memo: Improve explanation of dependencies
authorSebastián Ramírez <tiangolo@gmail.com>
Tue, 1 Jan 2019 15:27:02 +0000 (19:27 +0400)
committerSebastián Ramírez <tiangolo@gmail.com>
Tue, 1 Jan 2019 15:27:02 +0000 (19:27 +0400)
docs/src/dependencies/tutorial001.py
docs/tutorial/dependencies/first-steps-functions.md [deleted file]
docs/tutorial/dependencies/first-steps.md [new file with mode: 0644]
docs/tutorial/dependencies/intro.md [deleted file]
mkdocs.yml
tests/test_tutorial/test_dependencies/test_tutorial001.py

index 32ef351dab7c9e65d3094e6cb6f0f0aed156b14d..131a471a1d62122f8793fb34348c71785102ecac 100644 (file)
@@ -10,3 +10,8 @@ async def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
 @app.get("/items/")
 async def read_items(commons: dict = Depends(common_parameters)):
     return commons
+
+
+@app.get("/users/")
+async def read_users(commons: dict = Depends(common_parameters)):
+    return commons
diff --git a/docs/tutorial/dependencies/first-steps-functions.md b/docs/tutorial/dependencies/first-steps-functions.md
deleted file mode 100644 (file)
index f736a91..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-Let's see a very simple example of the **Dependency Injection** system.
-
-It will be so simple that it is not very useful, for now.
-
-But this way we can focus on how the **Dependency Injection** system works.
-
-In the next chapters we'll extend it to see how can it be so useful.
-
-## Create a dependency, or "dependable"
-
-Let's first focus on the dependency.
-
-It is just a function that can take all the same parameters that a path operation function can take:
-
-```Python hl_lines="6 7"
-{!./src/dependencies/tutorial001.py!}
-```
-
-That's it.
-
-**2 lines**.
-
-And it has the same shape and structure that all your path operation functions.
-
-You can think of it as a path operation function without the "decorator" (without the `@app.get("/some-path")`).
-
-And it can return anything you want.
-
-In this case, this dependency expects:
-
-* An optional query parameter `q` that is a `str`.
-* An optional query parameter `skip` that is an `int`, and by default is `0`.
-* An optional query parameter `limit` that is an `int`, and by default is `100`.
-
-And then it just returns a `dict` containing those values.
-
-## Import `Depends`
-
-```Python hl_lines="1"
-{!./src/dependencies/tutorial001.py!}
-```
-
-## Declare the dependency, in the "dependant"
-
-The same way you use `Body`, `Query`, etc. with your path operation function parameters, use `Depends` with a new parameter:
-
-```Python hl_lines="11"
-{!./src/dependencies/tutorial001.py!}
-```
-
-Although you use it in the parameters of your function too, `Depends` works a bit differently.
-
-You only give `Depends` a single parameter.
-
-This parameter must be a function with the same parameters that can be taken by a path operation function.
-
-Whenever a new request arrives, **FastAPI** will take care of:
-
-* Calling your dependency ("dependable") function with the correct parameters.
-* Get the result from your function.
-* Assign that result to the parameter in your path operation function.
-
-!!! note
-    Notice that you don't have to create a special class and pass it somewhere to **FastAPI** or anything similar.
-
-    You just pass it to `Depends` and **FastAPI** knows how to do the rest.
-
-## To `async` or not to `async`
-
-As dependencies will also be called by **FastAPI** (the same as your path operation functions), the same rules apply while defining your functions.
-
-You can use `async def` or normal `def`.
-
-And you can declare dependencies with `async def` inside of normal `def` path operation functions, or `def` dependencies inside of `async def` path operation functions.
-
-It doesn't matter. **FastAPI** will know what to do.
-
-!!! note
-    If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
-
-## Integrated wiht OpenAPI
-
-All the request declarations, validations and requirements of your dependencies (and sub-dependencies) will be integrated in the same OpenAPI schema.
-
-So, the interactive docs will have all the information they need, while you keep all the flexibility of the dependencies:
-
-<img src="/img/tutorial/dependencies/image01.png">
-
-## Recap
-
-Create Dependencies with **2 lines** of code.
\ No newline at end of file
diff --git a/docs/tutorial/dependencies/first-steps.md b/docs/tutorial/dependencies/first-steps.md
new file mode 100644 (file)
index 0000000..7a19618
--- /dev/null
@@ -0,0 +1,167 @@
+**FastAPI** has a very powerful but intuitive **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
+
+It is designed to be very simple to use, and to make it very easy for any developer to integrate other components with **FastAPI**.
+
+## "Dependency Injection"?
+
+**"Dependency Injection"** means, in programming, that there is a way for your code (in this case, your path operation functions) to declare things that it requires to work and use: "dependencies".
+
+And then, that system (in this case **FastAPI**) will take care of doing whatever is needed to provide your code with those needed dependencies ("inject" the dependencies).
+
+This is very useful when you need to:
+
+* Have shared logic (the same code logic again and again).
+* Share database connections.
+* Enforce security, authentication, role requirements, etc.
+* etc.
+
+All these, while minimizing code repetition.
+
+
+## First Steps
+
+Let's see a very simple example. It will be so simple that it is not very useful, for now.
+
+But this way we can focus on how the **Dependency Injection** system works.
+
+
+### Create a dependency, or "dependable"
+
+Let's first focus on the dependency.
+
+It is just a function that can take all the same parameters that a path operation function can take:
+
+```Python hl_lines="6 7"
+{!./src/dependencies/tutorial001.py!}
+```
+
+That's it.
+
+**2 lines**.
+
+And it has the same shape and structure that all your path operation functions.
+
+You can think of it as a path operation function without the "decorator" (without the `@app.get("/some-path")`).
+
+And it can return anything you want.
+
+In this case, this dependency expects:
+
+* An optional query parameter `q` that is a `str`.
+* An optional query parameter `skip` that is an `int`, and by default is `0`.
+* An optional query parameter `limit` that is an `int`, and by default is `100`.
+
+And then it just returns a `dict` containing those values.
+
+### Import `Depends`
+
+```Python hl_lines="1"
+{!./src/dependencies/tutorial001.py!}
+```
+
+### Declare the dependency, in the "dependant"
+
+The same way you use `Body`, `Query`, etc. with your path operation function parameters, use `Depends` with a new parameter:
+
+```Python hl_lines="11 16"
+{!./src/dependencies/tutorial001.py!}
+```
+
+Although you use `Depends` in the parameters of your function the same way you use `Body`, `Query`, etc, `Depends` works a bit differently.
+
+You only give `Depends` a single parameter.
+
+This parameter must be something like a function.
+
+And that function takes parameters in the same way that path operation functions do.
+
+!!! tip
+    You'll see what other "things", apart from functions, can be used as dependencies in the next chapter.
+
+Whenever a new request arrives, **FastAPI** will take care of:
+
+* Calling your dependency ("dependable") function with the correct parameters.
+* Get the result from your function.
+* Assign that result to the parameter in your path operation function.
+
+!!! note
+    Notice that you don't have to create a special class and pass it somewhere to **FastAPI** to "register" it or anything similar.
+
+    You just pass it to `Depends` and **FastAPI** knows how to do the rest.
+
+## To `async` or not to `async`
+
+As dependencies will also be called by **FastAPI** (the same as your path operation functions), the same rules apply while defining your functions.
+
+You can use `async def` or normal `def`.
+
+And you can declare dependencies with `async def` inside of normal `def` path operation functions, or `def` dependencies inside of `async def` path operation functions, etc.
+
+It doesn't matter. **FastAPI** will know what to do.
+
+!!! note
+    If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
+
+
+## Integrated with OpenAPI
+
+All the request declarations, validations and requirements of your dependencies (and sub-dependencies) will be integrated in the same OpenAPI schema.
+
+So, the interactive docs will have all the information from these dependencies too:
+
+<img src="/img/tutorial/dependencies/image01.png">
+
+
+## Simple usage
+
+If you look at it, *path operation functions* are declared to be used whenever a *path* and *operation* matches, and then **FastAPI** takes care of calling the function with the correct parameters and use the response.
+
+Actually, all (or most) of the web frameworks work in this same way.
+
+You never call those functions directly. They are called by your framework (in this case, **FastAPI**).
+
+With the Dependency Injection system, you can also tell **FastAPI** that your path operation function also "depends" on something else that should be executed before your *path operation function*, and **FastAPI** will take care of executing it and "injecting" the results.
+
+Other common terms for this same idea of "dependency injection" are:
+
+* resources
+* providers
+* services
+* injectables
+* components
+
+## **FastAPI** plug-ins
+
+Integrations and "plug-in"s can be built using the **Dependency Injection** system. But in fact, there is actually **no need to create "plug-ins"**, as by using dependencies it's possible to declare an infinite number of integrations and interactions that become available to your path operation functions.
+
+And dependencies can be created in a very simple and intuitive way that allow you to just import the Python packages you need, and integrate them with your API functions in a couple of lines of code, _literally_.
+
+You will see examples of this in the next chapters, about relational and NoSQL databases, security, etc.
+
+## **FastAPI** compatibility
+
+The simplicity of the dependency injection system makes **FastAPI** compatible with:
+
+* all the relational databases
+* NoSQL databases
+* external packages
+* external APIs
+* authentication and authorization systems
+* API usage monitoring systems
+* response data injection systems
+* etc.
+
+
+## Simple and Powerful
+
+Although the hierarchical dependency injection system is very simple to define and use, it's still very powerful.
+
+You can define dependencies that in turn can define dependencies themselves.
+
+In the end, a hierarchical tree of dependencies is built, and the **Dependency Injection** system takes care of solving all these dependencies for you (and your dependencies) and providing (injecting) the results at each step.
+
+## Integrated with **OpenAPI**
+
+All these dependencies, while declaring their requirements, add parameters, validations, etc. to your path operations. 
+
+**FastAPI** will take care of adding it all to the OpenAPI schema, so that it is shown in the interactive documentation systems.
diff --git a/docs/tutorial/dependencies/intro.md b/docs/tutorial/dependencies/intro.md
deleted file mode 100644 (file)
index 486d9a7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-**FastAPI** has a very powerful but intuitive **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
-
-It is designed to be very simple to use, and to make it very easy for any developer to integrate other components with **FastAPI**.
-
-## "Dependency Injection"?
-
-**"Dependency Injection"** means, in programming, that there is a way for your code (in this case, your path operation functions) to declare things that it requires to work and use.
-
-And then, that system (in this case **FastAPI**) will take care of doing whatever is needed to provide your code with that thing that it needs.
-
-If you look at it, path operation functions are declared to be used whenever a path and operation matches, and then **FastAPI** will take care of calling the function with the correct parameters and use the response.
-
-Actually, all (or most) of the web frameworks work in this same way.
-
-You never call those functions directly. They are called by your framework (in this case, **FastAPI**).
-
-With the Dependency Injection system, you can also tell **FastAPI** that your path operation function also "depends" on something else that should be executed before your path operation function, and **FastAPI** will take care of executing it and "injecting" the results.
-
-Other common terms for this same idea are:
-
-* resources
-* providers
-* services
-* injectables
-
-## **FastAPI** plug-ins
-
-Integrations and "plug-in"s can be built using the **Dependency Injection** system. But in fact, there is actually **no need to create "plug-ins"**, as by using dependencies it's possible to declare an infinite number of integrations and interactions that become available to your path operation functions.
-
-And dependencies can be created in a very simple and intuitive way that allow you to just import the Python packages you need, and integrate them with your API functions in a couple of lines of code, _literally_.
-
-## **FastAPI** compatibility
-
-The simplicity of the dependency injection system makes **FastAPI** compatible with:
-
-* all the relational databases
-* NoSQL databases
-* external packages
-* external APIs
-* authentication and authorization systems
-* API usage monitoring systems
-* response data injection systems
-* etc.
-
-
-## Simple and Powerful
-
-Although the hierarchical dependency injection system is very simple to define and use, it's still very powerful.
-
-You can define dependencies that in turn can define dependencies themselves.
-
-In the end, a hierarchical tree of dependencies is built, and the **Dependency Injection** system takes care of solving all these dependencies for you (and your dependencies) and providing the results at each step.
-
-## Integrated with **OpenAPI**
-
-All these dependencies, while declaring their requirements, might have been adding parameters, validations, etc. to your path operations. 
-
-**FastAPI** will take care of adding it all to the OpenAPI schema, so that it is shown in the interactive documentation systems.
index 4a9eb997436a3d394f5e0e83a796563957ef79da..6fe4d9763d084fa9552c54a99442877dfd8e6623 100644 (file)
@@ -23,8 +23,8 @@ nav:
         - Path Parameters: 'tutorial/path-params.md'
         - Query Parameters: 'tutorial/query-params.md'
         - Request Body: 'tutorial/body.md'
-        - Query Parameters - String Validations: 'tutorial/query-params-str-validations.md'
-        - Path Parameters - Numeric Validations: 'tutorial/path-params-numeric-validations.md'
+        - Query Parameters and String Validations: 'tutorial/query-params-str-validations.md'
+        - Path Parameters and Numeric Validations: 'tutorial/path-params-numeric-validations.md'
         - Body - Multiple Parameters: 'tutorial/body-multiple-params.md'
         - Body - Schema: 'tutorial/body-schema.md'
         - Body - Nested Models: 'tutorial/body-nested-models.md'
@@ -40,8 +40,7 @@ nav:
         - Path Operation Advanced Configuration: 'tutorial/path-operation-advanced-configuration.md'
         - Custom Response: 'tutorial/custom-response.md'
         - Dependencies:
-            - Dependencies Intro: 'tutorial/dependencies/intro.md'
-            - First Steps - Functions: 'tutorial/dependencies/first-steps-functions.md'
+            - First Steps: 'tutorial/dependencies/first-steps.md'
             - Classes as Dependencies: 'tutorial/dependencies/classes-as-dependencies.md'
             - Sub-dependencies: 'tutorial/dependencies/sub-dependencies.md'
             - Advanced Dependencies: 'tutorial/dependencies/advanced-dependencies.md'
index 94c164f4edb91430da0194e26b720a7595553700..b15ceb90164ab21cf028fc443d75457363fa6e24 100644 (file)
@@ -50,7 +50,49 @@ openapi_schema = {
                     },
                 ],
             }
-        }
+        },
+        "/users/": {
+            "get": {
+                "responses": {
+                    "200": {
+                        "description": "Successful Response",
+                        "content": {"application/json": {"schema": {}}},
+                    },
+                    "422": {
+                        "description": "Validation Error",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/HTTPValidationError"
+                                }
+                            }
+                        },
+                    },
+                },
+                "summary": "Read Users Get",
+                "operationId": "read_users_users__get",
+                "parameters": [
+                    {
+                        "required": False,
+                        "schema": {"title": "Q", "type": "string"},
+                        "name": "q",
+                        "in": "query",
+                    },
+                    {
+                        "required": False,
+                        "schema": {"title": "Skip", "type": "integer", "default": 0},
+                        "name": "skip",
+                        "in": "query",
+                    },
+                    {
+                        "required": False,
+                        "schema": {"title": "Limit", "type": "integer", "default": 100},
+                        "name": "limit",
+                        "in": "query",
+                    },
+                ],
+            }
+        },
     },
     "components": {
         "schemas": {
@@ -97,6 +139,7 @@ def test_openapi_schema():
         ("/items?q=foo", 200, {"q": "foo", "skip": 0, "limit": 100}),
         ("/items?q=foo&skip=5", 200, {"q": "foo", "skip": 5, "limit": 100}),
         ("/items?q=foo&skip=5&limit=30", 200, {"q": "foo", "skip": 5, "limit": 30}),
+        ("/users", 200, {"q": None, "skip": 0, "limit": 100}),
         ("/openapi.json", 200, openapi_schema),
     ],
 )