From d652b2cc1097d9ffffd6cb9bf9c3aef14a7f46f3 Mon Sep 17 00:00:00 2001 From: Shahar Ilany <31574996+ShaharIlany@users.noreply.github.com> Date: Wed, 24 Aug 2022 22:22:18 +0300 Subject: [PATCH] feat(tutorial006.py): create new tutorial for elements customization --- docs/en/docs/advanced/extending-openapi.md | 57 +++++++++++++++++++--- docs_src/extending_openapi/tutorial006.py | 43 ++++++++++++++++ 2 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 docs_src/extending_openapi/tutorial006.py diff --git a/docs/en/docs/advanced/extending-openapi.md b/docs/en/docs/advanced/extending-openapi.md index 36619696b5..05ed02b2b0 100644 --- a/docs/en/docs/advanced/extending-openapi.md +++ b/docs/en/docs/advanced/extending-openapi.md @@ -91,7 +91,7 @@ Once you go to CDN. @@ -135,10 +135,15 @@ You can probably right-click each link and select an option similar to `Save lin * `swagger-ui-bundle.js` * `swagger-ui.css` -And **ReDoc** uses the file: +**ReDoc** uses the file: * `redoc.standalone.js` +**Stoplight Elements** uses the files: + +* `web-components.min.js` +* `styles.min.css` + After that, your file structure could look like: ``` @@ -147,6 +152,8 @@ After that, your file structure could look like: │   ├── __init__.py │   ├── main.py └── static + ├── web-components.min.js + ├── styles.min.css ├── redoc.standalone.js ├── swagger-ui-bundle.js └── swagger-ui.css @@ -157,7 +164,7 @@ After that, your file structure could look like: * Import `StaticFiles`. * "Mount" a `StaticFiles()` instance in a specific path. -```Python hl_lines="7 11" +```Python hl_lines="8 12" {!../../../docs_src/extending_openapi/tutorial002.py!} ``` @@ -191,7 +198,7 @@ The first step is to disable the automatic docs, as those use the CDN by default To disable them, set their URLs to `None` when creating your `FastAPI` app: -```Python hl_lines="9" +```Python hl_lines="10" {!../../../docs_src/extending_openapi/tutorial002.py!} ``` @@ -209,7 +216,7 @@ You can re-use FastAPI's internal functions to create the HTML pages for the doc And similarly for ReDoc... -```Python hl_lines="2-6 14-22 25-27 30-36" +```Python hl_lines="2-7 15-23 26-28 31-37 39-46" {!../../../docs_src/extending_openapi/tutorial002.py!} ``` @@ -224,13 +231,13 @@ And similarly for ReDoc... Now, to be able to test that everything works, create a *path operation*: -```Python hl_lines="39-41" +```Python hl_lines="49-51" {!../../../docs_src/extending_openapi/tutorial002.py!} ``` ### Test it -Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page. +Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/elements, and reload the page. And even without Internet, you would be able to see the docs for your API and interact with it. @@ -312,3 +319,39 @@ presets: [ 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. + +## Configuring Stoplight Elements + +You can configure some extra Stoplight Elements parameters. + +To configure them, use the `get_stoplight_elements_html` built in function parameters. + +### Custom Stoplight Elements Config + +```Python hl_lines="24-37" +{!../../../docs_src/extending_openapi/tutorial006.py!} +``` + +- `openapi_url` OpenAPI document URL, supporting `http://`, `https://`, and documents containing `$ref` to other http(s) documents. +- `title` The page title +- `stoplight_elements_js_url` URL to static JS file. + - Default: `"https://unpkg.com/@stoplight/elements/web-components.min.js"` +- `stoplight_elements_css_url` URL to static CSS file. + - Default: `"https://unpkg.com/@stoplight/elements/styles.min.css"` +- `stoplight_elements_favicon_url` URL to an image that will be used as the page favicon. + - Default: `"https://fastapi.tiangolo.com/img/favicon.png"` +- `api_description_document` OpenAPI document, provided as YAML string, JSON string or JavaScript object. +- `base_path` Helps when using `RouterOptions.HISTORY` but docs are in a subdirectory like https://example.com/api/elements. +- `hide_internal` Pass `True` to filter out any content which has been marked as internal with `x-internal`. + - Default: `False` +- `hide_try_it` Pass `True` to hide the Try It feature.. + - Default: `False` +- `try_it_cors_proxy` Pass the URL of a CORS proxy used to send requests to the Try It feature. The provided url is prepended to the URL of an actual request. +- `try_it_credential_policy` Use to fetch the credential policy for the Try It feature + - Default: `TryItCredentialPolicyOptions.OMIT` +- `layout` There are two layouts for Elements: + - Default: `LayoutOptions.SIDEBAR` Three-column design. + - `LayoutOptions.STACKED` Everything in a single column, making integrations with existing websites that have their own sidebar or other columns already. +- `logo` URL to an image that will show as a small square logo next to the title, above the table of contents. +- `router` + - Default: `RouterOptions.HISTORY` \ No newline at end of file diff --git a/docs_src/extending_openapi/tutorial006.py b/docs_src/extending_openapi/tutorial006.py new file mode 100644 index 0000000000..fc11e16c8a --- /dev/null +++ b/docs_src/extending_openapi/tutorial006.py @@ -0,0 +1,43 @@ +from fastapi import FastAPI +from fastapi.openapi.docs import ( + get_stoplight_elements_html, + get_swagger_ui_oauth2_redirect_html, + TryItCredentialPolicyOptions, + LayoutOptions, + RouterOptions, +) +from fastapi.staticfiles import StaticFiles + +app = FastAPI(stoplight_elements_url=None) + +app.mount("/static", StaticFiles(directory="static"), name="static") + + +@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False) +async def swagger_ui_redirect(): + return get_swagger_ui_oauth2_redirect_html() + + +@app.get("/elements", include_in_schema=False) +async def elements_html(): + return get_stoplight_elements_html( + openapi_url=app.openapi_url, + title=app.title + " - Elements", + stoplight_elements_js_url="/static/web-components.min.js", + stoplight_elements_css_url="/static/styles.min.css", + stoplight_elements_favicon_url="https://fastapi.tiangolo.com/img/favicon.png", + api_description_document="", + base_path="", + hide_internal=False, + hide_try_it=False, + try_it_cors_proxy="", + try_it_credential_policy=TryItCredentialPolicyOptions.OMIT, + layout=LayoutOptions.SIDEBAR, + logo="", + router=RouterOptions.HISTORY, + ) + + +@app.get("/users/{username}") +async def read_user(username: str): + return {"message": f"Hello {username}"} \ No newline at end of file