mirror of https://github.com/tiangolo/fastapi.git
✨ Add Material for MkDocs Insiders features and cards (#9748)
* ➕ Add dependencies for MkDocs Insiders * 🙈 Add Insider's .cache to .gitignore * 🔧 Update MkDocs configs for Insiders * 💄 Add custom Insiders card layout, while the custom logo is provided from upstream * 🔨 Update docs.py script to dynamically enable insiders if it's installed * 👷 Add cache for MkDocs Material Insiders' cards * 🔊 Add a small log to the docs CLI * 🔊 Tweak logs, only after exporting languages * 🐛 Fix accessing non existing env var * 🔧 Invalidate deps cache * 🔧 Tweak cache IDs * 👷 Update cache for installing insiders * 🔊 Log insiders * 💚 Invalidate cache * 👷 Tweak cache keys * 👷 Trigger CI and test cache * 🔥 Remove cache comment * ⚡️ Optimize cache usage for first runs of docs * 👷 Tweak cache for MkDocs Material cards * 💚 Trigger CI to test cache
This commit is contained in:
parent
afc237ad53
commit
ed297bb2e0
|
|
@ -44,10 +44,14 @@ jobs:
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: ${{ env.pythonLocation }}
|
path: ${{ env.pythonLocation }}
|
||||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v03
|
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v05
|
||||||
- name: Install docs extras
|
- name: Install docs extras
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
run: pip install -r requirements-docs.txt
|
run: pip install -r requirements-docs.txt
|
||||||
|
# Install MkDocs Material Insiders here just to put it in the cache for the rest of the steps
|
||||||
|
- name: Install Material for MkDocs Insiders
|
||||||
|
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
|
||||||
|
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||||
- name: Export Language Codes
|
- name: Export Language Codes
|
||||||
id: show-langs
|
id: show-langs
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -76,7 +80,7 @@ jobs:
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: ${{ env.pythonLocation }}
|
path: ${{ env.pythonLocation }}
|
||||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v03
|
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v05
|
||||||
- name: Install docs extras
|
- name: Install docs extras
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
run: pip install -r requirements-docs.txt
|
run: pip install -r requirements-docs.txt
|
||||||
|
|
@ -85,6 +89,10 @@ jobs:
|
||||||
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
|
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||||
- name: Update Languages
|
- name: Update Languages
|
||||||
run: python ./scripts/docs.py update-languages
|
run: python ./scripts/docs.py update-languages
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
|
||||||
|
path: docs/${{ matrix.lang }}/.cache
|
||||||
- name: Build Docs
|
- name: Build Docs
|
||||||
run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
|
run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,4 @@ archive.zip
|
||||||
# vim temporary files
|
# vim temporary files
|
||||||
*~
|
*~
|
||||||
.*.sw?
|
.*.sw?
|
||||||
|
.cache
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,228 @@
|
||||||
|
# Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
|
||||||
|
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Configuration
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The same default card with a a configurable logo
|
||||||
|
|
||||||
|
# Definitions
|
||||||
|
definitions:
|
||||||
|
|
||||||
|
# Background image
|
||||||
|
- &background_image >-
|
||||||
|
{{ layout.background_image or "" }}
|
||||||
|
|
||||||
|
# Background color (default: indigo)
|
||||||
|
- &background_color >-
|
||||||
|
{%- if layout.background_color -%}
|
||||||
|
{{ layout.background_color }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set palette = config.theme.palette or {} -%}
|
||||||
|
{%- if not palette is mapping -%}
|
||||||
|
{%- set palette = palette | first -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- set primary = palette.get("primary", "indigo") -%}
|
||||||
|
{%- set primary = primary.replace(" ", "-") -%}
|
||||||
|
{{ {
|
||||||
|
"red": "#ef5552",
|
||||||
|
"pink": "#e92063",
|
||||||
|
"purple": "#ab47bd",
|
||||||
|
"deep-purple": "#7e56c2",
|
||||||
|
"indigo": "#4051b5",
|
||||||
|
"blue": "#2094f3",
|
||||||
|
"light-blue": "#02a6f2",
|
||||||
|
"cyan": "#00bdd6",
|
||||||
|
"teal": "#009485",
|
||||||
|
"green": "#4cae4f",
|
||||||
|
"light-green": "#8bc34b",
|
||||||
|
"lime": "#cbdc38",
|
||||||
|
"yellow": "#ffec3d",
|
||||||
|
"amber": "#ffc105",
|
||||||
|
"orange": "#ffa724",
|
||||||
|
"deep-orange": "#ff6e42",
|
||||||
|
"brown": "#795649",
|
||||||
|
"grey": "#757575",
|
||||||
|
"blue-grey": "#546d78",
|
||||||
|
"black": "#000000",
|
||||||
|
"white": "#ffffff"
|
||||||
|
}[primary] or "#4051b5" }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
# Text color (default: white)
|
||||||
|
- &color >-
|
||||||
|
{%- if layout.color -%}
|
||||||
|
{{ layout.color }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set palette = config.theme.palette or {} -%}
|
||||||
|
{%- if not palette is mapping -%}
|
||||||
|
{%- set palette = palette | first -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- set primary = palette.get("primary", "indigo") -%}
|
||||||
|
{%- set primary = primary.replace(" ", "-") -%}
|
||||||
|
{{ {
|
||||||
|
"red": "#ffffff",
|
||||||
|
"pink": "#ffffff",
|
||||||
|
"purple": "#ffffff",
|
||||||
|
"deep-purple": "#ffffff",
|
||||||
|
"indigo": "#ffffff",
|
||||||
|
"blue": "#ffffff",
|
||||||
|
"light-blue": "#ffffff",
|
||||||
|
"cyan": "#ffffff",
|
||||||
|
"teal": "#ffffff",
|
||||||
|
"green": "#ffffff",
|
||||||
|
"light-green": "#ffffff",
|
||||||
|
"lime": "#000000",
|
||||||
|
"yellow": "#000000",
|
||||||
|
"amber": "#000000",
|
||||||
|
"orange": "#000000",
|
||||||
|
"deep-orange": "#ffffff",
|
||||||
|
"brown": "#ffffff",
|
||||||
|
"grey": "#ffffff",
|
||||||
|
"blue-grey": "#ffffff",
|
||||||
|
"black": "#ffffff",
|
||||||
|
"white": "#000000"
|
||||||
|
}[primary] or "#ffffff" }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
# Font family (default: Roboto)
|
||||||
|
- &font_family >-
|
||||||
|
{%- if layout.font_family -%}
|
||||||
|
{{ layout.font_family }}
|
||||||
|
{%- elif config.theme.font != false -%}
|
||||||
|
{{ config.theme.font.get("text", "Roboto") }}
|
||||||
|
{%- else -%}
|
||||||
|
Roboto
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
# Site name
|
||||||
|
- &site_name >-
|
||||||
|
{{ config.site_name }}
|
||||||
|
|
||||||
|
# Page title
|
||||||
|
- &page_title >-
|
||||||
|
{{ page.meta.get("title", page.title) }}
|
||||||
|
|
||||||
|
# Page title with site name
|
||||||
|
- &page_title_with_site_name >-
|
||||||
|
{%- if not page.is_homepage -%}
|
||||||
|
{{ page.meta.get("title", page.title) }} - {{ config.site_name }}
|
||||||
|
{%- else -%}
|
||||||
|
{{ page.meta.get("title", page.title) }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
# Page description
|
||||||
|
- &page_description >-
|
||||||
|
{{ page.meta.get("description", config.site_description) or "" }}
|
||||||
|
|
||||||
|
|
||||||
|
# Start of custom modified logic
|
||||||
|
# Logo
|
||||||
|
- &logo >-
|
||||||
|
{%- if layout.logo -%}
|
||||||
|
{{ layout.logo }}
|
||||||
|
{%- elif config.theme.logo -%}
|
||||||
|
{{ config.docs_dir }}/{{ config.theme.logo }}
|
||||||
|
{%- endif -%}
|
||||||
|
# End of custom modified logic
|
||||||
|
|
||||||
|
# Logo (icon)
|
||||||
|
- &logo_icon >-
|
||||||
|
{{ config.theme.icon.logo or "" }}
|
||||||
|
|
||||||
|
# Meta tags
|
||||||
|
tags:
|
||||||
|
|
||||||
|
# Open Graph
|
||||||
|
og:type: website
|
||||||
|
og:title: *page_title_with_site_name
|
||||||
|
og:description: *page_description
|
||||||
|
og:image: "{{ image.url }}"
|
||||||
|
og:image:type: "{{ image.type }}"
|
||||||
|
og:image:width: "{{ image.width }}"
|
||||||
|
og:image:height: "{{ image.height }}"
|
||||||
|
og:url: "{{ page.canonical_url }}"
|
||||||
|
|
||||||
|
# Twitter
|
||||||
|
twitter:card: summary_large_image
|
||||||
|
twitter.title: *page_title_with_site_name
|
||||||
|
twitter:description: *page_description
|
||||||
|
twitter:image: "{{ image.url }}"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Specification
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Card size and layers
|
||||||
|
size: { width: 1200, height: 630 }
|
||||||
|
layers:
|
||||||
|
|
||||||
|
# Background
|
||||||
|
- background:
|
||||||
|
image: *background_image
|
||||||
|
color: *background_color
|
||||||
|
|
||||||
|
# Logo
|
||||||
|
- size: { width: 144, height: 144 }
|
||||||
|
offset: { x: 992, y: 64 }
|
||||||
|
background:
|
||||||
|
image: *logo
|
||||||
|
icon:
|
||||||
|
value: *logo_icon
|
||||||
|
color: *color
|
||||||
|
|
||||||
|
# Site name
|
||||||
|
- size: { width: 832, height: 42 }
|
||||||
|
offset: { x: 64, y: 64 }
|
||||||
|
typography:
|
||||||
|
content: *site_name
|
||||||
|
color: *color
|
||||||
|
font:
|
||||||
|
family: *font_family
|
||||||
|
style: Bold
|
||||||
|
|
||||||
|
# Page title
|
||||||
|
- size: { width: 832, height: 310 }
|
||||||
|
offset: { x: 62, y: 160 }
|
||||||
|
typography:
|
||||||
|
content: *page_title
|
||||||
|
align: start
|
||||||
|
color: *color
|
||||||
|
line:
|
||||||
|
amount: 3
|
||||||
|
height: 1.25
|
||||||
|
font:
|
||||||
|
family: *font_family
|
||||||
|
style: Bold
|
||||||
|
|
||||||
|
# Page description
|
||||||
|
- size: { width: 832, height: 64 }
|
||||||
|
offset: { x: 64, y: 512 }
|
||||||
|
typography:
|
||||||
|
content: *page_description
|
||||||
|
align: start
|
||||||
|
color: *color
|
||||||
|
line:
|
||||||
|
amount: 2
|
||||||
|
height: 1.5
|
||||||
|
font:
|
||||||
|
family: *font_family
|
||||||
|
style: Regular
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
plugins:
|
||||||
|
social:
|
||||||
|
cards_layout_dir: ../en/layouts
|
||||||
|
cards_layout: custom
|
||||||
|
cards_layout_options:
|
||||||
|
logo: ../en/docs/img/icon-white.svg
|
||||||
|
typeset:
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Define this here and not in the main mkdocs.yml file because that one is auto
|
||||||
|
# updated and written, and the script would remove the env var
|
||||||
|
INHERIT: !ENV [INSIDERS_FILE, '../en/mkdocs.no-insiders.yml']
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
INHERIT: ../en/mkdocs.maybe-insiders.yml
|
||||||
site_name: FastAPI
|
site_name: FastAPI
|
||||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||||
site_url: https://fastapi.tiangolo.com/
|
site_url: https://fastapi.tiangolo.com/
|
||||||
|
|
@ -24,6 +25,11 @@ theme:
|
||||||
- search.highlight
|
- search.highlight
|
||||||
- content.tabs.link
|
- content.tabs.link
|
||||||
- navigation.indexes
|
- navigation.indexes
|
||||||
|
- content.tooltips
|
||||||
|
- navigation.path
|
||||||
|
- content.code.annotate
|
||||||
|
- content.code.copy
|
||||||
|
- content.code.select
|
||||||
icon:
|
icon:
|
||||||
repo: fontawesome/brands/github-alt
|
repo: fontawesome/brands/github-alt
|
||||||
logo: img/icon-white.svg
|
logo: img/icon-white.svg
|
||||||
|
|
@ -33,8 +39,8 @@ repo_name: tiangolo/fastapi
|
||||||
repo_url: https://github.com/tiangolo/fastapi
|
repo_url: https://github.com/tiangolo/fastapi
|
||||||
edit_uri: ''
|
edit_uri: ''
|
||||||
plugins:
|
plugins:
|
||||||
- search
|
search: null
|
||||||
- markdownextradata:
|
markdownextradata:
|
||||||
data: ../en/data
|
data: ../en/data
|
||||||
nav:
|
nav:
|
||||||
- FastAPI: index.md
|
- FastAPI: index.md
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,9 @@ mkdocs-markdownextradata-plugin >=0.1.7,<0.3.0
|
||||||
typer-cli >=0.0.13,<0.0.14
|
typer-cli >=0.0.13,<0.0.14
|
||||||
typer[all] >=0.6.1,<0.8.0
|
typer[all] >=0.6.1,<0.8.0
|
||||||
pyyaml >=5.3.1,<7.0.0
|
pyyaml >=5.3.1,<7.0.0
|
||||||
|
# For Material for MkDocs, Chinese search
|
||||||
|
jieba==0.42.1
|
||||||
|
# For image processing by Material for MkDocs
|
||||||
|
pillow==9.5.0
|
||||||
|
# For image processing by Material for MkDocs
|
||||||
|
cairosvg==2.7.0
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from functools import lru_cache
|
||||||
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||||
|
from importlib import metadata
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
|
@ -34,6 +36,12 @@ site_path = Path("site").absolute()
|
||||||
build_site_path = Path("site_build").absolute()
|
build_site_path = Path("site_build").absolute()
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def is_mkdocs_insiders() -> bool:
|
||||||
|
version = metadata.version("mkdocs-material")
|
||||||
|
return "insiders" in version
|
||||||
|
|
||||||
|
|
||||||
def get_en_config() -> Dict[str, Any]:
|
def get_en_config() -> Dict[str, Any]:
|
||||||
return mkdocs.utils.yaml_load(en_config_path.read_text(encoding="utf-8"))
|
return mkdocs.utils.yaml_load(en_config_path.read_text(encoding="utf-8"))
|
||||||
|
|
||||||
|
|
@ -59,6 +67,14 @@ def complete_existing_lang(incomplete: str):
|
||||||
yield lang_path.name
|
yield lang_path.name
|
||||||
|
|
||||||
|
|
||||||
|
@app.callback()
|
||||||
|
def callback() -> None:
|
||||||
|
if is_mkdocs_insiders():
|
||||||
|
os.environ["INSIDERS_FILE"] = "../en/mkdocs.insiders.yml"
|
||||||
|
# For MacOS with insiders and Cairo
|
||||||
|
os.environ["DYLD_FALLBACK_LIBRARY_PATH"] = "/opt/homebrew/lib"
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
def new_lang(lang: str = typer.Argument(..., callback=lang_callback)):
|
def new_lang(lang: str = typer.Argument(..., callback=lang_callback)):
|
||||||
"""
|
"""
|
||||||
|
|
@ -93,6 +109,10 @@ def build_lang(
|
||||||
"""
|
"""
|
||||||
Build the docs for a language.
|
Build the docs for a language.
|
||||||
"""
|
"""
|
||||||
|
insiders_env_file = os.environ.get("INSIDERS_FILE")
|
||||||
|
print(f"Insiders file {insiders_env_file}")
|
||||||
|
if is_mkdocs_insiders():
|
||||||
|
print("Using insiders")
|
||||||
lang_path: Path = Path("docs") / lang
|
lang_path: Path = Path("docs") / lang
|
||||||
if not lang_path.is_dir():
|
if not lang_path.is_dir():
|
||||||
typer.echo(f"The language translation doesn't seem to exist yet: {lang}")
|
typer.echo(f"The language translation doesn't seem to exist yet: {lang}")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue