]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:memo: Add docs for custom response
authorSebastián Ramírez <tiangolo@gmail.com>
Sat, 15 Dec 2018 11:20:22 +0000 (15:20 +0400)
committerSebastián Ramírez <tiangolo@gmail.com>
Sat, 15 Dec 2018 11:20:22 +0000 (15:20 +0400)
docs/img/tutorial/custom-response/image01.png [new file with mode: 0644]
docs/tutorial/custom-response.md [new file with mode: 0644]
docs/tutorial/src/custom-response/tutorial001.py [new file with mode: 0644]
docs/tutorial/src/custom-response/tutorial002.py [new file with mode: 0644]
docs/tutorial/src/custom-response/tutorial003.py [new file with mode: 0644]
docs/tutorial/src/custom-response/tutorial004.py [new file with mode: 0644]
mkdocs.yml

diff --git a/docs/img/tutorial/custom-response/image01.png b/docs/img/tutorial/custom-response/image01.png
new file mode 100644 (file)
index 0000000..281746b
Binary files /dev/null and b/docs/img/tutorial/custom-response/image01.png differ
diff --git a/docs/tutorial/custom-response.md b/docs/tutorial/custom-response.md
new file mode 100644 (file)
index 0000000..a0da6cc
--- /dev/null
@@ -0,0 +1,115 @@
+!!! warning
+    This is a rather advanced topic.
+    
+    If you are starting with **FastAPI**, you might not need this.
+
+By default, **FastAPI** will return the responses using Starlette's `JSONResponse`.
+
+But you can override it.
+
+## Use `UJSONResponse`
+
+For example, if you are squeezing performance, you can use `ujson` and set the response to be Starlette's `UJSONResponse`.
+
+### Import `UJSONResponse`
+
+```Python hl_lines="2"
+{!./tutorial/src/custom-response/tutorial001.py!}
+```
+
+!!! note
+    Notice that you import it directly from `starlette.responses`, not from `fastapi`.
+
+### Make your path operation use it
+
+Make your path operation use `UJSONResponse` as the response class using the parameter `content_type`:
+
+```Python hl_lines="7"
+{!./tutorial/src/custom-response/tutorial001.py!}
+```
+
+!!! info
+    The parameter is called `content_type` because it will also be used to define the "media type" of the response.
+
+    And will be documented as such in OpenAPI.
+
+## HTML Response
+
+To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
+
+### Import `HTMLResponse`
+
+```Python hl_lines="2"
+{!./tutorial/src/custom-response/tutorial002.py!}
+```
+
+!!! note
+    Notice that you import it directly from `starlette.responses`, not from `fastapi`.
+
+
+### Define your `content_type` class
+
+Pass `HTMLResponse` as the parameter `content_type` of your path operation:
+
+```Python hl_lines="7"
+{!./tutorial/src/custom-response/tutorial002.py!}
+```
+
+!!! info
+    The parameter is called `content_type` because it will also be used to define the "media type" of the response.
+
+    In this case, the HTTP header `Content-Type` will be set to `text/html`.
+
+    And it will be documented as such in OpenAPI.
+
+
+### return a Starlette `Response`
+
+You can also override the response directly in your path operation.
+
+If you return an object that is an instance of Starlette's `Response`, it will be used as the response directly.
+
+The same example from above, returning an `HTMLResponse`, could look like:
+
+```Python hl_lines="7"
+{!./tutorial/src/custom-response/tutorial003.py!}
+```
+
+!!! info
+    Of course, the `Content-Type` header will come from the the `Response` object your returned.
+
+!!! warning
+    A `Response` returned directly by your path operation function won't be documented in OpenAPI and won't be visible in the automatic interactive docs.
+
+
+### Document in OpenAPI and override `Response`
+
+If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use the `content_type` parameter AND return a `Response` object.
+
+The `content_type` class will then be used only to document the OpenAPI path operation, but your `Response` will be used as is.
+
+#### Return an `HTMLResponse` directly
+
+For example, it could be something like:
+
+```Python hl_lines="7 23"
+{!./tutorial/src/custom-response/tutorial004.py!}
+```
+
+In this example, the function `generate_html_response()` already generates a Starlette `Response` instead of the HTML in a `str`.
+
+By returning the result of calling `generate_html_response()`, you are already returning a `Response` that will override the default **FastAPI** behavior.
+
+#### Declare `HTMLResponse` as `content_type`
+
+But by declaring it also in the path operation decorator:
+
+```Python hl_lines="21"
+{!./tutorial/src/custom-response/tutorial004.py!}
+```
+
+#### OpenAPI knows how to document it
+
+...**FastAPI** will be able to document it in OpenAPI and in the interactive docs as HTML with `text/html`:
+
+<img src="/img/tutorial/custom-response/image01.png">
diff --git a/docs/tutorial/src/custom-response/tutorial001.py b/docs/tutorial/src/custom-response/tutorial001.py
new file mode 100644 (file)
index 0000000..bba3f34
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from starlette.responses import UJSONResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", content_type=UJSONResponse)
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs/tutorial/src/custom-response/tutorial002.py b/docs/tutorial/src/custom-response/tutorial002.py
new file mode 100644 (file)
index 0000000..214e642
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI
+from starlette.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", content_type=HTMLResponse)
+async def read_items():
+    return """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
diff --git a/docs/tutorial/src/custom-response/tutorial003.py b/docs/tutorial/src/custom-response/tutorial003.py
new file mode 100644 (file)
index 0000000..ba0819c
--- /dev/null
@@ -0,0 +1,19 @@
+from fastapi import FastAPI
+from starlette.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items():
+    html_content = """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
+    return HTMLResponse(content=html_content, status_code=200)
diff --git a/docs/tutorial/src/custom-response/tutorial004.py b/docs/tutorial/src/custom-response/tutorial004.py
new file mode 100644 (file)
index 0000000..b19783c
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi import FastAPI
+from starlette.responses import HTMLResponse
+
+app = FastAPI()
+
+
+def generate_html_response():
+    html_content = """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
+    return HTMLResponse(content=html_content, status_code=200)
+
+
+@app.get("/items/", content_type=HTMLResponse)
+async def read_items():
+    return generate_html_response()
index 1f2b89311fdbc54bdbcab8a66daff72b7acb3be7..7ece1dd25e68a1d4e207b5fc42c59b5506ca2bcc 100644 (file)
@@ -36,6 +36,7 @@ nav:
         - Request Forms and Files: 'tutorial/request-forms-and-files.md'
         - Path Operation Configuration: 'tutorial/path-operation-configuration.md'
         - Path Operation Advanced Configuration: 'tutorial/path-operation-advanced-configuration.md'
+        - Custom Response: 'tutorial/custom-response.md'
     - Concurrency and async / await: 'async.md'
     - Deployment: 'deployment.md'