From 1f01ce9615fe83ea5235820266e3a78ae8768847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 28 Jun 2020 20:13:30 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Use=20Optional=20in=20docs=20(#1?= =?UTF-8?q?644)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated .py files with Optional tag (up to body_nested_models) * Update optionals * docs_src/ all updates, few I was unsure of * Updated markdown files with Optional param * es: Add Optional typing to index.md * Last of markdown files updated with Optional param * Update highlight lines * it: Add Optional typings * README.md: Update with Optional typings * Update more highlight increments * Update highlights * schema-extra-example.md: Update highlights * updating highlighting on website to reflect .py changes * Update highlighting for query-params & response-directly * Address PR comments * Get rid of unnecessary comment * ⏪ Revert Optional in Chinese docs as it probably also requires changes in text * 🎨 Apply format * ⏪ Revert modified example * ♻️ Simplify example in docs * 📝 Update OpenAPI callback example to use Optional * ✨ Add Optional types to tests * 📝 Update docs about query params, default to using Optional * 🎨 Update code examples line highlighting * 📝 Update nested models docs to use "type parameters" instead of "subtypes" * 📝 Add notes about FastAPI usage of None including: = None and = Query(None) and clarify relationship with Optional[str] * 📝 Add note about response_model_by_alias * ♻️ Simplify query param list example * 🔥 Remove test for removed example * ✅ Update test for updated example Co-authored-by: Christopher Nguyen Co-authored-by: yk396 Co-authored-by: Kai Chen --- README.md | 18 ++-- docs/en/docs/advanced/additional-responses.md | 4 +- .../docs/advanced/additional-status-codes.md | 2 +- docs/en/docs/advanced/openapi-callbacks.md | 8 +- docs/en/docs/advanced/response-directly.md | 2 +- docs/en/docs/advanced/testing-dependencies.md | 2 +- docs/en/docs/advanced/websockets.md | 2 +- docs/en/docs/deployment.md | 4 +- docs/en/docs/index.md | 18 ++-- docs/en/docs/tutorial/background-tasks.md | 2 +- docs/en/docs/tutorial/body-fields.md | 4 +- docs/en/docs/tutorial/body-multiple-params.md | 12 +-- docs/en/docs/tutorial/body-nested-models.md | 18 ++-- docs/en/docs/tutorial/body.md | 17 ++-- docs/en/docs/tutorial/cookie-params.md | 4 +- .../dependencies/classes-as-dependencies.md | 14 +-- docs/en/docs/tutorial/dependencies/index.md | 6 +- .../tutorial/dependencies/sub-dependencies.md | 6 +- docs/en/docs/tutorial/encoder.md | 2 +- docs/en/docs/tutorial/extra-data-types.md | 4 +- docs/en/docs/tutorial/extra-models.md | 4 +- docs/en/docs/tutorial/handling-errors.md | 2 +- docs/en/docs/tutorial/header-params.md | 6 +- .../path-params-numeric-validations.md | 4 +- .../tutorial/query-params-str-validations.md | 52 +++++++--- docs/en/docs/tutorial/query-params.md | 46 ++------- docs/en/docs/tutorial/response-model.md | 20 ++-- docs/en/docs/tutorial/schema-extra-example.md | 6 +- docs/en/docs/tutorial/security/oauth2-jwt.md | 8 +- .../docs/tutorial/security/simple-oauth2.md | 10 +- docs/es/docs/index.md | 11 ++- docs/it/docs/index.md | 11 ++- docs/pt/docs/index.md | 16 ++-- docs/ru/docs/index.md | 18 ++-- docs/zh/docs/deployment.md | 4 +- docs/zh/docs/index.md | 18 ++-- docs_src/additional_responses/tutorial002.py | 4 +- docs_src/additional_responses/tutorial004.py | 4 +- .../additional_status_codes/tutorial001.py | 6 +- docs_src/app_testing/main_b.py | 4 +- docs_src/background_tasks/tutorial002.py | 4 +- docs_src/body/tutorial001.py | 6 +- docs_src/body/tutorial002.py | 6 +- docs_src/body/tutorial003.py | 6 +- docs_src/body/tutorial004.py | 8 +- docs_src/body_fields/tutorial001.py | 8 +- docs_src/body_multiple_params/tutorial001.py | 10 +- docs_src/body_multiple_params/tutorial002.py | 8 +- docs_src/body_multiple_params/tutorial003.py | 8 +- docs_src/body_multiple_params/tutorial004.py | 10 +- docs_src/body_multiple_params/tutorial005.py | 6 +- docs_src/body_nested_models/tutorial001.py | 6 +- docs_src/body_nested_models/tutorial002.py | 6 +- docs_src/body_nested_models/tutorial003.py | 6 +- docs_src/body_nested_models/tutorial004.py | 8 +- docs_src/body_nested_models/tutorial005.py | 8 +- docs_src/body_nested_models/tutorial006.py | 8 +- docs_src/body_nested_models/tutorial007.py | 10 +- docs_src/body_updates/tutorial001.py | 8 +- docs_src/body_updates/tutorial002.py | 8 +- docs_src/cookie_params/tutorial001.py | 4 +- docs_src/dependencies/tutorial001.py | 4 +- docs_src/dependencies/tutorial002.py | 4 +- docs_src/dependencies/tutorial003.py | 4 +- docs_src/dependencies/tutorial004.py | 4 +- docs_src/dependencies/tutorial005.py | 6 +- docs_src/dependency_testing/tutorial001.py | 6 +- docs_src/encoder/tutorial001.py | 3 +- docs_src/extra_data_types/tutorial001.py | 9 +- docs_src/extra_models/tutorial001.py | 8 +- docs_src/extra_models/tutorial002.py | 4 +- docs_src/header_params/tutorial001.py | 4 +- docs_src/header_params/tutorial002.py | 6 +- docs_src/header_params/tutorial003.py | 4 +- docs_src/openapi_callbacks/tutorial001.py | 6 +- .../tutorial004.py | 6 +- .../tutorial001.py | 6 +- .../tutorial002.py | 6 +- .../tutorial003.py | 6 +- .../tutorial004.py | 6 +- .../tutorial005.py | 6 +- .../tutorial001.py | 4 +- docs_src/query_params/tutorial002.py | 4 +- docs_src/query_params/tutorial003.py | 4 +- docs_src/query_params/tutorial004.py | 4 +- docs_src/query_params/tutorial006.py | 6 +- docs_src/query_params/tutorial007.py | 11 --- .../tutorial001.py | 4 +- .../tutorial002.py | 4 +- .../tutorial003.py | 4 +- .../tutorial004.py | 4 +- .../tutorial007.py | 6 +- .../tutorial008.py | 4 +- .../tutorial009.py | 4 +- .../tutorial010.py | 4 +- .../tutorial011.py | 4 +- .../tutorial013.py | 2 +- docs_src/response_directly/tutorial001.py | 3 +- docs_src/response_model/tutorial001.py | 6 +- docs_src/response_model/tutorial002.py | 4 +- docs_src/response_model/tutorial003.py | 6 +- docs_src/response_model/tutorial004.py | 4 +- docs_src/response_model/tutorial005.py | 4 +- docs_src/response_model/tutorial006.py | 4 +- docs_src/schema_extra_example/tutorial001.py | 6 +- docs_src/schema_extra_example/tutorial002.py | 6 +- docs_src/schema_extra_example/tutorial003.py | 6 +- docs_src/security/tutorial003.py | 8 +- docs_src/security/tutorial004.py | 11 ++- docs_src/security/tutorial005.py | 12 +-- docs_src/sql_databases/sql_app/schemas.py | 4 +- .../sql_databases_peewee/sql_app/schemas.py | 4 +- docs_src/websockets/tutorial002.py | 8 +- tests/main.py | 5 +- tests/test_callable_endpoint.py | 3 +- tests/test_dependency_overrides.py | 4 +- tests/test_extra_routes.py | 4 +- tests/test_filter_pydantic_sub_model.py | 4 +- tests/test_infer_param_optionality.py | 6 +- tests/test_invalid_sequence_param.py | 4 +- tests/test_jsonable_encoder.py | 3 +- tests/test_param_class.py | 4 +- tests/test_serialize_response.py | 4 +- tests/test_serialize_response_dataclass.py | 4 +- tests/test_serialize_response_model.py | 4 +- tests/test_skip_defaults.py | 2 +- tests/test_sub_callbacks.py | 6 +- .../test_query_params/test_tutorial007.py | 95 ------------------- .../test_tutorial013.py | 9 +- tests/test_validate_response.py | 4 +- tests/test_validate_response_dataclass.py | 4 +- 131 files changed, 535 insertions(+), 466 deletions(-) delete mode 100644 docs_src/query_params/tutorial007.py delete mode 100644 tests/test_tutorial/test_query_params/test_tutorial007.py diff --git a/README.md b/README.md index b74421fa9..4c863c71f 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ $ pip install uvicorn * Create a file `main.py` with: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -142,7 +144,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -151,7 +153,9 @@ def read_item(item_id: int, q: str = None): If your code uses `async` / `await`, use `async def`: -```Python hl_lines="7 12" +```Python hl_lines="9 14" +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -163,7 +167,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -241,7 +245,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request. Declare the body using standard Python types, thanks to Pydantic. -```Python hl_lines="2 7 8 9 10 23 24 25" +```Python hl_lines="4 9 10 11 12 25 26 27" +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -251,7 +257,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: Optional[bool] = None @app.get("/") @@ -260,7 +266,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs/en/docs/advanced/additional-responses.md b/docs/en/docs/advanced/additional-responses.md index 4b2abaada..c8d443c3c 100644 --- a/docs/en/docs/advanced/additional-responses.md +++ b/docs/en/docs/advanced/additional-responses.md @@ -168,7 +168,7 @@ You can use this same `responses` parameter to add different media types for the For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image: -```Python hl_lines="17 18 19 20 21 22 23 24 28" +```Python hl_lines="19 20 21 22 23 24 28" {!../../../docs_src/additional_responses/tutorial002.py!} ``` @@ -228,7 +228,7 @@ You can use that technique to re-use some predefined responses in your *path ope For example: -```Python hl_lines="11 12 13 14 15 24" +```Python hl_lines="13 14 15 16 17 26" {!../../../docs_src/additional_responses/tutorial004.py!} ``` diff --git a/docs/en/docs/advanced/additional-status-codes.md b/docs/en/docs/advanced/additional-status-codes.md index b9a32cfa3..eb6031953 100644 --- a/docs/en/docs/advanced/additional-status-codes.md +++ b/docs/en/docs/advanced/additional-status-codes.md @@ -14,7 +14,7 @@ But you also want it to accept new items. And when the items didn't exist before To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want: -```Python hl_lines="2 19" +```Python hl_lines="4 23" {!../../../docs_src/additional_status_codes/tutorial001.py!} ``` diff --git a/docs/en/docs/advanced/openapi-callbacks.md b/docs/en/docs/advanced/openapi-callbacks.md index 15c0ba2a1..4c3d97e38 100644 --- a/docs/en/docs/advanced/openapi-callbacks.md +++ b/docs/en/docs/advanced/openapi-callbacks.md @@ -31,7 +31,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query This part is pretty normal, most of the code is probably already familiar to you: -```Python hl_lines="8 9 10 11 12 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53" +```Python hl_lines="10 11 12 13 14 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54" {!../../../docs_src/openapi_callbacks/tutorial001.py!} ``` @@ -92,7 +92,7 @@ Because of that, you need to declare what will be the `default_response_class`, But as we are never calling `app.include_router(some_router)`, we need to set the `default_response_class` during creation of the `APIRouter`. -```Python hl_lines="3 24" +```Python hl_lines="5 26" {!../../../docs_src/openapi_callbacks/tutorial001.py!} ``` @@ -105,7 +105,7 @@ It should look just like a normal FastAPI *path operation*: * It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`. * And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`. -```Python hl_lines="15 16 17 20 21 27 28 29 30 31" +```Python hl_lines="17 18 19 22 23 29 30 31 32 33" {!../../../docs_src/openapi_callbacks/tutorial001.py!} ``` @@ -172,7 +172,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router: -```Python hl_lines="34" +```Python hl_lines="36" {!../../../docs_src/openapi_callbacks/tutorial001.py!} ``` diff --git a/docs/en/docs/advanced/response-directly.md b/docs/en/docs/advanced/response-directly.md index f1dca1812..f0ab2831d 100644 --- a/docs/en/docs/advanced/response-directly.md +++ b/docs/en/docs/advanced/response-directly.md @@ -31,7 +31,7 @@ For example, you cannot put a Pydantic model in a `JSONResponse` without first c For those cases, you can use the `jsonable_encoder` to convert your data before passing it to a response: -```Python hl_lines="4 6 20 21" +```Python hl_lines="6 7 21 22" {!../../../docs_src/response_directly/tutorial001.py!} ``` diff --git a/docs/en/docs/advanced/testing-dependencies.md b/docs/en/docs/advanced/testing-dependencies.md index f2c283947..0dc20afff 100644 --- a/docs/en/docs/advanced/testing-dependencies.md +++ b/docs/en/docs/advanced/testing-dependencies.md @@ -28,7 +28,7 @@ To override a dependency for testing, you put as a key the original dependency ( And then **FastAPI** will call that override instead of the original dependency. -```Python hl_lines="24 25 28" +```Python hl_lines="26 27 30" {!../../../docs_src/dependency_testing/tutorial001.py!} ``` diff --git a/docs/en/docs/advanced/websockets.md b/docs/en/docs/advanced/websockets.md index 6cacc2e6f..083c75752 100644 --- a/docs/en/docs/advanced/websockets.md +++ b/docs/en/docs/advanced/websockets.md @@ -98,7 +98,7 @@ In WebSocket endpoints you can import from `fastapi` and use: They work the same way as for other FastAPI endpoints/*path operations*: -```Python hl_lines="56 57 58 59 60 61 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79" +```Python hl_lines="58 59 60 61 62 63 64 65 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83" {!../../../docs_src/websockets/tutorial002.py!} ``` diff --git a/docs/en/docs/deployment.md b/docs/en/docs/deployment.md index 94ab1b90b..5e62d1e8d 100644 --- a/docs/en/docs/deployment.md +++ b/docs/en/docs/deployment.md @@ -161,6 +161,8 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] * Create a `main.py` file with: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -172,7 +174,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` diff --git a/docs/en/docs/index.md b/docs/en/docs/index.md index b74421fa9..4c863c71f 100644 --- a/docs/en/docs/index.md +++ b/docs/en/docs/index.md @@ -131,6 +131,8 @@ $ pip install uvicorn * Create a file `main.py` with: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -142,7 +144,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -151,7 +153,9 @@ def read_item(item_id: int, q: str = None): If your code uses `async` / `await`, use `async def`: -```Python hl_lines="7 12" +```Python hl_lines="9 14" +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -163,7 +167,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -241,7 +245,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request. Declare the body using standard Python types, thanks to Pydantic. -```Python hl_lines="2 7 8 9 10 23 24 25" +```Python hl_lines="4 9 10 11 12 25 26 27" +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -251,7 +257,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: Optional[bool] = None @app.get("/") @@ -260,7 +266,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs/en/docs/tutorial/background-tasks.md b/docs/en/docs/tutorial/background-tasks.md index 3771eff71..7ee8d8a78 100644 --- a/docs/en/docs/tutorial/background-tasks.md +++ b/docs/en/docs/tutorial/background-tasks.md @@ -57,7 +57,7 @@ Using `BackgroundTasks` also works with the dependency injection system, you can **FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards: -```Python hl_lines="11 14 20 23" +```Python hl_lines="13 15 22 25" {!../../../docs_src/background_tasks/tutorial002.py!} ``` diff --git a/docs/en/docs/tutorial/body-fields.md b/docs/en/docs/tutorial/body-fields.md index 91e6b1a10..444b90145 100644 --- a/docs/en/docs/tutorial/body-fields.md +++ b/docs/en/docs/tutorial/body-fields.md @@ -6,7 +6,7 @@ The same way you can declare additional validation and metadata in *path operati First, you have to import it: -```Python hl_lines="2" +```Python hl_lines="4" {!../../../docs_src/body_fields/tutorial001.py!} ``` @@ -17,7 +17,7 @@ First, you have to import it: You can then use `Field` with model attributes: -```Python hl_lines="9 10" +```Python hl_lines="11 12 13 14" {!../../../docs_src/body_fields/tutorial001.py!} ``` diff --git a/docs/en/docs/tutorial/body-multiple-params.md b/docs/en/docs/tutorial/body-multiple-params.md index 6d5e6e39d..48883e4cd 100644 --- a/docs/en/docs/tutorial/body-multiple-params.md +++ b/docs/en/docs/tutorial/body-multiple-params.md @@ -8,7 +8,7 @@ First, of course, you can mix `Path`, `Query` and request body parameter declara And you can also declare body parameters as optional, by setting the default to `None`: -```Python hl_lines="17 18 19" +```Python hl_lines="19 20 21" {!../../../docs_src/body_multiple_params/tutorial001.py!} ``` @@ -30,7 +30,7 @@ In the previous example, the *path operations* would expect a JSON body with the But you can also declare multiple body parameters, e.g. `item` and `user`: -```Python hl_lines="20" +```Python hl_lines="22" {!../../../docs_src/body_multiple_params/tutorial002.py!} ``` @@ -72,7 +72,7 @@ If you declare it as is, because it is a singular value, **FastAPI** will assume But you can instruct **FastAPI** to treat it as another body key using `Body`: -```Python hl_lines="21" +```Python hl_lines="23" {!../../../docs_src/body_multiple_params/tutorial003.py!} ``` @@ -104,12 +104,12 @@ Of course, you can also declare additional query parameters whenever you need, a As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do: ```Python -q: str = None +q: Optional[str] = None ``` as in: -```Python hl_lines="25" +```Python hl_lines="27" {!../../../docs_src/body_multiple_params/tutorial004.py!} ``` @@ -131,7 +131,7 @@ item: Item = Body(..., embed=True) as in: -```Python hl_lines="15" +```Python hl_lines="17" {!../../../docs_src/body_multiple_params/tutorial005.py!} ``` diff --git a/docs/en/docs/tutorial/body-nested-models.md b/docs/en/docs/tutorial/body-nested-models.md index 993389c90..987de42a8 100644 --- a/docs/en/docs/tutorial/body-nested-models.md +++ b/docs/en/docs/tutorial/body-nested-models.md @@ -6,15 +6,15 @@ With **FastAPI**, you can define, validate, document, and use arbitrarily deeply You can define an attribute to be a subtype. For example, a Python `list`: -```Python hl_lines="12" +```Python hl_lines="14" {!../../../docs_src/body_nested_models/tutorial001.py!} ``` This will make `tags` be a list of items. Although it doesn't declare the type of each of the items. -## List fields with subtype +## List fields with type parameter -But Python has a specific way to declare lists with subtypes: +But Python has a specific way to declare lists with internal types, or "type parameters": ### Import typing's `List` @@ -24,12 +24,12 @@ First, import `List` from standard Python's `typing` module: {!../../../docs_src/body_nested_models/tutorial002.py!} ``` -### Declare a `List` with a subtype +### Declare a `List` with a type parameter -To declare types that have subtypes, like `list`, `dict`, `tuple`: +To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`: * Import them from the `typing` module -* Pass the subtype(s) as "type arguments" using square brackets: `[` and `]` +* Pass the internal type(s) as "type parameters" using square brackets: `[` and `]` ```Python from typing import List @@ -39,7 +39,7 @@ my_list: List[str] That's all standard Python syntax for type declarations. -Use that same standard syntax for model attributes with subtypes. +Use that same standard syntax for model attributes with internal types. So, in our example, we can make `tags` be specifically a "list of strings": @@ -71,7 +71,7 @@ Each attribute of a Pydantic model has a type. But that type can itself be another Pydantic model. -So, you can declare deeply nested JSON `object`s with specific attribute names, types and validations. +So, you can declare deeply nested JSON "objects" with specific attribute names, types and validations. All that, arbitrarily nested. @@ -174,7 +174,7 @@ You can define arbitrarily deeply nested models: ``` !!! info - Notice how `Offer` as a list of `Item`s, which in turn have an optional list of `Image`s + Notice how `Offer` has a list of `Item`s, which in turn have an optional list of `Image`s ## Bodies of pure lists diff --git a/docs/en/docs/tutorial/body.md b/docs/en/docs/tutorial/body.md index b2cde0762..baa013809 100644 --- a/docs/en/docs/tutorial/body.md +++ b/docs/en/docs/tutorial/body.md @@ -17,7 +17,7 @@ To declare a **request** body, you use regular expression that the parameter should match: -```Python hl_lines="8" +```Python hl_lines="10" {!../../../docs_src/query_params_str_validations/tutorial004.py!} ``` @@ -104,13 +126,13 @@ q: str instead of: ```Python -q: str = None +q: Optional[str] = None ``` But we are now declaring it with `Query`, for example like: ```Python -q: str = Query(None, min_length=3) +q: Optional[str] = Query(None, min_length=3) ``` So, when you need to declare a value as required while using `Query`, you can use `...` as the first argument: @@ -211,13 +233,13 @@ That information will be included in the generated OpenAPI and used by the docum You can add a `title`: -```Python hl_lines="7" +```Python hl_lines="10" {!../../../docs_src/query_params_str_validations/tutorial007.py!} ``` And a `description`: -```Python hl_lines="11" +```Python hl_lines="13" {!../../../docs_src/query_params_str_validations/tutorial008.py!} ``` @@ -239,7 +261,7 @@ But you still need it to be exactly `item-query`... Then you can declare an `alias`, and that alias is what will be used to find the parameter value: -```Python hl_lines="7" +```Python hl_lines="9" {!../../../docs_src/query_params_str_validations/tutorial009.py!} ``` @@ -251,7 +273,7 @@ You have to leave it there a while because there are clients using it, but you w Then pass the parameter `deprecated=True` to `Query`: -```Python hl_lines="16" +```Python hl_lines="18" {!../../../docs_src/query_params_str_validations/tutorial010.py!} ``` diff --git a/docs/en/docs/tutorial/query-params.md b/docs/en/docs/tutorial/query-params.md index 0efc57e1b..d5dec36de 100644 --- a/docs/en/docs/tutorial/query-params.md +++ b/docs/en/docs/tutorial/query-params.md @@ -63,7 +63,7 @@ The parameter values in your function will be: The same way, you can declare optional query parameters, by setting their default to `None`: -```Python hl_lines="7" +```Python hl_lines="9" {!../../../docs_src/query_params/tutorial002.py!} ``` @@ -72,11 +72,16 @@ In this case, the function parameter `q` will be optional, and will be `None` by !!! check Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter. +!!! note + FastAPI will know that `q` is optional because of the `= None`. + + The `Optional` in `Optional[str]` is not used by FastAPI (FastAPI will only use the `str` part), but the `Optional[str]` will let your editor help you finding errors in your code. + ## Query parameter type conversion You can also declare `bool` types, and they will be converted: -```Python hl_lines="7" +```Python hl_lines="9" {!../../../docs_src/query_params/tutorial003.py!} ``` @@ -121,7 +126,7 @@ And you don't have to declare them in any specific order. They will be detected by name: -```Python hl_lines="6 8" +```Python hl_lines="8 10" {!../../../docs_src/query_params/tutorial004.py!} ``` @@ -179,7 +184,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy And of course, you can define some parameters as required, some as having a default value, and some entirely optional: -```Python hl_lines="7" +```Python hl_lines="10" {!../../../docs_src/query_params/tutorial006.py!} ``` @@ -191,36 +196,3 @@ In this case, there are 3 query parameters: !!! tip You could also use `Enum`s the same way as with [Path Parameters](path-params.md#predefined-values){.internal-link target=_blank}. - -## Optional type declarations - -!!! warning - This might be an advanced use case. - - You might want to skip it. - -If you are using `mypy` it could complain with type declarations like: - -```Python -limit: int = None -``` - -With an error like: - -``` -Incompatible types in assignment (expression has type "None", variable has type "int") -``` - -In those cases you can use `Optional` to tell `mypy` that the value could be `None`, like: - -```Python -from typing import Optional - -limit: Optional[int] = None -``` - -In a *path operation* that could look like: - -```Python hl_lines="9" -{!../../../docs_src/query_params/tutorial007.py!} -``` diff --git a/docs/en/docs/tutorial/response-model.md b/docs/en/docs/tutorial/response-model.md index dd76eca6e..b7201ee77 100644 --- a/docs/en/docs/tutorial/response-model.md +++ b/docs/en/docs/tutorial/response-model.md @@ -35,13 +35,13 @@ But most importantly: Here we are declaring a `UserIn` model, it will contain a plaintext password: -```Python hl_lines="7 9" +```Python hl_lines="9 11" {!../../../docs_src/response_model/tutorial002.py!} ``` And we are using this model to declare our input and the same model to declare our output: -```Python hl_lines="15 16" +```Python hl_lines="17 18" {!../../../docs_src/response_model/tutorial002.py!} ``` @@ -58,19 +58,19 @@ But if we use the same model for another *path operation*, we could be sending o We can instead create an input model with the plaintext password and an output model without it: -```Python hl_lines="7 9 14" +```Python hl_lines="9 11 16" {!../../../docs_src/response_model/tutorial003.py!} ``` Here, even though our *path operation function* is returning the same input user that contains the password: -```Python hl_lines="22" +```Python hl_lines="24" {!../../../docs_src/response_model/tutorial003.py!} ``` ...we declared the `response_model` to be our model `UserOut`, that doesn't include the password: -```Python hl_lines="20" +```Python hl_lines="22" {!../../../docs_src/response_model/tutorial003.py!} ``` @@ -94,9 +94,9 @@ Your response model could have default values, like: {!../../../docs_src/response_model/tutorial004.py!} ``` -* `description: str = None` has a default of `None`. +* `description: Optional[str] = None` has a default of `None`. * `tax: float = 10.5` has a default of `10.5`. -* `tags: List[str] = []` has a default of an empty list: `[]`. +* `tags: List[str] = []` as a default of an empty list: `[]`. but you might want to omit them from the result if they were not actually stored. @@ -183,7 +183,9 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan This is because the JSON Schema generated in your app's OpenAPI (and the docs) will still be the one for the complete model, even if you use `response_model_include` or `response_model_exclude` to omit some attributes. -```Python hl_lines="29 35" + This also applies to `response_model_by_alias` that works similarly. + +```Python hl_lines="31 37" {!../../../docs_src/response_model/tutorial005.py!} ``` @@ -196,7 +198,7 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan If you forget to use a `set` and use a `list` or `tuple` instead, FastAPI will still convert it to a `set` and it will work correctly: -```Python hl_lines="29 35" +```Python hl_lines="31 37" {!../../../docs_src/response_model/tutorial006.py!} ``` diff --git a/docs/en/docs/tutorial/schema-extra-example.md b/docs/en/docs/tutorial/schema-extra-example.md index 8a497ccd5..d0f1b843e 100644 --- a/docs/en/docs/tutorial/schema-extra-example.md +++ b/docs/en/docs/tutorial/schema-extra-example.md @@ -10,7 +10,7 @@ There are several ways you can declare extra JSON Schema information. You can declare an example for a Pydantic model using `Config` and `schema_extra`, as described in Pydantic's docs: Schema customization: -```Python hl_lines="13 14 15 16 17 18 19 20 21" +```Python hl_lines="15 16 17 18 19 20 21 22 23" {!../../../docs_src/schema_extra_example/tutorial001.py!} ``` @@ -20,7 +20,7 @@ That extra info will be added as-is to the output JSON Schema. In `Field`, `Path`, `Query`, `Body` and others you'll see later, you can also declare extra info for the JSON Schema by passing any other arbitrary arguments to the function, for example, to add an `example`: -```Python hl_lines="2 8 9 10 11" +```Python hl_lines="4 10 11 12 13" {!../../../docs_src/schema_extra_example/tutorial002.py!} ``` @@ -33,7 +33,7 @@ The same way you can pass extra info to `Field`, you can do the same with `Path` For example, you can pass an `example` for a body request to `Body`: -```Python hl_lines="19 20 21 22 23 24" +```Python hl_lines="21 22 23 24 25 26" {!../../../docs_src/schema_extra_example/tutorial003.py!} ``` diff --git a/docs/en/docs/tutorial/security/oauth2-jwt.md b/docs/en/docs/tutorial/security/oauth2-jwt.md index 18b4e0e30..b1147cb4c 100644 --- a/docs/en/docs/tutorial/security/oauth2-jwt.md +++ b/docs/en/docs/tutorial/security/oauth2-jwt.md @@ -100,7 +100,7 @@ And another utility to verify if a received password matches the hash stored. And another one to authenticate and return a user. -```Python hl_lines="7 48 55 56 59 60 69 70 71 72 73 74 75" +```Python hl_lines="8 49 56 57 60 61 70 71 72 73 74 75 76" {!../../../docs_src/security/tutorial004.py!} ``` @@ -135,7 +135,7 @@ Define a Pydantic Model that will be used in the token endpoint for the response Create a utility function to generate a new access token. -```Python hl_lines="3 6 12 13 14 28 29 30 78 79 80 81 82 83 84 85 86" +```Python hl_lines="4 7 13 14 15 29 30 31 79 80 81 82 83 84 85 86 87" {!../../../docs_src/security/tutorial004.py!} ``` @@ -147,7 +147,7 @@ Decode the received token, verify it, and return the current user. If the token is invalid, return an HTTP error right away. -```Python hl_lines="89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106" +```Python hl_lines="90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107" {!../../../docs_src/security/tutorial004.py!} ``` @@ -157,7 +157,7 @@ Create a `timedelta` with the expiration time of the token. Create a real JWT access token and return it. -```Python hl_lines="115 116 117 118 119 120 121 122 123 124 125 126 127 128" +```Python hl_lines="116 117 118 119 120 121 122 123 124 125 126 127 128 129" {!../../../docs_src/security/tutorial004.py!} ``` diff --git a/docs/en/docs/tutorial/security/simple-oauth2.md b/docs/en/docs/tutorial/security/simple-oauth2.md index c95c6aa6b..2f58a6d10 100644 --- a/docs/en/docs/tutorial/security/simple-oauth2.md +++ b/docs/en/docs/tutorial/security/simple-oauth2.md @@ -49,7 +49,7 @@ Now let's use the utilities provided by **FastAPI** to handle this. First, import `OAuth2PasswordRequestForm`, and use it as a dependency with `Depends` for the path `/token`: -```Python hl_lines="2 74" +```Python hl_lines="4 76" {!../../../docs_src/security/tutorial003.py!} ``` @@ -90,7 +90,7 @@ If there is no such user, we return an error saying "incorrect username or passw For the error, we use the exception `HTTPException`: -```Python hl_lines="1 75 76 77" +```Python hl_lines="3 77 78 79" {!../../../docs_src/security/tutorial003.py!} ``` @@ -118,7 +118,7 @@ If your database is stolen, the thief won't have your users' plaintext passwords So, the thief won't be able to try to use those same passwords in another system (as many users use the same password everywhere, this would be dangerous). -```Python hl_lines="78 79 80 81" +```Python hl_lines="80 81 82 83" {!../../../docs_src/security/tutorial003.py!} ``` @@ -156,7 +156,7 @@ For this simple example, we are going to just be completely insecure and return But for now, let's focus on the specific details we need. -```Python hl_lines="83" +```Python hl_lines="85" {!../../../docs_src/security/tutorial003.py!} ``` @@ -181,7 +181,7 @@ Both of these dependencies will just return an HTTP error if the user doesn't ex So, in our endpoint, we will only get a user if the user exists, was correctly authenticated, and is active: -```Python hl_lines="56 57 58 59 60 61 62 63 64 65 67 68 69 70 88" +```Python hl_lines="58 59 60 61 62 63 64 65 66 67 69 70 71 72 90" {!../../../docs_src/security/tutorial003.py!} ``` diff --git a/docs/es/docs/index.md b/docs/es/docs/index.md index e795f9578..c2690b140 100644 --- a/docs/es/docs/index.md +++ b/docs/es/docs/index.md @@ -131,6 +131,7 @@ $ pip install uvicorn ```Python from fastapi import FastAPI +from typing import Optional app = FastAPI() @@ -141,7 +142,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -152,6 +153,7 @@ Si tu código usa `async` / `await`, usa `async def`: ```Python hl_lines="7 12" from fastapi import FastAPI +from typing import Optional app = FastAPI() @@ -162,7 +164,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -243,6 +245,7 @@ Declara el body usando las declaraciones de tipo estándares de Python gracias a ```Python hl_lines="2 7 8 9 10 23 24 25" from fastapi import FastAPI from pydantic import BaseModel +from typing import Optional app = FastAPI() @@ -250,7 +253,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: Optional[bool] = None @app.get("/") @@ -259,7 +262,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs/it/docs/index.md b/docs/it/docs/index.md index 20dd403ab..88d0c0e3d 100644 --- a/docs/it/docs/index.md +++ b/docs/it/docs/index.md @@ -136,6 +136,7 @@ $ pip install uvicorn ```Python from fastapi import FastAPI +from typing import Optional app = FastAPI() @@ -146,7 +147,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: str = Optional[None]): return {"item_id": item_id, "q": q} ``` @@ -157,6 +158,7 @@ If your code uses `async` / `await`, use `async def`: ```Python hl_lines="7 12" from fastapi import FastAPI +from typing import Optional app = FastAPI() @@ -167,7 +169,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -248,6 +250,7 @@ Declare the body using standard Python types, thanks to Pydantic. ```Python hl_lines="2 7 8 9 10 23 24 25" from fastapi import FastAPI from pydantic import BaseModel +from typing import Optional app = FastAPI() @@ -255,7 +258,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: bool = Optional[None] @app.get("/") @@ -264,7 +267,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs/pt/docs/index.md b/docs/pt/docs/index.md index 10b2d6855..20600eead 100644 --- a/docs/pt/docs/index.md +++ b/docs/pt/docs/index.md @@ -124,6 +124,8 @@ $ pip install uvicorn * Crie um arquivo `main.py` com: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -135,7 +137,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -144,7 +146,9 @@ def read_item(item_id: int, q: str = None): Se seu código utiliza `async` / `await`, use `async def`: -```Python hl_lines="7 12" +```Python hl_lines="9 14" +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -156,7 +160,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -234,7 +238,7 @@ Agora modifique o arquivo `main.py` para receber um corpo para uma requisição Declare o corpo utilizando tipos padrão Python, graças ao Pydantic. -```Python hl_lines="2 7 8 9 10 23 24 25" +```Python hl_lines="4 9 10 11 12 25 26 27" from fastapi import FastAPI from pydantic import BaseModel @@ -244,7 +248,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: Optional[bool] = None @app.get("/") @@ -253,7 +257,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs/ru/docs/index.md b/docs/ru/docs/index.md index 20dd403ab..5d5e806e5 100644 --- a/docs/ru/docs/index.md +++ b/docs/ru/docs/index.md @@ -135,6 +135,8 @@ $ pip install uvicorn * Create a file `main.py` with: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -146,7 +148,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -155,7 +157,9 @@ def read_item(item_id: int, q: str = None): If your code uses `async` / `await`, use `async def`: -```Python hl_lines="7 12" +```Python hl_lines="9 14" +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -167,7 +171,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -245,7 +249,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request. Declare the body using standard Python types, thanks to Pydantic. -```Python hl_lines="2 7 8 9 10 23 24 25" +```Python hl_lines="4 9 10 11 12 25 26 27" +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -255,7 +261,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: Optional[bool] = None @app.get("/") @@ -264,7 +270,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs/zh/docs/deployment.md b/docs/zh/docs/deployment.md index 6eb25824a..8cca1091e 100644 --- a/docs/zh/docs/deployment.md +++ b/docs/zh/docs/deployment.md @@ -162,6 +162,8 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] * 创建一个 `main.py` 文件,内容如下: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -173,7 +175,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md index e8427c90b..f3fac28d9 100644 --- a/docs/zh/docs/index.md +++ b/docs/zh/docs/index.md @@ -131,6 +131,8 @@ $ pip install uvicorn * 创建一个 `main.py` 文件并写入以下内容: ```Python +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -142,7 +144,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -151,7 +153,9 @@ def read_item(item_id: int, q: str = None): 如果你的代码里会出现 `async` / `await`,请使用 `async def`: -```Python hl_lines="7 12" +```Python hl_lines="9 14" +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -163,7 +167,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: str = None): +async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} ``` @@ -241,7 +245,9 @@ INFO: Application startup complete. 我们借助 Pydantic 来使用标准的 Python 类型声明请求体。 -```Python hl_lines="2 7 8 9 10 23 24 25" +```Python hl_lines="4 9 10 11 12 25 26 27" +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -251,7 +257,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: bool = None + is_offer: Optional[bool] = None @app.get("/") @@ -260,7 +266,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): +def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q} diff --git a/docs_src/additional_responses/tutorial002.py b/docs_src/additional_responses/tutorial002.py index 28bdb9b2a..a46e95959 100644 --- a/docs_src/additional_responses/tutorial002.py +++ b/docs_src/additional_responses/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from fastapi.responses import FileResponse from pydantic import BaseModel @@ -21,7 +23,7 @@ app = FastAPI() } }, ) -async def read_item(item_id: str, img: bool = None): +async def read_item(item_id: str, img: Optional[bool] = None): if img: return FileResponse("image.png", media_type="image/png") else: diff --git a/docs_src/additional_responses/tutorial004.py b/docs_src/additional_responses/tutorial004.py index f1b15fee1..361aecb8e 100644 --- a/docs_src/additional_responses/tutorial004.py +++ b/docs_src/additional_responses/tutorial004.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from fastapi.responses import FileResponse from pydantic import BaseModel @@ -23,7 +25,7 @@ app = FastAPI() response_model=Item, responses={**responses, 200: {"content": {"image/png": {}}}}, ) -async def read_item(item_id: str, img: bool = None): +async def read_item(item_id: str, img: Optional[bool] = None): if img: return FileResponse("image.png", media_type="image/png") else: diff --git a/docs_src/additional_status_codes/tutorial001.py b/docs_src/additional_status_codes/tutorial001.py index c1b88828d..ae101e0a0 100644 --- a/docs_src/additional_status_codes/tutorial001.py +++ b/docs_src/additional_status_codes/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Body, FastAPI, status from fastapi.responses import JSONResponse @@ -7,7 +9,9 @@ items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "siz @app.put("/items/{item_id}") -async def upsert_item(item_id: str, name: str = Body(None), size: int = Body(None)): +async def upsert_item( + item_id: str, name: Optional[str] = Body(None), size: Optional[int] = Body(None) +): if item_id in items: item = items[item_id] item["name"] = name diff --git a/docs_src/app_testing/main_b.py b/docs_src/app_testing/main_b.py index cb9ced094..df43db806 100644 --- a/docs_src/app_testing/main_b.py +++ b/docs_src/app_testing/main_b.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel @@ -14,7 +16,7 @@ app = FastAPI() class Item(BaseModel): id: str title: str - description: str = None + description: Optional[str] = None @app.get("/items/{item_id}", response_model=Item) diff --git a/docs_src/background_tasks/tutorial002.py b/docs_src/background_tasks/tutorial002.py index 9fe737012..e7517e8cd 100644 --- a/docs_src/background_tasks/tutorial002.py +++ b/docs_src/background_tasks/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import BackgroundTasks, Depends, FastAPI app = FastAPI() @@ -8,7 +10,7 @@ def write_log(message: str): log.write(message) -def get_query(background_tasks: BackgroundTasks, q: str = None): +def get_query(background_tasks: BackgroundTasks, q: Optional[str] = None): if q: message = f"found query: {q}\n" background_tasks.add_task(write_log, message) diff --git a/docs_src/body/tutorial001.py b/docs_src/body/tutorial001.py index e99a46ccc..52144bd2b 100644 --- a/docs_src/body/tutorial001.py +++ b/docs_src/body/tutorial001.py @@ -1,12 +1,14 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None app = FastAPI() diff --git a/docs_src/body/tutorial002.py b/docs_src/body/tutorial002.py index cce5eca49..644fabae9 100644 --- a/docs_src/body/tutorial002.py +++ b/docs_src/body/tutorial002.py @@ -1,12 +1,14 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None app = FastAPI() diff --git a/docs_src/body/tutorial003.py b/docs_src/body/tutorial003.py index 1d3e90240..c99ea694b 100644 --- a/docs_src/body/tutorial003.py +++ b/docs_src/body/tutorial003.py @@ -1,12 +1,14 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None app = FastAPI() diff --git a/docs_src/body/tutorial004.py b/docs_src/body/tutorial004.py index c389af241..7a222a390 100644 --- a/docs_src/body/tutorial004.py +++ b/docs_src/body/tutorial004.py @@ -1,19 +1,21 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None app = FastAPI() @app.put("/items/{item_id}") -async def create_item(item_id: int, item: Item, q: str = None): +async def create_item(item_id: int, item: Item, q: Optional[str] = None): result = {"item_id": item_id, **item.dict()} if q: result.update({"q": q}) diff --git a/docs_src/body_fields/tutorial001.py b/docs_src/body_fields/tutorial001.py index dcd5b9764..dabc48a0f 100644 --- a/docs_src/body_fields/tutorial001.py +++ b/docs_src/body_fields/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Body, FastAPI from pydantic import BaseModel, Field @@ -6,9 +8,11 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = Field(None, title="The description of the item", max_length=300) + description: Optional[str] = Field( + None, title="The description of the item", max_length=300 + ) price: float = Field(..., gt=0, description="The price must be greater than zero") - tax: float = None + tax: Optional[float] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_multiple_params/tutorial001.py b/docs_src/body_multiple_params/tutorial001.py index fbd368207..7ce0ae6f2 100644 --- a/docs_src/body_multiple_params/tutorial001.py +++ b/docs_src/body_multiple_params/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI, Path from pydantic import BaseModel @@ -6,17 +8,17 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None @app.put("/items/{item_id}") async def update_item( *, item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000), - q: str = None, - item: Item = None, + q: Optional[str] = None, + item: Optional[Item] = None, ): results = {"item_id": item_id} if q: diff --git a/docs_src/body_multiple_params/tutorial002.py b/docs_src/body_multiple_params/tutorial002.py index 54f6d9138..6b8748420 100644 --- a/docs_src/body_multiple_params/tutorial002.py +++ b/docs_src/body_multiple_params/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -6,14 +8,14 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None class User(BaseModel): username: str - full_name: str = None + full_name: Optional[str] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_multiple_params/tutorial003.py b/docs_src/body_multiple_params/tutorial003.py index 691fe848b..7e9e24374 100644 --- a/docs_src/body_multiple_params/tutorial003.py +++ b/docs_src/body_multiple_params/tutorial003.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Body, FastAPI from pydantic import BaseModel @@ -6,14 +8,14 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None class User(BaseModel): username: str - full_name: str = None + full_name: Optional[str] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_multiple_params/tutorial004.py b/docs_src/body_multiple_params/tutorial004.py index 359b33ccc..8dc0d374d 100644 --- a/docs_src/body_multiple_params/tutorial004.py +++ b/docs_src/body_multiple_params/tutorial004.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Body, FastAPI from pydantic import BaseModel @@ -6,14 +8,14 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None class User(BaseModel): username: str - full_name: str = None + full_name: Optional[str] = None @app.put("/items/{item_id}") @@ -23,7 +25,7 @@ async def update_item( item: Item, user: User, importance: int = Body(..., gt=0), - q: str = None + q: Optional[str] = None ): results = {"item_id": item_id, "item": item, "user": user, "importance": importance} if q: diff --git a/docs_src/body_multiple_params/tutorial005.py b/docs_src/body_multiple_params/tutorial005.py index 606d3bbbb..4657b4144 100644 --- a/docs_src/body_multiple_params/tutorial005.py +++ b/docs_src/body_multiple_params/tutorial005.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Body, FastAPI from pydantic import BaseModel @@ -6,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_nested_models/tutorial001.py b/docs_src/body_nested_models/tutorial001.py index 56db2a093..fe14fdf93 100644 --- a/docs_src/body_nested_models/tutorial001.py +++ b/docs_src/body_nested_models/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -6,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: list = [] diff --git a/docs_src/body_nested_models/tutorial002.py b/docs_src/body_nested_models/tutorial002.py index db33e483f..1770516a4 100644 --- a/docs_src/body_nested_models/tutorial002.py +++ b/docs_src/body_nested_models/tutorial002.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: List[str] = [] diff --git a/docs_src/body_nested_models/tutorial003.py b/docs_src/body_nested_models/tutorial003.py index f65195b62..33dbbe3a9 100644 --- a/docs_src/body_nested_models/tutorial003.py +++ b/docs_src/body_nested_models/tutorial003.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = set() diff --git a/docs_src/body_nested_models/tutorial004.py b/docs_src/body_nested_models/tutorial004.py index 6c2ca25eb..6037b32b7 100644 --- a/docs_src/body_nested_models/tutorial004.py +++ b/docs_src/body_nested_models/tutorial004.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -13,11 +13,11 @@ class Image(BaseModel): class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] - image: Image = None + image: Optional[Image] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_nested_models/tutorial005.py b/docs_src/body_nested_models/tutorial005.py index d6d9d6479..0c076d4f9 100644 --- a/docs_src/body_nested_models/tutorial005.py +++ b/docs_src/body_nested_models/tutorial005.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel, HttpUrl @@ -13,11 +13,11 @@ class Image(BaseModel): class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] - image: Image = None + image: Optional[Image] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_nested_models/tutorial006.py b/docs_src/body_nested_models/tutorial006.py index d64668518..1d2b4ce47 100644 --- a/docs_src/body_nested_models/tutorial006.py +++ b/docs_src/body_nested_models/tutorial006.py @@ -1,4 +1,4 @@ -from typing import List, Set +from typing import List, Optional, Set from fastapi import FastAPI from pydantic import BaseModel, HttpUrl @@ -13,11 +13,11 @@ class Image(BaseModel): class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] - images: List[Image] = None + images: Optional[List[Image]] = None @app.put("/items/{item_id}") diff --git a/docs_src/body_nested_models/tutorial007.py b/docs_src/body_nested_models/tutorial007.py index f4b699dbf..9f321643c 100644 --- a/docs_src/body_nested_models/tutorial007.py +++ b/docs_src/body_nested_models/tutorial007.py @@ -1,4 +1,4 @@ -from typing import List, Set +from typing import List, Optional, Set from fastapi import FastAPI from pydantic import BaseModel, HttpUrl @@ -13,16 +13,16 @@ class Image(BaseModel): class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] - images: List[Image] = None + images: Optional[List[Image]] = None class Offer(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float items: List[Item] diff --git a/docs_src/body_updates/tutorial001.py b/docs_src/body_updates/tutorial001.py index bf9249327..9b8f3ccf1 100644 --- a/docs_src/body_updates/tutorial001.py +++ b/docs_src/body_updates/tutorial001.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from fastapi.encoders import jsonable_encoder @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): - name: str = None - description: str = None - price: float = None + name: Optional[str] = None + description: Optional[str] = None + price: Optional[float] = None tax: float = 10.5 tags: List[str] = [] diff --git a/docs_src/body_updates/tutorial002.py b/docs_src/body_updates/tutorial002.py index 56cb8c4dc..46d27e67e 100644 --- a/docs_src/body_updates/tutorial002.py +++ b/docs_src/body_updates/tutorial002.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from fastapi.encoders import jsonable_encoder @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): - name: str = None - description: str = None - price: float = None + name: Optional[str] = None + description: Optional[str] = None + price: Optional[float] = None tax: float = 10.5 tags: List[str] = [] diff --git a/docs_src/cookie_params/tutorial001.py b/docs_src/cookie_params/tutorial001.py index bee934b06..67d03b133 100644 --- a/docs_src/cookie_params/tutorial001.py +++ b/docs_src/cookie_params/tutorial001.py @@ -1,8 +1,10 @@ +from typing import Optional + from fastapi import Cookie, FastAPI app = FastAPI() @app.get("/items/") -async def read_items(ads_id: str = Cookie(None)): +async def read_items(ads_id: Optional[str] = Cookie(None)): return {"ads_id": ads_id} diff --git a/docs_src/dependencies/tutorial001.py b/docs_src/dependencies/tutorial001.py index 131a471a1..a9da971dc 100644 --- a/docs_src/dependencies/tutorial001.py +++ b/docs_src/dependencies/tutorial001.py @@ -1,9 +1,11 @@ +from typing import Optional + from fastapi import Depends, FastAPI app = FastAPI() -async def common_parameters(q: str = None, skip: int = 0, limit: int = 100): +async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100): return {"q": q, "skip": skip, "limit": limit} diff --git a/docs_src/dependencies/tutorial002.py b/docs_src/dependencies/tutorial002.py index 9733c60c8..458f6b5bb 100644 --- a/docs_src/dependencies/tutorial002.py +++ b/docs_src/dependencies/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Depends, FastAPI app = FastAPI() @@ -7,7 +9,7 @@ fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz" class CommonQueryParams: - def __init__(self, q: str = None, skip: int = 0, limit: int = 100): + def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100): self.q = q self.skip = skip self.limit = limit diff --git a/docs_src/dependencies/tutorial003.py b/docs_src/dependencies/tutorial003.py index 3f7361968..3f3e940f8 100644 --- a/docs_src/dependencies/tutorial003.py +++ b/docs_src/dependencies/tutorial003.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Depends, FastAPI app = FastAPI() @@ -7,7 +9,7 @@ fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz" class CommonQueryParams: - def __init__(self, q: str = None, skip: int = 0, limit: int = 100): + def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100): self.q = q self.skip = skip self.limit = limit diff --git a/docs_src/dependencies/tutorial004.py b/docs_src/dependencies/tutorial004.py index 6c7ca4821..daa7b4670 100644 --- a/docs_src/dependencies/tutorial004.py +++ b/docs_src/dependencies/tutorial004.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Depends, FastAPI app = FastAPI() @@ -7,7 +9,7 @@ fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz" class CommonQueryParams: - def __init__(self, q: str = None, skip: int = 0, limit: int = 100): + def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100): self.q = q self.skip = skip self.limit = limit diff --git a/docs_src/dependencies/tutorial005.py b/docs_src/dependencies/tutorial005.py index 36b312352..c8923d143 100644 --- a/docs_src/dependencies/tutorial005.py +++ b/docs_src/dependencies/tutorial005.py @@ -1,14 +1,16 @@ +from typing import Optional + from fastapi import Cookie, Depends, FastAPI app = FastAPI() -def query_extractor(q: str = None): +def query_extractor(q: Optional[str] = None): return q def query_or_cookie_extractor( - q: str = Depends(query_extractor), last_query: str = Cookie(None) + q: str = Depends(query_extractor), last_query: Optional[str] = Cookie(None) ): if not q: return last_query diff --git a/docs_src/dependency_testing/tutorial001.py b/docs_src/dependency_testing/tutorial001.py index 67c3874a3..237d3b231 100644 --- a/docs_src/dependency_testing/tutorial001.py +++ b/docs_src/dependency_testing/tutorial001.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import Depends, FastAPI from fastapi.testclient import TestClient app = FastAPI() -async def common_parameters(q: str = None, skip: int = 0, limit: int = 100): +async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100): return {"q": q, "skip": skip, "limit": limit} @@ -21,7 +23,7 @@ async def read_users(commons: dict = Depends(common_parameters)): client = TestClient(app) -async def override_dependency(q: str = None): +async def override_dependency(q: Optional[str] = None): return {"q": q, "skip": 5, "limit": 10} diff --git a/docs_src/encoder/tutorial001.py b/docs_src/encoder/tutorial001.py index 11984dd96..a918fdd64 100644 --- a/docs_src/encoder/tutorial001.py +++ b/docs_src/encoder/tutorial001.py @@ -1,4 +1,5 @@ from datetime import datetime +from typing import Optional from fastapi import FastAPI from fastapi.encoders import jsonable_encoder @@ -10,7 +11,7 @@ fake_db = {} class Item(BaseModel): title: str timestamp: datetime - description: str = None + description: Optional[str] = None app = FastAPI() diff --git a/docs_src/extra_data_types/tutorial001.py b/docs_src/extra_data_types/tutorial001.py index 2b6d2f7b9..e8d7e1ea3 100644 --- a/docs_src/extra_data_types/tutorial001.py +++ b/docs_src/extra_data_types/tutorial001.py @@ -1,4 +1,5 @@ from datetime import datetime, time, timedelta +from typing import Optional from uuid import UUID from fastapi import Body, FastAPI @@ -9,10 +10,10 @@ app = FastAPI() @app.put("/items/{item_id}") async def read_items( item_id: UUID, - start_datetime: datetime = Body(None), - end_datetime: datetime = Body(None), - repeat_at: time = Body(None), - process_after: timedelta = Body(None), + start_datetime: Optional[datetime] = Body(None), + end_datetime: Optional[datetime] = Body(None), + repeat_at: Optional[time] = Body(None), + process_after: Optional[timedelta] = Body(None), ): start_process = start_datetime + process_after duration = end_datetime - start_process diff --git a/docs_src/extra_models/tutorial001.py b/docs_src/extra_models/tutorial001.py index 7ff4bba7e..e95844f60 100644 --- a/docs_src/extra_models/tutorial001.py +++ b/docs_src/extra_models/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel, EmailStr @@ -8,20 +10,20 @@ class UserIn(BaseModel): username: str password: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None class UserOut(BaseModel): username: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None class UserInDB(BaseModel): username: str hashed_password: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None def fake_password_hasher(raw_password: str): diff --git a/docs_src/extra_models/tutorial002.py b/docs_src/extra_models/tutorial002.py index 030699114..5bc6e707f 100644 --- a/docs_src/extra_models/tutorial002.py +++ b/docs_src/extra_models/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel, EmailStr @@ -7,7 +9,7 @@ app = FastAPI() class UserBase(BaseModel): username: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None class UserIn(UserBase): diff --git a/docs_src/header_params/tutorial001.py b/docs_src/header_params/tutorial001.py index e871de68d..7d69b027e 100644 --- a/docs_src/header_params/tutorial001.py +++ b/docs_src/header_params/tutorial001.py @@ -1,8 +1,10 @@ +from typing import Optional + from fastapi import FastAPI, Header app = FastAPI() @app.get("/items/") -async def read_items(user_agent: str = Header(None)): +async def read_items(user_agent: Optional[str] = Header(None)): return {"User-Agent": user_agent} diff --git a/docs_src/header_params/tutorial002.py b/docs_src/header_params/tutorial002.py index ba6cef1de..2de3dddd7 100644 --- a/docs_src/header_params/tutorial002.py +++ b/docs_src/header_params/tutorial002.py @@ -1,8 +1,12 @@ +from typing import Optional + from fastapi import FastAPI, Header app = FastAPI() @app.get("/items/") -async def read_items(strange_header: str = Header(None, convert_underscores=False)): +async def read_items( + strange_header: Optional[str] = Header(None, convert_underscores=False) +): return {"strange_header": strange_header} diff --git a/docs_src/header_params/tutorial003.py b/docs_src/header_params/tutorial003.py index 85d0fb3a2..6d0eefdd2 100644 --- a/docs_src/header_params/tutorial003.py +++ b/docs_src/header_params/tutorial003.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI, Header @@ -6,5 +6,5 @@ app = FastAPI() @app.get("/items/") -async def read_items(x_token: List[str] = Header(None)): +async def read_items(x_token: Optional[List[str]] = Header(None)): return {"X-Token values": x_token} diff --git a/docs_src/openapi_callbacks/tutorial001.py b/docs_src/openapi_callbacks/tutorial001.py index c9ca4eb96..dea7e89b4 100644 --- a/docs_src/openapi_callbacks/tutorial001.py +++ b/docs_src/openapi_callbacks/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import APIRouter, FastAPI from fastapi.responses import JSONResponse from pydantic import BaseModel, HttpUrl @@ -7,7 +9,7 @@ app = FastAPI() class Invoice(BaseModel): id: str - title: str = None + title: Optional[str] = None customer: str total: float @@ -32,7 +34,7 @@ def invoice_notification(body: InvoiceEvent): @app.post("/invoices/", callbacks=invoices_callback_router.routes) -def create_invoice(invoice: Invoice, callback_url: HttpUrl = None): +def create_invoice(invoice: Invoice, callback_url: Optional[HttpUrl] = None): """ Create an invoice. diff --git a/docs_src/path_operation_advanced_configuration/tutorial004.py b/docs_src/path_operation_advanced_configuration/tutorial004.py index 24be0cb94..fa867e794 100644 --- a/docs_src/path_operation_advanced_configuration/tutorial004.py +++ b/docs_src/path_operation_advanced_configuration/tutorial004.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] diff --git a/docs_src/path_operation_configuration/tutorial001.py b/docs_src/path_operation_configuration/tutorial001.py index 77437cd08..66ea442ea 100644 --- a/docs_src/path_operation_configuration/tutorial001.py +++ b/docs_src/path_operation_configuration/tutorial001.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI, status from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] diff --git a/docs_src/path_operation_configuration/tutorial002.py b/docs_src/path_operation_configuration/tutorial002.py index ed29ea014..01df041b8 100644 --- a/docs_src/path_operation_configuration/tutorial002.py +++ b/docs_src/path_operation_configuration/tutorial002.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] diff --git a/docs_src/path_operation_configuration/tutorial003.py b/docs_src/path_operation_configuration/tutorial003.py index 4c4b048c7..29bcb4a22 100644 --- a/docs_src/path_operation_configuration/tutorial003.py +++ b/docs_src/path_operation_configuration/tutorial003.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] diff --git a/docs_src/path_operation_configuration/tutorial004.py b/docs_src/path_operation_configuration/tutorial004.py index f9822aae4..ac95cc4bb 100644 --- a/docs_src/path_operation_configuration/tutorial004.py +++ b/docs_src/path_operation_configuration/tutorial004.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] diff --git a/docs_src/path_operation_configuration/tutorial005.py b/docs_src/path_operation_configuration/tutorial005.py index 7ae2acafc..c1b809887 100644 --- a/docs_src/path_operation_configuration/tutorial005.py +++ b/docs_src/path_operation_configuration/tutorial005.py @@ -1,4 +1,4 @@ -from typing import Set +from typing import Optional, Set from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: Set[str] = [] diff --git a/docs_src/path_params_numeric_validations/tutorial001.py b/docs_src/path_params_numeric_validations/tutorial001.py index fc1911872..11777bba7 100644 --- a/docs_src/path_params_numeric_validations/tutorial001.py +++ b/docs_src/path_params_numeric_validations/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI, Path, Query app = FastAPI() @@ -6,7 +8,7 @@ app = FastAPI() @app.get("/items/{item_id}") async def read_items( item_id: int = Path(..., title="The ID of the item to get"), - q: str = Query(None, alias="item-query"), + q: Optional[str] = Query(None, alias="item-query"), ): results = {"item_id": item_id} if q: diff --git a/docs_src/query_params/tutorial002.py b/docs_src/query_params/tutorial002.py index 6e9348817..32918465e 100644 --- a/docs_src/query_params/tutorial002.py +++ b/docs_src/query_params/tutorial002.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") -async def read_item(item_id: str, q: str = None): +async def read_item(item_id: str, q: Optional[str] = None): if q: return {"item_id": item_id, "q": q} return {"item_id": item_id} diff --git a/docs_src/query_params/tutorial003.py b/docs_src/query_params/tutorial003.py index bba18c410..c81a96785 100644 --- a/docs_src/query_params/tutorial003.py +++ b/docs_src/query_params/tutorial003.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") -async def read_item(item_id: str, q: str = None, short: bool = False): +async def read_item(item_id: str, q: Optional[str] = None, short: bool = False): item = {"item_id": item_id} if q: item.update({"q": q}) diff --git a/docs_src/query_params/tutorial004.py b/docs_src/query_params/tutorial004.py index 4407baf9a..37f97fa2a 100644 --- a/docs_src/query_params/tutorial004.py +++ b/docs_src/query_params/tutorial004.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI app = FastAPI() @@ -5,7 +7,7 @@ app = FastAPI() @app.get("/users/{user_id}/items/{item_id}") async def read_user_item( - user_id: int, item_id: str, q: str = None, short: bool = False + user_id: int, item_id: str, q: Optional[str] = None, short: bool = False ): item = {"item_id": item_id, "owner_id": user_id} if q: diff --git a/docs_src/query_params/tutorial006.py b/docs_src/query_params/tutorial006.py index d764c2a86..ffe328340 100644 --- a/docs_src/query_params/tutorial006.py +++ b/docs_src/query_params/tutorial006.py @@ -1,9 +1,13 @@ +from typing import Optional + from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") -async def read_user_item(item_id: str, needy: str, skip: int = 0, limit: int = None): +async def read_user_item( + item_id: str, needy: str, skip: int = 0, limit: Optional[int] = None +): item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit} return item diff --git a/docs_src/query_params/tutorial007.py b/docs_src/query_params/tutorial007.py deleted file mode 100644 index 8ef5b3004..000000000 --- a/docs_src/query_params/tutorial007.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Optional - -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_user_item(item_id: str, limit: Optional[int] = None): - item = {"item_id": item_id, "limit": limit} - return item diff --git a/docs_src/query_params_str_validations/tutorial001.py b/docs_src/query_params_str_validations/tutorial001.py index b06c33c3e..5d7bfb0ee 100644 --- a/docs_src/query_params_str_validations/tutorial001.py +++ b/docs_src/query_params_str_validations/tutorial001.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import FastAPI app = FastAPI() @app.get("/items/") -async def read_items(q: str = None): +async def read_items(q: Optional[str] = None): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) diff --git a/docs_src/query_params_str_validations/tutorial002.py b/docs_src/query_params_str_validations/tutorial002.py index 183180cd7..68ea58206 100644 --- a/docs_src/query_params_str_validations/tutorial002.py +++ b/docs_src/query_params_str_validations/tutorial002.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") -async def read_items(q: str = Query(None, max_length=50)): +async def read_items(q: Optional[str] = Query(None, max_length=50)): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) diff --git a/docs_src/query_params_str_validations/tutorial003.py b/docs_src/query_params_str_validations/tutorial003.py index 311ece816..e52acc72f 100644 --- a/docs_src/query_params_str_validations/tutorial003.py +++ b/docs_src/query_params_str_validations/tutorial003.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") -async def read_items(q: str = Query(None, min_length=3, max_length=50)): +async def read_items(q: Optional[str] = Query(None, min_length=3, max_length=50)): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) diff --git a/docs_src/query_params_str_validations/tutorial004.py b/docs_src/query_params_str_validations/tutorial004.py index 785db44c0..d2c30331f 100644 --- a/docs_src/query_params_str_validations/tutorial004.py +++ b/docs_src/query_params_str_validations/tutorial004.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @@ -5,7 +7,7 @@ app = FastAPI() @app.get("/items/") async def read_items( - q: str = Query(None, min_length=3, max_length=50, regex="^fixedquery$") + q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$") ): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: diff --git a/docs_src/query_params_str_validations/tutorial007.py b/docs_src/query_params_str_validations/tutorial007.py index 76b9ea811..e360feda9 100644 --- a/docs_src/query_params_str_validations/tutorial007.py +++ b/docs_src/query_params_str_validations/tutorial007.py @@ -1,10 +1,14 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") -async def read_items(q: str = Query(None, title="Query string", min_length=3)): +async def read_items( + q: Optional[str] = Query(None, title="Query string", min_length=3) +): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) diff --git a/docs_src/query_params_str_validations/tutorial008.py b/docs_src/query_params_str_validations/tutorial008.py index 339f80e93..238add471 100644 --- a/docs_src/query_params_str_validations/tutorial008.py +++ b/docs_src/query_params_str_validations/tutorial008.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @@ -5,7 +7,7 @@ app = FastAPI() @app.get("/items/") async def read_items( - q: str = Query( + q: Optional[str] = Query( None, title="Query string", description="Query string for the items to search in the database that have a good match", diff --git a/docs_src/query_params_str_validations/tutorial009.py b/docs_src/query_params_str_validations/tutorial009.py index 7f5010014..7e5c0b81a 100644 --- a/docs_src/query_params_str_validations/tutorial009.py +++ b/docs_src/query_params_str_validations/tutorial009.py @@ -1,10 +1,12 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") -async def read_items(q: str = Query(None, alias="item-query")): +async def read_items(q: Optional[str] = Query(None, alias="item-query")): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) diff --git a/docs_src/query_params_str_validations/tutorial010.py b/docs_src/query_params_str_validations/tutorial010.py index 051656c76..7921506b6 100644 --- a/docs_src/query_params_str_validations/tutorial010.py +++ b/docs_src/query_params_str_validations/tutorial010.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI, Query app = FastAPI() @@ -5,7 +7,7 @@ app = FastAPI() @app.get("/items/") async def read_items( - q: str = Query( + q: Optional[str] = Query( None, alias="item-query", title="Query string", diff --git a/docs_src/query_params_str_validations/tutorial011.py b/docs_src/query_params_str_validations/tutorial011.py index f1c0e5b5b..7fda267ed 100644 --- a/docs_src/query_params_str_validations/tutorial011.py +++ b/docs_src/query_params_str_validations/tutorial011.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI, Query @@ -6,6 +6,6 @@ app = FastAPI() @app.get("/items/") -async def read_items(q: List[str] = Query(None)): +async def read_items(q: Optional[List[str]] = Query(None)): query_items = {"q": q} return query_items diff --git a/docs_src/query_params_str_validations/tutorial013.py b/docs_src/query_params_str_validations/tutorial013.py index a433b3a16..95dd6999d 100644 --- a/docs_src/query_params_str_validations/tutorial013.py +++ b/docs_src/query_params_str_validations/tutorial013.py @@ -4,6 +4,6 @@ app = FastAPI() @app.get("/items/") -async def read_items(q: list = Query(None)): +async def read_items(q: list = Query([])): query_items = {"q": q} return query_items diff --git a/docs_src/response_directly/tutorial001.py b/docs_src/response_directly/tutorial001.py index 89c5968b1..6acdc0fc8 100644 --- a/docs_src/response_directly/tutorial001.py +++ b/docs_src/response_directly/tutorial001.py @@ -1,4 +1,5 @@ from datetime import datetime +from typing import Optional from fastapi import FastAPI from fastapi.encoders import jsonable_encoder @@ -9,7 +10,7 @@ from pydantic import BaseModel class Item(BaseModel): title: str timestamp: datetime - description: str = None + description: Optional[str] = None app = FastAPI() diff --git a/docs_src/response_model/tutorial001.py b/docs_src/response_model/tutorial001.py index 4fe9aeb50..57992ecfc 100644 --- a/docs_src/response_model/tutorial001.py +++ b/docs_src/response_model/tutorial001.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from pydantic import BaseModel @@ -8,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None tags: List[str] = [] diff --git a/docs_src/response_model/tutorial002.py b/docs_src/response_model/tutorial002.py index 67084b45e..373317eb9 100644 --- a/docs_src/response_model/tutorial002.py +++ b/docs_src/response_model/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel, EmailStr @@ -8,7 +10,7 @@ class UserIn(BaseModel): username: str password: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None # Don't do this in production! diff --git a/docs_src/response_model/tutorial003.py b/docs_src/response_model/tutorial003.py index 8450723c2..e14026dd8 100644 --- a/docs_src/response_model/tutorial003.py +++ b/docs_src/response_model/tutorial003.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel, EmailStr @@ -8,13 +10,13 @@ class UserIn(BaseModel): username: str password: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None class UserOut(BaseModel): username: str email: EmailStr - full_name: str = None + full_name: Optional[str] = None @app.post("/user/", response_model=UserOut) diff --git a/docs_src/response_model/tutorial004.py b/docs_src/response_model/tutorial004.py index 7a2373e0c..1e18f989d 100644 --- a/docs_src/response_model/tutorial004.py +++ b/docs_src/response_model/tutorial004.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from pydantic import BaseModel @@ -8,7 +8,7 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float tax: float = 10.5 tags: List[str] = [] diff --git a/docs_src/response_model/tutorial005.py b/docs_src/response_model/tutorial005.py index 65343f072..03933d1f7 100644 --- a/docs_src/response_model/tutorial005.py +++ b/docs_src/response_model/tutorial005.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -6,7 +8,7 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float tax: float = 10.5 diff --git a/docs_src/response_model/tutorial006.py b/docs_src/response_model/tutorial006.py index 127c6f7cf..629ab8a3a 100644 --- a/docs_src/response_model/tutorial006.py +++ b/docs_src/response_model/tutorial006.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -6,7 +8,7 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float tax: float = 10.5 diff --git a/docs_src/schema_extra_example/tutorial001.py b/docs_src/schema_extra_example/tutorial001.py index 59a583750..fab4d7a44 100644 --- a/docs_src/schema_extra_example/tutorial001.py +++ b/docs_src/schema_extra_example/tutorial001.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel @@ -6,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None class Config: schema_extra = { diff --git a/docs_src/schema_extra_example/tutorial002.py b/docs_src/schema_extra_example/tutorial002.py index 0a567bd79..df3df8854 100644 --- a/docs_src/schema_extra_example/tutorial002.py +++ b/docs_src/schema_extra_example/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from pydantic import BaseModel, Field @@ -6,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str = Field(..., example="Foo") - description: str = Field(None, example="A very nice Item") + description: Optional[str] = Field(None, example="A very nice Item") price: float = Field(..., example=35.4) - tax: float = Field(None, example=3.2) + tax: Optional[float] = Field(None, example=3.2) @app.put("/items/{item_id}") diff --git a/docs_src/schema_extra_example/tutorial003.py b/docs_src/schema_extra_example/tutorial003.py index 87fbefbb6..58c79f554 100644 --- a/docs_src/schema_extra_example/tutorial003.py +++ b/docs_src/schema_extra_example/tutorial003.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Body, FastAPI from pydantic import BaseModel @@ -6,9 +8,9 @@ app = FastAPI() class Item(BaseModel): name: str - description: str = None + description: Optional[str] = None price: float - tax: float = None + tax: Optional[float] = None @app.put("/items/{item_id}") diff --git a/docs_src/security/tutorial003.py b/docs_src/security/tutorial003.py index 5dabb393f..0fd15ae3c 100644 --- a/docs_src/security/tutorial003.py +++ b/docs_src/security/tutorial003.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from pydantic import BaseModel @@ -31,9 +33,9 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token") class User(BaseModel): username: str - email: str = None - full_name: str = None - disabled: bool = None + email: Optional[str] = None + full_name: Optional[str] = None + disabled: Optional[bool] = None class UserInDB(User): diff --git a/docs_src/security/tutorial004.py b/docs_src/security/tutorial004.py index 56f0eb0ea..f3cb6a905 100644 --- a/docs_src/security/tutorial004.py +++ b/docs_src/security/tutorial004.py @@ -1,4 +1,5 @@ from datetime import datetime, timedelta +from typing import Optional import jwt from fastapi import Depends, FastAPI, HTTPException, status @@ -31,14 +32,14 @@ class Token(BaseModel): class TokenData(BaseModel): - username: str = None + username: Optional[str] = None class User(BaseModel): username: str - email: str = None - full_name: str = None - disabled: bool = None + email: Optional[str] = None + full_name: Optional[str] = None + disabled: Optional[bool] = None class UserInDB(User): @@ -75,7 +76,7 @@ def authenticate_user(fake_db, username: str, password: str): return user -def create_access_token(data: dict, expires_delta: timedelta = None): +def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta diff --git a/docs_src/security/tutorial005.py b/docs_src/security/tutorial005.py index 489404d6f..05c29deb1 100644 --- a/docs_src/security/tutorial005.py +++ b/docs_src/security/tutorial005.py @@ -1,5 +1,5 @@ from datetime import datetime, timedelta -from typing import List +from typing import List, Optional import jwt from fastapi import Depends, FastAPI, HTTPException, Security, status @@ -43,15 +43,15 @@ class Token(BaseModel): class TokenData(BaseModel): - username: str = None + username: Optional[str] = None scopes: List[str] = [] class User(BaseModel): username: str - email: str = None - full_name: str = None - disabled: bool = None + email: Optional[str] = None + full_name: Optional[str] = None + disabled: Optional[bool] = None class UserInDB(User): @@ -91,7 +91,7 @@ def authenticate_user(fake_db, username: str, password: str): return user -def create_access_token(data: dict, expires_delta: timedelta = None): +def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta diff --git a/docs_src/sql_databases/sql_app/schemas.py b/docs_src/sql_databases/sql_app/schemas.py index 5f964f0a6..51655663a 100644 --- a/docs_src/sql_databases/sql_app/schemas.py +++ b/docs_src/sql_databases/sql_app/schemas.py @@ -1,11 +1,11 @@ -from typing import List +from typing import List, Optional from pydantic import BaseModel class ItemBase(BaseModel): title: str - description: str = None + description: Optional[str] = None class ItemCreate(ItemBase): diff --git a/docs_src/sql_databases_peewee/sql_app/schemas.py b/docs_src/sql_databases_peewee/sql_app/schemas.py index 0bb9215a8..b715604ee 100644 --- a/docs_src/sql_databases_peewee/sql_app/schemas.py +++ b/docs_src/sql_databases_peewee/sql_app/schemas.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any, List, Optional import peewee from pydantic import BaseModel @@ -15,7 +15,7 @@ class PeeweeGetterDict(GetterDict): class ItemBase(BaseModel): title: str - description: str = None + description: Optional[str] = None class ItemCreate(ItemBase): diff --git a/docs_src/websockets/tutorial002.py b/docs_src/websockets/tutorial002.py index 5be199cd6..53cdb41ff 100644 --- a/docs_src/websockets/tutorial002.py +++ b/docs_src/websockets/tutorial002.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Cookie, Depends, FastAPI, Query, WebSocket, status from fastapi.responses import HTMLResponse @@ -54,7 +56,9 @@ async def get(): async def get_cookie_or_token( - websocket: WebSocket, session: str = Cookie(None), token: str = Query(None) + websocket: WebSocket, + session: Optional[str] = Cookie(None), + token: Optional[str] = Query(None), ): if session is None and token is None: await websocket.close(code=status.WS_1008_POLICY_VIOLATION) @@ -65,7 +69,7 @@ async def get_cookie_or_token( async def websocket_endpoint( websocket: WebSocket, item_id: str, - q: int = None, + q: Optional[int] = None, cookie_or_token: str = Depends(get_cookie_or_token), ): await websocket.accept() diff --git a/tests/main.py b/tests/main.py index f32856cb6..35b787056 100644 --- a/tests/main.py +++ b/tests/main.py @@ -1,4 +1,5 @@ import http +from typing import Optional from fastapi import FastAPI, Path, Query @@ -48,7 +49,7 @@ def get_bool_id(item_id: bool): @app.get("/path/param/{item_id}") -def get_path_param_id(item_id: str = Path(None)): +def get_path_param_id(item_id: Optional[str] = Path(None)): return item_id @@ -160,7 +161,7 @@ def get_query_type(query: int): @app.get("/query/int/optional") -def get_query_type_optional(query: int = None): +def get_query_type_optional(query: Optional[int] = None): if query is None: return "foo bar" return f"foo bar {query}" diff --git a/tests/test_callable_endpoint.py b/tests/test_callable_endpoint.py index 8aaf44884..1882e9053 100644 --- a/tests/test_callable_endpoint.py +++ b/tests/test_callable_endpoint.py @@ -1,10 +1,11 @@ from functools import partial +from typing import Optional from fastapi import FastAPI from fastapi.testclient import TestClient -def main(some_arg, q: str = None): +def main(some_arg, q: Optional[str] = None): return {"some_arg": some_arg, "q": q} diff --git a/tests/test_dependency_overrides.py b/tests/test_dependency_overrides.py index 3cee6f8ad..8bb307971 100644 --- a/tests/test_dependency_overrides.py +++ b/tests/test_dependency_overrides.py @@ -1,3 +1,5 @@ +from typing import Optional + import pytest from fastapi import APIRouter, Depends, FastAPI from fastapi.testclient import TestClient @@ -36,7 +38,7 @@ app.include_router(router) client = TestClient(app) -async def overrider_dependency_simple(q: str = None): +async def overrider_dependency_simple(q: Optional[str] = None): return {"q": q, "skip": 5, "limit": 10} diff --git a/tests/test_extra_routes.py b/tests/test_extra_routes.py index a2459b358..6aba3e8dd 100644 --- a/tests/test_extra_routes.py +++ b/tests/test_extra_routes.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from fastapi.responses import JSONResponse from fastapi.testclient import TestClient @@ -8,7 +10,7 @@ app = FastAPI() class Item(BaseModel): name: str - price: float = None + price: Optional[float] = None @app.api_route("/items/{item_id}", methods=["GET"]) diff --git a/tests/test_filter_pydantic_sub_model.py b/tests/test_filter_pydantic_sub_model.py index 9ce753d1e..90a372976 100644 --- a/tests/test_filter_pydantic_sub_model.py +++ b/tests/test_filter_pydantic_sub_model.py @@ -1,3 +1,5 @@ +from typing import Optional + import pytest from fastapi import Depends, FastAPI from fastapi.testclient import TestClient @@ -16,7 +18,7 @@ class ModelC(ModelB): class ModelA(BaseModel): name: str - description: str = None + description: Optional[str] = None model_b: ModelB @validator("name") diff --git a/tests/test_infer_param_optionality.py b/tests/test_infer_param_optionality.py index 166c3fcc7..5e673d9c4 100644 --- a/tests/test_infer_param_optionality.py +++ b/tests/test_infer_param_optionality.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import APIRouter, FastAPI from fastapi.testclient import TestClient @@ -19,7 +21,7 @@ def get_user(user_id: str): @item_router.get("/") -def get_items(user_id: str = None): +def get_items(user_id: Optional[str] = None): if user_id is None: return [{"item_id": "i1", "user_id": "u1"}, {"item_id": "i2", "user_id": "u2"}] else: @@ -27,7 +29,7 @@ def get_items(user_id: str = None): @item_router.get("/{item_id}") -def get_item(item_id: str, user_id: str = None): +def get_item(item_id: str, user_id: Optional[str] = None): if user_id is None: return {"item_id": item_id} else: diff --git a/tests/test_invalid_sequence_param.py b/tests/test_invalid_sequence_param.py index 069337f79..f00dd7b93 100644 --- a/tests/test_invalid_sequence_param.py +++ b/tests/test_invalid_sequence_param.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Tuple +from typing import Dict, List, Optional, Tuple import pytest from fastapi import FastAPI, Query @@ -49,5 +49,5 @@ def test_invalid_simple_dict(): title: str @app.get("/items/") - def read_items(q: dict = Query(None)): + def read_items(q: Optional[dict] = Query(None)): pass # pragma: no cover diff --git a/tests/test_jsonable_encoder.py b/tests/test_jsonable_encoder.py index d4ae34442..2514edfde 100644 --- a/tests/test_jsonable_encoder.py +++ b/tests/test_jsonable_encoder.py @@ -1,6 +1,7 @@ from datetime import datetime, timezone from enum import Enum from pathlib import PurePath, PurePosixPath, PureWindowsPath +from typing import Optional import pytest from fastapi.encoders import jsonable_encoder @@ -60,7 +61,7 @@ class RoleEnum(Enum): class ModelWithConfig(BaseModel): - role: RoleEnum = None + role: Optional[RoleEnum] = None class Config: use_enum_values = True diff --git a/tests/test_param_class.py b/tests/test_param_class.py index bbb9eefcc..c2a9096d4 100644 --- a/tests/test_param_class.py +++ b/tests/test_param_class.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import FastAPI from fastapi.params import Param from fastapi.testclient import TestClient @@ -6,7 +8,7 @@ app = FastAPI() @app.get("/items/") -def read_items(q: str = Param(None)): +def read_items(q: Optional[str] = Param(None)): return {"q": q} diff --git a/tests/test_serialize_response.py b/tests/test_serialize_response.py index 1ec957177..31c08f50d 100644 --- a/tests/test_serialize_response.py +++ b/tests/test_serialize_response.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from fastapi.testclient import TestClient @@ -9,7 +9,7 @@ app = FastAPI() class Item(BaseModel): name: str - price: float = None + price: Optional[float] = None owner_ids: List[int] = None diff --git a/tests/test_serialize_response_dataclass.py b/tests/test_serialize_response_dataclass.py index 4bbb0c2c1..ea048127a 100644 --- a/tests/test_serialize_response_dataclass.py +++ b/tests/test_serialize_response_dataclass.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from fastapi import FastAPI from fastapi.testclient import TestClient @@ -10,7 +10,7 @@ app = FastAPI() @dataclass class Item: name: str - price: float = None + price: Optional[float] = None owner_ids: List[int] = None diff --git a/tests/test_serialize_response_model.py b/tests/test_serialize_response_model.py index adb7fda34..056e9c4b0 100644 --- a/tests/test_serialize_response_model.py +++ b/tests/test_serialize_response_model.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from fastapi import FastAPI from pydantic import BaseModel, Field @@ -9,7 +9,7 @@ app = FastAPI() class Item(BaseModel): name: str = Field(..., alias="aliased_name") - price: float = None + price: Optional[float] = None owner_ids: List[int] = None diff --git a/tests/test_skip_defaults.py b/tests/test_skip_defaults.py index ed84df66c..e41d1a286 100644 --- a/tests/test_skip_defaults.py +++ b/tests/test_skip_defaults.py @@ -19,7 +19,7 @@ class Model(BaseModel): class ModelSubclass(Model): y: int z: int = 0 - w: int = None + w: Optional[int] = None class ModelDefaults(BaseModel): diff --git a/tests/test_sub_callbacks.py b/tests/test_sub_callbacks.py index 3de3cea99..dc0e3424a 100644 --- a/tests/test_sub_callbacks.py +++ b/tests/test_sub_callbacks.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import APIRouter, FastAPI from fastapi.responses import JSONResponse from fastapi.testclient import TestClient @@ -8,7 +10,7 @@ app = FastAPI() class Invoice(BaseModel): id: str - title: str = None + title: Optional[str] = None customer: str total: float @@ -36,7 +38,7 @@ subrouter = APIRouter() @subrouter.post("/invoices/", callbacks=invoices_callback_router.routes) -def create_invoice(invoice: Invoice, callback_url: HttpUrl = None): +def create_invoice(invoice: Invoice, callback_url: Optional[HttpUrl] = None): """ Create an invoice. diff --git a/tests/test_tutorial/test_query_params/test_tutorial007.py b/tests/test_tutorial/test_query_params/test_tutorial007.py deleted file mode 100644 index 335c103a1..000000000 --- a/tests/test_tutorial/test_query_params/test_tutorial007.py +++ /dev/null @@ -1,95 +0,0 @@ -from fastapi.testclient import TestClient - -from query_params.tutorial007 import app - -client = TestClient(app) - -openapi_schema = { - "openapi": "3.0.2", - "info": {"title": "FastAPI", "version": "0.1.0"}, - "paths": { - "/items/{item_id}": { - "get": { - "responses": { - "200": { - "description": "Successful Response", - "content": {"application/json": {"schema": {}}}, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - "summary": "Read User Item", - "operationId": "read_user_item_items__item_id__get", - "parameters": [ - { - "required": True, - "schema": {"title": "Item Id", "type": "string"}, - "name": "item_id", - "in": "path", - }, - { - "required": False, - "schema": {"title": "Limit", "type": "integer"}, - "name": "limit", - "in": "query", - }, - ], - } - } - }, - "components": { - "schemas": { - "ValidationError": { - "title": "ValidationError", - "required": ["loc", "msg", "type"], - "type": "object", - "properties": { - "loc": { - "title": "Location", - "type": "array", - "items": {"type": "string"}, - }, - "msg": {"title": "Message", "type": "string"}, - "type": {"title": "Error Type", "type": "string"}, - }, - }, - "HTTPValidationError": { - "title": "HTTPValidationError", - "type": "object", - "properties": { - "detail": { - "title": "Detail", - "type": "array", - "items": {"$ref": "#/components/schemas/ValidationError"}, - } - }, - }, - } - }, -} - - -def test_openapi(): - response = client.get("/openapi.json") - assert response.status_code == 200, response.text - assert response.json() == openapi_schema - - -def test_read_item(): - response = client.get("/items/foo") - assert response.status_code == 200, response.text - assert response.json() == {"item_id": "foo", "limit": None} - - -def test_read_item_query(): - response = client.get("/items/foo?limit=5") - assert response.status_code == 200, response.text - assert response.json() == {"item_id": "foo", "limit": 5} diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py index 7b1eab2b7..f2293105c 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py @@ -31,7 +31,12 @@ openapi_schema = { "parameters": [ { "required": False, - "schema": {"title": "Q", "type": "array", "items": {}}, + "schema": { + "title": "Q", + "type": "array", + "items": {}, + "default": [], + }, "name": "q", "in": "query", } @@ -88,4 +93,4 @@ def test_query_no_values(): url = "/items/" response = client.get(url) assert response.status_code == 200, response.text - assert response.json() == {"q": None} + assert response.json() == {"q": []} diff --git a/tests/test_validate_response.py b/tests/test_validate_response.py index 25499e8f9..e9a17e542 100644 --- a/tests/test_validate_response.py +++ b/tests/test_validate_response.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional import pytest from fastapi import FastAPI @@ -10,7 +10,7 @@ app = FastAPI() class Item(BaseModel): name: str - price: float = None + price: Optional[float] = None owner_ids: List[int] = None diff --git a/tests/test_validate_response_dataclass.py b/tests/test_validate_response_dataclass.py index 9d78f65ec..1765dcb43 100644 --- a/tests/test_validate_response_dataclass.py +++ b/tests/test_validate_response_dataclass.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional import pytest from fastapi import FastAPI @@ -12,7 +12,7 @@ app = FastAPI() @dataclass class Item: name: str - price: float = None + price: Optional[float] = None owner_ids: List[int] = None