# ansible-specdoc
A utility for dynamically generating documentation from an Ansible module's spec.
This project was primarily designed for the [Linode Ansible Collection](https://github.com/linode/ansible_linode).
An example Ansible Collection using `ansible-specdoc` can be found [here](https://github.com/linode/ansible-specdoc-example).
## Usage
```sh
ansible-specdoc [-h] [-s] [-n MODULE_NAME] [-i INPUT_FILE] [-o OUTPUT_FILE] [-f {yaml,json,jinja2}] [-j] [-t TEMPLATE_FILE]
Generate Ansible Module documentation from spec.
options:
-h, --help show this help message and exit
-s, --stdin Read the module from stdin.
-n MODULE_NAME, --module-name MODULE_NAME
The name of the module (required for stdin)
-i INPUT_FILE, --input_file INPUT_FILE
The module to generate documentation from.
-o OUTPUT_FILE, --output_file OUTPUT_FILE
The file to output the documentation to.
-f {yaml,json,jinja2}, --output_format {yaml,json,jinja2}
The output format of the documentation.
-j, --inject Inject the output documentation into the `DOCUMENTATION`, `RETURN`, and `EXAMPLES` fields of input module.
-t TEMPLATE_FILE, --template_file TEMPLATE_FILE
The file to use as the template for templated formats.
-c, --clear_injected_fields,
Clears the DOCUMENTATION, RETURNS, and EXAMPLES fields in specified module and sets them to an empty string.
```
---
#### Generating a templated documentation file:
```shell
ansible-specdoc -f jinja2 -t path/to/my/template.md.j2 -i path/to/my/module.py -o path/to/output/file.md
```
---
#### Dynamically generating and injecting documentation back into module constants:
```shell
ansible-specdoc -j -i path/to/my/module.py
```
NOTE: Documentation string injection requires that you have `DOCUMENTATION`, `RETURN`, and `EXAMPLES` constants defined in your module.
---
#### Generating a raw documentation string (not recommended):
```shell
ansible-specdoc -f yaml -i path/to/my/module.py
```
## Implementation
### Importing SpecDoc Classes
All of the `ansible-specdoc` classes can be imported into an Ansible module using the following statement:
```python
from ansible_specdoc.objects import *
```
Alternatively, only specific classes can be imported using the following statement:
```python
from ansible_specdoc.objects import SpecDocMeta, SpecField, SpecReturnValue, FieldType, DeprecationInfo
```
### Declaring Module Metadata
The `ansible-specdoc` specification format requires that each module exports a `SPECDOC_META` object with the following structure:
```python
SPECDOC_META = SpecDocMeta(
description=['Module Description'],
requirements=['python >= 3.6'],
author=['Author Name'],
options=module_spec,
examples=[
'example module usage'
],
return_values={
'my_return_value': SpecReturnValue(
description='A generic return value.',
type=FieldType.string,
sample=['sample response']
),
}
)
```
### Declaring Argument Specification
Each `SpecField` object translates to a parameter that can be rendered into documentation and passed into Ansible for specification.
These fields should be declared in a dict format as shown below:
```python
module_spec = {
'example_argument': SpecField(
type=FieldType.string,
required=True,
description=['An example argument.']
)
}
```
This dict should be passed into the `options` field of the `SPECDOC_META` declaration.
### Passing Specification to Ansible
In order to retrieve the Ansible-compatible spec dict, use the `SPECDOC_META.ansible_spec` property.
### Other Notes
To prevent `ansible-specdoc` from executing module code, please ensure that all module logic executes using the following pattern:
```python
if __name__ == '__main__':
main()
```
---
To deprecate a module, specify the `deprecated` field as follows:
```python
SPECDOC_META = SpecDocMeta(
...
deprecated=DeprecationInfo(
alternative='my.new.module',
removed_in='1.0.0',
why='Reason for deprecation'
)
)
```
When deprecating a module, you will also need to update your `meta/runtime.yml` file.
Please refer to the [official Ansible deprecation documentation](https://docs.ansible.com/ansible/latest/dev_guide/module_lifecycle.html#deprecating-modules-and-plugins-in-a-collection) for more details.
## Templates
This repository provides an [example Markdown template](./template/module.md.j2) that can be used in conjunction with the `-t` argument.
Raw data
{
"_id": null,
"home_page": "https://github.com/linode/ansible-specdoc/",
"name": "ansible-specdoc",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "ansible",
"author": "Linode",
"author_email": "dev-dx@linode.com",
"download_url": "https://files.pythonhosted.org/packages/a1/81/3e821daf23d14307f666a9419112e3a042f68dc618370d330563bec3a2bb/ansible_specdoc-0.0.18.tar.gz",
"platform": null,
"description": "# ansible-specdoc\n\nA utility for dynamically generating documentation from an Ansible module's spec. \n\nThis project was primarily designed for the [Linode Ansible Collection](https://github.com/linode/ansible_linode).\n\nAn example Ansible Collection using `ansible-specdoc` can be found [here](https://github.com/linode/ansible-specdoc-example).\n\n## Usage\n\n```sh\nansible-specdoc [-h] [-s] [-n MODULE_NAME] [-i INPUT_FILE] [-o OUTPUT_FILE] [-f {yaml,json,jinja2}] [-j] [-t TEMPLATE_FILE]\n\nGenerate Ansible Module documentation from spec.\n\noptions:\n -h, --help show this help message and exit\n -s, --stdin Read the module from stdin.\n -n MODULE_NAME, --module-name MODULE_NAME\n The name of the module (required for stdin)\n -i INPUT_FILE, --input_file INPUT_FILE\n The module to generate documentation from.\n -o OUTPUT_FILE, --output_file OUTPUT_FILE\n The file to output the documentation to.\n -f {yaml,json,jinja2}, --output_format {yaml,json,jinja2}\n The output format of the documentation.\n -j, --inject Inject the output documentation into the `DOCUMENTATION`, `RETURN`, and `EXAMPLES` fields of input module.\n -t TEMPLATE_FILE, --template_file TEMPLATE_FILE\n The file to use as the template for templated formats.\n -c, --clear_injected_fields,\n Clears the DOCUMENTATION, RETURNS, and EXAMPLES fields in specified module and sets them to an empty string.\n```\n\n---\n\n#### Generating a templated documentation file:\n\n```shell\nansible-specdoc -f jinja2 -t path/to/my/template.md.j2 -i path/to/my/module.py -o path/to/output/file.md\n```\n\n---\n\n#### Dynamically generating and injecting documentation back into module constants:\n\n```shell\nansible-specdoc -j -i path/to/my/module.py\n```\n\nNOTE: Documentation string injection requires that you have `DOCUMENTATION`, `RETURN`, and `EXAMPLES` constants defined in your module.\n\n---\n\n#### Generating a raw documentation string (not recommended):\n\n```shell\nansible-specdoc -f yaml -i path/to/my/module.py\n```\n\n## Implementation\n\n### Importing SpecDoc Classes\n\nAll of the `ansible-specdoc` classes can be imported into an Ansible module using the following statement:\n\n```python\nfrom ansible_specdoc.objects import *\n```\n\nAlternatively, only specific classes can be imported using the following statement:\n\n```python\nfrom ansible_specdoc.objects import SpecDocMeta, SpecField, SpecReturnValue, FieldType, DeprecationInfo\n```\n\n### Declaring Module Metadata\nThe `ansible-specdoc` specification format requires that each module exports a `SPECDOC_META` object with the following structure:\n\n```python\nSPECDOC_META = SpecDocMeta(\n description=['Module Description'],\n requirements=['python >= 3.6'],\n author=['Author Name'],\n options=module_spec,\n examples=[\n 'example module usage'\n ],\n return_values={\n 'my_return_value': SpecReturnValue(\n description='A generic return value.',\n type=FieldType.string,\n sample=['sample response']\n ),\n }\n)\n```\n\n### Declaring Argument Specification\n\nEach `SpecField` object translates to a parameter that can be rendered into documentation and passed into Ansible for specification.\nThese fields should be declared in a dict format as shown below:\n\n```python\nmodule_spec = {\n 'example_argument': SpecField(\n type=FieldType.string,\n required=True,\n description=['An example argument.']\n )\n}\n```\n\nThis dict should be passed into the `options` field of the `SPECDOC_META` declaration.\n\n### Passing Specification to Ansible\n\nIn order to retrieve the Ansible-compatible spec dict, use the `SPECDOC_META.ansible_spec` property.\n\n### Other Notes\n\nTo prevent `ansible-specdoc` from executing module code, please ensure that all module logic executes using the following pattern:\n\n```python\nif __name__ == '__main__':\n main()\n```\n\n---\n\nTo deprecate a module, specify the `deprecated` field as follows:\n\n```python\nSPECDOC_META = SpecDocMeta(\n ...\n deprecated=DeprecationInfo(\n alternative='my.new.module',\n removed_in='1.0.0',\n why='Reason for deprecation'\n )\n)\n```\n\nWhen deprecating a module, you will also need to update your `meta/runtime.yml` file.\nPlease refer to the [official Ansible deprecation documentation](https://docs.ansible.com/ansible/latest/dev_guide/module_lifecycle.html#deprecating-modules-and-plugins-in-a-collection) for more details.\n\n## Templates\n\nThis repository provides an [example Markdown template](./template/module.md.j2) that can be used in conjunction with the `-t` argument.\n",
"bugtrack_url": null,
"license": "Apache License 2.0",
"summary": "A simple tool for generating Ansible collection documentation from module spec.",
"version": "0.0.18",
"project_urls": {
"Homepage": "https://github.com/linode/ansible-specdoc/"
},
"split_keywords": [
"ansible"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "33e275b4c5de78f13064f537b597e53827bb43eb9212a3963295fe37b8b09ecf",
"md5": "e32d60baef09b3aba5a5fba33fe34f2f",
"sha256": "08ac21d8745976286c6db55991ca1613d6852bbdec9d5faf4132a447321d207e"
},
"downloads": -1,
"filename": "ansible_specdoc-0.0.18-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e32d60baef09b3aba5a5fba33fe34f2f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 12537,
"upload_time": "2025-01-08T19:50:24",
"upload_time_iso_8601": "2025-01-08T19:50:24.375980Z",
"url": "https://files.pythonhosted.org/packages/33/e2/75b4c5de78f13064f537b597e53827bb43eb9212a3963295fe37b8b09ecf/ansible_specdoc-0.0.18-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a1813e821daf23d14307f666a9419112e3a042f68dc618370d330563bec3a2bb",
"md5": "f769c7613646b127e04615f73607135a",
"sha256": "1424b22e96a1bdedc5dd6e1294525f05035a3e1712d062a920d8506c3bfb3b7c"
},
"downloads": -1,
"filename": "ansible_specdoc-0.0.18.tar.gz",
"has_sig": false,
"md5_digest": "f769c7613646b127e04615f73607135a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 14821,
"upload_time": "2025-01-08T19:50:27",
"upload_time_iso_8601": "2025-01-08T19:50:27.067562Z",
"url": "https://files.pythonhosted.org/packages/a1/81/3e821daf23d14307f666a9419112e3a042f68dc618370d330563bec3a2bb/ansible_specdoc-0.0.18.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-08 19:50:27",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "linode",
"github_project": "ansible-specdoc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "PyYAML",
"specs": [
[
">=",
"6.0.1"
]
]
},
{
"name": "Jinja2",
"specs": [
[
">=",
"3.0.1"
]
]
},
{
"name": "redbaron",
"specs": [
[
">=",
"0.9.2"
]
]
}
],
"lcname": "ansible-specdoc"
}