| # 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 packaging.version import parse as parse_version |
| |
| import airflow |
| 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, |
| ) |
| |
| 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 in schema["examples"]: |
| if schema["type"] == "array": |
| ex = [ex] |
| 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 |
| """ |
| # TODO: handle arrays? probably missing more cases too |
| 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 |
| if section_name and schema["description"] and "default" in schema: |
| out.append( |
| { |
| "section": section_name, |
| "name": prefixed_name, |
| "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) |
| return out |
| |
| |
| 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" |