From d692c28f52a5390468bad0f321c24dc0173c08ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 14 Jan 2019 19:23:38 +0400 Subject: [PATCH] :memo: Add docs for bigger applications and APIRouter and update tests to match docs --- .../tutorial/bigger-applications/image01.png | Bin 0 -> 61037 bytes .../app/{tutorial003.py => main.py} | 4 +- .../app/routers/{tutorial002.py => items.py} | 4 +- .../app/routers/{tutorial001.py => users.py} | 6 +- docs/tutorial/bigger-applications.md | 279 +++++++++++++++++- .../{test_tutorial003.py => test_main.py} | 31 +- 6 files changed, 300 insertions(+), 24 deletions(-) create mode 100644 docs/img/tutorial/bigger-applications/image01.png rename docs/src/bigger_applications/app/{tutorial003.py => main.py} (53%) rename docs/src/bigger_applications/app/routers/{tutorial002.py => items.py} (75%) rename docs/src/bigger_applications/app/routers/{tutorial001.py => users.py} (68%) rename tests/test_tutorial/test_bigger_applications/{test_tutorial003.py => test_main.py} (96%) diff --git a/docs/img/tutorial/bigger-applications/image01.png b/docs/img/tutorial/bigger-applications/image01.png new file mode 100644 index 0000000000000000000000000000000000000000..78544b4034199b100cf5431b16b367fc85d135f2 GIT binary patch literal 61037 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 literal 0 HcmV?d00001 diff --git a/docs/src/bigger_applications/app/tutorial003.py b/docs/src/bigger_applications/app/main.py similarity index 53% rename from docs/src/bigger_applications/app/tutorial003.py rename to docs/src/bigger_applications/app/main.py index 4c2a348db..4e614a007 100644 --- a/docs/src/bigger_applications/app/tutorial003.py +++ b/docs/src/bigger_applications/app/main.py @@ -1,7 +1,7 @@ from fastapi import FastAPI -from .routers.tutorial001 import router as users_router -from .routers.tutorial002 import router as items_router +from .routers.items import router as items_router +from .routers.users import router as users_router app = FastAPI() diff --git a/docs/src/bigger_applications/app/routers/tutorial002.py b/docs/src/bigger_applications/app/routers/items.py similarity index 75% rename from docs/src/bigger_applications/app/routers/tutorial002.py rename to docs/src/bigger_applications/app/routers/items.py index 46a241902..2297e2d27 100644 --- a/docs/src/bigger_applications/app/routers/tutorial002.py +++ b/docs/src/bigger_applications/app/routers/items.py @@ -3,11 +3,11 @@ from fastapi import APIRouter router = APIRouter() -@router.get("/") +@router.get("/", tags=["items"]) async def read_items(): return [{"name": "Item Foo"}, {"name": "item Bar"}] -@router.get("/{item_id}") +@router.get("/{item_id}", tags=["items"]) async def read_item(item_id: str): return {"name": "Fake Specific Item", "item_id": item_id} diff --git a/docs/src/bigger_applications/app/routers/tutorial001.py b/docs/src/bigger_applications/app/routers/users.py similarity index 68% rename from docs/src/bigger_applications/app/routers/tutorial001.py rename to docs/src/bigger_applications/app/routers/users.py index 37e3fbc4a..e88b20cd1 100644 --- a/docs/src/bigger_applications/app/routers/tutorial001.py +++ b/docs/src/bigger_applications/app/routers/users.py @@ -3,16 +3,16 @@ from fastapi import APIRouter router = APIRouter() -@router.get("/users/") +@router.get("/users/", tags=["users"]) async def read_users(): return [{"username": "Foo"}, {"username": "Bar"}] -@router.get("/users/me") +@router.get("/users/me", tags=["users"]) async def read_user_me(): return {"username": "fakecurrentuser"} -@router.get("/users/{username}") +@router.get("/users/{username}", tags=["users"]) async def read_user(username: str): return {"username": username} diff --git a/docs/tutorial/bigger-applications.md b/docs/tutorial/bigger-applications.md index 056dcbbbf..81ebb0440 100644 --- a/docs/tutorial/bigger-applications.md +++ b/docs/tutorial/bigger-applications.md @@ -1,13 +1,284 @@ -Coming soon... +If you are building an application or a web API, it's rarely the case that you can put everything on a single file. + +**FastAPI** provides a convenience tool to structure your application while keeping all the flexibility. + + +## An example file structure + +Let's say you have a file structure like this: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── routers +│   ├── __init__.py +│   ├── items.py +│   └── users.py +``` + +!!! tip + There are two `__init__.py` files: one in each directory or subdirectory. + + This is what allows importing code from one file into another. + + For example, in `app/main.py` you could have a line like: + + ``` + from app.routers import items + ``` + + +* The `app` directory contains everything. +* This `app` directory has an empty file `app/__init__.py`. + * So, the `app` directory is a "Python package" (a collection of "Python modules"). +* The `app` directory also has a `app/main.py` file. + * As it is inside a Python package directory (because there's a file `__init__.py`), it is a "module" of that package: `app.main`. +* There's a subdirectory `app/routers/`. +* The subdirectory `app/routers` also has an empty file `__init__.py`. + * So, it is a "Python subpackage". +* The file `app/routers/items.py` is beside the `app/routers/__init__.py`. + * So, it's a submodule: `app.routers.items`. +* The file `app/routers/users.py` is beside the `app/routers/__init__.py`. + * So, it's a submodule: `app.routers.users`. + + +## `APIRouter` + +Let's say the file dedicated to handling just users is the submodule at `/app/routers/users.py`. + +You want to have the *path operations* related to your users separated from the rest of the code, to keep it organized. + +But it's still part of the same **FastAPI** application/web API (it's part of the same "Python Package"). + +You can create the *path operations* for that module using `APIRouter`. + + +### Import `APIRouter` + +You import it and create an "instance" the same way you would with the class `FastAPI`: + +```Python hl_lines="1 3" +{!./src/bigger_applications/app/routers/users.py!} +``` + + +### Path operations with `APIRouter` + +And then you use it to declare your *path operations*. + +Use it the same way you would use the `FastAPI` class: + +```Python hl_lines="6 11 16" +{!./src/bigger_applications/app/routers/users.py!} +``` + +You can think of `APIRouter` as a "mini `FastAPI`" class. + +All the same options are supported. + +All the same parameters, responses, dependencies, tags, etc. + +!!! tip + In this example, the variable is called `router`, but you can name it however you want. + +We are going to include this `APIrouter` in the main `FastAPI` app, but first, let's add another `APIRouter`. + + +## Another module with `APIRouter` + +Let's say you also have the endpoints dedicated to handling "Items" from your application in the module at `app/routers/items.py`. + +You have path operations for: + +* `/items/` +* `/items/{item_id}` + +It's all the same structure as with `app/routers/users.py`. + +But let's say that this time we are more lazy. + +And we don't want to have to explicitly type `/items/` in every path operation, we can do it later: + +```Python hl_lines="6 11 16" +{!./src/bigger_applications/app/routers/items.py!} +``` + + +## The main `FastAPI` + +Now, let's see the module at `app/main.py`. + +Here's where you import and use the class `FastAPI`. + +This will be the main file in your application that ties everything together. + +### Import `FastAPI` + +You import and create a `FastAPI` class as normally: + +```Python hl_lines="1 6" +{!./src/bigger_applications/app/main.py!} +``` + +### Import the `APIRouter` + +But this time we are not adding path operations directly with the `FastAPI` `app`. + +We import the `APIRouter`s from the other files: + +```Python hl_lines="3 4" +{!./src/bigger_applications/app/main.py!} +``` + +As the file `app/routers/items.py` is part of the same Python package, we can import it using "dot notation". + + +### How the importing works + +The section: ```Python -{!./src/bigger_applications/app/routers/tutorial001.py!} +from .routers.items import router ``` +Means: + +* Starting in the same package that this module (the file `app/main.py`) lives in (the directory `app/`)... +* look for the subpackage `routers` (the directory at `app/routers/`)... +* and from it, the submodule `items` (the file at `app/routers/items.py`)... +* and from that submodule, import the variable `router`. + +The variable `router` is the same one we created in the file `app/routers/items.py`. It's an `APIRouter`. + +We could also import it like: + ```Python -{!./src/bigger_applications/app/routers/tutorial002.py!} +from app.routers.items import router ``` +!!! info + The first version is a "relative import". + + The second version is an "absolute import". + + To learn more about Python Packages and Modules, read the official Python documentation about Modules. + + +### Avoid name collisions + +We are importing a variable named `router` from the submodule `items`. + +But we also have another variable named `router` in the submodule `users`. + +If we import one after the other, like: + ```Python -{!./src/bigger_applications/app/tutorial003.py!} +from .routers.items import router +from .routers.users import router +``` + +The `router` from `users` will overwrite the one form `items` and we won't be able to use them at the same time. + +So, to be able to use both of them in the same file, we rename them while importing them using `as`: + +```Python hl_lines="3 4" +{!./src/bigger_applications/app/main.py!} +``` + + +### Include an `APIRouter` + +Now, let's include the router from the submodule `users`, now in the variable `users_router`: + +```Python hl_lines="8" +{!./src/bigger_applications/app/main.py!} +``` + +With `app.include_router()` we can add an `APIRouter` to the main `FastAPI` application. + +It will include all the routes from that router as part of it. + +!!! note "Technical Details" + It will actually internally create a path operation for each path operation that was declared in the `APIRouter`. + + So, behind the scenes, it will actually work as if everything was the same single app. + + +!!! check + You don't have to worry about performance when including routers. + + This will take microseconds and will only happen at startup. + + So it won't affect performance. + + +### Include an `APIRouter` with a prefix + +Now, let's include the router form the `items` submodule, now in the variable `items_router`. + +But, remember that we were lazy and didn't add `/items/` to all the path operations? + +We can add a prefix to all the path operations using the parameter `prefix` of `app.include_router()`. + +As the path of each path operation has to start with `/`, like in: + +```Python hl_lines="1" +@router.get("/{item_id}", tags=["items"]) +async def read_item(item_id: str): + ... +``` + +...the prefix must not include a final `/`. + +So, the prefix in this case would be `/items`: + +```Python hl_lines="9" +{!./src/bigger_applications/app/main.py!} +``` + +The end result is that the item paths are now: + +* `/items/` +* `/items/{item_id}` + +...as we intended. + +!!! check + The `prefix` parameter is (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication. + + +!!! tip + You could also add path operations directly, for example with: `@app.get(...)`. + + Apart from `app.include_router()`, in the same **FastAPI** app. + + It would still work the same. + + +!!! info "Very Technical Details" + **Note**: this is a very technical detail that you probably can **just skip**. + + --- + + The `APIRouter`s are not "mounted", they are not isolated from the rest of the application. + + This is because we want to include their path operations in the OpenAPI schema and the user interfaces. + + As we cannot just isolate them and "mount" them independently of the rest, the path operations are "cloned" (re-created), not included directly. + + +## Check the automatic API docs + +Now, run `uvicorn`, using the module `app.main` and the variable `app`: + +```bash +uvicorn app.main:app --debug ``` + +And open the docs at http://127.0.0.1:8000/docs. + +You will see the automatic API docs, including the paths from all the submodules: + + diff --git a/tests/test_tutorial/test_bigger_applications/test_tutorial003.py b/tests/test_tutorial/test_bigger_applications/test_main.py similarity index 96% rename from tests/test_tutorial/test_bigger_applications/test_tutorial003.py rename to tests/test_tutorial/test_bigger_applications/test_main.py index 680bc8efe..eb68c4492 100644 --- a/tests/test_tutorial/test_bigger_applications/test_tutorial003.py +++ b/tests/test_tutorial/test_bigger_applications/test_main.py @@ -1,7 +1,7 @@ import pytest from starlette.testclient import TestClient -from bigger_applications.app.tutorial003 import app +from bigger_applications.app.main import app client = TestClient(app) @@ -17,10 +17,24 @@ openapi_schema = { "content": {"application/json": {"schema": {}}}, } }, + "tags": ["users"], "summary": "Read Users Get", "operationId": "read_users_users__get", } }, + "/users/me": { + "get": { + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + } + }, + "tags": ["users"], + "summary": "Read User Me Get", + "operationId": "read_user_me_users_me_get", + } + }, "/users/{username}": { "get": { "responses": { @@ -39,6 +53,7 @@ openapi_schema = { }, }, }, + "tags": ["users"], "summary": "Read User Get", "operationId": "read_user_users__username__get", "parameters": [ @@ -51,18 +66,6 @@ openapi_schema = { ], } }, - "/users/me": { - "get": { - "responses": { - "200": { - "description": "Successful Response", - "content": {"application/json": {"schema": {}}}, - } - }, - "summary": "Read User Me Get", - "operationId": "read_user_me_users_me_get", - } - }, "/items/": { "get": { "responses": { @@ -71,6 +74,7 @@ openapi_schema = { "content": {"application/json": {"schema": {}}}, } }, + "tags": ["items"], "summary": "Read Items Get", "operationId": "read_items_items__get", } @@ -93,6 +97,7 @@ openapi_schema = { }, }, }, + "tags": ["items"], "summary": "Read Item Get", "operationId": "read_item_items__item_id__get", "parameters": [