Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions docs/en/docs/advanced/extending-openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,82 @@ Now, to be able to test that everything works, create a *path operation*:
Now, you should be able to disconnect your WiFi, go to your docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, and reload the page.

And even without Internet, you would be able to see the docs for your API and interact with it.

## Configuring Swagger UI

You can configure some extra <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">Swagger UI parameters</a>.

To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.

`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly.

FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs.

### Disable Syntax Highlighting

For example, you could disable syntax highlighting in Swagger UI.

Without changing the settings, syntax highlighting is enabled by default:

<img src="/img/tutorial/extending-openapi/image02.png">

But you can disable it by setting `syntaxHighlight` to `False`:

```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial003.py!}
```

...and then Swagger UI won't show the syntax highlighting anymore:

<img src="/img/tutorial/extending-openapi/image03.png">

### Change the Theme

The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):

```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial004.py!}
```

That configuration would change the syntax highlighting color theme:

<img src="/img/tutorial/extending-openapi/image04.png">

### Change Default Swagger UI Parameters

FastAPI includes some default configuration parameters appropriate for most of the use cases.

It includes these default configurations:

```Python
{!../../../fastapi/openapi/docs.py[ln:7-13]!}
```

You can override any of them by setting a different value in the argument `swagger_ui_parameters`.

For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:

```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial005.py!}
```

### Other Swagger UI Parameters

To see all the other possible configurations you can use, read the official <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">docs for Swagger UI parameters</a>.

### JavaScript-only settings

Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).

FastAPI also includes these JavaScript-only `presets` settings:

```JavaScript
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
]
```

These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.

If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions docs_src/extending_openapi/tutorial003.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from fastapi import FastAPI

app = FastAPI(swagger_ui_parameters={"syntaxHighlight": False})


@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
8 changes: 8 additions & 0 deletions docs_src/extending_openapi/tutorial004.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from fastapi import FastAPI

app = FastAPI(swagger_ui_parameters={"syntaxHighlight.theme": "obsidian"})


@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
8 changes: 8 additions & 0 deletions docs_src/extending_openapi/tutorial005.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from fastapi import FastAPI

app = FastAPI(swagger_ui_parameters={"deepLinking": False})


@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
3 changes: 3 additions & 0 deletions fastapi/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def __init__(
callbacks: Optional[List[BaseRoute]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
swagger_ui_parameters: Optional[Dict[str, Any]] = None,
**extra: Any,
) -> None:
self._debug: bool = debug
Expand Down Expand Up @@ -120,6 +121,7 @@ def __init__(
self.redoc_url = redoc_url
self.swagger_ui_oauth2_redirect_url = swagger_ui_oauth2_redirect_url
self.swagger_ui_init_oauth = swagger_ui_init_oauth
self.swagger_ui_parameters = swagger_ui_parameters
self.extra = extra
self.dependency_overrides: Dict[Callable[..., Any], Callable[..., Any]] = {}

Expand Down Expand Up @@ -174,6 +176,7 @@ async def swagger_ui_html(req: Request) -> HTMLResponse:
title=self.title + " - Swagger UI",
oauth2_redirect_url=oauth2_redirect_url,
init_oauth=self.swagger_ui_init_oauth,
swagger_ui_parameters=self.swagger_ui_parameters,
)

self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False)
Expand Down
22 changes: 16 additions & 6 deletions fastapi/openapi/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
from fastapi.encoders import jsonable_encoder
from starlette.responses import HTMLResponse

swagger_ui_default_parameters = {
"dom_id": "#swagger-ui",
"layout": "BaseLayout",
"deepLinking": True,
"showExtensions": True,
"showCommonExtensions": True,
}


def get_swagger_ui_html(
*,
Expand All @@ -14,7 +22,11 @@ def get_swagger_ui_html(
swagger_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png",
oauth2_redirect_url: Optional[str] = None,
init_oauth: Optional[Dict[str, Any]] = None,
swagger_ui_parameters: Optional[Dict[str, Any]] = None,
) -> HTMLResponse:
current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
if swagger_ui_parameters:
current_swagger_ui_parameters.update(swagger_ui_parameters)

html = f"""
<!DOCTYPE html>
Expand All @@ -34,19 +46,17 @@ def get_swagger_ui_html(
url: '{openapi_url}',
"""

for key, value in current_swagger_ui_parameters.items():
html += f"{json.dumps(key)}: {json.dumps(jsonable_encoder(value))},\n"

if oauth2_redirect_url:
html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"

html += """
dom_id: '#swagger-ui',
presets: [
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "BaseLayout",
deepLinking: true,
showExtensions: true,
showCommonExtensions: true
})"""

if init_oauth:
Expand Down
41 changes: 41 additions & 0 deletions tests/test_tutorial/test_extending_openapi/test_tutorial003.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from fastapi.testclient import TestClient

from docs_src.extending_openapi.tutorial003 import app

client = TestClient(app)


def test_swagger_ui():
response = client.get("/docs")
assert response.status_code == 200, response.text
assert (
'"syntaxHighlight": false' in response.text
), "syntaxHighlight should be included and converted to JSON"
assert (
'"dom_id": "#swagger-ui"' in response.text
), "default configs should be preserved"
assert "presets: [" in response.text, "default configs should be preserved"
assert (
"SwaggerUIBundle.presets.apis," in response.text
), "default configs should be preserved"
assert (
"SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text
), "default configs should be preserved"
assert (
'"layout": "BaseLayout",' in response.text
), "default configs should be preserved"
assert (
'"deepLinking": true,' in response.text
), "default configs should be preserved"
assert (
'"showExtensions": true,' in response.text
), "default configs should be preserved"
assert (
'"showCommonExtensions": true,' in response.text
), "default configs should be preserved"


def test_get_users():
response = client.get("/users/foo")
assert response.status_code == 200, response.text
assert response.json() == {"message": "Hello foo"}
44 changes: 44 additions & 0 deletions tests/test_tutorial/test_extending_openapi/test_tutorial004.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from fastapi.testclient import TestClient

from docs_src.extending_openapi.tutorial004 import app

client = TestClient(app)


def test_swagger_ui():
response = client.get("/docs")
assert response.status_code == 200, response.text
assert (
'"syntaxHighlight": false' not in response.text
), "not used parameters should not be included"
assert (
'"syntaxHighlight.theme": "obsidian"' in response.text
), "parameters with middle dots should be included in a JSON compatible way"
assert (
'"dom_id": "#swagger-ui"' in response.text
), "default configs should be preserved"
assert "presets: [" in response.text, "default configs should be preserved"
assert (
"SwaggerUIBundle.presets.apis," in response.text
), "default configs should be preserved"
assert (
"SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text
), "default configs should be preserved"
assert (
'"layout": "BaseLayout",' in response.text
), "default configs should be preserved"
assert (
'"deepLinking": true,' in response.text
), "default configs should be preserved"
assert (
'"showExtensions": true,' in response.text
), "default configs should be preserved"
assert (
'"showCommonExtensions": true,' in response.text
), "default configs should be preserved"


def test_get_users():
response = client.get("/users/foo")
assert response.status_code == 200, response.text
assert response.json() == {"message": "Hello foo"}
44 changes: 44 additions & 0 deletions tests/test_tutorial/test_extending_openapi/test_tutorial005.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from fastapi.testclient import TestClient

from docs_src.extending_openapi.tutorial005 import app

client = TestClient(app)


def test_swagger_ui():
response = client.get("/docs")
assert response.status_code == 200, response.text
assert (
'"deepLinking": false,' in response.text
), "overridden configs should be preserved"
assert (
'"deepLinking": true' not in response.text
), "overridden configs should not include the old value"
assert (
'"syntaxHighlight": false' not in response.text
), "not used parameters should not be included"
assert (
'"dom_id": "#swagger-ui"' in response.text
), "default configs should be preserved"
assert "presets: [" in response.text, "default configs should be preserved"
assert (
"SwaggerUIBundle.presets.apis," in response.text
), "default configs should be preserved"
assert (
"SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text
), "default configs should be preserved"
assert (
'"layout": "BaseLayout",' in response.text
), "default configs should be preserved"
assert (
'"showExtensions": true,' in response.text
), "default configs should be preserved"
assert (
'"showCommonExtensions": true,' in response.text
), "default configs should be preserved"


def test_get_users():
response = client.get("/users/foo")
assert response.status_code == 200, response.text
assert response.json() == {"message": "Hello foo"}