380 lines
14 KiB
Python
380 lines
14 KiB
Python
# Disable Flake8 because of all the sphinx imports
|
|
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
"""Configuration of Airflow Chart Docs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
# Airflow documentation build configuration file, created by
|
|
# sphinx-quickstart on Thu Oct 9 20:50:01 2014.
|
|
#
|
|
# This file is execfile()d with the current directory set to its
|
|
# containing dir.
|
|
#
|
|
# Note that not all possible configuration values are present in this
|
|
# autogenerated file.
|
|
#
|
|
# All configuration values have a default; values that are commented out
|
|
# serve to show the default.
|
|
import json
|
|
import logging
|
|
import os
|
|
import re
|
|
from typing import Any
|
|
|
|
import yaml
|
|
from docs.utils.conf_constants import (
|
|
AIRFLOW_FAVICON_PATH,
|
|
AIRFLOW_REPO_ROOT_PATH,
|
|
AUTOAPI_OPTIONS,
|
|
BASIC_AUTOAPI_IGNORE_PATTERNS,
|
|
BASIC_SPHINX_EXTENSIONS,
|
|
SMARTQUOTES_EXCLUDES,
|
|
SPELLING_WORDLIST_PATH,
|
|
SPHINX_DESIGN_STATIC_PATH,
|
|
SUPPRESS_WARNINGS,
|
|
filter_autoapi_ignore_entries,
|
|
get_autodoc_mock_imports,
|
|
get_html_context,
|
|
get_html_sidebars,
|
|
get_html_theme_options,
|
|
get_intersphinx_mapping,
|
|
get_rst_epilogue,
|
|
)
|
|
from packaging.version import parse as parse_version
|
|
|
|
import airflow
|
|
|
|
PACKAGE_NAME = "helm-chart"
|
|
CHART_ROOT_PATH = AIRFLOW_REPO_ROOT_PATH / "chart"
|
|
CHART_DOC_PATH = CHART_ROOT_PATH / "docs"
|
|
CHART_STATIC_PATH = CHART_DOC_PATH / "static"
|
|
os.environ["AIRFLOW_PACKAGE_NAME"] = PACKAGE_NAME
|
|
|
|
CHART_YAML_FILE_PATH = CHART_ROOT_PATH / "Chart.yaml"
|
|
with CHART_YAML_FILE_PATH.open() as chart_file:
|
|
chart_yaml_contents = yaml.safe_load(chart_file)
|
|
|
|
PACKAGE_VERSION: str = chart_yaml_contents["version"]
|
|
|
|
# Adds to environment variables for easy access from other plugins like airflow_intersphinx.
|
|
os.environ["AIRFLOW_PACKAGE_NAME"] = PACKAGE_NAME
|
|
|
|
# Hack to allow changing for piece of the code to behave differently while
|
|
# the docs are being built. The main objective was to alter the
|
|
# behavior of the utils.apply_default that was hiding function headers
|
|
os.environ["BUILDING_AIRFLOW_DOCS"] = "TRUE"
|
|
|
|
# Use for generate rst_epilog and other post-generation substitutions
|
|
global_substitutions = {
|
|
"version": PACKAGE_VERSION,
|
|
"airflow-version": airflow.__version__,
|
|
"experimental": "This is an :ref:`experimental feature <experimental>`.",
|
|
}
|
|
|
|
# == Sphinx configuration ======================================================
|
|
|
|
# -- Project information -------------------------------------------------------
|
|
# See: https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
|
|
# General information about the project.
|
|
project = PACKAGE_NAME
|
|
# # The version info for the project you're documenting
|
|
version = PACKAGE_VERSION
|
|
# The full version, including alpha/beta/rc tags.
|
|
release = PACKAGE_VERSION
|
|
|
|
# -- General configuration -----------------------------------------------------
|
|
# See: https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
|
|
rst_epilog = get_rst_epilogue(PACKAGE_VERSION, False)
|
|
|
|
smartquotes_excludes = SMARTQUOTES_EXCLUDES
|
|
|
|
# Add any Sphinx extension module names here, as strings. They can be
|
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
# ones.
|
|
extensions = BASIC_SPHINX_EXTENSIONS
|
|
|
|
extensions.append("sphinx_jinja")
|
|
|
|
# List of patterns, relative to source directory, that match files and
|
|
# directories to ignore when looking for source files.
|
|
exclude_patterns: list[str] = []
|
|
|
|
# Add any paths that contain templates here, relative to this directory.
|
|
templates_path = ["templates"]
|
|
|
|
# If true, keep warnings as "system message" paragraphs in the built documents.
|
|
keep_warnings = True
|
|
|
|
# -- Options for HTML output ---------------------------------------------------
|
|
# See: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
|
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
# a list of builtin themes.
|
|
html_theme = "sphinx_airflow_theme"
|
|
|
|
html_title = f"{PACKAGE_NAME} Documentation"
|
|
|
|
conf_py_path = "/chart/docs/"
|
|
# A dictionary of values to pass into the template engine's context for all pages.
|
|
html_context = get_html_context(conf_py_path)
|
|
|
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
html_short_title = ""
|
|
|
|
# given, this must be the name of an image file (path relative to the
|
|
# configuration directory) that is the favicon of the docs. Modern browsers
|
|
# use this as the icon for tabs, windows and bookmarks. It should be a
|
|
# Windows-style icon file (.ico), which is 16x16 or 32x32 pixels large.
|
|
html_favicon = AIRFLOW_FAVICON_PATH.as_posix()
|
|
|
|
# Add any paths that contain custom static files (such as style sheets) here,
|
|
# relative to this directory. They are copied after the builtin static files,
|
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
html_static_path = [CHART_STATIC_PATH.as_posix(), SPHINX_DESIGN_STATIC_PATH.as_posix()]
|
|
|
|
html_js_files = ["gh-jira-links.js"]
|
|
|
|
html_css_files = ["custom.css"]
|
|
|
|
# -- Theme configuration -------------------------------------------------------
|
|
# Custom sidebar templates, maps document names to template names.
|
|
html_sidebars = get_html_sidebars(PACKAGE_VERSION)
|
|
|
|
# If false, no index is generated.
|
|
html_use_index = True
|
|
|
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
html_show_copyright = False
|
|
|
|
html_theme_options: dict[str, Any] = get_html_theme_options()
|
|
|
|
# A dictionary of values to pass into the template engine's context for all pages.
|
|
html_context = get_html_context(conf_py_path)
|
|
|
|
# == Extensions configuration ==================================================
|
|
|
|
# -- Options for sphinx_jinja ------------------------------------------
|
|
# See: https://github.com/tardyp/sphinx-jinja
|
|
|
|
airflow_version = parse_version(
|
|
re.search( # type: ignore[union-attr,arg-type]
|
|
r"__version__ = \"([0-9\.]*)(\.dev[0-9]*)?\"",
|
|
(AIRFLOW_REPO_ROOT_PATH / "airflow-core" / "src" / "airflow" / "__init__.py").read_text(),
|
|
).groups(0)[0]
|
|
)
|
|
|
|
|
|
def _str_representer(dumper, data):
|
|
style = "|" if "\n" in data else None # show as a block scalar if we have more than 1 line
|
|
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style)
|
|
|
|
|
|
yaml.add_representer(str, _str_representer)
|
|
|
|
|
|
def _format_default(value: Any) -> str:
|
|
if value == "":
|
|
return '""'
|
|
if value is None:
|
|
return "~"
|
|
return str(value)
|
|
|
|
|
|
def _format_examples(param_name: str, schema: dict) -> str | None:
|
|
if not schema.get("examples"):
|
|
return None
|
|
|
|
# Nicer to have the parameter name shown as well
|
|
out = ""
|
|
for ex_data in schema["examples"]:
|
|
ex = [ex_data] if schema["type"] == "array" else ex_data
|
|
out += yaml.dump({param_name: ex})
|
|
return out
|
|
|
|
|
|
def _get_params(root_schema: dict, prefix: str = "", default_section: str = "") -> list[dict]:
|
|
"""
|
|
Retrieve params.
|
|
|
|
Given an jsonschema objects properties dict, return a flattened list of all parameters
|
|
from that object and any nested objects
|
|
"""
|
|
out = []
|
|
for param_name, schema in root_schema.items():
|
|
prefixed_name = f"{prefix}.{param_name}" if prefix else param_name
|
|
section_name = schema["x-docsSection"] if "x-docsSection" in schema else default_section
|
|
common_out = {
|
|
"section": section_name,
|
|
"name": prefixed_name,
|
|
}
|
|
if section_name and "description" in schema and schema["description"] and "default" in schema:
|
|
out.append(
|
|
{
|
|
**common_out,
|
|
"description": schema["description"],
|
|
"default": _format_default(schema["default"]),
|
|
"examples": _format_examples(param_name, schema),
|
|
}
|
|
)
|
|
if schema.get("properties"):
|
|
out += _get_params(schema["properties"], prefixed_name, section_name)
|
|
items = schema.get("items")
|
|
if items:
|
|
out.extend(_process_array_items(items, prefixed_name, param_name, section_name))
|
|
return out
|
|
|
|
|
|
def _process_array_items(items: dict, parent_name: str, param_name: str, default_section: str) -> list[dict]:
|
|
"""Extract parameters from array item schemas."""
|
|
item_prefix = f"{parent_name}[]"
|
|
section_name = items.get("x-docsSection", default_section)
|
|
|
|
if items.get("properties"):
|
|
return _get_params(items["properties"], item_prefix, section_name)
|
|
|
|
if section_name and items.get("description") and "default" in items:
|
|
return [
|
|
{
|
|
"section": section_name,
|
|
"name": item_prefix,
|
|
"description": items["description"],
|
|
"default": _format_default(items["default"]),
|
|
"examples": _format_examples(param_name, items),
|
|
}
|
|
]
|
|
|
|
return []
|
|
|
|
|
|
schema_file = CHART_ROOT_PATH / "values.schema.json"
|
|
with schema_file.open() as config_file:
|
|
chart_schema = json.load(config_file)
|
|
|
|
params = _get_params(chart_schema["properties"])
|
|
|
|
# Now, split into sections
|
|
sections: dict[str, list[dict[str, str]]] = {}
|
|
for param in params:
|
|
if param["section"] not in sections:
|
|
sections[param["section"]] = []
|
|
|
|
sections[param["section"]].append(param)
|
|
|
|
# and order each section
|
|
for section in sections.values(): # type: ignore
|
|
section.sort(key=lambda i: i["name"]) # type: ignore
|
|
|
|
# and finally order the sections!
|
|
ordered_sections = []
|
|
for name in chart_schema["x-docsSectionOrder"]:
|
|
if name not in sections:
|
|
raise ValueError(f"Unable to find any parameters for section: {name}")
|
|
ordered_sections.append({"name": name, "params": sections.pop(name)})
|
|
|
|
if sections:
|
|
raise ValueError(f"Found section(s) which were not in `section_order`: {list(sections.keys())}")
|
|
|
|
jinja_contexts = {
|
|
"params_ctx": {"sections": ordered_sections},
|
|
"official_download_page": {
|
|
"base_url": "https://downloads.apache.org/airflow/helm-chart",
|
|
"closer_lua_url": "https://www.apache.org/dyn/closer.lua/airflow/helm-chart",
|
|
"package_name": PACKAGE_NAME,
|
|
"package_version": PACKAGE_VERSION,
|
|
},
|
|
}
|
|
|
|
|
|
# -- Options for sphinx.ext.autodoc --------------------------------------------
|
|
# See: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html
|
|
|
|
# This value contains a list of modules to be mocked up. This is useful when some external dependencies
|
|
# are not met at build time and break the building process.
|
|
autodoc_mock_imports = get_autodoc_mock_imports()
|
|
|
|
# The default options for autodoc directives. They are applied to all autodoc directives automatically.
|
|
autodoc_default_options = {"show-inheritance": True, "members": True}
|
|
|
|
autodoc_typehints = "description"
|
|
autodoc_typehints_description_target = "documented"
|
|
autodoc_typehints_format = "short"
|
|
|
|
|
|
# -- Options for sphinx.ext.intersphinx ----------------------------------------
|
|
# See: https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html
|
|
|
|
# This config value contains names of other projects that should
|
|
# be linked to in this documentation.
|
|
# Inventories are only downloaded once by docs/exts/docs_build/fetch_inventories.py.
|
|
intersphinx_mapping = get_intersphinx_mapping()
|
|
|
|
# -- Options for sphinx.ext.viewcode -------------------------------------------
|
|
# See: https://www.sphinx-doc.org/es/master/usage/extensions/viewcode.html
|
|
|
|
# If this is True, viewcode extension will emit viewcode-follow-imported event to resolve the name of
|
|
# the module by other extensions. The default is True.
|
|
viewcode_follow_imported_members = True
|
|
|
|
# -- Options for sphinx-autoapi ------------------------------------------------
|
|
# See: https://sphinx-autoapi.readthedocs.io/en/latest/config.html
|
|
|
|
# Paths (relative or absolute) to the source code that you wish to generate
|
|
# your API documentation from.
|
|
autoapi_dirs = [CHART_ROOT_PATH.as_posix()]
|
|
|
|
# A list of patterns to ignore when finding files
|
|
autoapi_ignore = BASIC_AUTOAPI_IGNORE_PATTERNS
|
|
|
|
autoapi_log = logging.getLogger("sphinx.autoapi.mappers.base")
|
|
autoapi_log.addFilter(filter_autoapi_ignore_entries)
|
|
|
|
# Keep the AutoAPI generated files on the filesystem after the run.
|
|
# Useful for debugging.
|
|
autoapi_keep_files = True
|
|
|
|
# Relative path to output the AutoAPI files into. This can also be used to place the generated documentation
|
|
# anywhere in your documentation hierarchy.
|
|
autoapi_root = "_api"
|
|
|
|
# Whether to insert the generated documentation into the TOC tree. If this is False, the default AutoAPI
|
|
# index page is not generated and you will need to include the generated documentation in a
|
|
# TOC tree entry yourself.
|
|
autoapi_add_toctree_entry = False
|
|
|
|
# By default autoapi will include private members -- we don't want that!
|
|
autoapi_options = AUTOAPI_OPTIONS
|
|
|
|
suppress_warnings = SUPPRESS_WARNINGS
|
|
|
|
# -- Options for ext.exampleinclude --------------------------------------------
|
|
exampleinclude_sourceroot = os.path.abspath("..")
|
|
|
|
# -- Options for ext.redirects -------------------------------------------------
|
|
redirects_file = "redirects.txt"
|
|
|
|
# -- Options for sphinxcontrib-spelling ----------------------------------------
|
|
spelling_word_list_filename = [SPELLING_WORDLIST_PATH.as_posix()]
|
|
spelling_exclude_patterns = ["changelog.rst"]
|
|
spelling_ignore_contributor_names = False
|
|
spelling_ignore_importable_modules = True
|
|
|
|
graphviz_output_format = "svg"
|