]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:memo: Add Query() parameters tutorial and update docs
authorSebastián Ramírez <tiangolo@gmail.com>
Fri, 14 Dec 2018 13:10:08 +0000 (17:10 +0400)
committerSebastián Ramírez <tiangolo@gmail.com>
Fri, 14 Dec 2018 13:10:08 +0000 (17:10 +0400)
15 files changed:
docs/img/tutorial/query-params-schema/image01.png [new file with mode: 0644]
docs/index.md
docs/tutorial/first-steps.md
docs/tutorial/query-params-schema.md [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial001.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial002.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial003.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial004.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial005.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial006.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial007.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial008.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial009.py [new file with mode: 0644]
docs/tutorial/src/query-params-schema/tutorial010.py [new file with mode: 0644]
mkdocs.yml

diff --git a/docs/img/tutorial/query-params-schema/image01.png b/docs/img/tutorial/query-params-schema/image01.png
new file mode 100644 (file)
index 0000000..901341f
Binary files /dev/null and b/docs/img/tutorial/query-params-schema/image01.png differ
index 39d40509c112dad1ba8541c8fd8647463f7d246b..3fc9b6067f002247805c1d806fb0d08641254e4b 100644 (file)
@@ -279,7 +279,7 @@ Try changing the line with:
 ![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
 
 
-For a more complete example including more features, [see the tutorial]().
+For a more complete example including more features, [see the tutorial](tutorial/intro/).
 
 **Spoiler alert**: the tutorial, although very short, includes:
 
index a09a1442ddbc1598c964f94cb873f118e482f40f..5572fc2e978fc99790aa7a6b72c8dc6effa9da85 100644 (file)
@@ -57,6 +57,33 @@ You will see the alternative automatic documentation (provided by <a href="https
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
+If you are curious about how the raw OpenAPI schema looks like, it is just an automatically generated JSON with the descriptions of all your API.
+
+You can see it directly at: <a href="http://127.0.0.1:8000/openapi.json" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
+
+It will show a JSON starting with something like:
+
+```JSON
+{
+    "openapi": "3.0.2",
+    "info": {
+        "title": "Fast API",
+        "version": "0.1.0"
+    },
+    "paths": {
+        "/items/": {
+            "get": {
+                "responses": {
+                    "200": {
+                        "description": "Successful Response",
+                        "content": {
+                            "application/json": {
+
+
+
+...
+```
+
 ## Recap, step by step
 
 ### Step 1: import `FastAPI`
diff --git a/docs/tutorial/query-params-schema.md b/docs/tutorial/query-params-schema.md
new file mode 100644 (file)
index 0000000..30b115f
--- /dev/null
@@ -0,0 +1,181 @@
+**FastAPI** allows you to declare additonal information and validation for your parameters.
+
+Let's take this application as example:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params-schema/tutorial001.py!}
+```
+
+The query parameter `q` is of type `str`, and by default is `None`, so it is optional.
+
+## Additional validation
+
+We are going to enforce that even though `q` is optional, whenever it is provided, it **doesn't exceed a length of 50 characters**.
+
+
+### Import `Query`
+
+To achieve that, first import `Query` from `fastapi`:
+
+```Python hl_lines="1"
+{!./tutorial/src/query-params-schema/tutorial002.py!}
+```
+
+## Use `Query` as the default value
+
+And now use it as the default value of your parameter, setting the parameter `max_length` to 50:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params-schema/tutorial002.py!}
+```
+
+As we have to replace the default value `None` with `Query(None)`, the first parameter to `Query` serves the same purpose of defining that default value. 
+
+So:
+
+```Python
+q: str = Query(None)
+```
+
+...makes the parameter optional, the same as:
+
+```Python
+q: str = None
+``` 
+
+But it declares it explicitly as being a query parameter.
+
+And then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:
+
+```Python
+q: str = Query(None, max_length=50)
+```
+
+This will validate the data, show a clear error when the data is not valid, and document the parameter in the OpenAPI schema endpoint.
+
+
+## Add more validations
+
+You can also add a parameter `min_length`:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params-schema/tutorial003.py!}
+```
+
+## Add regular expressions
+
+You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> that the parameter should match:
+
+```Python hl_lines="8"
+{!./tutorial/src/query-params-schema/tutorial004.py!}
+```
+
+This specific regular expression checks that the received parameter value:
+
+* `^`: starts with the following characters, doesn't have characters before.
+* `fixedquery`: has the exact value `fixedquery`.
+* `$`: ends there, doesn't have any more characters after `fixedquery`.
+
+If you feel lost with all these **"regular expression"** ideas, don't worry. They are a hard topic for many people. You can still do a lot of stuff without needing regular expressions yet.
+
+But whenever you need them and go and learn them, know that you can already use them directly in **FastAPI**.
+
+## Default values
+
+The same way that you can pass `None` as the first argument to be used as the default value, you can pass other values.
+
+Let's say that you want to declare the `q` query parameter to have a `min_length` of `3`, and to have a default value of `"fixedquery"`:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params-schema/tutorial005.py!}
+```
+
+!!! note
+    Having a default value also makes the parameter optional.
+
+## Make it required
+
+When we don't need to declare more validations or metadata, we can make the `q` query parameter required just by not declaring a default value, like:
+
+```Python
+q: str
+```
+
+instead of:
+
+```Python
+q: str = None
+```
+
+But we are now declaring it with `Query`, for example like:
+
+```Python
+q: 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:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params-schema/tutorial006.py!}
+```
+
+!!! info 
+    If you hadn't seen that `...` before: it is a a special single value, it is <a href="https://docs.python.org/3/library/constants.html#Ellipsis" target="_blank">part of Python and is called "Ellipsis"</a>.
+
+This will let **FastAPI** know that this parameter is required.
+
+## Declare more metadata
+
+You can add more information about the parameter.
+
+That information will be included in the generated OpenAPI and used by the documentation user interfaces and external tools.
+
+You can add a `title`:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params-schema/tutorial007.py!}
+```
+
+And a `description`:
+
+```Python hl_lines="11"
+{!./tutorial/src/query-params-schema/tutorial008.py!}
+```
+
+## Alias parameters
+
+Imagine that you want the parameter to be `item-query`.
+
+Like in:
+
+```
+http://127.0.0.1:8000/items/?item-query=foobaritems
+```
+
+But `item-query` is not a valid Python variable name.
+
+The closest would be `item_query`.
+
+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"
+{!./tutorial/src/query-params-schema/tutorial009.py!}
+```
+
+## Deprecating parameters
+
+Now let's say you don't like this parameter anymore.
+
+You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <abbr title="obsolete, recommended not to use it">deprecated</abbr>.
+
+Then pass the parameter `deprecated=True` to `Query`:
+
+```Python hl_lines="16"
+{!./tutorial/src/query-params-schema/tutorial010.py!}
+```
+
+The docs will show it like this:
+
+<img src="/img/tutorial/query-params-schema/image01.png">
diff --git a/docs/tutorial/src/query-params-schema/tutorial001.py b/docs/tutorial/src/query-params-schema/tutorial001.py
new file mode 100644 (file)
index 0000000..b06c33c
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = None):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial002.py b/docs/tutorial/src/query-params-schema/tutorial002.py
new file mode 100644 (file)
index 0000000..183180c
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, max_length=50)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial003.py b/docs/tutorial/src/query-params-schema/tutorial003.py
new file mode 100644 (file)
index 0000000..311ece8
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, min_length=3, max_length=50)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial004.py b/docs/tutorial/src/query-params-schema/tutorial004.py
new file mode 100644 (file)
index 0000000..785db44
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(None, min_length=3, max_length=50, regex="^fixedquery$")
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial005.py b/docs/tutorial/src/query-params-schema/tutorial005.py
new file mode 100644 (file)
index 0000000..22eb3ac
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query("fixedquery", min_length=3)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial006.py b/docs/tutorial/src/query-params-schema/tutorial006.py
new file mode 100644 (file)
index 0000000..720bf07
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(..., min_length=3)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial007.py b/docs/tutorial/src/query-params-schema/tutorial007.py
new file mode 100644 (file)
index 0000000..76b9ea8
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, title="Query string", min_length=3)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial008.py b/docs/tutorial/src/query-params-schema/tutorial008.py
new file mode 100644 (file)
index 0000000..339f80e
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        None,
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial009.py b/docs/tutorial/src/query-params-schema/tutorial009.py
new file mode 100644 (file)
index 0000000..7f50100
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, alias="item-query")):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/query-params-schema/tutorial010.py b/docs/tutorial/src/query-params-schema/tutorial010.py
new file mode 100644 (file)
index 0000000..051656c
--- /dev/null
@@ -0,0 +1,22 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        None,
+        alias="item-query",
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+        max_length=50,
+        regex="^fixedquery$",
+        deprecated=True,
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
index 089fe949257481409794c6f5a2fc3a3164faaeb2..2a4aca4e13e8294bd546de2d10ffcac572c01406 100644 (file)
@@ -22,6 +22,7 @@ nav:
         - Path Parameters: 'tutorial/path-params.md'
         - Query Parameters: 'tutorial/query-params.md'
         - Request Body: 'tutorial/body.md'
+        - Query Parameters with toppings: 'tutorial/query-params-schema.md'
     - Concurrency and async / await: 'async.md'
     - Deployment: 'deployment.md'