Skip to main content

A command line tool for generating Markdown documentation and .env files from pydantic BaseSettings.

Project description

⚙ 📝  Settings Doc  📝 ⚙

A (command line) tool for generating Markdown documentation and .env files from pydantic_settings.BaseSettings.

CircleCI Codecov GitHub tag (latest SemVer) Maintenance GitHub last commit PyPI - Downloads PyPI - License PyPI - Python Version Pydantic Version 2

The same way you are able to generate OpenAPI documentation from pydantic.BaseModel, settings-doc allows you to generate documentation from pydantic_settings.BaseSettings.

It is powered by the Jinja2 templating engine and Click framework. If you don't like the built-in templates, you can easily modify them or write completely custom ones. All attributes of the BaseSettings models are exposed to the templates.

Table of content

Installation

pip install settings-doc

Command-line usage

See settings-doc --help for all options.

Minimal example

Let's assume the following BaseSettings in src/settings.py of a project:

from pydantic_settings import BaseSettings

class AppSettings(BaseSettings):
    logging_level: str

You can generate a Markdown documentation into stdout with:

settings-doc generate --class src.settings.AppSettings --output-format markdown

Which will output:

# `LOGGING_LEVEL`

**Required**

Similarly, you can generate a .env file for local development with:

settings-doc generate --class src.settings.AppSettings --output-format dotenv

Which will output:

LOGGING_LEVEL=

Class auto-discovery

If you have a module with a single settings class or want to load multiple classes at once as a source, you can also use the --module option. The following example works exactly like the one above and will use the AppSettings class automatically.

settings-doc generate --module src.settings --output-format dotenv

If multiple classes contain a field with the same name, all instances will appear in the output.

Adding more information

You can add any extra field parameters to the settings. By default, settings-doc will utilise the default value, whether the parameter is required or optional, description, example value, and list of possible values:

from pydantic_settings import BaseSettings, Field

class AppSettings(BaseSettings):
    logging_level: str = Field(
        "WARNING",
        description="Log level.",
        examples=["WARNING"],
        possible_values=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
    )

Which will generate the following markdown:

# `LOGGING_LEVEL`

*Optional*, default value: `WARNING`

Log level.

## Examples

`WARNING`

## Possible values

`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`

or .env file:

# Log level.
# Possible values:
#   `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
# LOGGING_LEVEL=WARNING

You can find even more complex usage of settings-doc in one of my other projects.

Updating existing documentation

It is possible to generate documentation into an existing document. To fit with the heading structure, you can adjust the heading levels with --heading-offset. Additionally, you can specify the location where to generate the documentation with two marks set by --between <START MARK> <END MARK>.

Let's assume your README.md looks like this:

# My app

This app is distributes as a docker image and configurable via environment variables. See the list below.

# Environment variables
<!-- generated env. vars. start -->
<!-- generated env. vars. end -->

When you run:

settings-doc generate \
  --class src.settings.AppSettings \
  --output-format markdown \ 
  --update README.md \
  --between "<!-- generated env. vars. start -->" "<!-- generated env. vars. end -->" \
  --heading-offset 1

the updated README.md will get only the specified location overwritten:

# My app

This app is distributes as a docker image and configurable via environment variables. See the list below.

# Environment variables
<!-- generated env. vars. start -->
## `LOGGING_LEVEL`

*Optional*, default value: `WARNING`

Log level.

### Examples

`WARNING`

### Possible values

`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
<!-- generated env. vars. end -->

Advanced usage

Rendering documentation in code

The settings_doc.render() function can be used to render the documentation in code. It returns a string with the rendered documentation. Using the Minimal example from the command line usage, the code usage is as follows:

from settings_doc import render, OutputFormat

print(
    render(
        class_name="AppSettings",
        module="src.settings",
        output_format=OutputFormat.MARKDOWN,
    )
)

Custom templates

settings-doc comes with a few built-in templates. You can override them or write completely new ones.

To just modify the existing ones:

  1. Copy the built-in templates into a new directory:
    mkdir custom_templates
    settings-doc templates --copy-to custom_templates
    
  2. Modify the template copies in custom_templates to suit your needs. You can keep only the modified ones as settings-doc always falls back to the built-in ones.
  3. Use them when generating the documentation:
    settings-doc generate \
      --class src.settings.AppSettings \
      --output-format dotenv \
      --templates custom_templates
    

To create new ones, create a folder and then a Jinja2 template with a file names <OUTPUT_FORMAT>.jinja. Then simply reference both in the command line options:

mkdir custom_templates

echo "{{ field.description }}" > custom_templates/only_descriptions.jinja

settings-doc generate \
 --class src.settings.AppSettings \
 --output-format only_descriptions \
 --templates custom_templates

Custom settings attributes in templates

By default, there are several variables available in all templates:

  • heading_offset - the value of the --heading-offset option. Defaults to 0.
  • fields is a list of str / FieldInfo tuples. The string is the name of the settings attribute and the values come from BaseSettings.model_fields.values(). In other words, a list of individual settings fields and their names. If multiple classes are used to generate the documentation, FieldInfos from all classes are collected into fields. The information about original classes is not retained.
  • classes - a dictionary, where keys are the BaseSettings sub-classes and values are lists of extracted FieldInfos of that class. This can be used for example to split individual classes into sections.

Extra parameters unknown to pydantic can be stored as a dict in the json_schema_extra attribute.

To access information from the BaseSettings classes, use the classes variable in the templates:

{% for cls, fields in classes.items() %}
# {{ cls.__name__ }}
{% endfor %}

As a pre-commit hook

It's possible to use settings-doc as a pre-commit hook to keep your documentation up to date. There is one hook id per output format:

  • settings-doc-markdown
  • settings-doc-dotenv

There are two caveats:

  1. You have to provide all the arguments (except --output-format) in the args section.
  2. You have to provide additional_dependencies, specifying each package, that is imported in your module. For example, if you use YAML loading for your settings, and you have import yaml in your module, you have to specify it. Depending on how your imports are organized, you might need to specify all of your dependencies.

Example .pre-commit-config.yaml section provided below:

- repo: https://github.com/radeklat/settings-doc
  rev: '3.0.0'
  hooks:
    - id: settings-doc-markdown
      language: system
      args:
        - '--module'
        - 'src.settings'
        - '--update'
        - 'README.md'
        - '--between'
        - "<!-- generated env. vars. start -->"
        - "<!-- generated env. vars. end -->"
        - '--heading-offset'
        - '1'
      additional_dependencies:
        - "pyyaml>=5.3.1"

You can use the same hook to check if the documentation is up-to-date in CI:

pip install pre-commit
pre-commit run --all-files settings-doc-markdown  # or other settings-doc-<output-format>

Consider caching the ~/.cache/pre-commit environment cache for faster subsequent runs.

Features overview

  • Output into several formats with --output-format: markdown, dotenv
  • Writes into stdout by default, which allows piping to other tools for further processing.
  • Able to update specified file with --update, optionally between two given string marks with --between. Useful for keeping documentation up to date.
  • Additional templates and default template overrides via --templates.

Markdown

  • Allows setting a --heading-offset to fit into existing documentation.
  • Intelligently formats example values as:
    • Single line if all values fit within 75 characters.
    • List of values if all values won't fit on a single line.
    • List of <VALUE>: <DESCRIPTION> if example values are tuples of 1-2 items.

.env

  • Leaves environment variables commented if they have a default value as the app doesn't require them.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

settings_doc-4.3.2.tar.gz (16.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

settings_doc-4.3.2-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file settings_doc-4.3.2.tar.gz.

File metadata

  • Download URL: settings_doc-4.3.2.tar.gz
  • Upload date:
  • Size: 16.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.8.20 Linux/6.8.0-1020-aws

File hashes

Hashes for settings_doc-4.3.2.tar.gz
Algorithm Hash digest
SHA256 cb06aee969f0639abc88e77554a333803191de95e95259a11929cf878d312fab
MD5 bd527be600daeeba5785d0e5331f7874
BLAKE2b-256 ccc8ac0ebe94fc41e7c03a5be9f6aab1612e79a46bfad286a76fb7cd41a8cd50

See more details on using hashes here.

File details

Details for the file settings_doc-4.3.2-py3-none-any.whl.

File metadata

  • Download URL: settings_doc-4.3.2-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.8.20 Linux/6.8.0-1020-aws

File hashes

Hashes for settings_doc-4.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 04b561093905cab8f5ebaa30c9dacca1d57cd1dc3dd404b7c929b90e2d2d7c0b
MD5 e65f49792ab318e19ba94482d5b593e6
BLAKE2b-256 1d4886c853f6f98a0340594c751930ab876b09b28d4c29a0b218923eb95046c8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page