Package: settings-doc
⚙ 📝  Settings DocGen  📝 ⚙A command line tool for generating Markdown documentation and .env files frompydantic.BaseSettings.The same way you are able to generate OpenAPI documentation frompydantic.BaseModel,settings-docallows you to generate documentation frompydantic_settings.BaseSettings.It is powered by theJinja2templating engine andTyperframework. If you don't like the built-in templates, you can easily modify them or write completely custom ones. All attributes of theBaseSettingsmodels are exposed to the templates.Table of contentInstallationUsageMinimal exampleClass auto-discoveryAdding more informationUpdating existing documentationAdvanced usageCustom templatesCustom settings attributes in templatesAs a pre-commit hookFeatures overviewMarkdown.envInstallationpip install settings-docUsageSeesettings-doc --helpfor all options.Minimal exampleLet's assume the followingBaseSettingsinsrc/settings.pyof a project:frompydantic_settingsimportBaseSettingsclassAppSettings(BaseSettings):logging_level:strYou can generate a Markdown documentation into stdout with:settings-docgenerate--classsrc.settings.AppSettings--output-formatmarkdownWhich will output:# `LOGGING_LEVEL`**Required**Similarly, you can generate a.envfile for local development with:settings-docgenerate--classsrc.settings.AppSettings--output-formatdotenvWhich will output:LOGGING_LEVEL=Class auto-discoveryIf 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--moduleoption. The following example works exactly like the one above and will use theAppSettingsclass automatically.settings-docgenerate--modulesrc.settings--output-formatdotenvIf multiple classes contain a field with the same name, all instances will appear in the output.Adding more informationYou can add any extra field parameters to the settings. By default,settings-docwill utilise the default value, whether the parameter is required or optional, description, example value, and list of possible values:frompydantic_settingsimportBaseSettings,FieldclassAppSettings(BaseSettings):logging_level:str=Field("WARNING",description="Log level.",example="`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.envfile:# Log level.
# Possible values:
#   `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
# LOGGING_LEVEL=WARNINGYou can find even more complex usage ofsettings-docinone of my other projects.Updating existing documentationIt 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 yourREADME.mdlooks like this:# My appThis 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-docgenerate\--classsrc.settings.AppSettings\--output-formatmarkdown\--updateREADME.md\--between"<!-- generated env. vars. start -->""<!-- generated env. vars. end -->"\--heading-offset1the updatedREADME.mdwill get only the specified location overwritten:# My appThis 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 usageCustom templatessettings-doccomes with a few built-in templates. You can override them or write completely new ones.To just modify the existing ones:Copy the built-in templates into a new directory:mkdircustom_templates
settings-doctemplates--copy-tocustom_templatesModify the template copies incustom_templatesto suit your needs. You can keep only the modified ones assettings-docalways falls back to the built-in ones.Use them when generating the documentation:settings-docgenerate\--classsrc.settings.AppSettings\--output-formatdotenv\--templatescustom_templatesTo 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:mkdircustom_templatesecho"{{ field.description }}">custom_templates/only_descriptions.jinja

settings-docgenerate\--classsrc.settings.AppSettings\--output-formatonly_descriptions\--templatescustom_templatesCustom settings attributes in templatesBy default, there are several variables available in all templates:heading_offset- the value of the--heading-offsetoption. Defaults to0.fieldsis a list ofstr/FieldInfotuples. The string is the name of the settings attribute and the values come fromBaseSettings.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 intofields. The information about original classes is not retained.classes- a dictionary, where keys are theBaseSettingssub-classes and values are lists of extractedFieldInfos 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 thejson_schema_extraattribute.To access information from theBaseSettingsclasses, use theclassesvariable in the templates:{% for cls, fields in classes.items() %}
# {{ cls.__name__ }}
{% endfor %}As a pre-commit hookIt's possible to usesettings-docas a pre-commit hook to keep your documentation up to date. There is one hookidper output format:settings-doc-markdownsettings-doc-dotenvThere are two caveats:You have to provideallthe arguments (except--output-format) in theargssection.You have to provideadditional_dependencies, specifying each package, that is imported in
your module. For example, if you use YAML loading for your settings, and you haveimport yamlin
your module, you have to specify it. Depending on how your imports are organized, you might need to
specifyallof your dependencies.Example.pre-commit-config.yamlsection provided below:-repo:https://github.com/radeklat/settings-docrev:'3.0.0'hooks:-id:settings-doc-markdownargs:-'--module'-'src.settings'-'--update'-'README.md'-'--between'-"<!--generatedenv.vars.start-->"-"<!--generatedenv.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:pipinstallpre-commit
pre-commitrun--all-filessettings-doc-markdown# or other settings-doc-<output-format>Consider caching the~/.cache/pre-commitenvironment cache for faster subsequent runs.Features overviewOutput into several formats with--output-format: markdown, dotenvWrites 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.MarkdownAllows setting a--heading-offsetto 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..envLeaves environment variables commented if they have a default value as the app doesn't require them.