diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 021f53d0..aa72be1c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10"] runs-on: "ubuntu-20.04" env: PYTHON_VER: "${{ matrix.python-version }}" @@ -161,7 +161,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10"] runs-on: "ubuntu-20.04" env: PYTHON_VER: "${{ matrix.python-version }}" diff --git a/.readthedocs.yml b/.readthedocs.yml index 492d9c46..a9d358ef 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,12 +1,22 @@ --- +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required version: 2 -sphinx: - builder: "html" - configuration: "docs/source/conf.py" - fail_on_warning: false +# Set the version of Python in the build environment. +build: + os: "ubuntu-22.04" + tools: + python: "3.10" + +mkdocs: + configuration: "mkdocs.yml" + # fail_on_warning: true +# Use our docs/requirements.txt during installation. python: - version: 3.7 install: - requirements: "docs/requirements.txt" diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 56903bfb..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,153 +0,0 @@ -# Changelog - -## v1.2.0 - 2022-08 - -### Added - -- #128 Documentation for Nokia SROS duplicate lines/duplicate line detection -- #138 Added nxos_ssh to Napalm mapper - -### Changed - -- #113 Updated lib mapping docs -- #115 Switched build backend to poetry-core -- #121 Update banner parsing for EOS -- #129 Add type hints to the whole project and mypy testing setup and CI -- #134 Updated CODEOWNERS - -### Fixed - -- #122 Fixed encrypt type7 - -## v1.1.0 - 2022-04 - -### Added - -- #90 Uptime Conversions. -- #102 Add Ansible mapping for Nokia SrOS. -- #105 Add min_grouping_sizing to vlanlist_to_config method. -- #106 Add Nokia SrOS Config Parser. - -### Changed - -- #104 Optimize vlanconfig_to_list using builtin Regex methods. - -### Fixed - -- #99 Fixed decimal place in bits_to_name. -- #107 Fix issue when backup or intended is empty. - - -## v1.0.0 - 2021-11 - -### Added - -- #69 Normalise banner delimiter for IOS to ^C & support parsing delimiter ^ - -### Fixed - -- #79 F5 parser fix for irules with multiline single command lines. - -### Removed - -- #83 remove support for old function 'is_fqdn_valid' as prep for 1.0.0 - -## v0.2.5 - 2021-11 - -### Added - -- #76 Added wrapper for Python ipaddress methods for use with Jinja - -### Fixed - -- #75 Updated Python requirements to be loosened -- #76 Fixed doc errors with ip methods -- #77 Fixed CI pipeline for docker caching - -## v0.2.4 - 2021-11 - -### Added - -- #33 Add interface range compress function -- #53 Add get peer address function -- #59 Add bandwidth converting function -- #65 Added Docker caching -- #68 Add Fortinet Fortios Parser support - -### Changed - -- #64 CI implementation on GitHub actions - -### Fixed - -- #52 Update pyproject.toml build-server -- #55 update version in toml and init files -- #63 Fix lack of zero padding on ip to binary conversion -- #70 Fix lack of zero padding on ip to hex conversion -- #68 Update Black pinning - -## v0.2.3 - 2021-09 - -### Added - -- #45 Added a jinja2 convenience function - -### Changed - -- #46 Updated NAPALM Maps to include community drivers - -### Fixed - -- #49 Fix read the docs - -## v0.2.2 - 2021-09 - -### Added - -- #35 TCP/UDP Mappings -- #31 Interface range expansion -- #28 IPv6 Functionality to IP Module -- #34 Interface sorting - -### Changed - -- #39 Updated docs to include automation library mappings -- #41 Updated docs to include tcp/udp mappings - -### Fixed - -- Corrected contribution and attribution docs - -## v0.2.1 - 2021-06 - -### Added - -- #16 Cisco ASA Parser. - -### Changed - -- #17 Update interface mapping for Sync, TenGig, Port-channel. - -## v0.2.0 - 2021-06 - -### Fixed - -- Enable docstring tests -- Fix docstring tests -- Fix wording and links on README - -### Changed - -- Changed name of is_fqdn_valid to is_fqdn_resolvable, prepare to deprecate is_fqdn_valid -- Removed automatic import of all functions on initiation of package -- Moved interface mappings from variables to constants - -## v0.1.1 - 2021-05 - -### Added - -- Update travis configuration to release a new version from CI/CD pipeline - -## v0.1.0 - 2021-03-19 - -Initial release diff --git a/README.md b/README.md index b9c9e667..5adc023f 100644 --- a/README.md +++ b/README.md @@ -1,235 +1,40 @@ -# netutils +# Netutils -A Python library that is a collection of objects for common network automation tasks. +

+ + + +
+ + + + +
+

-This library intends to keep the following tenets: +## Overview -* Must not be any dependencies required to run the library. - * May be some optional dependencies, to be managed by the user in opt in fashion. -* Shall prefer functions over classes. -* Shall prefer a folder and file structure that is flat. -* Shall leverage docstrings as the primary documentation mechanism. - * Must provide examples in every public function. -* Shall retain a high test coverage. +A Python library that is a collection of functions that are used in the common network automation tasks. Tasks such as converting a BGP ASN to and from dotted format, normalizing an interface name, or "type 5" encrypting a password. The intention is to centralize these functions while keeping the library light. -# Function Groupings +## Documentation -Functions are grouped with like functions, such as IP or MAC address based functions. Included to date are groupings of: +Full web-based HTML documentation for this library can be found over on the [Netutils Docs](https://netutils.readthedocs.io) website: -* Bandwidth - Provides the ability to convert between various bandwidth values. -* Banner - Provides the ability to normalize the various banner delimiters. -* BGP ASN - Provides the ability to convert BGP ASN from integer to dot notation. -* Configuration - * Cleaning - Provides the ability to remove or replace lines based on regex matches. - * Compliance - Provides the ability to compare two configurations to sanely understand the differences. - * Parsing - Provides the ability to parse configuration for the minor differences that are there. -* DNS - Provides the ability to work with DNS, such as validating that a FQDN is resolvable. -* Interface - Provides the ability to work with interface names, expanding, abbreviating, and splitting the names. -* IP Address - Provides the ability to work with IP addresses, primarily exposing Python `ipaddress` functionality. -* Library Mapper - Provides mappings in expected vendor names between Netmiko, NAPALM, pyntc, ntc-templates, pyats, and scrapli. -* MAC Address - Provides the ability to work with MAC addresses such as validating or converting to integer. -* Password - Provides the ability to compare and encrypt common password schemas such as type5 and type7 Cisco passwords. -* Ping - Provides the ability to ping, currently only tcp ping. -* Protocol Mapper - Provides a mapping for protocol names to numbers and vice versa. -* Route - Provides the ability to provide a list of routes and an IP Address and return the longest prefix matched route. -* Time -Provides the ability to convert between integer time and string times. -* VLANs - Provide the ability to convert configuration into lists or lists into configuration. +- [User Guide](https://netutils.readthedocs.io/en/latest/user/lib_overview/) - Overview, Using the library, Getting Started. +- [Administrator Guide](https://netutils.readthedocs.io/en/latest/admin/install/) - How to Install, Configure, Upgrade, or Uninstall the library. +- [Developer Guide](https://netutils.readthedocs.io/en/latest/dev/contributing/) - Extending the library, Code Reference, Contribution Guide. +- [Release Notes / Changelog](https://netutils.readthedocs.io/en/latest/admin/release_notes/). +- [Frequently Asked Questions](https://netutils.readthedocs.io/en/latest/user/faq/). -# Installation +### Contributing to the Docs -Option 1: Install from PyPI. +All the Markdown source for the library documentation can be found under the [docs](https://github.com/networktocode/netutils/tree/develop/docs) folder in this repository. For simple edits, a Markdown capable editor is sufficient - clone the repository and edit away. -```bash -$ pip install netutils -``` +If you need to view the fully generated documentation site, you can build it with [mkdocs](https://www.mkdocs.org/). A container hosting the docs will be started using the invoke commands (details in the [Development Environment Guide](https://netutils.readthedocs.io/netutils/en/latest/dev/dev_environment/#docker-development-environment)) on [http://localhost:8001](http://localhost:8001). As your changes are saved, the live docs will be automatically reloaded. -Option 2: Install from a GitHub branch, such as develop as shown below. - -```bash -$ pip install git+https://github.com/networktocode/netutils.git@develop -``` - -# Examples - -While all functions come with examples in the docstrings, for quick reference of the types of problems this library intends to -solve the following examples are provided. - -The following function will help in deploying list of VLANs and match the configuration style in a standard IOS-like configurations. - -```python ->>> from netutils.vlan import vlanlist_to_config ->>> ->>> vlan_cfg = vlanlist_to_config([1, 2, 3, 5, 6, 1000, 1002, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1018]) ->>> ->>> vlan_cfg -["1-3,5,6,1000,1002,1004,1006,1008,1010,1012,1014", "1016,1018"] ->>> ->>> for index, line in enumerate(vlan_cfg): -... if index == 0: -... print(f" switchport trunk allowed vlan {line}") -... else: -... print(f" switchport trunk allowed vlan add {line}") -... - switchport trunk allowed vlan 1-3,5,6,1000,1002,1004,1006,1008,1010,1012,1014 - switchport trunk allowed vlan add 1016,1018 ->>> -``` - -You may want to compare a known password with a given encrypted password. This can help in verifying if the -passwords are as expected for compliance reasons. - -```python ->>> from netutils.password import compare_type5 ->>> ->>> compare_type5("cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") -True ->>> ->>> compare_type5("not_cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") -False ->>> -``` - -Often times interfaces will come in various different shortened names, and it is helpful to normalize them. - -```python ->>> from netutils.interface import canonical_interface_name ->>> ->>> canonical_interface_name("Gi1/0/1") -'GigabitEthernet1/0/1' ->>> ->>> canonical_interface_name("Eth1") -'Ethernet1' ->>> -``` - -These are just some examples of the many functions provided by this library. - -# Attribution - -The library was built to be a centralized place for common network automation code to be accessed. While in most cases it is -difficult, if not impossible to understand the origin of code, the following intends to describe the known motivation for where -code was derived from and in the few cases where actual code was directly taken from. Except where noted, all code is believed to -be unattributable, from @itdependsnetworks, or from another Network to Code employee. If this is in fact an error, please open an -issue, and the proper attribution will be provided. Any errors were not done out of malice, but rather the natural developer -workflow of pulling snippets of code from existing locations such as StackOverflow and Github over months and years of development. -As an example it is nearly impossible to understand the original author of Cisco type7 encryption/decryption in the sea of -available code, and remains unattributable though clearly originally developed prior to this library being created. - -Influencers -* [Netmiko](https://github.com/ktbyers/netmiko) -* [NAPALM](https://github.com/napalm-automation/napalm) -* [Ansible](https://github.com/ansible/ansible) -* [IPCal](https://github.com/ammyblabla/ipcal) -* [StackOverflow](https://stackoverflow.com/) -* [Python 3 Docs](https://docs.python.org/3/library/) - -In many instances variables and function names were reused, but the code was built from scratch to avoid any potential licensing -issues. Functions that were known to be rewritten and their known origin. - -| Function | Origin | -| -------- | ------ | -| asn_to_int | NAPALM | -| is_ip | IPCal | -| ip_to_bin | IPCal | -| get_usable_range | IPCal | -| encrypt_type7 | unknown | -| decrypt_type7 | unknown | -| vlan_to_list | Ansible | -| sanitize_config | NAPALM | - -Relevant PR's -* https://github.com/napalm-automation/napalm/pull/493 -* https://github.com/ansible/ansible/pull/39901 -* https://github.com/ansible/ansible/pull/26566 - -In building out the time conversion, the regex patterns are based on NAPALM implementation with their consent. - -# Contributing - -Pull requests are welcomed and automatically built and tested against multiple versions of Python through TravisCI. -Except for unit tests, testing is only supported on Python 3.7. - -The project is packaged with a light development environment based on `docker-compose` to help with the local development of the project and to run tests within TravisCI. - -The project is following Network to Code software development guidelines and are leveraging the following: -- Black, Pylint, Bandit, Mypy, flake8, and pydocstyle for Python linting and formatting. -- pytest, coverage, and unittest for unit tests. - -There are a number of things that are required in order to have a successful PR. - -- All new functions must contain at least 1 example in their docstrings. -- Docstrings must conform to the google docstring [convention](https://google.github.io/styleguide/pyguide.html#381-docstrings). -- Unit test for newly added functions are required. -- If applicable, tests related to config parsing and compliance must be added. -- Update the jinja2 filter (netutils.utils.jinja2_convenience_function) for any new functions (see below for details). -- If you create a new file in the `netutils` folder, you must create a new folder and `index.rst` in the docs folder (see below for details). -- Your PR must not introduce any required dependencies. You can introduce optional or development dependencies. - -## Adding to the jinja2 filter function - -To add a new function to the jinja2 filter, add a new entry to the `_JINJA2_FUNCTION_MAPPINGS` located in the `utils.py` file. When adding an entry, the key corresponds with the name to call the function and the value to the path to find the function. - -## Adding docs for a new python file - -If adding a new python file, the docs must be updated to account for the new file. - -1. Create a new folder in `docs/source/netutils` matching the name of your new file. -2. Create an `index.rst` file in that folder. -3. Add the following to the newly created file. - -```python -############################# -# ENTER THE TITLE OF THE PAGE -############################## - -.. automodule:: netutils.newfile - :members: -``` - -## CLI Helper Commands - -The project features a CLI helper based on [invoke](http://www.pyinvoke.org/) to help setup the development environment. The commands are listed below in 3 categories: -- `dev environment` -- `utility` -- `testing` - -Each command can be executed with `invoke `. Each command also has its own help `invoke --help` - -### Local dev environment - -``` - build Build all docker images. - clean Remove the project specific image. - rebuild Clean the Docker image and then rebuild without using cache. -``` - -### Utility - -``` - clean-docs Removes the build directory and all of its contents. - check-pypi-version Verify if the version specified already exists on PyPI. - cli Enter the image to perform troubleshooting or dev work. - html Creates html docs using sphinx-build command. -``` - -### Testing - -``` - bandit Run bandit to validate basic static code security analysis. - black Run black to check that Python files adhere to its style standards. - coverage Run the coverage report against pytest. - flake8 Run flake8 to check that Python files adhere to its style standards. - mypy Run mypy to validate typing-hints. - pylint Run pylint code analysis. - pydocstyle Run pydocstyle to validate docstring formatting adheres to NTC defined standards. - pytest Run pytest for the specified name and Python version. - tests Run all tests for the specified name and Python version. - yamllint Run yamllint to validate formatting adheres to NTC defined YAML standards. -``` +Any PRs with fixes or improvements are very welcome! ## Questions -Please see [the documentation](https://netutils.readthedocs.io/) for detailed documentation on how to use netutils. For any additional questions or -comments, feel free to swing by the [Network to Code slack channel](https://networktocode.slack.com/) (channel #networktocode). -Sign up [here](http://slack.networktocode.com/) - +For any questions or comments, please check the [FAQ](https://netutils.readthedocs.io/en/latest/user/faq/) first. Feel free to also swing by the [Network to Code Slack](https://networktocode.slack.com/) (channel `#networktocode`), sign up [here](http://slack.networktocode.com/) if you don't have an account. diff --git a/development_scripts.py b/development_scripts.py new file mode 100644 index 00000000..c77fc8a0 --- /dev/null +++ b/development_scripts.py @@ -0,0 +1,145 @@ +"""Developer script to generate markdown tables.""" +from jinja2 import Environment, BaseLoader, select_autoescape +from netutils.utils import _JINJA2_FUNCTION_MAPPINGS +from netutils import lib_mapper +from netutils.config.compliance import parser_map + +LIB_MAPPER_TEMPLATE = """| {{ header_src }} | | {{ header_dst }} | +| ---------- | -- | ------ | +{%- for key, val in _dict|dictsort %} +| {{ key }} | → | {{ val }} | +{%- endfor %} +""" + +PARSER_MAPPER_TEMPLATE = """| OS Name | Parser Class | +| ---------- | ------ | +{%- for key, val in _dict|dictsort %} +| {{ key }} | netutils.config.parser.{{ val.__name__ }} | +{%- endfor %} +""" + +JINJA_MAPPER_TEMPLATE = """| Filter name | Function | +| ---------- | ------ | +{%- for key, val in _dict|dictsort(false, 'value') %} +| {{ key }} | netutils.{{ val }} | +{%- endfor %} +""" + +TEMPLATE = { + "LIB_MAPPER_TEMPLATE": LIB_MAPPER_TEMPLATE, + "PARSER_MAPPER_TEMPLATE": PARSER_MAPPER_TEMPLATE, + "JINJA_MAPPER_TEMPLATE": JINJA_MAPPER_TEMPLATE, +} + + +MAPPER = { + "LIB_MAPPER_TEMPLATE": { + "ansible": { + "header_src": "NORMALIZED", + "header_dst": "ANSIBLE", + "_dict": lib_mapper.ANSIBLE_LIB_MAPPER, + "_file": "docs/user/lib_mapper/ansible.md", + }, + "ansible_reverse": { + "header_src": "ANSIBLE", + "header_dst": "NORMALIZED", + "_dict": lib_mapper.ANSIBLE_LIB_MAPPER_REVERSE, + "_file": "docs/user/lib_mapper/ansible_reverse.md", + }, + "napalm": { + "header_src": "NORMALIZED", + "header_dst": "NAPALM", + "_dict": lib_mapper.NAPALM_LIB_MAPPER, + "_file": "docs/user/lib_mapper/napalm.md", + }, + "napalm_reverse": { + "header_src": "NAPALM", + "header_dst": "NORMALIZED", + "_dict": lib_mapper.NAPALM_LIB_MAPPER_REVERSE, + "_file": "docs/user/lib_mapper/napalm_reverse.md", + }, + "ntctemplates": { + "header_src": "NORMALIZED", + "header_dst": "NTCTEMPLATES", + "_dict": lib_mapper.NTCTEMPLATES_LIB_MAPPER, + "_file": "docs/user/lib_mapper/ntctemplates.md", + }, + "ntctemplates_reverse": { + "header_src": "NTCTEMPLATES", + "header_dst": "NORMALIZED", + "_dict": lib_mapper.NTCTEMPLATES_LIB_MAPPER_REVERSE, + "_file": "docs/user/lib_mapper/ntctemplates_reverse.md", + }, + "pyats": { + "header_src": "NORMALIZED", + "header_dst": "PYATS", + "_dict": lib_mapper.PYATS_LIB_MAPPER, + "_file": "docs/user/lib_mapper/pyats.md", + }, + "pyats_reverse": { + "header_src": "PYATS", + "header_dst": "NORMALIZED", + "_dict": lib_mapper.PYATS_LIB_MAPPER_REVERSE, + "_file": "docs/user/lib_mapper/pyats_reverse.md", + }, + "pyntc": { + "header_src": "NORMALIZED", + "header_dst": "PYNTC", + "_dict": lib_mapper.PYNTC_LIB_MAPPER, + "_file": "docs/user/lib_mapper/pyntc.md", + }, + "pyntc_reverse": { + "header_src": "PYNTC", + "header_dst": "NORMALIZED", + "_dict": lib_mapper.PYNTC_LIB_MAPPER_REVERSE, + "_file": "docs/user/lib_mapper/pyntc_reverse.md", + }, + "scrapli": { + "header_src": "NORMALIZED", + "header_dst": "SCRAPLI", + "_dict": lib_mapper.SCRAPLI_LIB_MAPPER, + "_file": "docs/user/lib_mapper/scrapli.md", + }, + "scrapli_reverse": { + "header_src": "SCRAPLI", + "header_dst": "NORMALIZED", + "_dict": lib_mapper.SCRAPLI_LIB_MAPPER_REVERSE, + "_file": "docs/user/lib_mapper/scrapli_reverse.md", + }, + }, + "PARSER_MAPPER_TEMPLATE": { + "default": { + "_dict": parser_map, + "_file": "docs/dev/include_parser_list.md", + }, + }, + "JINJA_MAPPER_TEMPLATE": { + "default": { + "_dict": _JINJA2_FUNCTION_MAPPINGS, + "_file": "docs/user/include_jinja_list.md", + }, + }, +} + + +def main(test=False): + """Generate or test generation of standard files.""" + env = Environment(loader=BaseLoader, autoescape=select_autoescape()) + + for template_name, value in MAPPER.items(): + for data in value.values(): + _file = data["_file"] + output = env.from_string(TEMPLATE[template_name]).render(**data) + if test: + with open(_file, encoding="utf8") as file: + actual = file.read() + if output != actual: + return False + else: + with open(_file, "w", encoding="utf8") as file: + file.write(output) + return True + + +if __name__ == "__main__": + main() diff --git a/docs/admin/install.md b/docs/admin/install.md new file mode 100644 index 00000000..e6dba18e --- /dev/null +++ b/docs/admin/install.md @@ -0,0 +1,13 @@ +# Installation + +Option 1: Install from PyPI. + +```bash +$ pip install netutils +``` + +Option 2: Install from a GitHub branch, such as develop as shown below. + +```bash +$ pip install git+https://github.com/networktocode/netutils.git@develop +``` \ No newline at end of file diff --git a/docs/admin/release_notes/index.md b/docs/admin/release_notes/index.md new file mode 100644 index 00000000..12cb5169 --- /dev/null +++ b/docs/admin/release_notes/index.md @@ -0,0 +1,3 @@ +# Release Notes + +All the published release notes can be found via the navigation menu. All patch releases are included in the same minor release (e.g. `v1.2`) document. diff --git a/docs/admin/release_notes/version_0.1.md b/docs/admin/release_notes/version_0.1.md new file mode 100644 index 00000000..baa53062 --- /dev/null +++ b/docs/admin/release_notes/version_0.1.md @@ -0,0 +1,15 @@ +# v0.1 Release Notes + +## Release Overview + +- Initial Release + +## [v0.1.1] - 2021-05 + +### Added + +- Update travis configuration to release a new version from CI/CD pipeline. + +## [v0.1.0] - 2021-03-19 + +- Initial release. diff --git a/docs/admin/release_notes/version_0.2.md b/docs/admin/release_notes/version_0.2.md new file mode 100644 index 00000000..534b86bd --- /dev/null +++ b/docs/admin/release_notes/version_0.2.md @@ -0,0 +1,98 @@ +# v0.2 Release Notes + +## Release Overview + +- Update docs, docstrings, and docstring tests +- Changed name of is_fqdn_valid to is_fqdn_resolvable, prepare to deprecate is_fqdn_valid +- Removed automatic import of all functions on initiation of package +- Moved interface mappings from variables to constants + +## [v0.2.5] - 2021-11 + +### Added + +- [#76](https://github.com/networktocode/netutils/issues/76) Added wrapper for Python ipaddress methods for use with Jinja + +### Fixed + +- [#75](https://github.com/networktocode/netutils/issues/75) Updated Python requirements to be loosened +- [#76](https://github.com/networktocode/netutils/issues/76) Fixed doc errors with ip methods +- [#77](https://github.com/networktocode/netutils/issues/77) Fixed CI pipeline for docker caching + +## [v0.2.4] - 2021-11 + +### Added + +- [#33](https://github.com/networktocode/netutils/issues/33) Add interface range compress function +- [#53](https://github.com/networktocode/netutils/issues/53) Add get peer address function +- [#59](https://github.com/networktocode/netutils/issues/59) Add bandwidth converting function +- [#65](https://github.com/networktocode/netutils/issues/65) Added Docker caching +- [#68](https://github.com/networktocode/netutils/issues/68) Add Fortinet Fortios Parser support + +### Changed + +- [#64](https://github.com/networktocode/netutils/issues/64) CI implementation on GitHub actions + +### Fixed + +- [#52](https://github.com/networktocode/netutils/issues/52) Update pyproject.toml build-server +- [#55](https://github.com/networktocode/netutils/issues/55) update version in toml and init files +- [#63](https://github.com/networktocode/netutils/issues/63) Fix lack of zero padding on ip to binary conversion +- [#70](https://github.com/networktocode/netutils/issues/70) Fix lack of zero padding on ip to hex conversion +- [#68](https://github.com/networktocode/netutils/issues/68) Update Black pinning + +## [v0.2.3] - 2021-09 + +### Added + +- [#45](https://github.com/networktocode/netutils/issues/45) Added a jinja2 convenience function + +### Changed + +- [#46](https://github.com/networktocode/netutils/issues/46) Updated NAPALM Maps to include community drivers + +### Fixed + +- [#49](https://github.com/networktocode/netutils/issues/49) Fix read the docs + +## [v0.2.2] - 2021-09 + +### Added + +- [#35](https://github.com/networktocode/netutils/issues/35) TCP/UDP Mappings +- [#31](https://github.com/networktocode/netutils/issues/31) Interface range expansion +- [#28](https://github.com/networktocode/netutils/issues/28) IPv6 Functionality to IP Module +- [#34](https://github.com/networktocode/netutils/issues/34) Interface sorting + +### Changed + +- [#39](https://github.com/networktocode/netutils/issues/39) Updated docs to include automation library mappings +- [#41](https://github.com/networktocode/netutils/issues/41) Updated docs to include tcp/udp mappings + +### Fixed + +- Corrected contribution and attribution docs + +## [v0.2.1] - 2021-06 + +### Added + +- [#16](https://github.com/networktocode/netutils/issues/16) Cisco ASA Parser. + +### Changed + +- [#17](https://github.com/networktocode/netutils/issues/17) Update interface mapping for Sync, TenGig, Port-channel. + +## [v0.2.0] - 2021-06 + +### Fixed + +- Enable docstring tests +- Fix docstring tests +- Fix wording and links on README + +### Changed + +- Changed name of is_fqdn_valid to is_fqdn_resolvable, prepare to deprecate is_fqdn_valid +- Removed automatic import of all functions on initiation of package +- Moved interface mappings from variables to constants \ No newline at end of file diff --git a/docs/admin/release_notes/version_1.0.md b/docs/admin/release_notes/version_1.0.md new file mode 100644 index 00000000..b549f075 --- /dev/null +++ b/docs/admin/release_notes/version_1.0.md @@ -0,0 +1,21 @@ +# v1.0 Release Notes + +## Release Overview + +- Commit to SemVer +- F5 fixes + +## v1.0.0 - 2021-11 + +### Added + +- [#69](https://github.com/networktocode/netutils/issues/69) Normalise banner delimiter for IOS to ^C & support parsing delimiter ^. + +### Fixed + +- [#79](https://github.com/networktocode/netutils/issues/79) F5 parser fix for irules with multiline single command lines. + +### Removed + +- [#83](https://github.com/networktocode/netutils/issues/83) Remove support for old function 'is_fqdn_valid' as prep for 1.0.0. + diff --git a/docs/admin/release_notes/version_1.1.md b/docs/admin/release_notes/version_1.1.md new file mode 100644 index 00000000..58711846 --- /dev/null +++ b/docs/admin/release_notes/version_1.1.md @@ -0,0 +1,23 @@ +# v1.1 Release Notes + +## Release Overview + +- Added Nokia SrOS + +## [v1.1.0] - 2022-04 + +### Added + +- [#90](https://github.com/networktocode/netutils/issues/90) Uptime Conversions. +- [#102](https://github.com/networktocode/netutils/issues/102) Add Ansible mapping for Nokia SrOS. +- [#105](https://github.com/networktocode/netutils/issues/105) Add min_grouping_sizing to vlanlist_to_config method. +- [#106](https://github.com/networktocode/netutils/issues/106) Add Nokia SrOS Config Parser. + +### Changed + +- [#104](https://github.com/networktocode/netutils/issues/104) Optimize vlanconfig_to_list using builtin Regex methods. + +### Fixed + +- [#99](https://github.com/networktocode/netutils/issues/99) Fixed decimal place in bits_to_name. +- [#107](https://github.com/networktocode/netutils/issues/107) Fix issue when backup or intended is empty. \ No newline at end of file diff --git a/docs/admin/release_notes/version_1.2.md b/docs/admin/release_notes/version_1.2.md new file mode 100644 index 00000000..9488bb6a --- /dev/null +++ b/docs/admin/release_notes/version_1.2.md @@ -0,0 +1,27 @@ +# v1.2 Release Notes + +## Release Overview + +- Added type hints and mypy testing +- Encrypt type7 updated + + +## [v1.2.0] - 2022-08 + +### Added + +- [#128](https://github.com/networktocode/netutils/issues/128) Documentation for Nokia SROS duplicate lines/duplicate line detection +- [#138](https://github.com/networktocode/netutils/issues/138) Added nxos_ssh to Napalm mapper + +### Changed + +- [#113](https://github.com/networktocode/netutils/issues/113) Updated lib mapping docs +- [#115](https://github.com/networktocode/netutils/issues/115) Switched build backend to poetry-core +- [#121](https://github.com/networktocode/netutils/issues/121) Update banner parsing for EOS +- [#129](https://github.com/networktocode/netutils/issues/129) Add type hints to the whole project and mypy testing setup and CI +- [#134](https://github.com/networktocode/netutils/issues/134) Updated CODEOWNERS + +### Fixed + +- [#122](https://github.com/networktocode/netutils/issues/122) Fixed encrypt type7 + diff --git a/docs/admin/uninstall.md b/docs/admin/uninstall.md new file mode 100644 index 00000000..c6f249a5 --- /dev/null +++ b/docs/admin/uninstall.md @@ -0,0 +1,7 @@ +# Uninstall + +Uninstall from environment. + +```bash +$ pip uninstall netutils +``` \ No newline at end of file diff --git a/docs/admin/upgrade.md b/docs/admin/upgrade.md new file mode 100644 index 00000000..6204d1fa --- /dev/null +++ b/docs/admin/upgrade.md @@ -0,0 +1,7 @@ +# Upgrading the Library + +Upgrade from PyPI. + +```bash +$ pip install netutils --upgrade +``` \ No newline at end of file diff --git a/docs/assets/extra.css b/docs/assets/extra.css new file mode 100644 index 00000000..50884f4a --- /dev/null +++ b/docs/assets/extra.css @@ -0,0 +1,152 @@ +:root>* { + --md-accent-fg-color: #ff8504; + --md-primary-fg-color: #ff8504; + --md-typeset-a-color: #0097ff; +} + +[data-md-color-scheme="slate"] { + --md-default-bg-color: hsla(var(--md-hue), 0%, 15%, 1); + --md-typeset-a-color: #0097ff; +} + +/* Accessibility: Increase fonts for dark theme */ +[data-md-color-scheme="slate"] .md-typeset { + font-size: 0.9rem; +} + +[data-md-color-scheme="slate"] .md-typeset table:not([class]) { + font-size: 0.7rem; +} + +.md-tabs__link { + font-size: 0.8rem; +} + +.md-tabs__link--active { + color: var(--md-primary-fg-color); +} + +.md-header__button.md-logo :is(img, svg) { + height: 2rem; +} + +.md-header__button.md-logo :-webkit-any(img, svg) { + height: 2rem; +} + +.md-header__title { + font-size: 1.2rem; +} + +img.logo { + height: 100px; +} + +img.copyright-logo { + height: 24px; + vertical-align: middle; +} + +[data-md-color-primary=black] .md-header { + background-color: #212121; +} + +@media screen and (min-width: 76.25em) { + [data-md-color-primary=black] .md-tabs { + background-color: #212121; + } +} + +/* Customization for mkdocstrings */ +/* Indentation. */ +div.doc-contents:not(.first) { + padding-left: 25px; + border-left: .2rem solid var(--md-typeset-table-color); +} + +/* Mark external links as such. */ +a.autorefs-external::after { + /* https://primer.style/octicons/arrow-up-right-24 */ + background-image: url('data:image/svg+xml,'); + content: ' '; + + display: inline-block; + position: relative; + top: 0.1em; + margin-left: 0.2em; + margin-right: 0.1em; + + height: 1em; + width: 1em; + border-radius: 100%; + background-color: var(--md-typeset-a-color); +} + +a.autorefs-external:hover::after { + background-color: var(--md-accent-fg-color); +} + + +/* Customization for mkdocs-version-annotations */ +:root { + /* Icon for "version-added" admonition: Material Design Icons "plus-box-outline" */ + --md-admonition-icon--version-added: url('data:image/svg+xml;charset=utf-8,'); + /* Icon for "version-changed" admonition: Material Design Icons "delta" */ + --md-admonition-icon--version-changed: url('data:image/svg+xml;charset=utf-8,'); + /* Icon for "version-removed" admonition: Material Design Icons "minus-circle-outline" */ + --md-admonition-icon--version-removed: url('data:image/svg+xml;charset=utf-8,'); +} + +/* "version-added" admonition in green */ +.md-typeset .admonition.version-added, +.md-typeset details.version-added { + border-color: rgb(0, 200, 83); +} + +.md-typeset .version-added>.admonition-title, +.md-typeset .version-added>summary { + background-color: rgba(0, 200, 83, .1); +} + +.md-typeset .version-added>.admonition-title::before, +.md-typeset .version-added>summary::before { + background-color: rgb(0, 200, 83); + -webkit-mask-image: var(--md-admonition-icon--version-added); + mask-image: var(--md-admonition-icon--version-added); +} + +/* "version-changed" admonition in orange */ +.md-typeset .admonition.version-changed, +.md-typeset details.version-changed { + border-color: rgb(255, 145, 0); +} + +.md-typeset .version-changed>.admonition-title, +.md-typeset .version-changed>summary { + background-color: rgba(255, 145, 0, .1); +} + +.md-typeset .version-changed>.admonition-title::before, +.md-typeset .version-changed>summary::before { + background-color: rgb(255, 145, 0); + -webkit-mask-image: var(--md-admonition-icon--version-changed); + mask-image: var(--md-admonition-icon--version-changed); +} + +/* "version-removed" admonition in red */ +.md-typeset .admonition.version-removed, +.md-typeset details.version-removed { + border-color: rgb(255, 82, 82); +} + +.md-typeset .version-removed>.admonition-title, +.md-typeset .version-removed>summary { + background-color: rgba(255, 82, 82, .1); +} + +.md-typeset .version-removed>.admonition-title::before, +.md-typeset .version-removed>summary::before { + background-color: rgb(255, 82, 82); + -webkit-mask-image: var(--md-admonition-icon--version-removed); + mask-image: var(--md-admonition-icon--version-removed); +} diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico new file mode 100644 index 00000000..9685c83b Binary files /dev/null and b/docs/assets/favicon.ico differ diff --git a/docs/assets/networktocode_bw.png b/docs/assets/networktocode_bw.png new file mode 100644 index 00000000..075c4926 Binary files /dev/null and b/docs/assets/networktocode_bw.png differ diff --git a/docs/assets/networktocode_logo.png b/docs/assets/networktocode_logo.png new file mode 100644 index 00000000..b2a3cba2 Binary files /dev/null and b/docs/assets/networktocode_logo.png differ diff --git a/docs/assets/networktocode_logo.svg b/docs/assets/networktocode_logo.svg new file mode 100644 index 00000000..348e5241 --- /dev/null +++ b/docs/assets/networktocode_logo.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/overrides/partials/copyright.html b/docs/assets/overrides/partials/copyright.html new file mode 100644 index 00000000..b623894d --- /dev/null +++ b/docs/assets/overrides/partials/copyright.html @@ -0,0 +1,20 @@ + + + + + +
diff --git a/docs/dev/arch_decision.md b/docs/dev/arch_decision.md new file mode 100644 index 00000000..ff0d58ac --- /dev/null +++ b/docs/dev/arch_decision.md @@ -0,0 +1,16 @@ +# Architecture Decision Records + +The intention is to document deviations from a standard pattern. + +## Optional Import for OUI Mapping + +The following code is purposeful to ensure that we only import the large `OUI_MAPPINGS` if required. This does not effect the jinja mappings which will load the larger oui_mappings file. + +```python +@_valid_mac +def get_oui(mac: str) -> str: + from netutils.oui_mappings import OUI_MAPPINGS # pylint: disable=import-outside-toplevel +``` +## Has Lib + +_Pending updates from napalm inclusion_ \ No newline at end of file diff --git a/docs/dev/attribution.md b/docs/dev/attribution.md new file mode 100644 index 00000000..135ecf6e --- /dev/null +++ b/docs/dev/attribution.md @@ -0,0 +1,33 @@ +# Attribution + +The library was built to be a centralized place for common network automation code to be accessed. While in most cases it is difficult, if not impossible to understand the origin of code, the following intends to describe the known motivation for where code was derived from and in the few cases where actual code was directly taken from. Except where noted, all code is believed to be unattributable, from @itdependsnetworks, or from another Network to Code employee. If this is in fact an error, please open an issue, and the proper attribution will be provided. Any errors were not done out of malice, but rather the natural developer workflow of pulling snippets of code from existing locations such as StackOverflow and Github over months and years of development. As an example it is nearly impossible to understand the original author of Cisco type7 encryption/decryption in the sea of available code, and remains unattributable though clearly originally developed prior to this library being created. + +Influencers + +- [Netmiko](https://github.com/ktbyers/netmiko) +- [NAPALM](https://github.com/napalm-automation/napalm) +- [Ansible](https://github.com/ansible/ansible) +- [IPCal](https://github.com/ammyblabla/ipcal) +- [StackOverflow](https://stackoverflow.com/) +- [Python 3 Docs](https://docs.python.org/3/library/) + +In many instances variables and function names were reused, but the code was built from scratch to avoid any potential licensing issues. Functions that were known to be rewritten and their known origin. + +| Function | Origin | +| ---------------- | ------- | +| asn_to_int | NAPALM | +| is_ip | IPCal | +| ip_to_bin | IPCal | +| get_usable_range | IPCal | +| encrypt_type7 | unknown | +| decrypt_type7 | unknown | +| vlan_to_list | Ansible | +| sanitize_config | NAPALM | + +Relevant PR's + +- [NAPALM #493](https://github.com/napalm-automation/napalm/pull/493) +- [Ansible #39901](https://github.com/ansible/ansible/pull/39901) +- [Ansible #26566](https://github.com/ansible/ansible/pull/26566) + +In building out the time conversion, the regex patterns are based on NAPALM implementation with their consent. \ No newline at end of file diff --git a/docs/dev/code_reference/asn.md b/docs/dev/code_reference/asn.md new file mode 100644 index 00000000..11646459 --- /dev/null +++ b/docs/dev/code_reference/asn.md @@ -0,0 +1,5 @@ +# BGP ASNs + +::: netutils.asn + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/bandwidth.md b/docs/dev/code_reference/bandwidth.md new file mode 100644 index 00000000..7fb2c861 --- /dev/null +++ b/docs/dev/code_reference/bandwidth.md @@ -0,0 +1,5 @@ +# Bandwidth + +::: netutils.bandwidth + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/banner.md b/docs/dev/code_reference/banner.md new file mode 100644 index 00000000..494a3050 --- /dev/null +++ b/docs/dev/code_reference/banner.md @@ -0,0 +1,5 @@ +# Banner + +::: netutils.banner + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/configs.md b/docs/dev/code_reference/configs.md new file mode 100644 index 00000000..4ae07072 --- /dev/null +++ b/docs/dev/code_reference/configs.md @@ -0,0 +1,5 @@ +# Configs + +::: netutils.config + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/dns.md b/docs/dev/code_reference/dns.md new file mode 100644 index 00000000..b9db6de9 --- /dev/null +++ b/docs/dev/code_reference/dns.md @@ -0,0 +1,5 @@ +# DNS + +::: netutils.dns + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/index.md b/docs/dev/code_reference/index.md new file mode 100644 index 00000000..dba1498e --- /dev/null +++ b/docs/dev/code_reference/index.md @@ -0,0 +1,3 @@ +# Code Reference + +Auto-generated code reference documentation from docstrings. This is the official method to document examples of using the code, this ensures that there is always an example and that the example is accurate. diff --git a/docs/dev/code_reference/interface.md b/docs/dev/code_reference/interface.md new file mode 100644 index 00000000..83d0097b --- /dev/null +++ b/docs/dev/code_reference/interface.md @@ -0,0 +1,5 @@ +# Interface + +::: netutils.interface + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/ip.md b/docs/dev/code_reference/ip.md new file mode 100644 index 00000000..092ee677 --- /dev/null +++ b/docs/dev/code_reference/ip.md @@ -0,0 +1,5 @@ +# IP Address + +::: netutils.ip + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/lib_mapping.md b/docs/dev/code_reference/lib_mapping.md new file mode 100644 index 00000000..4994e259 --- /dev/null +++ b/docs/dev/code_reference/lib_mapping.md @@ -0,0 +1,7 @@ +# Library Mapping + +::: netutils.lib_mapper + options: + show_submodules: True + +Review how to use code within the [user documentation](../../user/lib_use_cases_lib_mapper.md) \ No newline at end of file diff --git a/docs/dev/code_reference/mac.md b/docs/dev/code_reference/mac.md new file mode 100644 index 00000000..80f9bf51 --- /dev/null +++ b/docs/dev/code_reference/mac.md @@ -0,0 +1,5 @@ +# Mac Address + +::: netutils.mac + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/password.md b/docs/dev/code_reference/password.md new file mode 100644 index 00000000..11646459 --- /dev/null +++ b/docs/dev/code_reference/password.md @@ -0,0 +1,5 @@ +# BGP ASNs + +::: netutils.asn + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/ping.md b/docs/dev/code_reference/ping.md new file mode 100644 index 00000000..88e1f01e --- /dev/null +++ b/docs/dev/code_reference/ping.md @@ -0,0 +1,5 @@ +# Ping + +::: netutils.ping + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/protocol_mapper.md b/docs/dev/code_reference/protocol_mapper.md new file mode 100644 index 00000000..3bd23057 --- /dev/null +++ b/docs/dev/code_reference/protocol_mapper.md @@ -0,0 +1,7 @@ +# Protocol Mapper + +::: netutils.protocol_mapper + options: + show_submodules: True + +Review how to use code within the [user documentation](../../user/lib_use_cases_protocol_mappers.md) \ No newline at end of file diff --git a/docs/dev/code_reference/route.md b/docs/dev/code_reference/route.md new file mode 100644 index 00000000..fb34c29c --- /dev/null +++ b/docs/dev/code_reference/route.md @@ -0,0 +1,5 @@ +# Route + +::: netutils.route + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/time.md b/docs/dev/code_reference/time.md new file mode 100644 index 00000000..2b09fd26 --- /dev/null +++ b/docs/dev/code_reference/time.md @@ -0,0 +1,5 @@ +# Time + +::: netutils.time + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/code_reference/utils.md b/docs/dev/code_reference/utils.md new file mode 100644 index 00000000..b6f61e86 --- /dev/null +++ b/docs/dev/code_reference/utils.md @@ -0,0 +1,7 @@ +# Protocol Mapper + +::: netutils.utils + options: + show_submodules: True + +Review how to use code within the [user documentation](../../user/lib_use_cases_jinja_filters.md) \ No newline at end of file diff --git a/docs/dev/code_reference/vlan.md b/docs/dev/code_reference/vlan.md new file mode 100644 index 00000000..b619743d --- /dev/null +++ b/docs/dev/code_reference/vlan.md @@ -0,0 +1,5 @@ +# VLAN + +::: netutils.vlan + options: + show_submodules: True \ No newline at end of file diff --git a/docs/dev/contributing.md b/docs/dev/contributing.md new file mode 100644 index 00000000..b3ac7cb5 --- /dev/null +++ b/docs/dev/contributing.md @@ -0,0 +1,102 @@ +# Contributing + +Pull requests are welcomed and automatically built and tested against multiple versions of Python through GitHub Actions. + +Except for unit tests, testing is only supported on Python 3.9. + +The project is packaged with a light development environment based on `Docker` to help with the local development of the project and to run tests within GitHub Actions. + +The project is following Network to Code software development guidelines and are leveraging the following: + +- Black, Pylint, Bandit, Mypy, flake8, and pydocstyle for Python linting and formatting. +- pytest, coverage, and unittest for unit tests. + +There are a number of things that are required in order to have a successful PR. + +- All new functions must contain at least 1 example in their docstrings. +- Docstrings must conform to the google docstring [convention](https://google.github.io/styleguide/pyguide.html#381-docstrings). +- Unit test for newly added functions are required. +- If applicable, tests related to config parsing and compliance must be added. +- Update the jinja2 filter (netutils.utils.jinja2_convenience_function) for any new functions (see below for details). +- If you create a new file in the `netutils` folder, you must add a new file for including Python and update `mkdocs.yml` to include the addition (see below for details). +- Your PR must not introduce any required dependencies. You can introduce optional or development dependencies. + +Documentation is built using [mkdocs](https://www.mkdocs.org/). The [Docker based development environment](dev_environment.md#docker-development-environment) can be started by running `invoke docs` [http://localhost:8001](http://localhost:8001) that auto-refreshes when you make any changes to your local files. + +## Adding docs for a new python file + +If adding a new python file, the docs must be updated to account for the new file. + +1. Create a new markdown file in `docs/dev/code_reference` matching the name of your new file such as `dns.md`. +2. Apply the following pattern to the newly created file. +3. Update the `mydocs.yml` to point to the new file + +```python +# DNS + +::: netutils.dns + options: + show_submodules: True +``` + +Update the mkdocs as appropriate, as shown in this truncated example of adding DNS. + +```yaml +nav: + - Developer Guide: + - Extending the Library: "dev/extending.md" + - Contributing to the Library: "dev/contributing.md" + - Development Environment: "dev/dev_environment.md" + - Development Config: "dev/dev_config.md" + - Code Attribution to the Library: "dev/attribution.md" + - Code Reference: + - "dev/code_reference/index.md" + - ASN: "dev/code_reference/asn.md" + - Bandwidth: "dev/code_reference/bandwidth.md" + - Banner: "dev/code_reference/banner.md" + - Configs: "dev/code_reference/configs.md" + - DNS: "dev/code_reference/dns.md" <<-- Added +``` + +## Adding Lib Mapper, jinja2 filter, or Config Parser + +When adding to any of these features, you must run the `development_scripts` from the root directory. This process requires having Jinja2 on the machine that will run the process. This is automatically tested via pytest. + +## Adding to the jinja2 filter function + +To add a new function to the jinja2 filter, add a new entry to the `_JINJA2_FUNCTION_MAPPINGS` located in the `utils.py` file. When adding an entry, the key corresponds with the name to call the function and the value to the path to find the function. + + +## Branching Policy + +The branching policy includes the following tenets: + +- The develop branch is the primary branch to develop off of. +- If there is a reason to have a patch version, the maintainers may use cherry-picking strategy. +- PRs intended to add new features should be sourced from the develop branch. +- PRs intended to address bug fixes and security patches should be sourced from the develop branch. +- PRs intended to add new features that break backward compatibility should be discussed before a PR is created. + +Netutils will observe semantic versioning, as of 1.0. This may result in an quick turn around in minor versions to keep pace with an ever growing feature set. + +## Release Policy + +Netutils has currently no intended scheduled release schedule, and will release new features in minor versions. + +When a new release is created the following should happen. + +- A release PR is created with: + - Update to the changelog in `docs/admin/release_notes/version_..md` file to reflect the changes. + - Change the version from `..-beta` to `..` in pyproject.toml. + - Set the PR to the main +- Ensure the tests for the PR pass. +- Merge the PR. +- Create a new tag: + - The tag should be in the form of `v..`. + - The title should be in the form of `v..`. + - The description should be the changes that were added to the `version_..md` document. +- If merged into `main`, then push from `main` to `develop`, in order to retain the merge commit created when the PR was merged +- A post release PR is created with. + - Change the version from `..` to `..-beta` pyproject.toml. + - Set the PR to the `develop`. + - Once tests pass, merge. \ No newline at end of file diff --git a/docs/dev/dev_config.md b/docs/dev/dev_config.md new file mode 100644 index 00000000..ae5462bd --- /dev/null +++ b/docs/dev/dev_config.md @@ -0,0 +1,71 @@ +# Config Parsers Development + +## Current Included Parsers + +--8<-- "docs/dev/include_parser_list.md" + +## Building for Actual Use Cases + +The library attempts to model actual configuration as shown in the running configuration, traditionally shown with a `show run` or similar command. Accounting for use cases that do not exist in the running configuration, are generally outside the scope of the project. + +There are occasions where there will be a exceptions for valid running configuration and will be documented below. + +### Fortinet Fortios Parser + +In order to support html blocks that exist in Fortios configurations, some preprocessing is executed, this is a regex that specifically grabs everything between quotes after the 'set buffer' sub-command. It's explicitly looking for double quote followed by a newline ("\n) to end the captured data. This support for html data will not support any other html that doesn't follow this convention. + +### F5 Parser + +The "ltm rule" configuration sections are not uniform nor standardized; therefor, these sections are completely removed from the configuration in a preprocessing event. + +### Nokia SROS Parser + +The section banners have been simplified to extract the section header itself. This means that `echo "System Configuration"` will be converted to just "System Configuration". + +### Duplicate Line Detection + +In some circumstances replacing lines, such as secrets without uniqueness in the replacement, will result in duplicated lines that are invalid configuration, such as:: + +```text +snmp-server community <> RO SNMP_ACL_RO +snmp-server community <> RO SNMP_ACL_RO +``` + +There are some known use cases, such as the below that are considered:: + +```text +router bgp 6500 + bgp router-id 10.0.0.11 + ! + address-family ipv4 unicast + redistribute connected + exit-address-family <--- duplicated hierarchy + ! + address-family l2vpn evpn + neighbor underlay activate + exit-address-family <--- duplicated hierarchy +``` + +Documented use cases that are actual configuration on a network device are considered valid and should be opened for bug fixes. However, configuration that does not actually exist on the running config of network devices are out of scope for the parser. + +## New Parsers + + +There are a series of considerations documented below, when developing a new parser. + +- Creation of a new class that must be created in `netutils/config/parser.py` file. +- Creation of a parser class that inherits from the class `BaseConfigParser` in the Python Method Resolution Order (MRO). + - In nearly all cases should inherit directory off of `BaseSpaceConfigParser` or `BaseBraceConfigParser`. + - `BaseSpaceConfigParser` is for Cisco IOS-like configurations. + - `BaseBraceConfigParser` is for JUNOS-like configurations that use curly braces. +- Create the class name in the format of `{os_name.title()}ConfigParser`. + - The classes `__init__` method must keep true to the signature or `__init__(self, config)`. + - The class must provide a `self.config_lines` that is a list of `ConfigLine` named tuples. +- Build tests for the `tests/unit/mock/config/compliance/{os_name}/*` and `tests/unit/mock/config/parser/{os_name}/*`. +- Add to `netutils/config/compliance.py` the `parser_map`, that maps the name of the parser to the Plugin. +- Fill out docstrings in the class and methods within the class that describe the parameters and an Example that compiles. +- The following tips will generally be applicable. + - Generally a class method should provide a `comment_chars` and `banner_start` as well as sometimes `banner_end`. + - Generally on the `__init__` should call the `build_config_relationship` method. + - Often can inherit directly from `CiscoConfigParser`. + - Observe the existing patterns, make use of `super`, and inheritance to reuse existing code. \ No newline at end of file diff --git a/docs/dev/dev_environment.md b/docs/dev/dev_environment.md new file mode 100644 index 00000000..01cd8762 --- /dev/null +++ b/docs/dev/dev_environment.md @@ -0,0 +1,103 @@ +# Building Your Development Environment + +## Quickstart + +The development environment can be used in two ways: + +1. `Recommended` All services are spun up using Docker and a local mount so you can develop locally, but Netutils is spun up within the Docker container. +2. With a local poetry environment if you wish to develop outside of Docker. + +This is a quick reference guide if you're already familiar with the development environment provided, which you can read more about later in this document. + +### Invoke + +The [Invoke](http://www.pyinvoke.org/) library is used to provide some helper commands based on the environment. There are a few configuration parameters which can be passed to Invoke to override the default configuration: + +- `local`: a boolean flag indicating if invoke tasks should be run on the host or inside the docker containers (default: False, commands will be run in docker containers) + +Using **Invoke** these configuration options can be overridden using [several methods](https://docs.pyinvoke.org/en/stable/concepts/configuration.html). Perhaps the simplest is setting an environment variable `INVOKE_NETUTILS_VARIABLE_NAME` where `VARIABLE_NAME` is the variable you are trying to override. There is an example `invoke.yml` (`invoke.example.yml`) in this directory which can be used as a starting point. + +### Docker Development Environment + +!!! tip + This is the recommended option for development. + +This project is managed by [Python Poetry](https://python-poetry.org/) and has a few requirements to setup your development environment: + +1. Install Poetry, see the [Poetry Documentation](https://python-poetry.org/docs/#installation) for your operating system. +2. Install Docker, see the [Docker documentation](https://docs.docker.com/get-docker/) for your operating system. + +Once you have Poetry and Docker installed you can run the following commands (in the root of the repository) to install all other development dependencies in an isolated Python virtual environment: + +```shell +poetry shell +poetry install +cp development/creds.example.env development/creds.env +invoke build +invoke start +``` + +Live documentation can be viewed at [http://localhost:8001](http://localhost:8001). + +To either stop or destroy the development environment use the following options. + +- **invoke stop** - Stop the containers, but keep all underlying systems intact +- **invoke destroy** - Stop and remove all containers, volumes, etc. (This results in data loss due to the volume being deleted) + +## Poetry + +Poetry is used in lieu of the "virtualenv" commands and is leveraged in both environments. The virtual environment will provide all of the Python packages required to manage the development environment such as **Invoke**. See the [Local Development Environment](#local-poetry-development-environment) section to see how to install Netutils if you're going to be developing locally (i.e. not using the Docker container). + +The `pyproject.toml` file outlines all of the relevant dependencies for the project: + +- `tool.poetry.dependencies` - the main list of dependencies. +- `tool.poetry.dev-dependencies` - development dependencies, to facilitate linting, testing, and documentation building. + +The `poetry shell` command is used to create and enable a virtual environment managed by Poetry, so all commands ran going forward are executed within the virtual environment. This is similar to running the `source venv/bin/activate` command with virtualenvs. To install project dependencies in the virtual environment, you should run `poetry install` - this will install **both** project and development dependencies. + +For more details about Poetry and its commands please check out its [online documentation](https://python-poetry.org/docs/). + +## Full Docker Development Environment + +This project is set up with a number of **Invoke** tasks consumed as simple CLI commands to get developing fast. You'll use a few `invoke` commands to get your environment up and running. + +## CLI Helper Commands + +The project features a CLI helper based on [invoke](http://www.pyinvoke.org/) to help setup the development environment. The commands are listed below in 3 categories: +- `dev environment` +- `utility` +- `testing` + +Each command can be executed with `invoke `. Each command also has its own help `invoke --help` + +### Local dev environment + +``` + build Build all docker images. + clean Remove the project specific image. + docs Build and serve docs locally. + rebuild Clean the Docker image and then rebuild without using cache. + +``` + +### Utility + +``` + cli Enter the image to perform troubleshooting or dev work. + clean-container Remove stopped containers that source for image `netutils:` +``` + +### Testing + +``` + bandit Run bandit to validate basic static code security analysis. + black Run black to check that Python files adhere to its style standards. + coverage Run the coverage report against pytest. + flake8 Run flake8 to check that Python files adhere to its style standards. + mypy Run mypy to validate typing-hints. + pylint Run pylint code analysis. + pydocstyle Run pydocstyle to validate docstring formatting adheres to NTC defined standards. + pytest Run pytest for the specified name and Python version. + tests Run all tests for the specified name and Python version. + yamllint Run yamllint to validate formatting adheres to NTC defined YAML standards. +``` \ No newline at end of file diff --git a/docs/dev/extending.md b/docs/dev/extending.md new file mode 100644 index 00000000..e974b82a --- /dev/null +++ b/docs/dev/extending.md @@ -0,0 +1,4 @@ +# Extending the Library + +Extending the library is welcome, however it is best to open an issue first, to ensure that a PR would be accepted and makes sense in terms of features and design. + diff --git a/docs/dev/include_parser_list.md b/docs/dev/include_parser_list.md new file mode 100644 index 00000000..cf94b258 --- /dev/null +++ b/docs/dev/include_parser_list.md @@ -0,0 +1,12 @@ +| OS Name | Parser Class | +| ---------- | ------ | +| arista_eos | netutils.config.parser.EOSConfigParser | +| bigip_f5 | netutils.config.parser.F5ConfigParser | +| cisco_aireos | netutils.config.parser.AIREOSConfigParser | +| cisco_asa | netutils.config.parser.ASAConfigParser | +| cisco_ios | netutils.config.parser.IOSConfigParser | +| cisco_nxos | netutils.config.parser.NXOSConfigParser | +| fortinet_fortios | netutils.config.parser.FortinetConfigParser | +| juniper_junos | netutils.config.parser.JunosConfigParser | +| linux | netutils.config.parser.LINUXConfigParser | +| nokia_sros | netutils.config.parser.NokiaConfigParser | \ No newline at end of file diff --git a/docs/images/.keep b/docs/images/.keep new file mode 100644 index 00000000..e69de29b diff --git a/docs/images/icon-Netutils.png b/docs/images/icon-Netutils.png new file mode 100644 index 00000000..7ae2f426 Binary files /dev/null and b/docs/images/icon-Netutils.png differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..f32fd72b --- /dev/null +++ b/docs/index.md @@ -0,0 +1,6 @@ +--- +hide: + - navigation +--- + +--8<-- "README.md" diff --git a/docs/requirements.txt b/docs/requirements.txt index 9b0a1811..f403e1aa 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,8 @@ -m2r2==0.2.7 -mistune==0.8.4 -Sphinx -toml -sphinx-rtd-theme \ No newline at end of file +mkdocs==1.3.1 +# Material for MkDocs theme +mkdocs-material==8.3.9 +# Render custom markdown for version added/changed/remove notes +mkdocs-version-annotations==1.0.0 +# Automatic documentation from sources, for MkDocs +mkdocstrings==0.19 +mkdocstrings-python==0.7.1 \ No newline at end of file diff --git a/docs/source/_static/schema-page.css b/docs/source/_static/schema-page.css deleted file mode 100644 index 78f9f02c..00000000 --- a/docs/source/_static/schema-page.css +++ /dev/null @@ -1,62 +0,0 @@ -body { - font-family: 'Fira Sans', 'Noto Sans', 'Source Sans Pro', 'Segoe UI', Roboto, 'Lucida Sans Unicode', 'Lucida Grande', 'DejaVu Sans', sans-serif; -} -@media (min-width: 60em) { - body { - display: flex; - flex-direction: row; - } -} -#jschemer-nav { - min-width: 15rem; - padding: 1em; -} -.jschemer-schema { - border: 0.05em solid #CCC; - border-radius: 0.25em; - margin: 0.5em; - max-width: 60em; - padding: 1em; -} -.jschemer-schema code, -.jschemer-schema pre { - background-color: rgba(27, 31, 35, 0.05); - border-radius: 0.1em; - font-size: 85%; - line-height: 1.5; -} -.jschemer-schema pre { - padding: 1em 0.5em; -} -.jschemer-schema code { - display: inline; - font-family: 'Fira Mono', 'Noto Mono', 'Source Code Pro', Consolas, 'Roboto Mono', 'Lucida Console', Monaco, 'DejaVu Sans Mono', monospace; - font-size: 85%; - line-height: inherit; - padding: 0.2em 0.4em; - word-wrap: normal; -} -.jschemer-schema pre > code { - background-color: transparent; - padding: 0; -} -.jschemer-schema h1 { - display: inline; - font-size: 1.5em; - vertical-align: middle; -} -.jschemer-schema h1 code::before { - content: '"'; -} -.jschemer-schema h1 code::after { - content: '"'; -} -.jschemer-schema h2 { - font-size: 1em; -} -main > .jschemer-schema > details > summary > h1 { - font-size: 2em; -} -main ul { - list-style: disc; -} \ No newline at end of file diff --git a/docs/source/_static/theme_overrides.css b/docs/source/_static/theme_overrides.css deleted file mode 100644 index 63ee6cc7..00000000 --- a/docs/source/_static/theme_overrides.css +++ /dev/null @@ -1,13 +0,0 @@ -/* override table width restrictions */ -@media screen and (min-width: 767px) { - - .wy-table-responsive table td { - /* !important prevents the common CSS stylesheets from overriding - this as on RTD they are loaded after this stylesheet */ - white-space: normal !important; - } - - .wy-table-responsive { - overflow: visible !important; - } -} diff --git a/docs/source/attribution/index.rst b/docs/source/attribution/index.rst deleted file mode 100644 index 0e535ee1..00000000 --- a/docs/source/attribution/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -########### -Attribution -########### - -.. mdinclude:: ../../../README.md - :start-line: 108 - :end-line: 145 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 8660f462..00000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,95 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# pylint: disable=W,C -import os -import sys -import toml -from jinja2 import Environment, FileSystemLoader - - -sys.path.insert(0, os.path.abspath("../..")) -from netutils import lib_mapper # noqa: E402 - -DIR_PATH = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.abspath("sphinxext")) -toml_dict = toml.load("../../pyproject.toml") - -# -- Project information ----------------------------------------------------- - -project = toml_dict["tool"]["poetry"]["name"] -copyright = f"{toml_dict['tool']['poetry']['authors'][0]}, 2021" -author = ",".join(toml_dict["tool"]["poetry"]["authors"]) - -# The full version, including alpha/beta/rc tags -release = toml_dict["tool"]["poetry"]["version"] - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon", "m2r2", "exec"] - -autodoc_default_options = { - "members": True, - "show-inheritance": True, - "special-members": "__init__", - "undoc-members": True, -} - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - -# -- 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_rtd_theme" - -# 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 = ["_static"] - - -def build_mapping_tables(app): - """Build the library mappings tables.""" - env = Environment(loader=FileSystemLoader(f"{DIR_PATH}")) - template_file = env.get_template("table_template.j2") - - LIST_OF_MAP_DICTS = [] - for attr in dir(lib_mapper): - if (attr.endswith("MAPPER_REVERSE") or attr.endswith("_MAPPER")) and not ( - attr.startswith("_") or attr.startswith("NETMIKO") or attr.startswith("MAIN") - ): - LIST_OF_MAP_DICTS.append(attr) - - for dict_name in LIST_OF_MAP_DICTS: - lib_name = dict_name.split("_")[0] - filename = f"{lib_name}_reverse" if "REVERSE" in dict_name else lib_name - headers = ["NORMALIZED", lib_name] if "REVERSE" in dict_name else [lib_name, "NORMALIZED"] - rendered_template = template_file.render(lib_names=headers, mappings=getattr(lib_mapper, dict_name)) - with open(f"{DIR_PATH}/netutils/lib_mapping/{filename}_table.rst", "w") as table_file: - table_file.write(rendered_template) - - -def setup(app): - """Call methods during builder initiated.""" - app.connect("builder-inited", build_mapping_tables) diff --git a/docs/source/contributing/index.rst b/docs/source/contributing/index.rst deleted file mode 100644 index 3aec60de..00000000 --- a/docs/source/contributing/index.rst +++ /dev/null @@ -1,8 +0,0 @@ -############ -Contributing -############ - -.. mdinclude:: ../../../README.md - :start-line: 148 - :end-line: 234 - diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst deleted file mode 100644 index dd83b1a8..00000000 --- a/docs/source/examples/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -######## -Examples -######## - -.. mdinclude:: ../../../README.md - :start-line: 53 - :end-line: 105 \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index aee8b299..00000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. netutils documentation master file, created by - sphinx-quickstart on Wed May 5 01:15:43 2021. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to netutils's documentation! -==================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - overview/index - installation/index - examples/index - netutils/index - attribution/index - contributing/index - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` diff --git a/docs/source/installation/index.rst b/docs/source/installation/index.rst deleted file mode 100644 index 9e1bb66a..00000000 --- a/docs/source/installation/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -############ -Installation -############ - -.. mdinclude:: ../../../README.md - :start-line: 39 - :end-line: 50 \ No newline at end of file diff --git a/docs/source/netutils/asn/index.rst b/docs/source/netutils/asn/index.rst deleted file mode 100644 index cadaaac0..00000000 --- a/docs/source/netutils/asn/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -********* -BGP ASNs -********* - -.. automodule:: netutils.asn - :members: \ No newline at end of file diff --git a/docs/source/netutils/bandwidth/index.rst b/docs/source/netutils/bandwidth/index.rst deleted file mode 100644 index ae5b96d1..00000000 --- a/docs/source/netutils/bandwidth/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -********* -Bandwidth -********* - -.. automodule:: netutils.bandwidth - :members: \ No newline at end of file diff --git a/docs/source/netutils/banner/index.rst b/docs/source/netutils/banner/index.rst deleted file mode 100644 index 06a746b5..00000000 --- a/docs/source/netutils/banner/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -******* -Banner -******* - -.. automodule:: netutils.banner - :members: \ No newline at end of file diff --git a/docs/source/netutils/configs/index.rst b/docs/source/netutils/configs/index.rst deleted file mode 100644 index 3c49cc5b..00000000 --- a/docs/source/netutils/configs/index.rst +++ /dev/null @@ -1,49 +0,0 @@ -******* -Configs -******* - -.. automodule:: netutils.config.clean - :members: - -.. automodule:: netutils.config.compliance - :members: - -.. automodule:: netutils.config.parser - :members: - -Edge Cases -============== - -Fortinet Fortios Parser ------------------------ -- In order to support html blocks that exist in Fortios configurations, some preprocessing is executed, this is a regex that specifically grabs everything between quotes after the 'set buffer' sub-command. It's explicitly looking for double quote followed by a newline ("\n) to end the captured data. This support for html data will not support any other html that doesn't follow this convention. - -F5 Parser ------------------------ -- The "ltm rule" configuration sections are not uniform nor standardized; therefor, these sections are completely removed from the configuration in a preprocessing event. - -Nokia SROS Parser ------------------ -- The section banners have been simplified to extract the section header itself. This means that `echo "System Configuration"` will be converted to just "System Configuration". - -Duplicate Line Detection --------------------------- -In some circumstances replacing lines, such as secrets without uniqueness in the replacement, will result in duplicated lines that are invalid configuration, such as:: - - snmp-server community <> RO SNMP_ACL_RO - snmp-server community <> RO SNMP_ACL_RO - -There are some known use cases, such as the below that are considered:: - - router bgp 6500 - bgp router-id 10.0.0.11 - ! - address-family ipv4 unicast - redistribute connected - exit-address-family <--- duplicated hierarchy - ! - address-family l2vpn evpn - neighbor underlay activate - exit-address-family <--- duplicated hierarchy - -Documented use cases that are actual configuration on a network device are considered valid and should be opened for bug fixes. However, configuration that does not actually exist on the running config of network devices are out of scope for the parser. diff --git a/docs/source/netutils/dns/index.rst b/docs/source/netutils/dns/index.rst deleted file mode 100644 index 5032e8cc..00000000 --- a/docs/source/netutils/dns/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -**** -DNS -**** - -.. automodule:: netutils.dns - :members: \ No newline at end of file diff --git a/docs/source/netutils/index.rst b/docs/source/netutils/index.rst deleted file mode 100644 index 3f24639f..00000000 --- a/docs/source/netutils/index.rst +++ /dev/null @@ -1,23 +0,0 @@ -****************** -Netutils Functions -****************** - -.. toctree:: - :maxdepth: 2 - - asn/index - bandwidth/index - banner/index - configs/index - dns/index - interface/index - ip/index - lib_mapping/index - mac/index - password/index - ping/index - protocol_mapper/index - route/index - time/index - utilities/index - vlan/index diff --git a/docs/source/netutils/interface/index.rst b/docs/source/netutils/interface/index.rst deleted file mode 100644 index 77dfdf97..00000000 --- a/docs/source/netutils/interface/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -*********** -Interfaces -*********** - -.. automodule:: netutils.interface - :members: \ No newline at end of file diff --git a/docs/source/netutils/ip/index.rst b/docs/source/netutils/ip/index.rst deleted file mode 100644 index 7af1d2ab..00000000 --- a/docs/source/netutils/ip/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -************** -IP addresses -************** - -.. automodule:: netutils.ip - :members: \ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/ANSIBLE_reverse_table.rst b/docs/source/netutils/lib_mapping/ANSIBLE_reverse_table.rst deleted file mode 100755 index 01b2482c..00000000 --- a/docs/source/netutils/lib_mapping/ANSIBLE_reverse_table.rst +++ /dev/null @@ -1,78 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NORMALIZEDANSIBLE
arista_eosarista.eos.eos
ciena_saosciena.saos6.saos6
cisco_asacisco.asa.asa
cisco_ioscisco.ios.ios
cisco_xrcisco.iosxr.iosxr
cisco_nxoscisco.nxos.nxos
huaweicommunity.network.ce
dell_os6dellemc.os6.os6
dell_os9dellemc.os9.os9
dell_os10dellemc.os10.0s10
ericsson_iposcommunity.network.eric_eccli
extreme_exoscommunity.network.exos
extreme_netironcommunity.network.ironware
extreme_noscommunity.network.nos
extreme_slxcommunity.network.slxos
extreme_vspcommunity.network.voss
juniper_junosjunipernetworks.junos.junos
lenovo_cnoscommunity.network.cnos
lenovo_enoscommunity.network.enos
mikrotik_routeroscommunity.network.routeros
nokia_sroscommunity.network.sros
pluribuscommunity.network.netvisor
ruckus_icxcommunity.network.icx
vyosvyos.vyos.vyos
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/ANSIBLE_table.rst b/docs/source/netutils/lib_mapping/ANSIBLE_table.rst deleted file mode 100755 index d5fb3069..00000000 --- a/docs/source/netutils/lib_mapping/ANSIBLE_table.rst +++ /dev/null @@ -1,78 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ANSIBLENORMALIZED
arista.eos.eosarista_eos
ciena.saos6.saos6ciena_saos
cisco.asa.asacisco_asa
cisco.ios.ioscisco_ios
cisco.iosxr.iosxrcisco_xr
cisco.nxos.nxoscisco_nxos
community.network.cehuawei
dellemc.os6.os6dell_os6
dellemc.os9.os9dell_os9
dellemc.os10.0s10dell_os10
community.network.eric_eccliericsson_ipos
community.network.exosextreme_exos
community.network.ironwareextreme_netiron
community.network.nosextreme_nos
community.network.slxosextreme_slx
community.network.vossextreme_vsp
junipernetworks.junos.junosjuniper_junos
community.network.cnoslenovo_cnos
community.network.enoslenovo_enos
community.network.routerosmikrotik_routeros
community.network.netvisorpluribus
community.network.icxruckus_icx
community.network.srosnokia_sros
vyos.vyos.vyosvyos
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/NAPALM_reverse_table.rst b/docs/source/netutils/lib_mapping/NAPALM_reverse_table.rst deleted file mode 100755 index b5513e2c..00000000 --- a/docs/source/netutils/lib_mapping/NAPALM_reverse_table.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NORMALIZEDNAPALM
arista_eoseos
brocade_vyosvyos
cisco_asaasa
cisco_iosios
cisco_nxosnxos
cisco_xriosxr
cisco_wlccisco_wlc_ssh
fortinetfortios
huawei_vrphuawei
juniper_junosjunos
paloalto_panospanos
nokia_srossros
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/NAPALM_table.rst b/docs/source/netutils/lib_mapping/NAPALM_table.rst deleted file mode 100755 index a693ce4d..00000000 --- a/docs/source/netutils/lib_mapping/NAPALM_table.rst +++ /dev/null @@ -1,45 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NAPALMNORMALIZED
asacisco_asa
cisco_wlc_sshcisco_wlc
eosarista_eos
fortiosfortinet
huaweihuawei_vrp
ioscisco_ios
nxos_sshcisco_nxos
nxoscisco_nxos
iosxrcisco_xr
junosjuniper_junos
panospaloalto_panos
srosnokia_sros
vyosbrocade_vyos
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/NTCTEMPLATES_reverse_table.rst b/docs/source/netutils/lib_mapping/NTCTEMPLATES_reverse_table.rst deleted file mode 100755 index 7da16de3..00000000 --- a/docs/source/netutils/lib_mapping/NTCTEMPLATES_reverse_table.rst +++ /dev/null @@ -1,339 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NORMALIZEDNTCTEMPLATES
a10a10
accedianaccedian
adtran_osadtran_os
alcatel_aosalcatel_aos
alcatel_srosalcatel_sros
apresia_aeosapresia_aeos
arista_eosarista_eos
aruba_osaruba_os
aruba_osswitcharuba_osswitch
aruba_procurvearuba_procurve
avaya_ersavaya_ers
avaya_vspavaya_vsp
allied_telesis_awplusallied_telesis_awplus
broadcom_icosbroadcom_icos
brocade_fosbrocade_fos
brocade_fastironbrocade_fastiron
brocade_netironbrocade_netiron
brocade_nosbrocade_nos
brocade_vdxbrocade_vdx
brocade_vyosbrocade_vyos
checkpoint_gaiacheckpoint_gaia
calix_b6calix_b6
centec_oscentec_os
ciena_saosciena_saos
cisco_asacisco_asa
cisco_ftdcisco_ftd
cisco_ioscisco_ios
cisco_nxoscisco_nxos
cisco_s300cisco_s300
cisco_tpcisco_tp
cisco_wlccisco_wlc
cisco_xecisco_xe
cisco_xrcisco_xr
cloudgenix_ioncloudgenix_ion
coriantcoriant
dell_dnos9dell_dnos9
dell_force10dell_force10
dell_os6dell_os6
dell_os9dell_os9
dell_os10dell_os10
dell_powerconnectdell_powerconnect
dell_isilondell_isilon
dlink_dsdlink_ds
endaceendace
eltexeltex
eltex_esreltex_esr
enterasysenterasys
ericsson_iposericsson_ipos
extremeextreme
extreme_ersextreme_ers
extreme_exosextreme_exos
extreme_netironextreme_netiron
extreme_nosextreme_nos
extreme_slxextreme_slx
extreme_vdxextreme_vdx
extreme_vspextreme_vsp
extreme_wingextreme_wing
f5_ltmf5_ltm
f5_tmshf5_tmsh
f5_linuxf5_linux
flexvnfflexvnf
fortinetfortinet
genericgeneric
generic_termservergeneric_termserver
hp_comwarehp_comware
hp_procurvehp_procurve
huaweihuawei
huawei_smartaxhuawei_smartax
huawei_olthuawei_olt
huawei_vrpv8huawei_vrpv8
ipinfusion_ocnosipinfusion_ocnos
juniperjuniper
juniper_junosjuniper_junos
juniper_screenosjuniper_screenos
keymilekeymile
keymile_noskeymile_nos
linuxlinux
mikrotik_routerosmikrotik_routeros
mikrotik_switchosmikrotik_switchos
mellanoxmellanox
mellanox_mlnxosmellanox_mlnxos
mrv_lxmrv_lx
mrv_optiswitchmrv_optiswitch
netapp_cdotnetapp_cdot
netgear_prosafenetgear_prosafe
netscalernetscaler
nokia_srosnokia_sros
oneaccess_oneosoneaccess_oneos
ovs_linuxovs_linux
paloalto_panospaloalto_panos
pluribuspluribus
quanta_meshquanta_mesh
rad_etxrad_etx
raisecom_roapraisecom_roap
ruckus_fastironruckus_fastiron
ruijie_osruijie_os
sixwind_ossixwind_os
sophos_sfossophos_sfos
tplink_jetstreamtplink_jetstream
ubiquiti_edgeubiquiti_edge
ubiquiti_edgerouterubiquiti_edgerouter
ubiquiti_edgeswitchubiquiti_edgeswitch
ubiquiti_unifiswitchubiquiti_unifiswitch
vyatta_vyosvyatta_vyos
vyosvyos
watchguard_firewarewatchguard_fireware
zte_zxroszte_zxros
yamahayamaha
watchguard_fireboxwatchguard_firebox
huawei_vrphuawei_vrp
vmware_nsxvvmware_nsxv
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/NTCTEMPLATES_table.rst b/docs/source/netutils/lib_mapping/NTCTEMPLATES_table.rst deleted file mode 100755 index 35ab51ff..00000000 --- a/docs/source/netutils/lib_mapping/NTCTEMPLATES_table.rst +++ /dev/null @@ -1,339 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NTCTEMPLATESNORMALIZED
a10a10
accedianaccedian
adtran_osadtran_os
alcatel_aosalcatel_aos
alcatel_srosalcatel_sros
apresia_aeosapresia_aeos
arista_eosarista_eos
aruba_osaruba_os
aruba_osswitcharuba_osswitch
aruba_procurvearuba_procurve
avaya_ersavaya_ers
avaya_vspavaya_vsp
allied_telesis_awplusallied_telesis_awplus
broadcom_icosbroadcom_icos
brocade_fosbrocade_fos
brocade_fastironbrocade_fastiron
brocade_netironbrocade_netiron
brocade_nosbrocade_nos
brocade_vdxbrocade_vdx
brocade_vyosbrocade_vyos
checkpoint_gaiacheckpoint_gaia
calix_b6calix_b6
centec_oscentec_os
ciena_saosciena_saos
cisco_asacisco_asa
cisco_ftdcisco_ftd
cisco_ioscisco_ios
cisco_nxoscisco_nxos
cisco_s300cisco_s300
cisco_tpcisco_tp
cisco_wlccisco_wlc
cisco_xecisco_xe
cisco_xrcisco_xr
cloudgenix_ioncloudgenix_ion
coriantcoriant
dell_dnos9dell_dnos9
dell_force10dell_force10
dell_os6dell_os6
dell_os9dell_os9
dell_os10dell_os10
dell_powerconnectdell_powerconnect
dell_isilondell_isilon
dlink_dsdlink_ds
endaceendace
eltexeltex
eltex_esreltex_esr
enterasysenterasys
ericsson_iposericsson_ipos
extremeextreme
extreme_ersextreme_ers
extreme_exosextreme_exos
extreme_netironextreme_netiron
extreme_nosextreme_nos
extreme_slxextreme_slx
extreme_vdxextreme_vdx
extreme_vspextreme_vsp
extreme_wingextreme_wing
f5_ltmf5_ltm
f5_tmshf5_tmsh
f5_linuxf5_linux
flexvnfflexvnf
fortinetfortinet
genericgeneric
generic_termservergeneric_termserver
hp_comwarehp_comware
hp_procurvehp_procurve
huaweihuawei
huawei_smartaxhuawei_smartax
huawei_olthuawei_olt
huawei_vrpv8huawei_vrpv8
ipinfusion_ocnosipinfusion_ocnos
juniperjuniper
juniper_junosjuniper_junos
juniper_screenosjuniper_screenos
keymilekeymile
keymile_noskeymile_nos
linuxlinux
mikrotik_routerosmikrotik_routeros
mikrotik_switchosmikrotik_switchos
mellanoxmellanox
mellanox_mlnxosmellanox_mlnxos
mrv_lxmrv_lx
mrv_optiswitchmrv_optiswitch
netapp_cdotnetapp_cdot
netgear_prosafenetgear_prosafe
netscalernetscaler
nokia_srosnokia_sros
oneaccess_oneosoneaccess_oneos
ovs_linuxovs_linux
paloalto_panospaloalto_panos
pluribuspluribus
quanta_meshquanta_mesh
rad_etxrad_etx
raisecom_roapraisecom_roap
ruckus_fastironruckus_fastiron
ruijie_osruijie_os
sixwind_ossixwind_os
sophos_sfossophos_sfos
tplink_jetstreamtplink_jetstream
ubiquiti_edgeubiquiti_edge
ubiquiti_edgerouterubiquiti_edgerouter
ubiquiti_edgeswitchubiquiti_edgeswitch
ubiquiti_unifiswitchubiquiti_unifiswitch
vyatta_vyosvyatta_vyos
vyosvyos
watchguard_firewarewatchguard_fireware
zte_zxroszte_zxros
yamahayamaha
watchguard_fireboxwatchguard_firebox
huawei_vrphuawei_vrp
vmware_nsxvvmware_nsxv
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/PYATS_reverse_table.rst b/docs/source/netutils/lib_mapping/PYATS_reverse_table.rst deleted file mode 100755 index 405e1a43..00000000 --- a/docs/source/netutils/lib_mapping/PYATS_reverse_table.rst +++ /dev/null @@ -1,36 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NORMALIZEDPYATS
cisco_asaasa
f5_tmshbigip
cisco_dnacdnac
cisco_iosiosxe
cisco_xriosxr
juniper_junosjunos
linuxlinux
cisco_nxosnxos
nokia_srossros
cisco_viptellaviptela
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/PYATS_table.rst b/docs/source/netutils/lib_mapping/PYATS_table.rst deleted file mode 100755 index 1ffc20c7..00000000 --- a/docs/source/netutils/lib_mapping/PYATS_table.rst +++ /dev/null @@ -1,39 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PYATSNORMALIZED
asacisco_asa
bigipf5_tmsh
dnaccisco_dnac
ioscisco_ios
iosxecisco_ios
iosxrcisco_xr
junosjuniper_junos
linuxlinux
nxoscisco_nxos
srosnokia_sros
viptelacisco_viptella
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/PYNTC_reverse_table.rst b/docs/source/netutils/lib_mapping/PYNTC_reverse_table.rst deleted file mode 100755 index c6ce781d..00000000 --- a/docs/source/netutils/lib_mapping/PYNTC_reverse_table.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - -
NORMALIZEDPYNTC
cisco_asacisco_asa_ssh
arista_eosarista_eos_eapi
f5_tmshf5_tmos_icontrol
cisco_ioscisco_ios_ssh
juniper_junosjuniper_junos_netconf
cisco_nxoscisco_nxos_nxapi
cisco_wlccisco_aireos_ssh
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/PYNTC_table.rst b/docs/source/netutils/lib_mapping/PYNTC_table.rst deleted file mode 100755 index 53470f21..00000000 --- a/docs/source/netutils/lib_mapping/PYNTC_table.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - -
PYNTCNORMALIZED
cisco_asa_sshcisco_asa
arista_eos_eapiarista_eos
f5_tmos_icontrolf5_tmsh
cisco_ios_sshcisco_ios
juniper_junos_netconfjuniper_junos
cisco_nxos_nxapicisco_nxos
cisco_aireos_sshcisco_wlc
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/SCRAPLI_reverse_table.rst b/docs/source/netutils/lib_mapping/SCRAPLI_reverse_table.rst deleted file mode 100755 index cdd7f74f..00000000 --- a/docs/source/netutils/lib_mapping/SCRAPLI_reverse_table.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - -
NORMALIZEDSCRAPLI
cisco_ioscisco_iosxe
cisco_xrcisco_iosxr
cisco_nxoscisco_nxos
arista_eosarista_eos
juniper_junosjuniper_junos
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/SCRAPLI_table.rst b/docs/source/netutils/lib_mapping/SCRAPLI_table.rst deleted file mode 100755 index f420334b..00000000 --- a/docs/source/netutils/lib_mapping/SCRAPLI_table.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. raw:: html - - - - - - - - - - - - - - - - - - - -
SCRAPLINORMALIZED
cisco_iosxecisco_ios
cisco_iosxrcisco_xr
cisco_nxoscisco_nxos
arista_eosarista_eos
juniper_junosjuniper_junos
\ No newline at end of file diff --git a/docs/source/netutils/lib_mapping/index.rst b/docs/source/netutils/lib_mapping/index.rst deleted file mode 100644 index 52af9f92..00000000 --- a/docs/source/netutils/lib_mapping/index.rst +++ /dev/null @@ -1,91 +0,0 @@ -***************** -Library Mappings -***************** - -These dictionaries provide mappings in expected vendor names between Netmiko, NAPALM, pyntc, ntc-templates, pyats, and scrapli. For each non-reversed mapper, the keys of the dictionary represent the driver used for that library while the values represent the "normalized" driver based on netmiko. - -These dictionaries allow you to keep your Source of Truth platform data consistent and still easily switch between automation libraries. For example, you may be storing your device platform data in Nautobot. In a Nautobot platform, you can store the NAPALM driver needed for that platform. What if you wanted to write -a python script to leverage the backup capabilities of pyntc? Here's an example of how you could use the following dictionaries to perform mappings from your stored Nautobot NAPALM driver to the pyntc driver needed for your script. - -.. code-block:: python - - import pynautobot - from netutils.lib_mapper import NAPALM_LIB_MAPPER, PYNTC_LIB_MAPPER_REVERSE - from pyntc import ntc_device as NTC - - - # Get device from Nautobot - nautobot = pynautobot.api(url="http://mynautobotinstance.com",token="mytoken") - - # Get Napalm driver and save for later use. - device = nautobot.dcim.devices.get(name="mydevice") - sot_driver = device.platform.napalm_driver - - - # Connect to device via Napalm - driver = napalm.get_network_driver("ios") - - device = driver( - hostname="device.name", - username="demo", - password="secret" - ) - - # Do Napalm tasks - - pyntc_driver = PYNTC_LIB_MAPPER_REVERSE.get(NAPALM_LIB_MAPPER.get(sot_driver)) - net_con = NTC(host=device.name, username="demo", password="secret", device_type=pyntc_driver) - - # Do pyntc tasks - -Another use case could be using an example like the above in an Ansible filter. That would allow you to write a filter utilizing whichever automation library you needed without having to store the driver for each one in your Source of Truth. - -Napalm Mapper -============================== -.. include:: NAPALM_table.rst - -Reverse Napalm Mapper -============================== -.. include:: NAPALM_reverse_table.rst - -PyNTC Mapper -============================== -.. include:: PYNTC_table.rst - -Reverse PyNTC Mapper -============================== -.. include:: PYNTC_reverse_table.rst - -Ansible Mapper -============================== -.. include:: ANSIBLE_table.rst - -Reverse Ansible Mapper -============================== -.. include:: ANSIBLE_reverse_table.rst - -PyATS Mapper -============================== -.. include:: PYATS_table.rst - -Reverse PyATS Mapper -============================== -.. include:: PYATS_reverse_table.rst - -Scrapli Mapper -============================== -.. include:: SCRAPLI_table.rst - -Reverse Scrapli Mapper -============================== -.. include:: SCRAPLI_reverse_table.rst - -NTC Templates Mapper -============================== -.. include:: NTCTEMPLATES_table.rst - -Reverse NTC Templates Mapper -============================== -.. include:: NTCTEMPLATES_reverse_table.rst - - diff --git a/docs/source/netutils/mac/index.rst b/docs/source/netutils/mac/index.rst deleted file mode 100644 index b946598c..00000000 --- a/docs/source/netutils/mac/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -************** -MAC addresses -************** - -.. automodule:: netutils.mac - :members: \ No newline at end of file diff --git a/docs/source/netutils/password/index.rst b/docs/source/netutils/password/index.rst deleted file mode 100644 index 76b64e05..00000000 --- a/docs/source/netutils/password/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -*********** -Passwords -*********** - -.. automodule:: netutils.password - :members: \ No newline at end of file diff --git a/docs/source/netutils/ping/index.rst b/docs/source/netutils/ping/index.rst deleted file mode 100644 index 959ae66e..00000000 --- a/docs/source/netutils/ping/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -****** -Ping -****** - -.. automodule:: netutils.ping - :members: \ No newline at end of file diff --git a/docs/source/netutils/protocol_mapper/index.rst b/docs/source/netutils/protocol_mapper/index.rst deleted file mode 100644 index 5ddc9223..00000000 --- a/docs/source/netutils/protocol_mapper/index.rst +++ /dev/null @@ -1,68 +0,0 @@ -***************** -Protocol Mappers -***************** - -These protocol mappers can be used when you have either the application protocol name or number but need the corresponding value. Something to note is that these mappings are divided up per IP protocol. -The reasoning behind this is that the same port number could be tied to two different application protocols depending on the underlying IP protocol. For example, when using UDP, port 13400 is the application protocol `doip-disc`. Looking at the same port using TCP the application protocol is `doip-data`. - - -Here are currently available mappers: - - * **DCCP_NAME_TO_NUM** - Allows mapping from a known DCCP application protocol name to DCCP application protocol number. - - * **DCCP_NUM_TO_NAME** - Allows mapping from a known DCCP application protocol name to DCCP application protocol number. - - * **PROTO_NAME_TO_NUM** - Allows mapping from a known IP protocol name to IP protocol number. - - * **PROTO_NUM_TO_NAME** - Allows mapping from a known IP protocol number to IP protocol name. - - * **SCTP_NAME_TO_NUM** - Allows mapping from a known SCTP application protocol name to SCTP application protocol number. - - * **SCTP_NUM_TO_NAME** - Allows mapping from a known SCTP application protocol number to SCTP application protocol name. - - * **TCP_NAME_TO_NUM** - Allows mapping from a known TCP application protocol name to TCP application protocol number. - - * **TCP_NUM_TO_NAME** - Allows mapping from a known TCP application protocol number to TCP application protocol name. - - * **UDP_NAME_TO_NUM** - Allows mapping from a known UDP application protocol name to UDP application protocol number. - - * **UDP_NUM_TO_NAME** - Allows mapping from a known UDP application protocol number to UDP application protocol name. - - -Here are a few examples showing how you would use these in your python code. - -.. code-block:: python - - from netutils.protocol_mapper import ( - - PROTO_NAME_TO_NUM, - PROTO_NUM_TO_NAME, - TCP_NAME_TO_NUM, - TCP_NUM_TO_NAME, - UDP_NAME_TO_NUM, - UDP_NUM_TO_NAME, - SCTP_NAME_TO_NUM, - SCTP_NUM_TO_NAME, - DCCP_NAME_TO_NUM, - DCCP_NUM_TO_NAME, - ) - - # Get DCCP protocol port from known DCCP application name - LTP_DEEPSPACE_PORT = DCCP_NAME_TO_NUM("ltp-deepspace") - print(LTP_DEEPSPACE_PORT) - # 1113 - - # Get TCP protocol port from known TCP application name - SSH_PORT = TCP_NAME_TO_NUM["ssh"] - print(SSH_PORT) - # 22 - - # Get SCTP protocol name from known SCTP application port. - SCTP_PORT_1021_APPLICATION_NAME = SCTP_NUM_TO_NAME[1021] - print(SCTP_PORT_1021_APPLICATION_NAME) - # "exp1" - - # Get UDP protocol name from known UDP application port - UDP_PORT_20_APPLICATION_NAME = UDP_NUM_TO_NAME[20] - print(UDP_PORT_20_APPLICATION_NAME) - # "ftp-data \ No newline at end of file diff --git a/docs/source/netutils/route/index.rst b/docs/source/netutils/route/index.rst deleted file mode 100644 index 555c421b..00000000 --- a/docs/source/netutils/route/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -********* -Routing -********* - -.. automodule:: netutils.route - :members: \ No newline at end of file diff --git a/docs/source/netutils/time/index.rst b/docs/source/netutils/time/index.rst deleted file mode 100644 index ba12a978..00000000 --- a/docs/source/netutils/time/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -******* -Time -******* - -.. automodule:: netutils.time - :members: \ No newline at end of file diff --git a/docs/source/netutils/utilities/index.rst b/docs/source/netutils/utilities/index.rst deleted file mode 100644 index 57c6c598..00000000 --- a/docs/source/netutils/utilities/index.rst +++ /dev/null @@ -1,116 +0,0 @@ -******************* -Netutils Utilities -******************* - -Netutils to Jinja2 Filters -============================ - -In an effort to simplify the process of adding netutils' functions to jinja2 as filters we have created a convenience function. Let's go through how you could add the filters to your jinja2 environment. -Here is the current folder structure. - -.. code-block:: python - - . - ├── jinja2_environment.py - └── templates - └── test.j2 - -Below is the code in the `test.j2` file. - -.. code-block:: jinja - - IP Address + 200 = {{ "192.168.0.1/10" | ip_addition(200) }} - -Below is a code in the `jinja2_environment.py` folder. - -.. code-block:: python - - from jinja2.loaders import FileSystemLoader, PackageLoader - from jinja2 import Environment, PackageLoader, select_autoescape - from netutils.utils import jinja2_convenience_function - - env = Environment( - loader=FileSystemLoader("templates"), - autoescape=select_autoescape() - ) - - env.filters.update(jinja2_convenience_function()) - - template = env.get_template("test.j2") - result = template.render() - print(result) - -When you run `jinja2_environment.py` the output will be: - -.. code-block:: python - - IP Address + 200 = 192.168.0.201 - - -Netutils to Jinja2 Filters List -====================================== - -The below list shows what jinja2 filters are added when you add them using the process above. The keys of the dictionary are the names you would use to call the jinja2 filter. - -.. note:: - The jinja2 filter names match the python function names. - -.. exec:: - import json - from netutils.utils import jinja2_convenience_function - data = list(jinja2_convenience_function().keys()) - json_obj = json.dumps(data, sort_keys=True, indent=4) - json_obj = json_obj[:-1] + " ]" - print(f".. code-block:: JavaScript\n\n {json_obj}\n\n") - - -ipaddress Convenience Functions ---------------------------------- - -When adding the netutils functions to your jinja2 environment, you also gain access to the built-in ipaddress python library using these three jinja2 filters. - -.. code-block:: python - - "ipaddress_address": "ip.ipaddress_address", - "ipaddress_interface": "ip.ipaddress_interface", - "ipaddress_network": "ip.ipaddress_network", - -When using these filters, you must specify an attribute of that given class. Here is an example of how you would use the `version` if the `ipaddress_interface` filter. - -.. code-block:: python - - . - ├── jinja2_environment.py - └── templates - └── test.j2 - -Below is the code in the `test.j2` file. - -.. code-block:: jinja - - The version of 192.168.0.1/24 is IPv{{ "192.168.0.1/24" | ipaddress_interface("version") }}. - -Below is a code in the `jinja2_environment.py` folder. - -.. code-block:: python - - from jinja2.loaders import FileSystemLoader, PackageLoader - from jinja2 import Environment, PackageLoader, select_autoescape - from netutils.utils import jinja2_convenience_function - - env = Environment( - loader=FileSystemLoader("templates"), - autoescape=select_autoescape() - ) - - env.filters.update(jinja2_convenience_function()) - - template = env.get_template("test.j2") - result = template.render() - print(result) - -When you run `jinja2_environment.py` the output will be: - -.. code-block:: python - - The version of 192.168.0.1/24 is IPv4. \ No newline at end of file diff --git a/docs/source/netutils/vlan/index.rst b/docs/source/netutils/vlan/index.rst deleted file mode 100644 index 59397828..00000000 --- a/docs/source/netutils/vlan/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -******* -VLANS -******* - -.. automodule:: netutils.vlan - :members: \ No newline at end of file diff --git a/docs/source/overview/index.rst b/docs/source/overview/index.rst deleted file mode 100644 index 267fe23e..00000000 --- a/docs/source/overview/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -********* -Overview -********* - -.. mdinclude:: ../../../README.md - :start-line: 0 - :end-line: 36 \ No newline at end of file diff --git a/docs/source/sphinxext/exec.py b/docs/source/sphinxext/exec.py deleted file mode 100644 index 6cdf5b26..00000000 --- a/docs/source/sphinxext/exec.py +++ /dev/null @@ -1,46 +0,0 @@ -"""File used to define sphinx exec directive.""" -import sys -from os.path import basename - -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - -from docutils.parsers.rst import Directive -from docutils import nodes, statemachine - - -class ExecDirective(Directive): - """Execute the specified python code and insert the output into the document.""" - - has_content = True - - def run(self): - """Function used when adding the directive to an index.rst.""" - old_stdoutout, sys.stdout = sys.stdout, StringIO() - - tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) - source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) - - try: - exec("\n".join(self.content)) # pylint: disable=exec-used - text = sys.stdout.getvalue() - lines = statemachine.string2lines(text, tab_width, convert_whitespace=True) - self.state_machine.insert_input(lines, source) - return [] - except Exception: # pylint: disable=W0703 - return [ - nodes.error( - None, - nodes.paragraph(text=f"Unable to execute python code at {basename(source)}:{self.lineno}:"), - nodes.paragraph(text=str(sys.exc_info()[1])), - ) - ] - finally: - sys.stdout = old_stdoutout - - -def setup(app): - """Adds class as sphinx directive.""" - app.add_directive("exec", ExecDirective) diff --git a/docs/source/table_template.j2 b/docs/source/table_template.j2 deleted file mode 100644 index b9394d03..00000000 --- a/docs/source/table_template.j2 +++ /dev/null @@ -1,9 +0,0 @@ -.. raw:: html - - - {% for lib_name in lib_names %}{% endfor %} - {% for specific_driver, normalized_driver in mappings.items() %} - - - {% endfor %} -
{{lib_name|upper}}
{{ specific_driver }}{{ normalized_driver }}
\ No newline at end of file diff --git a/docs/user/faq.md b/docs/user/faq.md new file mode 100644 index 00000000..b269462c --- /dev/null +++ b/docs/user/faq.md @@ -0,0 +1,11 @@ +# Frequently Asked Questions + +## Which OS Config types have Parsers? + +The documentation is provided in the [development docs](../../dev/dev_config/#current-included-parsers). + +For creating new Parsers, see the [new parsers](../../dev/dev_config/#new-parsers) docs. + +## Can you provide an example of how to use the functions? + +The documentation is always provided in the function for [code docs](../../dev/code_reference/) for each function. There is additional documentation in [Use Cases](../lib_use_cases/) and subsequent sections. \ No newline at end of file diff --git a/docs/user/include_jinja_list.md b/docs/user/include_jinja_list.md new file mode 100644 index 00000000..f0647c14 --- /dev/null +++ b/docs/user/include_jinja_list.md @@ -0,0 +1,63 @@ +| Filter name | Function | +| ---------- | ------ | +| asn_to_int | netutils.asn.asn_to_int | +| bits_to_name | netutils.bandwidth.bits_to_name | +| bytes_to_name | netutils.bandwidth.bytes_to_name | +| name_to_bits | netutils.bandwidth.name_to_bits | +| name_to_bytes | netutils.bandwidth.name_to_bytes | +| name_to_name | netutils.bandwidth.name_to_name | +| delimiter_change | netutils.banner.delimiter_change | +| normalise_delimiter_caret_c | netutils.banner.normalise_delimiter_caret_c | +| clean_config | netutils.config.clean.clean_config | +| sanitize_config | netutils.config.clean.sanitize_config | +| config_compliance | netutils.config.compliance.compliance | +| config_section_not_parsed | netutils.config.compliance.config_section_not_parsed | +| diff_network_config | netutils.config.compliance.diff_network_config | +| feature_compliance | netutils.config.compliance.feature_compliance | +| find_unordered_cfg_lines | netutils.config.compliance.find_unordered_cfg_lines | +| section_config | netutils.config.compliance.section_config | +| fqdn_to_ip | netutils.dns.fqdn_to_ip | +| is_fqdn_resolvable | netutils.dns.is_fqdn_resolvable | +| abbreviated_interface_name | netutils.interface.abbreviated_interface_name | +| abbreviated_interface_name_list | netutils.interface.abbreviated_interface_name_list | +| canonical_interface_name | netutils.interface.canonical_interface_name | +| canonical_interface_name_list | netutils.interface.canonical_interface_name_list | +| interface_range_compress | netutils.interface.interface_range_compress | +| interface_range_expansion | netutils.interface.interface_range_expansion | +| sort_interface_list | netutils.interface.sort_interface_list | +| split_interface | netutils.interface.split_interface | +| cidr_to_netmask | netutils.ip.cidr_to_netmask | +| cidr_to_netmaskv6 | netutils.ip.cidr_to_netmaskv6 | +| get_all_host | netutils.ip.get_all_host | +| get_broadcast_address | netutils.ip.get_broadcast_address | +| get_first_usable | netutils.ip.get_first_usable | +| get_peer_ip | netutils.ip.get_peer_ip | +| get_usable_range | netutils.ip.get_usable_range | +| ip_addition | netutils.ip.ip_addition | +| ip_subtract | netutils.ip.ip_subtract | +| ip_to_bin | netutils.ip.ip_to_bin | +| ip_to_hex | netutils.ip.ip_to_hex | +| ipaddress_address | netutils.ip.ipaddress_address | +| ipaddress_interface | netutils.ip.ipaddress_interface | +| ipaddress_network | netutils.ip.ipaddress_network | +| is_ip | netutils.ip.is_ip | +| is_netmask | netutils.ip.is_netmask | +| netmask_to_cidr | netutils.ip.netmask_to_cidr | +| get_oui | netutils.mac.get_oui | +| is_valid_mac | netutils.mac.is_valid_mac | +| mac_normalize | netutils.mac.mac_normalize | +| mac_to_format | netutils.mac.mac_to_format | +| mac_to_int | netutils.mac.mac_to_int | +| mac_type | netutils.mac.mac_type | +| compare_type5 | netutils.password.compare_type5 | +| compare_type7 | netutils.password.compare_type7 | +| decrypt_type7 | netutils.password.decrypt_type7 | +| encrypt_type5 | netutils.password.encrypt_type5 | +| encrypt_type7 | netutils.password.encrypt_type7 | +| get_hash_salt | netutils.password.get_hash_salt | +| tcp_ping | netutils.ping.tcp_ping | +| longest_prefix_match | netutils.route.longest_prefix_match | +| uptime_seconds_to_string | netutils.time.uptime_seconds_to_string | +| uptime_string_to_seconds | netutils.time.uptime_string_to_seconds | +| vlanconfig_to_list | netutils.vlan.vlanconfig_to_list | +| vlanlist_to_config | netutils.vlan.vlanlist_to_config | \ No newline at end of file diff --git a/docs/user/lib_getting_started.md b/docs/user/lib_getting_started.md new file mode 100644 index 00000000..d6dba101 --- /dev/null +++ b/docs/user/lib_getting_started.md @@ -0,0 +1,7 @@ +# Getting Started with the Library + +The library's primary use case is providing Python functions for the community. The primary way to use it is the same as any Python library. You `import` the functions, and use them, there are many examples on the [Use Cases](./lib_use_cases.md) page. + +## Install the Library + +To install the library, please follow the instructions detailed in the [Installation Guide](../admin/install.md). \ No newline at end of file diff --git a/docs/user/lib_mapper/ansible.md b/docs/user/lib_mapper/ansible.md new file mode 100644 index 00000000..2983bc9e --- /dev/null +++ b/docs/user/lib_mapper/ansible.md @@ -0,0 +1,26 @@ +| NORMALIZED | | ANSIBLE | +| ---------- | -- | ------ | +| arista.eos.eos | → | arista_eos | +| ciena.saos6.saos6 | → | ciena_saos | +| cisco.asa.asa | → | cisco_asa | +| cisco.ios.ios | → | cisco_ios | +| cisco.iosxr.iosxr | → | cisco_xr | +| cisco.nxos.nxos | → | cisco_nxos | +| community.network.ce | → | huawei | +| community.network.cnos | → | lenovo_cnos | +| community.network.enos | → | lenovo_enos | +| community.network.eric_eccli | → | ericsson_ipos | +| community.network.exos | → | extreme_exos | +| community.network.icx | → | ruckus_icx | +| community.network.ironware | → | extreme_netiron | +| community.network.netvisor | → | pluribus | +| community.network.nos | → | extreme_nos | +| community.network.routeros | → | mikrotik_routeros | +| community.network.slxos | → | extreme_slx | +| community.network.sros | → | nokia_sros | +| community.network.voss | → | extreme_vsp | +| dellemc.os10.0s10 | → | dell_os10 | +| dellemc.os6.os6 | → | dell_os6 | +| dellemc.os9.os9 | → | dell_os9 | +| junipernetworks.junos.junos | → | juniper_junos | +| vyos.vyos.vyos | → | vyos | \ No newline at end of file diff --git a/docs/user/lib_mapper/ansible_reverse.md b/docs/user/lib_mapper/ansible_reverse.md new file mode 100644 index 00000000..be3b0e32 --- /dev/null +++ b/docs/user/lib_mapper/ansible_reverse.md @@ -0,0 +1,26 @@ +| ANSIBLE | | NORMALIZED | +| ---------- | -- | ------ | +| arista_eos | → | arista.eos.eos | +| ciena_saos | → | ciena.saos6.saos6 | +| cisco_asa | → | cisco.asa.asa | +| cisco_ios | → | cisco.ios.ios | +| cisco_nxos | → | cisco.nxos.nxos | +| cisco_xr | → | cisco.iosxr.iosxr | +| dell_os10 | → | dellemc.os10.0s10 | +| dell_os6 | → | dellemc.os6.os6 | +| dell_os9 | → | dellemc.os9.os9 | +| ericsson_ipos | → | community.network.eric_eccli | +| extreme_exos | → | community.network.exos | +| extreme_netiron | → | community.network.ironware | +| extreme_nos | → | community.network.nos | +| extreme_slx | → | community.network.slxos | +| extreme_vsp | → | community.network.voss | +| huawei | → | community.network.ce | +| juniper_junos | → | junipernetworks.junos.junos | +| lenovo_cnos | → | community.network.cnos | +| lenovo_enos | → | community.network.enos | +| mikrotik_routeros | → | community.network.routeros | +| nokia_sros | → | community.network.sros | +| pluribus | → | community.network.netvisor | +| ruckus_icx | → | community.network.icx | +| vyos | → | vyos.vyos.vyos | \ No newline at end of file diff --git a/docs/user/lib_mapper/napalm.md b/docs/user/lib_mapper/napalm.md new file mode 100644 index 00000000..a5cd7261 --- /dev/null +++ b/docs/user/lib_mapper/napalm.md @@ -0,0 +1,15 @@ +| NORMALIZED | | NAPALM | +| ---------- | -- | ------ | +| asa | → | cisco_asa | +| cisco_wlc_ssh | → | cisco_wlc | +| eos | → | arista_eos | +| fortios | → | fortinet | +| huawei | → | huawei_vrp | +| ios | → | cisco_ios | +| iosxr | → | cisco_xr | +| junos | → | juniper_junos | +| nxos | → | cisco_nxos | +| nxos_ssh | → | cisco_nxos | +| panos | → | paloalto_panos | +| sros | → | nokia_sros | +| vyos | → | brocade_vyos | \ No newline at end of file diff --git a/docs/user/lib_mapper/napalm_reverse.md b/docs/user/lib_mapper/napalm_reverse.md new file mode 100644 index 00000000..cd4b80f3 --- /dev/null +++ b/docs/user/lib_mapper/napalm_reverse.md @@ -0,0 +1,14 @@ +| NAPALM | | NORMALIZED | +| ---------- | -- | ------ | +| arista_eos | → | eos | +| brocade_vyos | → | vyos | +| cisco_asa | → | asa | +| cisco_ios | → | ios | +| cisco_nxos | → | nxos | +| cisco_wlc | → | cisco_wlc_ssh | +| cisco_xr | → | iosxr | +| fortinet | → | fortios | +| huawei_vrp | → | huawei | +| juniper_junos | → | junos | +| nokia_sros | → | sros | +| paloalto_panos | → | panos | \ No newline at end of file diff --git a/docs/user/lib_mapper/ntctemplates.md b/docs/user/lib_mapper/ntctemplates.md new file mode 100644 index 00000000..af8d70b6 --- /dev/null +++ b/docs/user/lib_mapper/ntctemplates.md @@ -0,0 +1,113 @@ +| NORMALIZED | | NTCTEMPLATES | +| ---------- | -- | ------ | +| a10 | → | a10 | +| accedian | → | accedian | +| adtran_os | → | adtran_os | +| alcatel_aos | → | alcatel_aos | +| alcatel_sros | → | alcatel_sros | +| allied_telesis_awplus | → | allied_telesis_awplus | +| apresia_aeos | → | apresia_aeos | +| arista_eos | → | arista_eos | +| aruba_os | → | aruba_os | +| aruba_osswitch | → | aruba_osswitch | +| aruba_procurve | → | aruba_procurve | +| avaya_ers | → | avaya_ers | +| avaya_vsp | → | avaya_vsp | +| broadcom_icos | → | broadcom_icos | +| brocade_fastiron | → | brocade_fastiron | +| brocade_fos | → | brocade_fos | +| brocade_netiron | → | brocade_netiron | +| brocade_nos | → | brocade_nos | +| brocade_vdx | → | brocade_vdx | +| brocade_vyos | → | brocade_vyos | +| calix_b6 | → | calix_b6 | +| centec_os | → | centec_os | +| checkpoint_gaia | → | checkpoint_gaia | +| ciena_saos | → | ciena_saos | +| cisco_asa | → | cisco_asa | +| cisco_ftd | → | cisco_ftd | +| cisco_ios | → | cisco_ios | +| cisco_nxos | → | cisco_nxos | +| cisco_s300 | → | cisco_s300 | +| cisco_tp | → | cisco_tp | +| cisco_wlc | → | cisco_wlc | +| cisco_xe | → | cisco_xe | +| cisco_xr | → | cisco_xr | +| cloudgenix_ion | → | cloudgenix_ion | +| coriant | → | coriant | +| dell_dnos9 | → | dell_dnos9 | +| dell_force10 | → | dell_force10 | +| dell_isilon | → | dell_isilon | +| dell_os10 | → | dell_os10 | +| dell_os6 | → | dell_os6 | +| dell_os9 | → | dell_os9 | +| dell_powerconnect | → | dell_powerconnect | +| dlink_ds | → | dlink_ds | +| eltex | → | eltex | +| eltex_esr | → | eltex_esr | +| endace | → | endace | +| enterasys | → | enterasys | +| ericsson_ipos | → | ericsson_ipos | +| extreme | → | extreme | +| extreme_ers | → | extreme_ers | +| extreme_exos | → | extreme_exos | +| extreme_netiron | → | extreme_netiron | +| extreme_nos | → | extreme_nos | +| extreme_slx | → | extreme_slx | +| extreme_vdx | → | extreme_vdx | +| extreme_vsp | → | extreme_vsp | +| extreme_wing | → | extreme_wing | +| f5_linux | → | f5_linux | +| f5_ltm | → | f5_ltm | +| f5_tmsh | → | f5_tmsh | +| flexvnf | → | flexvnf | +| fortinet | → | fortinet | +| generic | → | generic | +| generic_termserver | → | generic_termserver | +| hp_comware | → | hp_comware | +| hp_procurve | → | hp_procurve | +| huawei | → | huawei | +| huawei_olt | → | huawei_olt | +| huawei_smartax | → | huawei_smartax | +| huawei_vrp | → | huawei_vrp | +| huawei_vrpv8 | → | huawei_vrpv8 | +| ipinfusion_ocnos | → | ipinfusion_ocnos | +| juniper | → | juniper | +| juniper_junos | → | juniper_junos | +| juniper_screenos | → | juniper_screenos | +| keymile | → | keymile | +| keymile_nos | → | keymile_nos | +| linux | → | linux | +| mellanox | → | mellanox | +| mellanox_mlnxos | → | mellanox_mlnxos | +| mikrotik_routeros | → | mikrotik_routeros | +| mikrotik_switchos | → | mikrotik_switchos | +| mrv_lx | → | mrv_lx | +| mrv_optiswitch | → | mrv_optiswitch | +| netapp_cdot | → | netapp_cdot | +| netgear_prosafe | → | netgear_prosafe | +| netscaler | → | netscaler | +| nokia_sros | → | nokia_sros | +| oneaccess_oneos | → | oneaccess_oneos | +| ovs_linux | → | ovs_linux | +| paloalto_panos | → | paloalto_panos | +| pluribus | → | pluribus | +| quanta_mesh | → | quanta_mesh | +| rad_etx | → | rad_etx | +| raisecom_roap | → | raisecom_roap | +| ruckus_fastiron | → | ruckus_fastiron | +| ruijie_os | → | ruijie_os | +| sixwind_os | → | sixwind_os | +| sophos_sfos | → | sophos_sfos | +| tplink_jetstream | → | tplink_jetstream | +| ubiquiti_edge | → | ubiquiti_edge | +| ubiquiti_edgerouter | → | ubiquiti_edgerouter | +| ubiquiti_edgeswitch | → | ubiquiti_edgeswitch | +| ubiquiti_unifiswitch | → | ubiquiti_unifiswitch | +| vmware_nsxv | → | vmware_nsxv | +| vyatta_vyos | → | vyatta_vyos | +| vyos | → | vyos | +| watchguard_firebox | → | watchguard_firebox | +| watchguard_fireware | → | watchguard_fireware | +| yamaha | → | yamaha | +| zte_zxros | → | zte_zxros | \ No newline at end of file diff --git a/docs/user/lib_mapper/ntctemplates_reverse.md b/docs/user/lib_mapper/ntctemplates_reverse.md new file mode 100644 index 00000000..08f191f0 --- /dev/null +++ b/docs/user/lib_mapper/ntctemplates_reverse.md @@ -0,0 +1,113 @@ +| NTCTEMPLATES | | NORMALIZED | +| ---------- | -- | ------ | +| a10 | → | a10 | +| accedian | → | accedian | +| adtran_os | → | adtran_os | +| alcatel_aos | → | alcatel_aos | +| alcatel_sros | → | alcatel_sros | +| allied_telesis_awplus | → | allied_telesis_awplus | +| apresia_aeos | → | apresia_aeos | +| arista_eos | → | arista_eos | +| aruba_os | → | aruba_os | +| aruba_osswitch | → | aruba_osswitch | +| aruba_procurve | → | aruba_procurve | +| avaya_ers | → | avaya_ers | +| avaya_vsp | → | avaya_vsp | +| broadcom_icos | → | broadcom_icos | +| brocade_fastiron | → | brocade_fastiron | +| brocade_fos | → | brocade_fos | +| brocade_netiron | → | brocade_netiron | +| brocade_nos | → | brocade_nos | +| brocade_vdx | → | brocade_vdx | +| brocade_vyos | → | brocade_vyos | +| calix_b6 | → | calix_b6 | +| centec_os | → | centec_os | +| checkpoint_gaia | → | checkpoint_gaia | +| ciena_saos | → | ciena_saos | +| cisco_asa | → | cisco_asa | +| cisco_ftd | → | cisco_ftd | +| cisco_ios | → | cisco_ios | +| cisco_nxos | → | cisco_nxos | +| cisco_s300 | → | cisco_s300 | +| cisco_tp | → | cisco_tp | +| cisco_wlc | → | cisco_wlc | +| cisco_xe | → | cisco_xe | +| cisco_xr | → | cisco_xr | +| cloudgenix_ion | → | cloudgenix_ion | +| coriant | → | coriant | +| dell_dnos9 | → | dell_dnos9 | +| dell_force10 | → | dell_force10 | +| dell_isilon | → | dell_isilon | +| dell_os10 | → | dell_os10 | +| dell_os6 | → | dell_os6 | +| dell_os9 | → | dell_os9 | +| dell_powerconnect | → | dell_powerconnect | +| dlink_ds | → | dlink_ds | +| eltex | → | eltex | +| eltex_esr | → | eltex_esr | +| endace | → | endace | +| enterasys | → | enterasys | +| ericsson_ipos | → | ericsson_ipos | +| extreme | → | extreme | +| extreme_ers | → | extreme_ers | +| extreme_exos | → | extreme_exos | +| extreme_netiron | → | extreme_netiron | +| extreme_nos | → | extreme_nos | +| extreme_slx | → | extreme_slx | +| extreme_vdx | → | extreme_vdx | +| extreme_vsp | → | extreme_vsp | +| extreme_wing | → | extreme_wing | +| f5_linux | → | f5_linux | +| f5_ltm | → | f5_ltm | +| f5_tmsh | → | f5_tmsh | +| flexvnf | → | flexvnf | +| fortinet | → | fortinet | +| generic | → | generic | +| generic_termserver | → | generic_termserver | +| hp_comware | → | hp_comware | +| hp_procurve | → | hp_procurve | +| huawei | → | huawei | +| huawei_olt | → | huawei_olt | +| huawei_smartax | → | huawei_smartax | +| huawei_vrp | → | huawei_vrp | +| huawei_vrpv8 | → | huawei_vrpv8 | +| ipinfusion_ocnos | → | ipinfusion_ocnos | +| juniper | → | juniper | +| juniper_junos | → | juniper_junos | +| juniper_screenos | → | juniper_screenos | +| keymile | → | keymile | +| keymile_nos | → | keymile_nos | +| linux | → | linux | +| mellanox | → | mellanox | +| mellanox_mlnxos | → | mellanox_mlnxos | +| mikrotik_routeros | → | mikrotik_routeros | +| mikrotik_switchos | → | mikrotik_switchos | +| mrv_lx | → | mrv_lx | +| mrv_optiswitch | → | mrv_optiswitch | +| netapp_cdot | → | netapp_cdot | +| netgear_prosafe | → | netgear_prosafe | +| netscaler | → | netscaler | +| nokia_sros | → | nokia_sros | +| oneaccess_oneos | → | oneaccess_oneos | +| ovs_linux | → | ovs_linux | +| paloalto_panos | → | paloalto_panos | +| pluribus | → | pluribus | +| quanta_mesh | → | quanta_mesh | +| rad_etx | → | rad_etx | +| raisecom_roap | → | raisecom_roap | +| ruckus_fastiron | → | ruckus_fastiron | +| ruijie_os | → | ruijie_os | +| sixwind_os | → | sixwind_os | +| sophos_sfos | → | sophos_sfos | +| tplink_jetstream | → | tplink_jetstream | +| ubiquiti_edge | → | ubiquiti_edge | +| ubiquiti_edgerouter | → | ubiquiti_edgerouter | +| ubiquiti_edgeswitch | → | ubiquiti_edgeswitch | +| ubiquiti_unifiswitch | → | ubiquiti_unifiswitch | +| vmware_nsxv | → | vmware_nsxv | +| vyatta_vyos | → | vyatta_vyos | +| vyos | → | vyos | +| watchguard_firebox | → | watchguard_firebox | +| watchguard_fireware | → | watchguard_fireware | +| yamaha | → | yamaha | +| zte_zxros | → | zte_zxros | \ No newline at end of file diff --git a/docs/user/lib_mapper/pyats.md b/docs/user/lib_mapper/pyats.md new file mode 100644 index 00000000..b6e7886f --- /dev/null +++ b/docs/user/lib_mapper/pyats.md @@ -0,0 +1,13 @@ +| NORMALIZED | | PYATS | +| ---------- | -- | ------ | +| asa | → | cisco_asa | +| bigip | → | f5_tmsh | +| dnac | → | cisco_dnac | +| ios | → | cisco_ios | +| iosxe | → | cisco_ios | +| iosxr | → | cisco_xr | +| junos | → | juniper_junos | +| linux | → | linux | +| nxos | → | cisco_nxos | +| sros | → | nokia_sros | +| viptela | → | cisco_viptella | \ No newline at end of file diff --git a/docs/user/lib_mapper/pyats_reverse.md b/docs/user/lib_mapper/pyats_reverse.md new file mode 100644 index 00000000..61acbd08 --- /dev/null +++ b/docs/user/lib_mapper/pyats_reverse.md @@ -0,0 +1,12 @@ +| PYATS | | NORMALIZED | +| ---------- | -- | ------ | +| cisco_asa | → | asa | +| cisco_dnac | → | dnac | +| cisco_ios | → | iosxe | +| cisco_nxos | → | nxos | +| cisco_viptella | → | viptela | +| cisco_xr | → | iosxr | +| f5_tmsh | → | bigip | +| juniper_junos | → | junos | +| linux | → | linux | +| nokia_sros | → | sros | \ No newline at end of file diff --git a/docs/user/lib_mapper/pyntc.md b/docs/user/lib_mapper/pyntc.md new file mode 100644 index 00000000..5ff18d52 --- /dev/null +++ b/docs/user/lib_mapper/pyntc.md @@ -0,0 +1,9 @@ +| NORMALIZED | | PYNTC | +| ---------- | -- | ------ | +| arista_eos_eapi | → | arista_eos | +| cisco_aireos_ssh | → | cisco_wlc | +| cisco_asa_ssh | → | cisco_asa | +| cisco_ios_ssh | → | cisco_ios | +| cisco_nxos_nxapi | → | cisco_nxos | +| f5_tmos_icontrol | → | f5_tmsh | +| juniper_junos_netconf | → | juniper_junos | \ No newline at end of file diff --git a/docs/user/lib_mapper/pyntc_reverse.md b/docs/user/lib_mapper/pyntc_reverse.md new file mode 100644 index 00000000..46495200 --- /dev/null +++ b/docs/user/lib_mapper/pyntc_reverse.md @@ -0,0 +1,9 @@ +| PYNTC | | NORMALIZED | +| ---------- | -- | ------ | +| arista_eos | → | arista_eos_eapi | +| cisco_asa | → | cisco_asa_ssh | +| cisco_ios | → | cisco_ios_ssh | +| cisco_nxos | → | cisco_nxos_nxapi | +| cisco_wlc | → | cisco_aireos_ssh | +| f5_tmsh | → | f5_tmos_icontrol | +| juniper_junos | → | juniper_junos_netconf | \ No newline at end of file diff --git a/docs/user/lib_mapper/scrapli.md b/docs/user/lib_mapper/scrapli.md new file mode 100644 index 00000000..5e9602c1 --- /dev/null +++ b/docs/user/lib_mapper/scrapli.md @@ -0,0 +1,7 @@ +| NORMALIZED | | SCRAPLI | +| ---------- | -- | ------ | +| arista_eos | → | arista_eos | +| cisco_iosxe | → | cisco_ios | +| cisco_iosxr | → | cisco_xr | +| cisco_nxos | → | cisco_nxos | +| juniper_junos | → | juniper_junos | \ No newline at end of file diff --git a/docs/user/lib_mapper/scrapli_reverse.md b/docs/user/lib_mapper/scrapli_reverse.md new file mode 100644 index 00000000..ae98d43f --- /dev/null +++ b/docs/user/lib_mapper/scrapli_reverse.md @@ -0,0 +1,7 @@ +| SCRAPLI | | NORMALIZED | +| ---------- | -- | ------ | +| arista_eos | → | arista_eos | +| cisco_ios | → | cisco_iosxe | +| cisco_nxos | → | cisco_nxos | +| cisco_xr | → | cisco_iosxr | +| juniper_junos | → | juniper_junos | \ No newline at end of file diff --git a/docs/user/lib_overview.md b/docs/user/lib_overview.md new file mode 100644 index 00000000..05d3212f --- /dev/null +++ b/docs/user/lib_overview.md @@ -0,0 +1,29 @@ +# Library Overview + +A Python library that is a collection of functions for common network automation tasks. + +This library intends to keep the following tenets: + +- Must not be any dependencies required to run the library. + - May be some optional dependencies, to be managed by the user in opt in fashion. +- Shall prefer functions over classes. +- Shall prefer a folder and file structure that is flat. +- Shall leverage docstrings as the primary documentation mechanism. + - Must provide examples in every public function. +- Shall retain a high test coverage. + +## Description/Overview + +A Python library that is a collection of functions that are used in the common network automation tasks. Tasks such as converting a BGP ASN to and from dotted format, normalizing an interface name, or "type 5" encrypting a password. The intention is to centralize these functions while keeping the library light. + + +## Audience (User Personas) - Who should use this Library? + +The intended audience is those who are programming network automation tasks with Python. Whether you are a seasoned veteran or a casual scripter, this library should help to reduce duplication between various reinventing the wheel. + +## Authors and Maintainers + +- @itdependsnetworks +- @jeffkala +- @qduk +- @abates diff --git a/docs/user/lib_use_cases.md b/docs/user/lib_use_cases.md new file mode 100644 index 00000000..5093d091 --- /dev/null +++ b/docs/user/lib_use_cases.md @@ -0,0 +1,80 @@ +# Using the Library + +As the Python library is intended to be a low-level implementation, the primary use case is within Code. On this page as well as subsequent pages we will provide an overview on the type of functions and examples. + +# Function Groupings + +Functions are grouped with like functions, such as IP or MAC address based functions. Included to date are groupings of: + +- Bandwidth - Provides the ability to convert between various bandwidth values. +- Banner - Provides the ability to normalize the various banner delimiters. +- BGP ASN - Provides the ability to convert BGP ASN from integer to dot notation. +- Configuration + - Cleaning - Provides the ability to remove or replace lines based on regex matches. + - Compliance - Provides the ability to compare two configurations to sanely understand the differences. + - Parsing - Provides the ability to parse configuration for the minor differences that are there. +- DNS - Provides the ability to work with DNS, such as validating that a FQDN is resolvable. +- Interface - Provides the ability to work with interface names, expanding, abbreviating, and splitting the names. +- IP Address - Provides the ability to work with IP addresses, primarily exposing Python `ipaddress` functionality. +- Library Mapper - Provides mappings in expected vendor names between Netmiko, NAPALM, pyntc, ntc-templates, pyats, and scrapli. +- MAC Address - Provides the ability to work with MAC addresses such as validating or converting to integer. +- Password - Provides the ability to compare and encrypt common password schemas such as type5 and type7 Cisco passwords. +- Ping - Provides the ability to ping, currently only tcp ping. +- Protocol Mapper - Provides a mapping for protocol names to numbers and vice versa. +- Route - Provides the ability to provide a list of routes and an IP Address and return the longest prefix matched route. +- Time -Provides the ability to convert between integer time and string times. +- VLANs - Provide the ability to convert configuration into lists or lists into configuration. + +## Examples + +While all functions come with examples in the docstrings, for quick reference of the types of problems this library intends to solve the following examples are provided. + +The following function will help in deploying list of VLANs and match the configuration style in a standard IOS-like configurations. + +```python +>>> from netutils.vlan import vlanlist_to_config +>>> +>>> vlan_cfg = vlanlist_to_config([1, 2, 3, 5, 6, 1000, 1002, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1018]) +>>> +>>> vlan_cfg +["1-3,5,6,1000,1002,1004,1006,1008,1010,1012,1014", "1016,1018"] +>>> +>>> for index, line in enumerate(vlan_cfg): +... if index == 0: +... print(f" switchport trunk allowed vlan {line}") +... else: +... print(f" switchport trunk allowed vlan add {line}") +... + switchport trunk allowed vlan 1-3,5,6,1000,1002,1004,1006,1008,1010,1012,1014 + switchport trunk allowed vlan add 1016,1018 +>>> +``` + +You may want to compare a known password with a given encrypted password. This can help in verifying if the passwords are as expected for compliance reasons. + +```python +>>> from netutils.password import compare_type5 +>>> +>>> compare_type5("cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") +True +>>> +>>> compare_type5("not_cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") +False +>>> +``` + +Often times interfaces will come in various different shortened names, and it is helpful to normalize them. + +```python +>>> from netutils.interface import canonical_interface_name +>>> +>>> canonical_interface_name("Gi1/0/1") +'GigabitEthernet1/0/1' +>>> +>>> canonical_interface_name("Eth1") +'Ethernet1' +>>> +``` + +!!! tip + These are just some examples of the many functions provided by this library. Please review the Developer code for Examples on every public function diff --git a/docs/user/lib_use_cases_jinja_filters.md b/docs/user/lib_use_cases_jinja_filters.md new file mode 100644 index 00000000..d433d54d --- /dev/null +++ b/docs/user/lib_use_cases_jinja_filters.md @@ -0,0 +1,120 @@ +# Netutils to Jinja2 Filters + +In an effort to simplify the process of adding netutils' functions to jinja2 as filters we have created a convenience function. Let's go through how you could add the filters to your jinja2 environment. +Here is the current folder structure. + +```bash +. +├── jinja2_environment.py +├── templates +└── test.j2 +``` + +Below is the code in the `test.j2` file. + +```jinja + +IP Address + 200 = {{ "192.168.0.1/10" | ip_addition(200) }} + +``` +Below is a code in the `jinja2_environment.py` folder. + +```python + +from jinja2.loaders import FileSystemLoader, PackageLoader +from jinja2 import Environment, PackageLoader, select_autoescape +from netutils.utils import jinja2_convenience_function + +env = Environment( + loader=FileSystemLoader("templates"), + autoescape=select_autoescape() +) + +env.filters.update(jinja2_convenience_function()) + +template = env.get_template("test.j2") +result = template.render() +print(result) +``` + +When you run `jinja2_environment.py` the output will be: + +```text + +IP Address + 200 = 192.168.0.201 + +``` + +## Netutils to Ansible Jinja2 Filters + +In Ansible, one can add with the following code by adding to a folder called `filter_plugins` in a file called `nutils.py` as an example. + +```python +from netutils.utils import jinja2_convenience_function +class FilterModule(object): + def filters(self): + return jinja2_convenience_function() +``` + +## ipaddress Convenience Functions + +When adding the netutils functions to your jinja2 environment, you also gain access to the built-in ipaddress python library using these three jinja2 filters. + +```python + "ipaddress_address": "ip.ipaddress_address", + "ipaddress_interface": "ip.ipaddress_interface", + "ipaddress_network": "ip.ipaddress_network", +``` + +When using these filters, you must specify an attribute of that given class. Here is an example of how you would use the `version` if the `ipaddress_interface` filter. + +```bash +. +├── jinja2_environment.py +├── templates +└── test.j2 +``` + +Below is the code in the `test.j2` file. + +```jinja + +The version of 192.168.0.1/24 is IPv{{ "192.168.0.1/24" | ipaddress_interface("version") }}. + +``` + +Below is a code in the `jinja2_environment.py` folder. + +```python +from jinja2.loaders import FileSystemLoader, PackageLoader +from jinja2 import Environment, PackageLoader, select_autoescape +from netutils.utils import jinja2_convenience_function + +env = Environment( + loader=FileSystemLoader("templates"), + autoescape=select_autoescape() +) + +env.filters.update(jinja2_convenience_function()) + +template = env.get_template("test.j2") +result = template.render() +print(result) +``` + +When you run `jinja2_environment.py` the output will be: + +```text +The version of 192.168.0.1/24 is IPv4. +``` + +## Netutils to Jinja2 Filters List + + +The below list shows what jinja2 filters are added when you add them using the process above. The keys of the dictionary are the names you would use to call the jinja2 filter. + +!!! note + + The jinja2 filter names match the python function names. + +--8<-- "docs/user/include_jinja_list.md" \ No newline at end of file diff --git a/docs/user/lib_use_cases_lib_mapper.md b/docs/user/lib_use_cases_lib_mapper.md new file mode 100644 index 00000000..f73e4e24 --- /dev/null +++ b/docs/user/lib_use_cases_lib_mapper.md @@ -0,0 +1,88 @@ +# Library Mappings + +These dictionaries provide mappings in expected vendor names between Netmiko, NAPALM, pyntc, ntc-templates, pyats, and scrapli. For each non-reversed mapper, the keys of the dictionary represent the driver used for that library while the values represent the "normalized" driver based on netmiko. + +These dictionaries allow you to keep your Source of Truth platform data consistent and still easily switch between automation libraries. For example, you may be storing your device platform data in Nautobot. In a Nautobot platform, you can store the NAPALM driver needed for that platform. What if you wanted to write a python script to leverage the backup capabilities of pyntc? Here's an example of how you could use the following dictionaries to perform mappings from your stored Nautobot NAPALM driver to the pyntc driver needed for your script. + +```python + +import pynautobot +from netutils.lib_mapper import NAPALM_LIB_MAPPER, PYNTC_LIB_MAPPER_REVERSE +from pyntc import ntc_device as NTC + + +# Get device from Nautobot +nautobot = pynautobot.api(url="http://mynautobotinstance.com",token="mytoken") + +# Get Napalm driver and save for later use. +device = nautobot.dcim.devices.get(name="mydevice") +sot_driver = device.platform.napalm_driver + + +# Connect to device via Napalm +driver = napalm.get_network_driver("ios") + +device = driver( + hostname="device.name", + username="demo", + password="secret" +) + +# Do Napalm tasks + +pyntc_driver = PYNTC_LIB_MAPPER_REVERSE.get(NAPALM_LIB_MAPPER.get(sot_driver)) +net_con = NTC(host=device.name, username="demo", password="secret", device_type=pyntc_driver) + +# Do pyntc tasks +``` + +Another use case could be using an example like the above in an Ansible filter. That would allow you to write a filter utilizing whichever automation library you needed without having to store the driver for each one in your Source of Truth. + + +## Ansible Mapper + +--8<-- "docs/user/lib_mapper/ansible.md" + +## Reverse Ansible Mapper + +--8<-- "docs/user/lib_mapper/ansible_reverse.md" + +## Napalm Mapper + +--8<-- "docs/user/lib_mapper/napalm.md" + +## Reverse Napalm Mapper + +--8<-- "docs/user/lib_mapper/napalm_reverse.md" + +## NTC Templates Mapper + +--8<-- "docs/user/lib_mapper/ntctemplates.md" + +## Reverse NTC Templates Mapper + +--8<-- "docs/user/lib_mapper/ntctemplates_reverse.md" + +## PyATS Mapper + +--8<-- "docs/user/lib_mapper/pyats.md" + +## Reverse PyATS Mapper + +--8<-- "docs/user/lib_mapper/pyats_reverse.md" + +## PyNTC Mapper + +--8<-- "docs/user/lib_mapper/pyntc.md" + +## Reverse PyNTC Mapper + +--8<-- "docs/user/lib_mapper/pyntc_reverse.md" + +## Scrapli Mapper + +--8<-- "docs/user/lib_mapper/scrapli.md" + +## Reverse Scrapli Mapper +--8<-- "docs/user/lib_mapper/scrapli_reverse.md" + diff --git a/docs/user/lib_use_cases_protocol_mappers.md b/docs/user/lib_use_cases_protocol_mappers.md new file mode 100644 index 00000000..1dc1fb7d --- /dev/null +++ b/docs/user/lib_use_cases_protocol_mappers.md @@ -0,0 +1,67 @@ +# Protocol Mappers + +These protocol mappers can be used when you have either the application protocol name or number but need the corresponding value. Something to note is that these mappings are divided up per IP protocol. +The reasoning behind this is that the same port number could be tied to two different application protocols depending on the underlying IP protocol. For example, when using UDP, port 13400 is the application protocol `doip-disc`. Looking at the same port using TCP the application protocol is `doip-data`. + + +Here are currently available mappers: + +- **DCCP_NAME_TO_NUM** - Allows mapping from a known DCCP application protocol name to DCCP application protocol number. + +- **DCCP_NUM_TO_NAME** - Allows mapping from a known DCCP application protocol name to DCCP application protocol number. + +- **PROTO_NAME_TO_NUM** - Allows mapping from a known IP protocol name to IP protocol number. + +- **PROTO_NUM_TO_NAME** - Allows mapping from a known IP protocol number to IP protocol name. + +- **SCTP_NAME_TO_NUM** - Allows mapping from a known SCTP application protocol name to SCTP application protocol number. + +- **SCTP_NUM_TO_NAME** - Allows mapping from a known SCTP application protocol number to SCTP application protocol name. + +- **TCP_NAME_TO_NUM** - Allows mapping from a known TCP application protocol name to TCP application protocol number. + +- **TCP_NUM_TO_NAME** - Allows mapping from a known TCP application protocol number to TCP application protocol name. + +- **UDP_NAME_TO_NUM** - Allows mapping from a known UDP application protocol name to UDP application protocol number. + +- **UDP_NUM_TO_NAME** - Allows mapping from a known UDP application protocol number to UDP application protocol name. + + +Here are a few examples showing how you would use these in your python code. + +```python + +from netutils.protocol_mapper import ( + + PROTO_NAME_TO_NUM, + PROTO_NUM_TO_NAME, + TCP_NAME_TO_NUM, + TCP_NUM_TO_NAME, + UDP_NAME_TO_NUM, + UDP_NUM_TO_NAME, + SCTP_NAME_TO_NUM, + SCTP_NUM_TO_NAME, + DCCP_NAME_TO_NUM, + DCCP_NUM_TO_NAME, +) + +# Get DCCP protocol port from known DCCP application name +LTP_DEEPSPACE_PORT = DCCP_NAME_TO_NUM("ltp-deepspace") +print(LTP_DEEPSPACE_PORT) +# 1113 + +# Get TCP protocol port from known TCP application name +SSH_PORT = TCP_NAME_TO_NUM["ssh"] +print(SSH_PORT) +# 22 + +# Get SCTP protocol name from known SCTP application port. +SCTP_PORT_1021_APPLICATION_NAME = SCTP_NUM_TO_NAME[1021] +print(SCTP_PORT_1021_APPLICATION_NAME) +# "exp1" + +# Get UDP protocol name from known UDP application port +UDP_PORT_20_APPLICATION_NAME = UDP_NUM_TO_NAME[20] +print(UDP_PORT_20_APPLICATION_NAME) +# "ftp-data +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..d47bb2b5 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,139 @@ +--- +dev_addr: "127.0.0.1:8001" +edit_uri: "edit/develop/docs" +site_dir: "netutils/static/netutils/docs" +site_name: "Netutils Documentation" +site_url: "https://netutils.readthedocs.io/en/latest/" +repo_url: "https://github.com/networktocode/netutils" +copyright: "Copyright © The Authors" +theme: + name: "material" + navigation_depth: 4 + custom_dir: "docs/assets/overrides" + hljs_languages: + - "python" + - "yaml" + features: + - "navigation.tracking" + - "navigation.tabs" + - "navigation.tabs.sticky" + - "search.suggest" + - "search.highlight" + - "search.share" + - "navigation.indexes" + favicon: "assets/favicon.ico" + logo: "assets/networktocode_logo.svg" + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: "default" + primary: "black" + toggle: + icon: "material/weather-sunny" + name: "Switch to dark mode" + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: "slate" + primary: "black" + toggle: + icon: "material/weather-night" + name: "Switch to light mode" +extra_css: + - "assets/extra.css" + +# needed for RTD version flyout menu +# jquery is not (yet) injected by RTD automatically and it might be dropped +# as a dependency in the future +extra_javascript: + - "https://code.jquery.com/jquery-3.6.0.min.js" + +extra: + generator: false + ntc_sponsor: true + social: + - icon: "fontawesome/solid/rss" + link: "https://blog.networktocode.com/" + name: "Network to Code Blog" + - icon: "fontawesome/brands/youtube" + link: "https://www.youtube.com/channel/UCwBh-dDdoqzxXKyvTw3BuTw" + name: "Network to Code Videos" + - icon: "fontawesome/brands/slack" + link: "https://www.networktocode.com/community/" + name: "Network to Code Community" + - icon: "fontawesome/brands/github" + link: "https://github.com/networktocode/" + name: "GitHub Organization" + - icon: "fontawesome/brands/twitter" + link: "https://twitter.com/networktocode" + name: "Network to Code Twitter" +markdown_extensions: + - "admonition" + - "toc": + permalink: true + - "attr_list" + - "md_in_html" + - "pymdownx.highlight": + anchor_linenums: true + - "pymdownx.inlinehilite" + - "pymdownx.snippets" + - "pymdownx.superfences" + - "footnotes" +plugins: + - "search" + - "mkdocs-version-annotations" + - "mkdocstrings": + default_handler: "python" + handlers: + python: + paths: ["."] + options: + show_root_heading: true +watch: + - "README.md" + +nav: + - Overview: "index.md" + - User Guide: + - Library Overview: "user/lib_overview.md" + - Using the Library: "user/lib_use_cases.md" + - Jinja Filters: "user/lib_use_cases_jinja_filters.md" + - Library Mapper: "user/lib_use_cases_lib_mapper.md" + - Protocol Mapper: "user/lib_use_cases_protocol_mappers.md" + - Getting Started: "user/lib_getting_started.md" + - Frequently Asked Questions: "user/faq.md" + - Administrator Guide: + - Install and Configure: "admin/install.md" + - Upgrade: "admin/upgrade.md" + - Uninstall: "admin/uninstall.md" + - Release Notes: + - "admin/release_notes/index.md" + - v0.1: "admin/release_notes/version_0.1.md" + - v0.2: "admin/release_notes/version_0.2.md" + - v1.0: "admin/release_notes/version_1.0.md" + - v1.1: "admin/release_notes/version_1.1.md" + - v1.2: "admin/release_notes/version_1.2.md" + - Developer Guide: + - Extending the Library: "dev/extending.md" + - Contributing to the Library: "dev/contributing.md" + - Development Environment: "dev/dev_environment.md" + - Config Parser Development: "dev/dev_config.md" + - Code Attribution to the Library: "dev/attribution.md" + - Code Reference: + - "dev/code_reference/index.md" + - ASN: "dev/code_reference/asn.md" + - Bandwidth: "dev/code_reference/bandwidth.md" + - Banner: "dev/code_reference/banner.md" + - Configs: "dev/code_reference/configs.md" + - DNS: "dev/code_reference/dns.md" + - Interface: "dev/code_reference/interface.md" + - IP: "dev/code_reference/ip.md" + - Library Mapping: "dev/code_reference/lib_mapping.md" + - Mac Address: "dev/code_reference/mac.md" + - Password: "dev/code_reference/password.md" + - Ping: "dev/code_reference/ping.md" + - Protocol Mapper: "dev/code_reference/protocol_mapper.md" + - Route: "dev/code_reference/route.md" + - Time: "dev/code_reference/time.md" + - Utils: "dev/code_reference/utils.md" + - VLAN: "dev/code_reference/vlan.md" diff --git a/netutils/asn.py b/netutils/asn.py index 10d1dd53..04323b4e 100644 --- a/netutils/asn.py +++ b/netutils/asn.py @@ -10,7 +10,7 @@ def asn_to_int(asplain: str) -> int: Returns: Integer value within of the given asplain value provided. - Example: + Examples: >>> from netutils.asn import asn_to_int >>> asn_to_int("65000") 65000 diff --git a/netutils/bandwidth.py b/netutils/bandwidth.py index 84fd9b45..01ea8baf 100644 --- a/netutils/bandwidth.py +++ b/netutils/bandwidth.py @@ -44,7 +44,7 @@ def name_to_bits(speed: str) -> int: Returns: value of bandwidth to be converted to bps - Example: + Examples: >>> from netutils.bandwidth import name_to_bits >>> name_to_bits("10Gbps") 10000000000 @@ -76,7 +76,7 @@ def name_to_bytes(speed: str) -> float: Returns: value of bandwidth to be converted to Bps - Example: + Examples: >>> from netutils.bandwidth import name_to_bytes >>> name_to_bytes("10Gbps") 1250000000.0 @@ -111,7 +111,7 @@ def bits_to_name( # pylint: disable=too-many-branches,too-many-return-statement Returns: Name value for speed in bits - Example: + Examples: >>> from netutils.bandwidth import bits_to_name >>> bits_to_name(125000) '125Kbps' @@ -141,7 +141,7 @@ def bytes_to_name(speed: float, nbr_decimal: int = 0) -> str: Returns: Name value for speed in bytes - Example: + Examples: >>> from netutils.bandwidth import bytes_to_name >>> bytes_to_name(10000.0) '10.0KBps' @@ -172,7 +172,7 @@ def name_to_name(speed: str, speed_type: str, nbr_decimal: int = 0) -> str: Returns: The named value which user wishes to return to. - Example: + Examples: >>> from netutils.bandwidth import name_to_name >>> name_to_name("10Gbps", "Kbps") '10000000.0Kbps' diff --git a/netutils/banner.py b/netutils/banner.py index be9df8c6..1f82a81a 100644 --- a/netutils/banner.py +++ b/netutils/banner.py @@ -15,7 +15,7 @@ def delimiter_change(config: str, from_delimiter: str, to_delimiter: str) -> str Returns: Configuration with delimiter replaced. - Example: + Examples: >>> from netutils.banner import delimiter_change >>> delimiter_change("banner login ^\n******************\n TEST BANNER\n******************^", "^", "^C") 'banner login ^C\n******************\n TEST BANNER\n******************^C' @@ -40,7 +40,7 @@ def normalise_delimiter_caret_c(delimiter: str, config: str) -> str: Returns: Configuration with delimiter normalised to ^C. - Example: + Examples: >>> from netutils.banner import normalise_delimiter_caret_c >>> normalise_delimiter_caret_c("^", "banner login ^\n******************\n TEST BANNER\n******************^") 'banner login ^C\n******************\n TEST BANNER\n******************^C' diff --git a/netutils/config/clean.py b/netutils/config/clean.py index 71a4a636..7d635cca 100644 --- a/netutils/config/clean.py +++ b/netutils/config/clean.py @@ -15,7 +15,7 @@ def clean_config(config: str, filters: t.List[t.Dict[str, str]]) -> str: Returns: Stripped down configuration. - Example: + Examples: >>> from netutils.config.clean import clean_config >>> config = '''Building configuration... ... Current configuration : 1582 bytes @@ -62,7 +62,7 @@ def sanitize_config(config: str, filters: t.Optional[t.List[t.Dict[str, str]]] = Returns: str: Sanitized configuration. - Example: + Examples: >>> from netutils.config.clean import sanitize_config >>> config = '''enable secret 5 $1$nc08$bizeEFbgCBKjZP4nurNCd.!''' >>> SANITIZE_FILTERS = [ diff --git a/netutils/config/compliance.py b/netutils/config/compliance.py index 07f4b21f..703b3db2 100644 --- a/netutils/config/compliance.py +++ b/netutils/config/compliance.py @@ -42,7 +42,7 @@ def _check_configs_differences(intended_cfg: str, actual_cfg: str, network_os: s Returns: Config fragments that are missing, extra or unordered_compliant. - Example: + Examples: >>> from netutils.config.compliance import _check_configs_differences >>> intended_cfg = '''ntp server 10.10.10.10 ... ntp server 10.10.10.11''' @@ -83,7 +83,7 @@ def _is_feature_ordered_compliant(feature_intended_cfg: str, feature_actual_cfg: Returns: bool - Example: + Examples: >>> feature_intended_cfg = '''router bgp 100 ... bgp router-id 10.6.6.5''' >>> @@ -129,7 +129,7 @@ def compliance( Returns: dict: Compliance information per feature. - Example: + Examples: >>> features = [ ... { ... "name": "hostname", @@ -201,7 +201,7 @@ def config_section_not_parsed( Returns: Config that was not parsed or section not found. - Example: + Examples: >>> features = [{ ... "name": "BGP", ... "ordered": True, @@ -242,7 +242,7 @@ def diff_network_config(compare_config: str, base_config: str, network_os: str) Returns: base_config: The string of additional commands in compare_config separated by a newline. - Example: + Examples: >>> compare_config = '''router bgp 100 ... bgp router-id 10.6.6.5 ... ! @@ -295,7 +295,7 @@ def feature_compliance( Returns: dict: Compliance information of a single feature. - Example: + Examples: >>> feature = { ... "name": "ntp", ... "ordered": True, @@ -354,7 +354,7 @@ def find_unordered_cfg_lines(intended_cfg: str, actual_cfg: str) -> t.Tuple[bool Returns: list: List of tuples with unordered_compliant cfg lines. - Example: + Examples: >>> intended_cfg = ''' ... ntp server 10.10.10.10 ... ntp server 10.10.10.11 @@ -394,7 +394,7 @@ def section_config(feature: t.Dict[str, t.Union[str, bool, t.List[str]]], device Returns: The hash report data mapping file hashes to report data. - Example: + Examples: >>> feature = { ... "name": "BGP", ... "ordered": False, diff --git a/netutils/config/parser.py b/netutils/config/parser.py index 72bad867..93f3324b 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -110,7 +110,7 @@ def is_comment(self, line: str) -> bool: Returns: True if line is a comment, else False. - Example: + Examples: >>> BaseSpaceConfigParser("interface Ethernet1/1").is_comment("interface Ethernet1/1") False >>> BaseSpaceConfigParser("!").is_comment("!") @@ -129,7 +129,7 @@ def config_lines_only(self) -> str: Returns: The non-space and non-comment lines from ``config``. - Example: + Examples: >>> config = '''! ... aaa group server tacacs+ auth ... server 10.1.1.1 @@ -163,7 +163,7 @@ def get_leading_space_count(config_line: str) -> int: Returns: The number of leading spaces. - Example: + Examples: >>> config = '''interface GigabitEthernet1\n description link to ISP''' >>> config_line = " description link to ISP" >>> indent_level = BaseSpaceConfigParser(config).get_leading_space_count(config_line) @@ -287,7 +287,7 @@ def _update_config_lines(self, config_line: str) -> None: def build_config_relationship(self) -> t.List[ConfigLine]: r"""Parse text tree of config lines and their parents. - Example: + Examples: >>> config = ( ... "interface Ethernet1/1\n" ... " vlan 10\n" @@ -353,7 +353,8 @@ def find_all_children(self, pattern: str, match_type: str = "exact") -> t.List[s Returns: configuration under that parent pattern. - Example: + + Examples: >>> config = ''' ... router bgp 45000 ... address-family ipv4 unicast @@ -386,7 +387,8 @@ def find_children_w_parents( Returns: configuration under that parent pattern. - Example: + + Examples: >>> config = ''' ... router bgp 45000 ... address-family ipv4 unicast @@ -438,7 +440,7 @@ def config_lines_only(self) -> str: def build_config_relationship(self) -> t.List[ConfigLine]: r"""Parse text tree of config lines and their parents. - Example: + Examples: >>> config = '''auth ldap system-auth { ... port ldaps ... servers { ams-lda01.ntc.com } @@ -482,7 +484,7 @@ def _build_multiline_config(self, delimiter: str) -> t.Optional[ConfigLine]: Returns: The multiline string text that was added to ``self.config_lines``. - Example: + Examples: >>> config = ( ... 'sys syslog {\n' ... ' include "\n' @@ -643,7 +645,7 @@ def _update_config_lines(self, config_line: str) -> None: def build_config_relationship(self) -> t.List[ConfigLine]: r"""Parse text tree of config lines and their parents. - Example: + Examples: >>> config = ''' ... interface Ethernet1/1 ... vlan 10 @@ -795,7 +797,7 @@ def _clean_config_f5(self, config_text: str) -> str: # pylint: disable=no-self- def build_config_relationship(self) -> t.List[ConfigLine]: r"""Parse text tree of config lines and their parents. - Example: + Examples: >>> config = '''apm resource webtop-link aShare { ... application-uri http://funshare.example.com ... customization-group a_customization_group @@ -847,7 +849,7 @@ def _build_multiline_single_configuration_line(self, delimiter: str, prev_line: Returns: The multiline string text that was added to ``self.config_lines``. - Example: + Examples: config = '''apm resource webtop-link aShare { application-uri http://funshare.example.com customization-group a_customization_group @@ -937,7 +939,7 @@ def _update_config_lines(self, config_line: str) -> None: def build_config_relationship(self) -> t.List[ConfigLine]: r"""Parse text tree of config lines and their parents. - Example: + Examples: >>> config = ''' ... interface Management0/0 ... management-only @@ -1004,7 +1006,7 @@ def is_end_next(self, line: str) -> bool: # pylint: disable=no-self-use Returns: True if line has 'end' or 'next', else False. - Example: + Examples: >>> FortinetConfigParser("config system virtual-switch").is_end_next("config system virtual-switch") False >>> FortinetConfigParser("end").is_end_next("end") diff --git a/netutils/dns.py b/netutils/dns.py index 680751f7..965ae879 100644 --- a/netutils/dns.py +++ b/netutils/dns.py @@ -14,7 +14,7 @@ def fqdn_to_ip(hostname: str) -> str: Returns: The IP Address of a valid FQDN. - Example: + Examples: >>> from netutils.dns import fqdn_to_ip >>> from netutils.ip import is_ip >>> is_ip(fqdn_to_ip("google.com")) @@ -40,7 +40,7 @@ def is_fqdn_resolvable(hostname: str) -> bool: Returns: bool: The result as to whether or not the domain was valid. - Example: + Examples: >>> from netutils.dns import is_fqdn_resolvable >>> is_fqdn_resolvable("google.com") True diff --git a/netutils/interface.py b/netutils/interface.py index 3e597359..eb2afc07 100644 --- a/netutils/interface.py +++ b/netutils/interface.py @@ -18,7 +18,7 @@ def interface_range_expansion(interface_pattern: str) -> t.List[str]: Returns: Contains the expanded list of interfaces. - Example: + Examples: >>> from netutils.interface import interface_range_expansion >>> interface_range_expansion("Gi0/[1-4]") ['Gi0/1', 'Gi0/2', 'Gi0/3', 'Gi0/4'] @@ -74,7 +74,7 @@ def split_interface(interface: str) -> t.Tuple[str, str]: Returns: The split between the name of the interface the value. - Example: + Examples: >>> from netutils.interface import split_interface >>> split_interface("GigabitEthernet1/0/1") ('GigabitEthernet', '1/0/1') @@ -106,7 +106,7 @@ def canonical_interface_name( Returns: The name of the interface in the long form. - Example: + Examples: >>> from netutils.interface import canonical_interface_name >>> canonical_interface_name("Gi1/0/1") 'GigabitEthernet1/0/1' @@ -158,7 +158,7 @@ def canonical_interface_name_list( Raises: ValueError: Raised if any interface name in list cannot be converted to its long form and verify parameter is set to true. - Example: + Examples: >>> from netutils.interface import canonical_interface_name_list >>> canonical_interface_name_list(["Gi1/0/1", "Gi1/0/2", "Eth1"]) ['GigabitEthernet1/0/1', 'GigabitEthernet1/0/2', 'Ethernet1'] @@ -215,7 +215,7 @@ def abbreviated_interface_name( Returns: The name of the interface in the abbreviated form. - Example: + Examples: >>> abbreviated_interface_name("GigabitEthernet1/0/1") 'Gi1/0/1' >>> abbreviated_interface_name("Eth1") @@ -275,7 +275,6 @@ def __eq__(self, other: t.Any) -> t.Any: # noqa: D105 @abstractmethod def weight(self) -> int: """Weight property.""" - ... @property def terminal(self) -> bool: @@ -439,7 +438,7 @@ def sort_interface_list(interfaces: t.List[str]) -> t.List[str]: Returns: list[str]: A **new** sorted, unique list elements from the input. - Example: + Examples: >>> sort_interface_list(["Gi1/0/1", "Gi1/0/3", "Gi1/0/3.100", "Gi1/0/2", "Gi1/0/2.50", "Gi2/0/2", "Po40", "Po160", "Lo10"]) ['Gi1/0/1', 'Gi1/0/2', 'Gi1/0/2.50', 'Gi1/0/3', 'Gi1/0/3.100', 'Gi2/0/2', 'Lo10', 'Po40', 'Po160'] >>> sort_interface_list(['GigabitEthernet1/0/1', 'GigabitEthernet1/0/3', 'GigabitEthernet1/0/2', "GigabitEthernett3/0/5", 'GigabitEthernet3/0/7', 'GigabitEthernet2/0/8.5', 'Port-channel40', 'Vlan20', 'Loopback10']) @@ -478,7 +477,7 @@ def abbreviated_interface_name_list( # pylint: disable=R0913, R0914 Raises: ValueError: Raised if any interface name in list cannot be converted to its abbreviated form and verify parameter is set to true. - Example: + Examples: >>> from netutils.interface import abbreviated_interface_name_list >>> abbreviated_interface_name_list(["GigabitEthernet1/0/1", "GigabitEthernet1/0/2", "Ethernet1"]) ['Gi1/0/1', 'Gi1/0/2', 'Et1'] @@ -552,7 +551,7 @@ def _check_order_option_exists(order: str) -> None: def _ranges_in_list(numbers: t.List[int]) -> t.List[t.List[int]]: """Find contiguous ranges in a list of numbers. - Example: + Examples: >>> _ranges_in_list([1, 2, 3, 5, 6, 8]) [[1, 2, 3], [5, 6], [8]] @@ -572,7 +571,7 @@ def interface_range_compress(interface_list: t.List[str]) -> t.List[str]: there is no check against correct interface names! Also interface names must use the same abbreviation! E.g. Gi =! GigabitEthernet - Example: + Examples: >>> interface_range_compress(["Gi1/0/1", "Gi1/0/2", "Gi1/0/3", "Gi1/0/5"]) ['Gi1/0/1-3', 'Gi1/0/5'] >>> interface_range_compress(["Gi0/1", "Gi0/2", "Gi0/4", "Gi1/0", "Gi1/1"]) diff --git a/netutils/ip.py b/netutils/ip.py index c70d9966..3ff39487 100644 --- a/netutils/ip.py +++ b/netutils/ip.py @@ -16,7 +16,7 @@ def ipaddress_address(ip: str, attr: str) -> t.Any: Returns: Returns the value provided by the ipaddress.ip_address attribute provided. - Example: + Examples: >>> from netutils.ip import ipaddress_address >>> ipaddress_address('10.1.1.1', 'version') 4 @@ -43,7 +43,7 @@ def ipaddress_interface(ip: str, attr: str) -> t.Any: Returns: Returns the value provided by the ipaddress.ip_interface attribute provided. - Example: + Examples: >>> from netutils.ip import ipaddress_interface >>> ipaddress_interface('10.1.1.1/24', 'version') 4 @@ -67,7 +67,7 @@ def ipaddress_network(ip: str, attr: str) -> t.Any: Returns: Returns the value provided by the ipaddress.ip_network attribute provided. - Example: + Examples: >>> from netutils.ip import ipaddress_network >>> ipaddress_network('10.1.1.0/24', 'version') 4 @@ -91,7 +91,7 @@ def ip_to_hex(ip: str) -> str: Returns: HEX value of the IP address. - Example: + Examples: >>> from netutils.ip import ip_to_hex >>> ip_to_hex("10.100.100.100") '0a646464' @@ -111,7 +111,7 @@ def ip_addition(ip: str, val: int) -> str: Returns: IP address formatted string with the newly added IP address. - Example: + Examples: >>> from netutils.ip import ip_addition >>> ip_addition("10.100.100.100", 200) '10.100.101.44' @@ -129,7 +129,7 @@ def ip_to_bin(ip: str) -> str: Returns: Binary value of the IP address. - Example: + Examples: >>> from netutils.ip import ip_to_bin >>> ip_to_bin("10.100.100.100") '00001010011001000110010001100100' @@ -149,7 +149,7 @@ def ip_subtract(ip: str, val: int) -> str: Returns: IP address formatted string with the newly subtracted IP address. - Example: + Examples: >>> from netutils.ip import ip_subtract >>> ip_subtract("10.100.100.100", 200) '10.100.99.156' @@ -167,7 +167,7 @@ def is_ip(ip: str) -> bool: Returns: The result as to whether or not the string is a valid IP address. - Example: + Examples: >>> from netutils.ip import is_ip >>> is_ip("10.100.100.256") False @@ -191,7 +191,7 @@ def is_netmask(netmask: str) -> bool: Returns: True if string is a valid subnet mask. Otherwise, false. - Example: + Examples: >>> from netutils.ip import is_netmask >>> is_netmask('255.255.255.0') True @@ -215,7 +215,7 @@ def netmask_to_cidr(netmask: str) -> int: Returns: CIDR representation of subnet mask. - Example: + Examples: >>> from netutils.ip import netmask_to_cidr >>> netmask_to_cidr("255.255.255.0") 24 @@ -238,7 +238,7 @@ def cidr_to_netmask(cidr: int) -> str: Returns: Decimal format representation of CIDR value. - Example: + Examples: >>> from netutils.ip import cidr_to_netmask >>> cidr_to_netmask(24) '255.255.255.0' @@ -259,7 +259,7 @@ def cidr_to_netmaskv6(cidr: int) -> str: Returns: Decimal format (IPv6) representation of CIDR value. - Example: + Examples: >>> from netutils.ip import cidr_to_netmaskv6 >>> cidr_to_netmaskv6(24) 'ffff:ff00::' @@ -280,7 +280,7 @@ def get_all_host(ip_network: str) -> t.Generator[str, None, None]: Returns: Generator of usable IP Addresses within network. - Example: + Examples: >>> from netutils.ip import get_all_host >>> print(list(get_all_host("10.100.100.0/29"))) ['10.100.100.1', '10.100.100.2', '10.100.100.3', '10.100.100.4', '10.100.100.5', '10.100.100.6'] @@ -298,7 +298,7 @@ def get_broadcast_address(ip_network: str) -> str: Returns: IP address formatted string with the broadcast IP address in the network. - Example: + Examples: >>> from netutils.ip import get_broadcast_address >>> get_broadcast_address("10.100.0.0/16") '10.100.255.255' @@ -316,7 +316,7 @@ def get_first_usable(ip_network: str) -> str: Returns: IP address formatted string with the first usable IP address in the network. - Example: + Examples: >>> from netutils.ip import get_first_usable >>> get_first_usable("10.100.0.0/16") '10.100.0.1' @@ -337,7 +337,7 @@ def get_peer_ip(ip_interface: str) -> str: Returns: IP address formatted string with the corresponding peer IP. - Example: + Examples: >>> from netutils.ip import get_peer_ip >>> get_peer_ip('10.0.0.1/255.255.255.252') '10.0.0.2' @@ -375,7 +375,7 @@ def get_usable_range(ip_network: str) -> str: Returns: String of usable IP Addresses within network. - Example: + Examples: >>> from netutils.ip import get_usable_range >>> get_usable_range("10.100.100.0/29") '10.100.100.1 - 10.100.100.6' diff --git a/netutils/mac.py b/netutils/mac.py index fa3c441b..67fa4698 100644 --- a/netutils/mac.py +++ b/netutils/mac.py @@ -33,7 +33,7 @@ def is_valid_mac(mac: str) -> bool: Returns: The result as to whether or not the string is a valid MAC address. - Example: + Examples: >>> from netutils.mac import is_valid_mac >>> is_valid_mac("aa.bb.cc.dd.ee.ff") True @@ -58,7 +58,7 @@ def mac_to_format(mac: str, frmt: str = "MAC_NO_SPECIAL") -> str: Returns: A MAC address in the specified format. - Example: + Examples: >>> from netutils.mac import mac_to_format >>> mac_to_format("aa.bb.cc.dd.ee.ff", "MAC_DASH_FOUR") 'aabb-ccdd-eeff' @@ -82,7 +82,7 @@ def mac_to_int(mac: str) -> int: Returns: The valid MAC address converted to an integer. - Example: + Examples: >>> from netutils.mac import mac_to_int >>> mac_to_int("aa.bb.cc.dd.ee.ff") 187723572702975 @@ -101,7 +101,7 @@ def mac_type(mac: str) -> t.Optional[str]: Returns: The regex pattern type of the MAC address. - Example: + Examples: >>> from netutils.mac import mac_type >>> mac_type("aa.bb.cc.dd.ee.ff") 'MAC_DOT_TWO' @@ -125,7 +125,7 @@ def mac_normalize(mac: str) -> str: Returns: The MAC address with no special characters. - Example: + Examples: >>> from netutils.mac import mac_normalize >>> mac_normalize("aa.bb.cc.dd.ee.ff") 'aabbccddeeff' @@ -148,7 +148,7 @@ def get_oui(mac: str) -> str: Returns: The name of the company the mac is related to. - Example: + Examples: >>> from netutils.mac import get_oui >>> from netutils.oui_mappings import OUI_MAPPINGS >>> get_oui("cc.79.d7.dd.ee.ff") diff --git a/netutils/password.py b/netutils/password.py index 119c2a53..282b215f 100644 --- a/netutils/password.py +++ b/netutils/password.py @@ -97,7 +97,7 @@ def compare_type5( Returns: Whether or not the password is as compared to. - Example: + Examples: >>> from netutils.password import compare_type5 >>> compare_type5("cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") True @@ -126,7 +126,7 @@ def compare_type7( Returns: Whether or not the password is as compared to. - Example: + Examples: >>> from netutils.password import compare_type7 >>> compare_type7("cisco","121A0C041104") True @@ -150,7 +150,7 @@ def decrypt_type7(encrypted_password: str) -> str: Returns: The unencrypted_password password. - Example: + Examples: >>> from netutils.password import decrypt_type7 >>> decrypt_type7("121A0C041104") 'cisco' @@ -183,7 +183,7 @@ def encrypt_type5(unencrypted_password: str, salt: t.Optional[str] = None, salt_ Returns: The encrypted password. - Example: + Examples: >>> from netutils.password import encrypt_type5 >>> encrypt_type5("cisco") # doctest: +SKIP '$1$MHkb$v2MFmDkQX66TTxLkFF50K/' @@ -206,7 +206,7 @@ def encrypt_type7(unencrypted_password: str, salt: t.Optional[int] = None) -> st Returns: The encrypted password. - Example: + Examples: >>> from netutils.password import encrypt_type7 >>> encrypt_type7("cisco", 11) '110A1016141D' @@ -242,7 +242,7 @@ def get_hash_salt(encrypted_password: str) -> str: Returns: The encrypted password. - Example: + Examples: >>> from netutils.password import get_hash_salt >>> get_hash_salt('$1$ZLGo$J.gAGxS2wqO96drs0Cith/') 'ZLGo' diff --git a/netutils/ping.py b/netutils/ping.py index d11ebad9..046e777f 100644 --- a/netutils/ping.py +++ b/netutils/ping.py @@ -13,7 +13,7 @@ def tcp_ping(ip: str, port: int, timeout: int = 1) -> bool: # pylint: disable=i Returns: The result as to whether or not you were able ping the IP address. - Example: + Examples: >>> from netutils.ping import tcp_ping >>> tcp_ping("1.1.1.1", 443) True diff --git a/netutils/route.py b/netutils/route.py index 1dde8ca7..2e0e474b 100644 --- a/netutils/route.py +++ b/netutils/route.py @@ -18,7 +18,7 @@ def longest_prefix_match(ip_addr: str, routes: t.List[t.Dict[str, str]]) -> str: Returns: Longest Match Route - Example: + Examples: >>> from netutils.route import longest_prefix_match >>> lookup = "10.1.1.245" >>> routes = [{"network": "192.168.1.1", "mask": "255.255.255.255"},{"network": "10.1.1.0", "mask": "24"}] diff --git a/netutils/time.py b/netutils/time.py index c39f3965..1d6c4872 100644 --- a/netutils/time.py +++ b/netutils/time.py @@ -14,7 +14,7 @@ def uptime_seconds_to_string(uptime_seconds: int) -> str: Returns: Uptime in string format. - Example: + Examples: >>> from netutils.time import uptime_seconds_to_string >>> uptime_seconds_to_string(7250) '2 hours, 50 seconds' @@ -40,7 +40,7 @@ def uptime_string_to_seconds(uptime_string: str) -> int: Returns: Uptime string converted to seconds. - Example: + Examples: >>> from netutils.time import uptime_string_to_seconds >>> uptime_string_to_seconds("58 minutes") 3480 diff --git a/netutils/utils.py b/netutils/utils.py index 4f0f814b..41f7da6b 100644 --- a/netutils/utils.py +++ b/netutils/utils.py @@ -73,7 +73,7 @@ def jinja2_convenience_function() -> t.Dict[str, t.Callable[..., t.Any]]: Returns: Keys are the function names for the Jinja2 filter and values are the function objects. - Example: + Examples: >>> from netutils.utils import jinja2_convenience_function >>> function_mappings = jinja2_convenience_function() >>> function_mappings["get_first_usable"]("192.168.0.0/24") diff --git a/netutils/vlan.py b/netutils/vlan.py index a4d549c3..be2d68d3 100644 --- a/netutils/vlan.py +++ b/netutils/vlan.py @@ -23,7 +23,7 @@ def vlanlist_to_config( Returns: Sorted string list of integers according to IOS-like vlan list rules - Example: + Examples: >>> from netutils.vlan import vlanlist_to_config >>> vlanlist_to_config([1, 2, 3, 5, 6, 1000, 1002, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1018]) ['1-3,5,6,1000,1002,1004,1006,1008,1010,1012,1014', '1016,1018'] @@ -103,7 +103,7 @@ def vlanconfig_to_list(vlan_config: str) -> t.List[int]: Returns: Sorted string list of integers according to IOS-like vlan list rules - Example: + Examples: >>> vlan_config = '''switchport trunk allowed vlan 1025,1069-1072,1114,1173-1181,1501,1502''' >>> vlanconfig_to_list(vlan_config) [1025, 1069, 1070, 1071, 1072, 1114, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1501, 1502] diff --git a/poetry.lock b/poetry.lock index bc7c7b5e..08a0c71f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,58 +8,51 @@ python-versions = "*" [[package]] name = "astroid" -version = "2.9.0" +version = "2.11.7" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false -python-versions = "~=3.6" +python-versions = ">=3.6.2" [package.dependencies] lazy-object-proxy = ">=1.4.0" +setuptools = ">=20.0" typed-ast = {version = ">=1.4.0,<2.0", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} -wrapt = ">=1.11,<1.14" - -[[package]] -name = "atomicwrites" -version = "1.4.0" -description = "Atomic file writes." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +wrapt = ">=1.11,<2" [[package]] name = "attrs" -version = "21.2.0" +version = "22.1.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] -name = "babel" -version = "2.9.1" +name = "Babel" +version = "2.10.3" description = "Internationalization utilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] pytz = ">=2015.7" [[package]] name = "bandit" -version = "1.7.1" +version = "1.7.4" description = "Security oriented static analyser for python code." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [package.dependencies] colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} @@ -67,61 +60,68 @@ GitPython = ">=1.0.1" PyYAML = ">=5.3.1" stevedore = ">=1.20.0" +[package.extras] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"] +toml = ["toml"] +yaml = ["PyYAML"] + [[package]] name = "black" -version = "21.11b1" +version = "22.10.0" description = "The uncompromising code formatter." category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7" [package.dependencies] -click = ">=7.1.2" -dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} +click = ">=8.0.0" mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0,<1" +pathspec = ">=0.9.0" platformdirs = ">=2" -regex = ">=2021.4.4" -tomli = ">=0.2.6,<2.0.0" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} -typing-extensions = [ - {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, - {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, -] +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -python2 = ["typed-ast (>=1.4.3)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "cached-property" +version = "1.5.2" +description = "A decorator for caching properties in classes." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "certifi" -version = "2021.10.8" +version = "2022.9.24" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "charset-normalizer" -version = "2.0.8" +version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "dev" optional = false -python-versions = ">=3.5.0" +python-versions = ">=3.6.0" [package.extras] unicode_backport = ["unicodedata2"] [[package]] name = "click" -version = "8.0.3" +version = "8.1.3" description = "Composable command line interface toolkit" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -129,7 +129,7 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.5" description = "Cross-platform colored terminal text." category = "dev" optional = false @@ -137,44 +137,61 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.1.2" +version = "6.5.0" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] toml = ["tomli"] [[package]] -name = "dataclasses" -version = "0.8" -description = "A backport of the dataclasses module for Python 3.6" +name = "dill" +version = "0.3.5.1" +description = "serialize all of python" category = "dev" optional = false -python-versions = ">=3.6, <3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" + +[package.extras] +graph = ["objgraph (>=1.7.2)"] [[package]] name = "docutils" -version = "0.17.1" +version = "0.19" description = "Docutils -- Python Documentation Utilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [[package]] name = "flake8" -version = "4.0.1" +version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] -importlib-metadata = {version = "<4.3", markers = "python_version < \"3.8\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.8.0,<2.9.0" -pyflakes = ">=2.4.0,<2.5.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] [[package]] name = "gitdb" @@ -188,20 +205,34 @@ python-versions = ">=3.6" smmap = ">=3.0.1,<6" [[package]] -name = "gitpython" -version = "3.1.20" -description = "Python Git Library" +name = "GitPython" +version = "3.1.28" +description = "GitPython is a python library used to interact with Git repositories" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} + +[[package]] +name = "griffe" +version = "0.22.2" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +cached-property = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +async = ["aiofiles (>=0.7,<1.0)"] [[package]] name = "idna" -version = "3.3" +version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" category = "dev" optional = false @@ -209,7 +240,7 @@ python-versions = ">=3.5" [[package]] name = "imagesize" -version = "1.3.0" +version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" category = "dev" optional = false @@ -217,19 +248,20 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "4.2.0" +version = "5.0.0" description = "Read metadata from Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +perf = ["ipython"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "iniconfig" @@ -241,7 +273,7 @@ python-versions = "*" [[package]] name = "invoke" -version = "1.6.0" +version = "1.7.3" description = "Pythonic task execution" category = "dev" optional = false @@ -249,24 +281,25 @@ python-versions = "*" [[package]] name = "isort" -version = "5.8.0" +version = "5.10.1" description = "A Python utility / library to sort Python imports." category = "dev" optional = false -python-versions = ">=3.6,<4.0" +python-versions = ">=3.6.1,<4.0" [package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements_deprecated_finder = ["pip-api", "pipreqs"] [[package]] -name = "jinja2" -version = "3.0.3" +name = "Jinja2" +version = "3.1.2" description = "A very fast and expressive template engine." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] MarkupSafe = ">=2.0" @@ -276,32 +309,46 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "lazy-object-proxy" -version = "1.6.0" +version = "1.7.1" description = "A fast and thorough lazy object proxy." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.6" [[package]] name = "m2r2" -version = "0.3.1" +version = "0.3.3" description = "Markdown and reStructuredText in a single file." category = "dev" optional = false python-versions = "*" [package.dependencies] -docutils = "*" -mistune = "*" +docutils = ">=0.19" +mistune = "0.8.4" [[package]] -name = "markupsafe" -version = "2.0.1" -description = "Safely add untrusted strings to HTML/XML markup." +name = "Markdown" +version = "3.3.7" +description = "Python implementation of Markdown." category = "dev" optional = false python-versions = ">=3.6" +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "MarkupSafe" +version = "2.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" +optional = false +python-versions = ">=3.7" + [[package]] name = "mccabe" version = "0.6.1" @@ -310,6 +357,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "mistune" version = "0.8.4" @@ -318,6 +373,106 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "mkdocs" +version = "1.3.1" +description = "Project documentation with Markdown." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +click = ">=3.3" +ghp-import = ">=1.0" +importlib-metadata = ">=4.3" +Jinja2 = ">=2.10.2" +Markdown = ">=3.2.1,<3.4" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +PyYAML = ">=3.10" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "0.4.1" +description = "Automatically link across pages in MkDocs." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +Markdown = ">=3.3" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-material" +version = "8.3.9" +description = "Documentation that simply works" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +jinja2 = ">=3.0.2" +markdown = ">=3.2" +mkdocs = ">=1.3.0" +mkdocs-material-extensions = ">=1.0.3" +pygments = ">=2.12" +pymdown-extensions = ">=9.4" + +[[package]] +name = "mkdocs-material-extensions" +version = "1.0.3" +description = "Extension pack for Python Markdown." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "mkdocs-version-annotations" +version = "1.0.0" +description = "MkDocs plugin to add custom admonitions for documenting version differences" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" + +[[package]] +name = "mkdocstrings" +version = "0.19.0" +description = "Automatic documentation from sources, for MkDocs." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +Jinja2 = ">=2.11.1" +Markdown = ">=3.3" +MarkupSafe = ">=1.1" +mkdocs = ">=1.2" +mkdocs-autorefs = ">=0.3.1" +pymdown-extensions = ">=6.3" + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "0.7.1" +description = "A Python handler for mkdocstrings." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +griffe = ">=0.11.1" +mkdocstrings = ">=0.19" + [[package]] name = "mypy" version = "0.961" @@ -358,15 +513,15 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pathspec" -version = "0.9.0" +version = "0.10.1" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.7" [[package]] name = "pbr" -version = "5.8.0" +version = "5.10.0" description = "Python Build Reasonableness" category = "dev" optional = false @@ -374,14 +529,14 @@ python-versions = ">=2.6" [[package]] name = "platformdirs" -version = "2.4.0" +version = "2.5.2" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] [[package]] @@ -409,11 +564,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" -version = "2.8.0" +version = "2.7.0" description = "Python style guide checker" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydocstyle" @@ -431,58 +586,75 @@ toml = ["toml"] [[package]] name = "pyflakes" -version = "2.4.0" +version = "2.3.1" description = "passive checker of Python programs" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] -name = "pygments" -version = "2.10.0" +name = "Pygments" +version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" + +[package.extras] +plugins = ["importlib-metadata"] [[package]] name = "pylint" -version = "2.12.0" +version = "2.13.9" description = "python code static checker" category = "dev" optional = false -python-versions = "~=3.6" +python-versions = ">=3.6.2" [package.dependencies] -astroid = ">=2.9.0,<2.10" +astroid = ">=2.11.5,<=2.12.0-dev0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +dill = ">=0.2" isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.7" +mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" -toml = ">=0.9.2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} +[package.extras] +testutil = ["gitpython (>3)"] + +[[package]] +name = "pymdown-extensions" +version = "9.6" +description = "Extension pack for Python Markdown." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +markdown = ">=3.2" + [[package]] name = "pyparsing" -version = "3.0.6" -description = "Python parsing module" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.6.8" [package.extras] diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "6.2.5" +version = "7.1.3" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} @@ -490,21 +662,32 @@ iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" [[package]] name = "pytz" -version = "2021.3" +version = "2022.4" description = "World timezone definitions, modern and historical" category = "dev" optional = false python-versions = "*" [[package]] -name = "pyyaml" +name = "PyYAML" version = "6.0" description = "YAML parser and emitter for Python" category = "dev" @@ -512,30 +695,54 @@ optional = false python-versions = ">=3.6" [[package]] -name = "regex" -version = "2021.11.10" -description = "Alternative regular expression module, to replace re." +name = "pyyaml_env_tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" + +[package.dependencies] +pyyaml = "*" [[package]] name = "requests" -version = "2.26.0" +version = "2.28.1" description = "Python HTTP for Humans." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" [package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "setuptools" +version = "65.4.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "smmap" @@ -554,8 +761,8 @@ optional = false python-versions = "*" [[package]] -name = "sphinx" -version = "4.3.0" +name = "Sphinx" +version = "5.2.3" description = "Python documentation generator" category = "dev" optional = false @@ -563,15 +770,16 @@ python-versions = ">=3.6" [package.dependencies] alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.20" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.12" requests = ">=2.5.0" -snowballstemmer = ">=1.1" +snowballstemmer = ">=2.0" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" @@ -581,23 +789,22 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.900)", "docutils-stubs", "types-typed-ast", "types-pkg-resources", "types-requests"] -test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] [[package]] name = "sphinx-rtd-theme" -version = "1.0.0" +version = "0.5.1" description = "Read the Docs theme for Sphinx" category = "dev" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +python-versions = "*" [package.dependencies] -docutils = "<0.18" -sphinx = ">=1.6" +sphinx = "*" [package.extras] -dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] +dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] [[package]] name = "sphinxcontrib-applehelp" @@ -608,7 +815,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -620,7 +827,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -632,8 +839,8 @@ optional = false python-versions = ">=3.6" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest", "html5lib"] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] [[package]] name = "sphinxcontrib-jsmath" @@ -644,7 +851,7 @@ optional = false python-versions = ">=3.5" [package.extras] -test = ["pytest", "flake8", "mypy"] +test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" @@ -655,7 +862,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -667,7 +874,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -692,15 +899,15 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "1.2.2" +version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "typed-ast" -version = "1.5.0" +version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false @@ -708,28 +915,39 @@ python-versions = ">=3.6" [[package]] name = "typing-extensions" -version = "4.0.0" -description = "Backported and Experimental Type Hints for Python 3.6+" +version = "4.4.0" +description = "Backported and Experimental Type Hints for Python 3.7+" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "urllib3" -version = "1.26.7" +version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "watchdog" +version = "2.1.9" +description = "Filesystem events monitoring" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + [[package]] name = "wrapt" -version = "1.13.3" +version = "1.14.1" description = "Module for decorators, wrappers and monkey patching." category = "dev" optional = false @@ -737,32 +955,33 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "yamllint" -version = "1.26.3" +version = "1.28.0" description = "A linter for YAML files." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] pathspec = ">=0.5.3" pyyaml = "*" +setuptools = "*" [[package]] name = "zipp" -version = "3.6.0" +version = "3.9.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" -python-versions = "^3.6" -content-hash = "9d23f91405a5a3ea5cc425913d6c78c410cb941d131ee3bf36dad117cc421934" +python-versions = "^3.7" +content-hash = "ee5e81329bf31db68b0e567aa22c780ea84a24b4f41a31188e85b4195f69783f" [metadata.files] alabaster = [ @@ -770,250 +989,301 @@ alabaster = [ {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, ] astroid = [ - {file = "astroid-2.9.0-py3-none-any.whl", hash = "sha256:776ca0b748b4ad69c00bfe0fff38fa2d21c338e12c84aa9715ee0d473c422778"}, - {file = "astroid-2.9.0.tar.gz", hash = "sha256:5939cf55de24b92bda00345d4d0659d01b3c7dafb5055165c330bc7c568ba273"}, -] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, + {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, + {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, ] attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] -babel = [ - {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, - {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, +Babel = [ + {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"}, + {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"}, ] bandit = [ - {file = "bandit-1.7.1-py3-none-any.whl", hash = "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4"}, - {file = "bandit-1.7.1.tar.gz", hash = "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c"}, + {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, + {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, ] black = [ - {file = "black-21.11b1-py3-none-any.whl", hash = "sha256:802c6c30b637b28645b7fde282ed2569c0cd777dbe493a41b6a03c1d903f99ac"}, - {file = "black-21.11b1.tar.gz", hash = "sha256:a042adbb18b3262faad5aff4e834ff186bb893f95ba3a8013f09de1e5569def2"}, + {file = "black-22.10.0-1fixedarch-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa"}, + {file = "black-22.10.0-1fixedarch-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef"}, + {file = "black-22.10.0-1fixedarch-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6"}, + {file = "black-22.10.0-1fixedarch-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d"}, + {file = "black-22.10.0-1fixedarch-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4"}, + {file = "black-22.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb"}, + {file = "black-22.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7"}, + {file = "black-22.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66"}, + {file = "black-22.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae"}, + {file = "black-22.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b"}, + {file = "black-22.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d"}, + {file = "black-22.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650"}, + {file = "black-22.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d"}, + {file = "black-22.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff"}, + {file = "black-22.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87"}, + {file = "black-22.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395"}, + {file = "black-22.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0"}, + {file = "black-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383"}, + {file = "black-22.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de"}, + {file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"}, + {file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"}, +] +cached-property = [ + {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, + {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, ] certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, + {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, + {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, ] charset-normalizer = [ - {file = "charset-normalizer-2.0.8.tar.gz", hash = "sha256:735e240d9a8506778cd7a453d97e817e536bb1fc29f4f6961ce297b9c7a917b0"}, - {file = "charset_normalizer-2.0.8-py3-none-any.whl", hash = "sha256:83fcdeb225499d6344c8f7f34684c2981270beacc32ede2e669e94f7fa544405"}, + {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, ] click = [ - {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, - {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] coverage = [ - {file = "coverage-6.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:675adb3b3380967806b3cbb9c5b00ceb29b1c472692100a338730c1d3e59c8b9"}, - {file = "coverage-6.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95a58336aa111af54baa451c33266a8774780242cab3704b7698d5e514840758"}, - {file = "coverage-6.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0a595a781f8e186580ff8e3352dd4953b1944289bec7705377c80c7e36c4d6c"}, - {file = "coverage-6.1.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d3c5f49ce6af61154060640ad3b3281dbc46e2e0ef2fe78414d7f8a324f0b649"}, - {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:310c40bed6b626fd1f463e5a83dba19a61c4eb74e1ac0d07d454ebbdf9047e9d"}, - {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a4d48e42e17d3de212f9af44f81ab73b9378a4b2b8413fd708d0d9023f2bbde4"}, - {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ffa545230ca2ad921ad066bf8fd627e7be43716b6e0fcf8e32af1b8188ccb0ab"}, - {file = "coverage-6.1.2-cp310-cp310-win32.whl", hash = "sha256:cd2d11a59afa5001ff28073ceca24ae4c506da4355aba30d1e7dd2bd0d2206dc"}, - {file = "coverage-6.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:96129e41405887a53a9cc564f960d7f853cc63d178f3a182fdd302e4cab2745b"}, - {file = "coverage-6.1.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1de9c6f5039ee2b1860b7bad2c7bc3651fbeb9368e4c4d93e98a76358cdcb052"}, - {file = "coverage-6.1.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:80cb70264e9a1d04b519cdba3cd0dc42847bf8e982a4d55c769b9b0ee7cdce1e"}, - {file = "coverage-6.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:ba6125d4e55c0b8e913dad27b22722eac7abdcb1f3eab1bd090eee9105660266"}, - {file = "coverage-6.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8492d37acdc07a6eac6489f6c1954026f2260a85a4c2bb1e343fe3d35f5ee21a"}, - {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66af99c7f7b64d050d37e795baadf515b4561124f25aae6e1baa482438ecc388"}, - {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ebcc03e1acef4ff44f37f3c61df478d6e469a573aa688e5a162f85d7e4c3860d"}, - {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98d44a8136eebbf544ad91fef5bd2b20ef0c9b459c65a833c923d9aa4546b204"}, - {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c18725f3cffe96732ef96f3de1939d81215fd6d7d64900dcc4acfe514ea4fcbf"}, - {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c8e9c4bcaaaa932be581b3d8b88b677489975f845f7714efc8cce77568b6711c"}, - {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:06d009e8a29483cbc0520665bc46035ffe9ae0e7484a49f9782c2a716e37d0a0"}, - {file = "coverage-6.1.2-cp36-cp36m-win32.whl", hash = "sha256:e5432d9c329b11c27be45ee5f62cf20a33065d482c8dec1941d6670622a6fb8f"}, - {file = "coverage-6.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:82fdcb64bf08aa5db881db061d96db102c77397a570fbc112e21c48a4d9cb31b"}, - {file = "coverage-6.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:94f558f8555e79c48c422045f252ef41eb43becdd945e9c775b45ebfc0cbd78f"}, - {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:046647b96969fda1ae0605f61288635209dd69dcd27ba3ec0bf5148bc157f954"}, - {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cc799916b618ec9fd00135e576424165691fec4f70d7dc12cfaef09268a2478c"}, - {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62646d98cf0381ffda301a816d6ac6c35fc97aa81b09c4c52d66a15c4bef9d7c"}, - {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:27a3df08a855522dfef8b8635f58bab81341b2fb5f447819bc252da3aa4cf44c"}, - {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:610c0ba11da8de3a753dc4b1f71894f9f9debfdde6559599f303286e70aeb0c2"}, - {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:35b246ae3a2c042dc8f410c94bcb9754b18179cdb81ff9477a9089dbc9ecc186"}, - {file = "coverage-6.1.2-cp37-cp37m-win32.whl", hash = "sha256:0cde7d9fe2fb55ff68ebe7fb319ef188e9b88e0a3d1c9c5db7dd829cd93d2193"}, - {file = "coverage-6.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:958ac66272ff20e63d818627216e3d7412fdf68a2d25787b89a5c6f1eb7fdd93"}, - {file = "coverage-6.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a300b39c3d5905686c75a369d2a66e68fd01472ea42e16b38c948bd02b29e5bd"}, - {file = "coverage-6.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d3855d5d26292539861f5ced2ed042fc2aa33a12f80e487053aed3bcb6ced13"}, - {file = "coverage-6.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:586d38dfc7da4a87f5816b203ff06dd7c1bb5b16211ccaa0e9788a8da2b93696"}, - {file = "coverage-6.1.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a34fccb45f7b2d890183a263578d60a392a1a218fdc12f5bce1477a6a68d4373"}, - {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bc1ee1318f703bc6c971da700d74466e9b86e0c443eb85983fb2a1bd20447263"}, - {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3f546f48d5d80a90a266769aa613bc0719cb3e9c2ef3529d53f463996dd15a9d"}, - {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd92ece726055e80d4e3f01fff3b91f54b18c9c357c48fcf6119e87e2461a091"}, - {file = "coverage-6.1.2-cp38-cp38-win32.whl", hash = "sha256:24ed38ec86754c4d5a706fbd5b52b057c3df87901a8610d7e5642a08ec07087e"}, - {file = "coverage-6.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:97ef6e9119bd39d60ef7b9cd5deea2b34869c9f0b9777450a7e3759c1ab09b9b"}, - {file = "coverage-6.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e5a8c947a2a89c56655ecbb789458a3a8e3b0cbf4c04250331df8f647b3de59"}, - {file = "coverage-6.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a39590d1e6acf6a3c435c5d233f72f5d43b585f5be834cff1f21fec4afda225"}, - {file = "coverage-6.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9d2c2e3ce7b8cc932a2f918186964bd44de8c84e2f9ef72dc616f5bb8be22e71"}, - {file = "coverage-6.1.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3348865798c077c695cae00da0924136bb5cc501f236cfd6b6d9f7a3c94e0ec4"}, - {file = "coverage-6.1.2-cp39-cp39-win32.whl", hash = "sha256:fae3fe111670e51f1ebbc475823899524e3459ea2db2cb88279bbfb2a0b8a3de"}, - {file = "coverage-6.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:af45eea024c0e3a25462fade161afab4f0d9d9e0d5a5d53e86149f74f0a35ecc"}, - {file = "coverage-6.1.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:eab14fdd410500dae50fd14ccc332e65543e7b39f6fc076fe90603a0e5d2f929"}, - {file = "coverage-6.1.2.tar.gz", hash = "sha256:d9a635114b88c0ab462e0355472d00a180a5fbfd8511e7f18e4ac32652e7d972"}, -] -dataclasses = [ - {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, - {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, + {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, + {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, +] +dill = [ + {file = "dill-0.3.5.1-py2.py3-none-any.whl", hash = "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302"}, + {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, ] docutils = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, + {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, + {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, ] flake8 = [ - {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, - {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] +ghp-import = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, ] gitdb = [ {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, ] -gitpython = [ - {file = "GitPython-3.1.20-py3-none-any.whl", hash = "sha256:b1e1c269deab1b08ce65403cf14e10d2ef1f6c89e33ea7c5e5bb0222ea593b8a"}, - {file = "GitPython-3.1.20.tar.gz", hash = "sha256:df0e072a200703a65387b0cfdf0466e3bab729c0458cf6b7349d0e9877636519"}, +GitPython = [ + {file = "GitPython-3.1.28-py3-none-any.whl", hash = "sha256:77bfbd299d8709f6af7e0c70840ef26e7aff7cf0c1ed53b42dd7fc3a310fcb02"}, + {file = "GitPython-3.1.28.tar.gz", hash = "sha256:6bd3451b8271132f099ceeaf581392eaf6c274af74bb06144307870479d0697c"}, +] +griffe = [ + {file = "griffe-0.22.2-py3-none-any.whl", hash = "sha256:cea5415ac6a92f4a22638e3f1f2e661402bac09fb8e8266936d67185a7e0d0fb"}, + {file = "griffe-0.22.2.tar.gz", hash = "sha256:1408e336a4155392bbd81eed9f2f44bf144e71b9c664e905630affe83bbc088e"}, ] idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] imagesize = [ - {file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"}, - {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, - {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, + {file = "importlib_metadata-5.0.0-py3-none-any.whl", hash = "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"}, + {file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] invoke = [ - {file = "invoke-1.6.0-py2-none-any.whl", hash = "sha256:e6c9917a1e3e73e7ea91fdf82d5f151ccfe85bf30cc65cdb892444c02dbb5f74"}, - {file = "invoke-1.6.0-py3-none-any.whl", hash = "sha256:769e90caeb1bd07d484821732f931f1ad8916a38e3f3e618644687fc09cb6317"}, - {file = "invoke-1.6.0.tar.gz", hash = "sha256:374d1e2ecf78981da94bfaf95366216aaec27c2d6a7b7d5818d92da55aa258d3"}, + {file = "invoke-1.7.3-py3-none-any.whl", hash = "sha256:d9694a865764dd3fd91f25f7e9a97fb41666e822bbb00e670091e3f43933574d"}, + {file = "invoke-1.7.3.tar.gz", hash = "sha256:41b428342d466a82135d5ab37119685a989713742be46e42a3a399d685579314"}, ] isort = [ - {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"}, - {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"}, + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] -jinja2 = [ - {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, - {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, +Jinja2 = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] lazy-object-proxy = [ - {file = "lazy-object-proxy-1.6.0.tar.gz", hash = "sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726"}, - {file = "lazy_object_proxy-1.6.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b"}, - {file = "lazy_object_proxy-1.6.0-cp27-cp27m-win32.whl", hash = "sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e"}, - {file = "lazy_object_proxy-1.6.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93"}, - {file = "lazy_object_proxy-1.6.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741"}, - {file = "lazy_object_proxy-1.6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587"}, - {file = "lazy_object_proxy-1.6.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4"}, - {file = "lazy_object_proxy-1.6.0-cp36-cp36m-win32.whl", hash = "sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f"}, - {file = "lazy_object_proxy-1.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3"}, - {file = "lazy_object_proxy-1.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981"}, - {file = "lazy_object_proxy-1.6.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2"}, - {file = "lazy_object_proxy-1.6.0-cp37-cp37m-win32.whl", hash = "sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd"}, - {file = "lazy_object_proxy-1.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837"}, - {file = "lazy_object_proxy-1.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653"}, - {file = "lazy_object_proxy-1.6.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3"}, - {file = "lazy_object_proxy-1.6.0-cp38-cp38-win32.whl", hash = "sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8"}, - {file = "lazy_object_proxy-1.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf"}, - {file = "lazy_object_proxy-1.6.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad"}, - {file = "lazy_object_proxy-1.6.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43"}, - {file = "lazy_object_proxy-1.6.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a"}, - {file = "lazy_object_proxy-1.6.0-cp39-cp39-win32.whl", hash = "sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61"}, - {file = "lazy_object_proxy-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b"}, + {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, + {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, + {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, + {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, + {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, + {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, + {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, ] m2r2 = [ - {file = "m2r2-0.3.1-py3-none-any.whl", hash = "sha256:c2b62b8dec16f82d9e4d8aecf58830a87835ca90441716fc571e573e32c7d829"}, - {file = "m2r2-0.3.1.tar.gz", hash = "sha256:6bf2d74e4cd15ce8a795999326cc7a4924af69ac1d114cac8064c1599ab11892"}, -] -markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, + {file = "m2r2-0.3.3-py3-none-any.whl", hash = "sha256:2ee32a5928c3598b67c70e6d22981ec936c03d5bfd2f64229e77678731952f16"}, + {file = "m2r2-0.3.3.tar.gz", hash = "sha256:f9b6e9efbc2b6987dbd43d2fd15a6d115ba837d8158ae73295542635b4086e75"}, +] +Markdown = [ + {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, + {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, +] +MarkupSafe = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] +mergedeep = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] mistune = [ {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, ] +mkdocs = [ + {file = "mkdocs-1.3.1-py3-none-any.whl", hash = "sha256:fda92466393127d2da830bc6edc3a625a14b436316d1caf347690648e774c4f0"}, + {file = "mkdocs-1.3.1.tar.gz", hash = "sha256:a41a2ff25ce3bbacc953f9844ba07d106233cd76c88bac1f59cb1564ac0d87ed"}, +] +mkdocs-autorefs = [ + {file = "mkdocs-autorefs-0.4.1.tar.gz", hash = "sha256:70748a7bd025f9ecd6d6feeba8ba63f8e891a1af55f48e366d6d6e78493aba84"}, + {file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"}, +] +mkdocs-material = [ + {file = "mkdocs-material-8.3.9.tar.gz", hash = "sha256:dc82b667d2a83f0de581b46a6d0949732ab77e7638b87ea35b770b33bc02e75a"}, + {file = "mkdocs_material-8.3.9-py2.py3-none-any.whl", hash = "sha256:263f2721f3abe533b61f7c8bed435a0462620912742c919821ac2d698b4bfe67"}, +] +mkdocs-material-extensions = [ + {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"}, + {file = "mkdocs_material_extensions-1.0.3-py3-none-any.whl", hash = "sha256:a82b70e533ce060b2a5d9eb2bc2e1be201cf61f901f93704b4acf6e3d5983a44"}, +] +mkdocs-version-annotations = [ + {file = "mkdocs-version-annotations-1.0.0.tar.gz", hash = "sha256:6786024b37d27b330fda240b76ebec8e7ce48bd5a9d7a66e99804559d088dffa"}, + {file = "mkdocs_version_annotations-1.0.0-py3-none-any.whl", hash = "sha256:385004eb4a7530dd87a227e08cd907ce7a8fe21fdf297720a4149c511bcf05f5"}, +] +mkdocstrings = [ + {file = "mkdocstrings-0.19.0-py3-none-any.whl", hash = "sha256:3217d510d385c961f69385a670b2677e68e07b5fea4a504d86bf54c006c87c7d"}, + {file = "mkdocstrings-0.19.0.tar.gz", hash = "sha256:efa34a67bad11229d532d89f6836a8a215937548623b64f3698a1df62e01cc3e"}, +] +mkdocstrings-python = [ + {file = "mkdocstrings-python-0.7.1.tar.gz", hash = "sha256:c334b382dca202dfa37071c182418a6df5818356a95d54362a2b24822ca3af71"}, + {file = "mkdocstrings_python-0.7.1-py3-none-any.whl", hash = "sha256:a22060bfa374697678e9af4e62b020d990dad2711c98f7a9fac5c0345bef93c7"}, +] mypy = [ {file = "mypy-0.961-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0"}, {file = "mypy-0.961-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15"}, @@ -1048,16 +1318,16 @@ packaging = [ {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, + {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, + {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, ] pbr = [ - {file = "pbr-5.8.0-py2.py3-none-any.whl", hash = "sha256:176e8560eaf61e127817ef93d8a844803abb27a4d4637f0ff3bb783129be2e0a"}, - {file = "pbr-5.8.0.tar.gz", hash = "sha256:672d8ebee84921862110f23fcec2acea191ef58543d34dfe9ef3d9f13c31cddf"}, + {file = "pbr-5.10.0-py2.py3-none-any.whl", hash = "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"}, + {file = "pbr-5.10.0.tar.gz", hash = "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a"}, ] platformdirs = [ - {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, - {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, + {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, + {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -1068,38 +1338,46 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ - {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, - {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, ] pydocstyle = [ {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, ] pyflakes = [ - {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, - {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] -pygments = [ - {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, - {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, +Pygments = [ + {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, + {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, ] pylint = [ - {file = "pylint-2.12.0-py3-none-any.whl", hash = "sha256:ba00afcb1550bc217bbcb0eb76c10cb8335f7417a3323bdd980c29fb5b59f8d2"}, - {file = "pylint-2.12.0.tar.gz", hash = "sha256:245c87e5da54c35b623c21b35debf87d93b18bf9e0229515cc172d0b83d627cd"}, + {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, + {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, +] +pymdown-extensions = [ + {file = "pymdown_extensions-9.6-py3-none-any.whl", hash = "sha256:1e36490adc7bfcef1fdb21bb0306e93af99cff8ec2db199bd17e3bf009768c11"}, + {file = "pymdown_extensions-9.6.tar.gz", hash = "sha256:b956b806439bbff10f726103a941266beb03fbe99f897c7d5e774d7170339ad9"}, ] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, + {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, + {file = "pytz-2022.4-py2.py3-none-any.whl", hash = "sha256:2c0784747071402c6e99f0bafdb7da0fa22645f06554c7ae06bf6358897e9c91"}, + {file = "pytz-2022.4.tar.gz", hash = "sha256:48ce799d83b6f8aab2020e369b627446696619e79645419610b9facd909b3174"}, ] -pyyaml = [ +PyYAML = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, @@ -1107,6 +1385,13 @@ pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, @@ -1134,85 +1419,21 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] -regex = [ - {file = "regex-2021.11.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9345b6f7ee578bad8e475129ed40123d265464c4cfead6c261fd60fc9de00bcf"}, - {file = "regex-2021.11.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:416c5f1a188c91e3eb41e9c8787288e707f7d2ebe66e0a6563af280d9b68478f"}, - {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0538c43565ee6e703d3a7c3bdfe4037a5209250e8502c98f20fea6f5fdf2965"}, - {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee1227cf08b6716c85504aebc49ac827eb88fcc6e51564f010f11a406c0a667"}, - {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6650f16365f1924d6014d2ea770bde8555b4a39dc9576abb95e3cd1ff0263b36"}, - {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30ab804ea73972049b7a2a5c62d97687d69b5a60a67adca07eb73a0ddbc9e29f"}, - {file = "regex-2021.11.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68a067c11463de2a37157930d8b153005085e42bcb7ad9ca562d77ba7d1404e0"}, - {file = "regex-2021.11.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:162abfd74e88001d20cb73ceaffbfe601469923e875caf9118333b1a4aaafdc4"}, - {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9ed0b1e5e0759d6b7f8e2f143894b2a7f3edd313f38cf44e1e15d360e11749b"}, - {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:473e67837f786404570eae33c3b64a4b9635ae9f00145250851a1292f484c063"}, - {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2fee3ed82a011184807d2127f1733b4f6b2ff6ec7151d83ef3477f3b96a13d03"}, - {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d5fd67df77bab0d3f4ea1d7afca9ef15c2ee35dfb348c7b57ffb9782a6e4db6e"}, - {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5d408a642a5484b9b4d11dea15a489ea0928c7e410c7525cd892f4d04f2f617b"}, - {file = "regex-2021.11.10-cp310-cp310-win32.whl", hash = "sha256:98ba568e8ae26beb726aeea2273053c717641933836568c2a0278a84987b2a1a"}, - {file = "regex-2021.11.10-cp310-cp310-win_amd64.whl", hash = "sha256:780b48456a0f0ba4d390e8b5f7c661fdd218934388cde1a974010a965e200e12"}, - {file = "regex-2021.11.10-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:dba70f30fd81f8ce6d32ddeef37d91c8948e5d5a4c63242d16a2b2df8143aafc"}, - {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1f54b9b4b6c53369f40028d2dd07a8c374583417ee6ec0ea304e710a20f80a0"}, - {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fbb9dc00e39f3e6c0ef48edee202f9520dafb233e8b51b06b8428cfcb92abd30"}, - {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666abff54e474d28ff42756d94544cdfd42e2ee97065857413b72e8a2d6a6345"}, - {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5537f71b6d646f7f5f340562ec4c77b6e1c915f8baae822ea0b7e46c1f09b733"}, - {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2e07c6a26ed4bea91b897ee2b0835c21716d9a469a96c3e878dc5f8c55bb23"}, - {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca5f18a75e1256ce07494e245cdb146f5a9267d3c702ebf9b65c7f8bd843431e"}, - {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:74cbeac0451f27d4f50e6e8a8f3a52ca074b5e2da9f7b505c4201a57a8ed6286"}, - {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:3598893bde43091ee5ca0a6ad20f08a0435e93a69255eeb5f81b85e81e329264"}, - {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:50a7ddf3d131dc5633dccdb51417e2d1910d25cbcf842115a3a5893509140a3a"}, - {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:61600a7ca4bcf78a96a68a27c2ae9389763b5b94b63943d5158f2a377e09d29a"}, - {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:563d5f9354e15e048465061509403f68424fef37d5add3064038c2511c8f5e00"}, - {file = "regex-2021.11.10-cp36-cp36m-win32.whl", hash = "sha256:93a5051fcf5fad72de73b96f07d30bc29665697fb8ecdfbc474f3452c78adcf4"}, - {file = "regex-2021.11.10-cp36-cp36m-win_amd64.whl", hash = "sha256:b483c9d00a565633c87abd0aaf27eb5016de23fed952e054ecc19ce32f6a9e7e"}, - {file = "regex-2021.11.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fff55f3ce50a3ff63ec8e2a8d3dd924f1941b250b0aac3d3d42b687eeff07a8e"}, - {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32d2a2b02ccbef10145df9135751abea1f9f076e67a4e261b05f24b94219e36"}, - {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53db2c6be8a2710b359bfd3d3aa17ba38f8aa72a82309a12ae99d3c0c3dcd74d"}, - {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2207ae4f64ad3af399e2d30dde66f0b36ae5c3129b52885f1bffc2f05ec505c8"}, - {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5ca078bb666c4a9d1287a379fe617a6dccd18c3e8a7e6c7e1eb8974330c626a"}, - {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd33eb9bdcfbabab3459c9ee651d94c842bc8a05fabc95edf4ee0c15a072495e"}, - {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05b7d6d7e64efe309972adab77fc2af8907bb93217ec60aa9fe12a0dad35874f"}, - {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:42b50fa6666b0d50c30a990527127334d6b96dd969011e843e726a64011485da"}, - {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6e1d2cc79e8dae442b3fa4a26c5794428b98f81389af90623ffcc650ce9f6732"}, - {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:0416f7399e918c4b0e074a0f66e5191077ee2ca32a0f99d4c187a62beb47aa05"}, - {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ce298e3d0c65bd03fa65ffcc6db0e2b578e8f626d468db64fdf8457731052942"}, - {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dc07f021ee80510f3cd3af2cad5b6a3b3a10b057521d9e6aaeb621730d320c5a"}, - {file = "regex-2021.11.10-cp37-cp37m-win32.whl", hash = "sha256:e71255ba42567d34a13c03968736c5d39bb4a97ce98188fafb27ce981115beec"}, - {file = "regex-2021.11.10-cp37-cp37m-win_amd64.whl", hash = "sha256:07856afef5ffcc052e7eccf3213317fbb94e4a5cd8177a2caa69c980657b3cb4"}, - {file = "regex-2021.11.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba05430e819e58544e840a68b03b28b6d328aff2e41579037e8bab7653b37d83"}, - {file = "regex-2021.11.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f301b11b9d214f83ddaf689181051e7f48905568b0c7017c04c06dfd065e244"}, - {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aaa4e0705ef2b73dd8e36eeb4c868f80f8393f5f4d855e94025ce7ad8525f50"}, - {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:788aef3549f1924d5c38263104dae7395bf020a42776d5ec5ea2b0d3d85d6646"}, - {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8af619e3be812a2059b212064ea7a640aff0568d972cd1b9e920837469eb3cb"}, - {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85bfa6a5413be0ee6c5c4a663668a2cad2cbecdee367630d097d7823041bdeec"}, - {file = "regex-2021.11.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f23222527b307970e383433daec128d769ff778d9b29343fb3496472dc20dabe"}, - {file = "regex-2021.11.10-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:da1a90c1ddb7531b1d5ff1e171b4ee61f6345119be7351104b67ff413843fe94"}, - {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f5be7805e53dafe94d295399cfbe5227f39995a997f4fd8539bf3cbdc8f47ca8"}, - {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a955b747d620a50408b7fdf948e04359d6e762ff8a85f5775d907ceced715129"}, - {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:139a23d1f5d30db2cc6c7fd9c6d6497872a672db22c4ae1910be22d4f4b2068a"}, - {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ca49e1ab99593438b204e00f3970e7a5f70d045267051dfa6b5f4304fcfa1dbf"}, - {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:96fc32c16ea6d60d3ca7f63397bff5c75c5a562f7db6dec7d412f7c4d2e78ec0"}, - {file = "regex-2021.11.10-cp38-cp38-win32.whl", hash = "sha256:0617383e2fe465732af4509e61648b77cbe3aee68b6ac8c0b6fe934db90be5cc"}, - {file = "regex-2021.11.10-cp38-cp38-win_amd64.whl", hash = "sha256:a3feefd5e95871872673b08636f96b61ebef62971eab044f5124fb4dea39919d"}, - {file = "regex-2021.11.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7f325be2804246a75a4f45c72d4ce80d2443ab815063cdf70ee8fb2ca59ee1b"}, - {file = "regex-2021.11.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:537ca6a3586931b16a85ac38c08cc48f10fc870a5b25e51794c74df843e9966d"}, - {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef2afb0fd1747f33f1ee3e209bce1ed582d1896b240ccc5e2697e3275f037c7"}, - {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:432bd15d40ed835a51617521d60d0125867f7b88acf653e4ed994a1f8e4995dc"}, - {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b43c2b8a330a490daaef5a47ab114935002b13b3f9dc5da56d5322ff218eeadb"}, - {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:962b9a917dd7ceacbe5cd424556914cb0d636001e393b43dc886ba31d2a1e449"}, - {file = "regex-2021.11.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa8c626d6441e2d04b6ee703ef2d1e17608ad44c7cb75258c09dd42bacdfc64b"}, - {file = "regex-2021.11.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c5fb32cc6077abad3bbf0323067636d93307c9fa93e072771cf9a64d1c0f3ef"}, - {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cd410a1cbb2d297c67d8521759ab2ee3f1d66206d2e4328502a487589a2cb21b"}, - {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e6096b0688e6e14af6a1b10eaad86b4ff17935c49aa774eac7c95a57a4e8c296"}, - {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:529801a0d58809b60b3531ee804d3e3be4b412c94b5d267daa3de7fadef00f49"}, - {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f594b96fe2e0821d026365f72ac7b4f0b487487fb3d4aaf10dd9d97d88a9737"}, - {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2409b5c9cef7054dde93a9803156b411b677affc84fca69e908b1cb2c540025d"}, - {file = "regex-2021.11.10-cp39-cp39-win32.whl", hash = "sha256:3b5df18db1fccd66de15aa59c41e4f853b5df7550723d26aa6cb7f40e5d9da5a"}, - {file = "regex-2021.11.10-cp39-cp39-win_amd64.whl", hash = "sha256:83ee89483672b11f8952b158640d0c0ff02dc43d9cb1b70c1564b49abe92ce29"}, - {file = "regex-2021.11.10.tar.gz", hash = "sha256:f341ee2df0999bfdf7a95e448075effe0db212a59387de1a70690e4acb03d4c6"}, +pyyaml_env_tag = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] requests = [ - {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, - {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] +setuptools = [ + {file = "setuptools-65.4.1-py3-none-any.whl", hash = "sha256:1b6bdc6161661409c5f21508763dc63ab20a9ac2f8ba20029aaaa7fdb9118012"}, + {file = "setuptools-65.4.1.tar.gz", hash = "sha256:3050e338e5871e70c72983072fe34f6032ae1cdeeeb67338199c2f74e083a80e"}, +] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] smmap = [ {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, @@ -1222,13 +1443,13 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -sphinx = [ - {file = "Sphinx-4.3.0-py3-none-any.whl", hash = "sha256:7e2b30da5f39170efcd95c6270f07669d623c276521fee27ad6c380f49d2bf5b"}, - {file = "Sphinx-4.3.0.tar.gz", hash = "sha256:6d051ab6e0d06cba786c4656b0fe67ba259fe058410f49e95bee6e49c4052cbf"}, +Sphinx = [ + {file = "Sphinx-5.2.3.tar.gz", hash = "sha256:5b10cb1022dac8c035f75767799c39217a05fc0fe2d6fe5597560d38e44f0363"}, + {file = "sphinx-5.2.3-py3-none-any.whl", hash = "sha256:7abf6fabd7b58d0727b7317d5e2650ef68765bbe0ccb63c8795fa8683477eaa2"}, ] sphinx-rtd-theme = [ - {file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"}, - {file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"}, + {file = "sphinx_rtd_theme-0.5.1-py2.py3-none-any.whl", hash = "sha256:fa6bebd5ab9a73da8e102509a86f3fcc36dec04a0b52ea80e5a033b2aba00113"}, + {file = "sphinx_rtd_theme-0.5.1.tar.gz", hash = "sha256:eda689eda0c7301a80cf122dad28b1861e5605cbf455558f3775e1e8200e83a5"}, ] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, @@ -1263,95 +1484,140 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tomli = [ - {file = "tomli-1.2.2-py3-none-any.whl", hash = "sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade"}, - {file = "tomli-1.2.2.tar.gz", hash = "sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee"}, + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] typed-ast = [ - {file = "typed_ast-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b310a207ee9fde3f46ba327989e6cba4195bc0c8c70a158456e7b10233e6bed"}, - {file = "typed_ast-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52ca2b2b524d770bed7a393371a38e91943f9160a190141e0df911586066ecda"}, - {file = "typed_ast-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14fed8820114a389a2b7e91624db5f85f3f6682fda09fe0268a59aabd28fe5f5"}, - {file = "typed_ast-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:65c81abbabda7d760df7304d843cc9dbe7ef5d485504ca59a46ae2d1731d2428"}, - {file = "typed_ast-1.5.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:37ba2ab65a0028b1a4f2b61a8fe77f12d242731977d274a03d68ebb751271508"}, - {file = "typed_ast-1.5.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:49af5b8f6f03ed1eb89ee06c1d7c2e7c8e743d720c3746a5857609a1abc94c94"}, - {file = "typed_ast-1.5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e4374a76e61399a173137e7984a1d7e356038cf844f24fd8aea46c8029a2f712"}, - {file = "typed_ast-1.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ea517c2bb11c5e4ba7a83a91482a2837041181d57d3ed0749a6c382a2b6b7086"}, - {file = "typed_ast-1.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:51040bf45aacefa44fa67fb9ebcd1f2bec73182b99a532c2394eea7dabd18e24"}, - {file = "typed_ast-1.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:806e0c7346b9b4af8c62d9a29053f484599921a4448c37fbbcbbf15c25138570"}, - {file = "typed_ast-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a67fd5914603e2165e075f1b12f5a8356bfb9557e8bfb74511108cfbab0f51ed"}, - {file = "typed_ast-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:224afecb8b39739f5c9562794a7c98325cb9d972712e1a98b6989a4720219541"}, - {file = "typed_ast-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:155b74b078be842d2eb630dd30a280025eca0a5383c7d45853c27afee65f278f"}, - {file = "typed_ast-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:361b9e5d27bd8e3ccb6ea6ad6c4f3c0be322a1a0f8177db6d56264fa0ae40410"}, - {file = "typed_ast-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:618912cbc7e17b4aeba86ffe071698c6e2d292acbd6d1d5ec1ee724b8c4ae450"}, - {file = "typed_ast-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7e6731044f748340ef68dcadb5172a4b1f40847a2983fe3983b2a66445fbc8e6"}, - {file = "typed_ast-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e8a9b9c87801cecaad3b4c2b8876387115d1a14caa602c1618cedbb0cb2a14e6"}, - {file = "typed_ast-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec184dfb5d3d11e82841dbb973e7092b75f306b625fad7b2e665b64c5d60ab3f"}, - {file = "typed_ast-1.5.0.tar.gz", hash = "sha256:ff4ad88271aa7a55f19b6a161ed44e088c393846d954729549e3cde8257747bb"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.0-py3-none-any.whl", hash = "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"}, - {file = "typing_extensions-4.0.0.tar.gz", hash = "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed"}, + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] urllib3 = [ - {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, - {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, + {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, + {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, +] +watchdog = [ + {file = "watchdog-2.1.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a735a990a1095f75ca4f36ea2ef2752c99e6ee997c46b0de507ba40a09bf7330"}, + {file = "watchdog-2.1.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b17d302850c8d412784d9246cfe8d7e3af6bcd45f958abb2d08a6f8bedf695d"}, + {file = "watchdog-2.1.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee3e38a6cc050a8830089f79cbec8a3878ec2fe5160cdb2dc8ccb6def8552658"}, + {file = "watchdog-2.1.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64a27aed691408a6abd83394b38503e8176f69031ca25d64131d8d640a307591"}, + {file = "watchdog-2.1.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:195fc70c6e41237362ba720e9aaf394f8178bfc7fa68207f112d108edef1af33"}, + {file = "watchdog-2.1.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bfc4d351e6348d6ec51df007432e6fe80adb53fd41183716017026af03427846"}, + {file = "watchdog-2.1.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8250546a98388cbc00c3ee3cc5cf96799b5a595270dfcfa855491a64b86ef8c3"}, + {file = "watchdog-2.1.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:117ffc6ec261639a0209a3252546b12800670d4bf5f84fbd355957a0595fe654"}, + {file = "watchdog-2.1.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:97f9752208f5154e9e7b76acc8c4f5a58801b338de2af14e7e181ee3b28a5d39"}, + {file = "watchdog-2.1.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:247dcf1df956daa24828bfea5a138d0e7a7c98b1a47cf1fa5b0c3c16241fcbb7"}, + {file = "watchdog-2.1.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:226b3c6c468ce72051a4c15a4cc2ef317c32590d82ba0b330403cafd98a62cfd"}, + {file = "watchdog-2.1.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d9820fe47c20c13e3c9dd544d3706a2a26c02b2b43c993b62fcd8011bcc0adb3"}, + {file = "watchdog-2.1.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:70af927aa1613ded6a68089a9262a009fbdf819f46d09c1a908d4b36e1ba2b2d"}, + {file = "watchdog-2.1.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed80a1628cee19f5cfc6bb74e173f1b4189eb532e705e2a13e3250312a62e0c9"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9f05a5f7c12452f6a27203f76779ae3f46fa30f1dd833037ea8cbc2887c60213"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_armv7l.whl", hash = "sha256:255bb5758f7e89b1a13c05a5bceccec2219f8995a3a4c4d6968fe1de6a3b2892"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_i686.whl", hash = "sha256:d3dda00aca282b26194bdd0adec21e4c21e916956d972369359ba63ade616153"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_ppc64.whl", hash = "sha256:186f6c55abc5e03872ae14c2f294a153ec7292f807af99f57611acc8caa75306"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_s390x.whl", hash = "sha256:b530ae007a5f5d50b7fbba96634c7ee21abec70dc3e7f0233339c81943848dc1"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:4f4e1c4aa54fb86316a62a87b3378c025e228178d55481d30d857c6c438897d6"}, + {file = "watchdog-2.1.9-py3-none-win32.whl", hash = "sha256:5952135968519e2447a01875a6f5fc8c03190b24d14ee52b0f4b1682259520b1"}, + {file = "watchdog-2.1.9-py3-none-win_amd64.whl", hash = "sha256:7a833211f49143c3d336729b0020ffd1274078e94b0ae42e22f596999f50279c"}, + {file = "watchdog-2.1.9-py3-none-win_ia64.whl", hash = "sha256:ad576a565260d8f99d97f2e64b0f97a48228317095908568a9d5c786c829d428"}, + {file = "watchdog-2.1.9.tar.gz", hash = "sha256:43ce20ebb36a51f21fa376f76d1d4692452b2527ccd601950d69ed36b9e21609"}, ] wrapt = [ - {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"}, - {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"}, - {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"}, - {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"}, - {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"}, - {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"}, - {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"}, - {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"}, - {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"}, - {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"}, - {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"}, - {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"}, - {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"}, - {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"}, - {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"}, - {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"}, - {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"}, - {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"}, - {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"}, + {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, + {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, + {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, + {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, + {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, + {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, + {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, + {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, + {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, + {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, + {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, + {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, + {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, + {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, + {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, + {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] yamllint = [ - {file = "yamllint-1.26.3.tar.gz", hash = "sha256:3934dcde484374596d6b52d8db412929a169f6d9e52e20f9ade5bf3523d9b96e"}, + {file = "yamllint-1.28.0.tar.gz", hash = "sha256:9e3d8ddd16d0583214c5fdffe806c9344086721f107435f68bad990e5a88826b"}, ] zipp = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, + {file = "zipp-3.9.0-py3-none-any.whl", hash = "sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980"}, + {file = "zipp-3.9.0.tar.gz", hash = "sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb"}, ] diff --git a/pyproject.toml b/pyproject.toml index ffe7040a..6f10bcb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,25 +13,23 @@ classifiers = [ "Intended Audience :: Developers", "Development Status :: 4 - Beta", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", ] include = [ - "CHANGELOG.md", "LICENSE", "README.md", "netutils/protocols.json" ] [tool.poetry.dependencies] -python = "^3.6" +python = "^3.7" [tool.poetry.dev-dependencies] bandit = "*" -black = {version="^21.10b0", python="^3.6.2"} +black = "*" coverage = "*" invoke = "*" flake8 = "*" @@ -45,6 +43,11 @@ sphinx-rtd-theme = "*" toml = "*" yamllint = "*" mypy = "^0.961" +mkdocs = "1.3.1" +mkdocs-material = "8.3.9" +mkdocstrings = "0.19" +mkdocstrings-python = "0.7.1" +mkdocs-version-annotations = "1.0.0" [tool.black] line-length = 120 diff --git a/tasks.py b/tasks.py index 7b2bb611..671c5226 100644 --- a/tasks.py +++ b/tasks.py @@ -46,7 +46,7 @@ def is_truthy(arg): PROJECT_VERSION = PYPROJECT_CONFIG["tool"]["poetry"]["version"] -def run_cmd(context, exec_cmd, local=INVOKE_LOCAL): +def run_cmd(context, exec_cmd, local=INVOKE_LOCAL, port=None): """Wrapper to run the invoke task commands. Args: @@ -62,7 +62,14 @@ def run_cmd(context, exec_cmd, local=INVOKE_LOCAL): result = context.run(exec_cmd, pty=True) else: print(f"DOCKER - Running command: {exec_cmd} container: {IMAGE_NAME}:{IMAGE_VER}") - result = context.run(f"docker run -it -v {PWD}:/local {IMAGE_NAME}:{IMAGE_VER} sh -c '{exec_cmd}'", pty=True) + if port: + result = context.run( + f"docker run -it -p {port} -v {PWD}:/local {IMAGE_NAME}:{IMAGE_VER} sh -c '{exec_cmd}'", pty=True + ) + else: + result = context.run( + f"docker run -it -v {PWD}:/local {IMAGE_NAME}:{IMAGE_VER} sh -c '{exec_cmd}'", pty=True + ) return result @@ -255,27 +262,14 @@ def tests(context, local=INVOKE_LOCAL): @task -def html(context, sourcedir="docs/source", builddir="docs/build"): - """Creates html docs using sphinx-build command. - - Args: - context (obj): Used to run specific commands - sourcedir (str, optional): Source directory for sphinx to use. Defaults to "source". - builddir (str, optional): Output directory for sphinx to use. Defaults to "build". - """ - print("Building html documentation...") - clean_docs(context, builddir) - command = f"sphinx-build {sourcedir} {builddir}" - context.run(command) +def clean_container(context): + """Remove stopped containers that source for image `netutils:`.""" + exec_cmd = """docker container rm $(docker container ls -a | grep -E "^\S+\s+netutils:" | awk 'NR>1 {print $1}')""" # noqa: W605 # pylint:disable=anomalous-backslash-in-string + run_cmd(context, exec_cmd, local=True) @task -def clean_docs(context, builddir="docs/build"): - """Removes the build directory and all of its contents. - - Args: - context (obj): Used to run specific commands - builddir (str, optional): Directory to be removed. Defaults to "build". - """ - print(f"Removing everything under {builddir} directory...") - context.run("rm -rf " + builddir) +def docs(context, local=INVOKE_LOCAL): + """Build and serve docs locally for development.""" + exec_cmd = "mkdocs serve -v --dev-addr=0.0.0.0:8001" + run_cmd(context, exec_cmd, local, port="8001:8001") diff --git a/tests/unit/test_basics.py b/tests/unit/test_basics.py new file mode 100644 index 00000000..e5339cf6 --- /dev/null +++ b/tests/unit/test_basics.py @@ -0,0 +1,21 @@ +"""Basic tests that do not require netutils.""" +import os +import unittest +import toml + + +class TestDocsPackaging(unittest.TestCase): + """Test Version in doc requirements is the same pyproject.""" + + def test_version(self): + """Verify that pyproject.toml dev dependecies have the same versions as in the docs requirements.txt.""" + parent_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) + poetry_details = toml.load(os.path.join(parent_path, "pyproject.toml"))["tool"]["poetry"]["dev-dependencies"] + with open(f"{parent_path}/docs/requirements.txt", "r", encoding="utf-8") as file: + requirements = [line for line in file.read().splitlines() if (len(line) > 0 and not line.startswith("#"))] + for pkg in requirements: + if len(pkg.split("==")) == 2: + pkg, version = pkg.split("==") + else: + version = "*" + self.assertEqual(poetry_details[pkg], version) diff --git a/tests/unit/test_docs.py b/tests/unit/test_docs.py index 92f985d7..aab31f7d 100644 --- a/tests/unit/test_docs.py +++ b/tests/unit/test_docs.py @@ -1,111 +1,10 @@ -"""Test for the sphinx documentation.""" -import subprocess -import glob -import os -import re -import pytest +"""Update docs tests to include assurance that development script ran.""" +import sys -UNDOCUMENTED_FILES = ["__init__", "constants", "lib_mapper", "protocol_mapper", "variables"] +sys.path.append("...") +from development_scripts import main # noqa:E402 pylint: disable=wrong-import-position -SPHINX_DIRECTORIES = [ - { - "source_dir": "docs/source/", - "build_dir": "docs/build/", - } -] -MODULE_FOLDERS = [{"doc_module_folder": "../../docs/source/netutils/", "netutils_module_folder": "../../netutils/"}] - -START_END_LINES = [ - { - "name": "overview", - "start_value": "# netutils\n", - "end_value": "* VLANs - Provide the ability to convert configuration into lists or lists into configuration.\n", - }, - { - "name": "installation", - "start_value": "Option 1: Install from PyPI.\n", - "end_value": "```\n", - }, - { - "name": "examples", - "start_value": "While all functions come with examples in the docstrings, for quick reference of the types of problems this library intends to\n", - "end_value": "These are just some examples of the many functions provided by this library.\n", - }, - { - "name": "attribution", - "start_value": "The library was built to be a centralized place for common network automation code to be accessed. While in most cases it is\n", - "end_value": "In building out the time conversion, the regex patterns are based on NAPALM implementation with their consent.\n", - }, - { - "name": "contributing", - "start_value": "Pull requests are welcomed and automatically built and tested against multiple versions of Python through TravisCI.\n", - "end_value": "Sign up [here](http://slack.networktocode.com/)\n", - }, -] - - -with open("README.md", "r", encoding="utf-8") as file: - README_LIST = file.readlines() - - -def _get_readme_line(folder_name, start_end): - - regex_dict = {"start": r"(:start-line:\s+(?P\d+))", "end": r"(:end-line:\s+(?P\d+))"} - with open(f"{SPHINX_DIRECTORIES[0]['source_dir']}/{folder_name}/index.rst", "r", encoding="utf-8") as index_file: - for line in index_file.readlines(): - match = re.search(regex_dict[start_end], line) - if match: - break - - if match: - int_value = int(match.groupdict()["value"]) - return int_value - - raise Exception( - f"Not able to find {start_end} line value from {SPHINX_DIRECTORIES[0]['source_dir']}/{folder_name}/index.rst. Ensure each line is spelled correctly and exists. " - ) - - -@pytest.mark.parametrize("data", SPHINX_DIRECTORIES) -def test_sphinx_build(data): - sphinx_dummy_build = subprocess.run( # pylint: disable=W1510 - ["sphinx-build", "-b", "dummy", "-W", data["source_dir"], data["build_dir"]], stdout=subprocess.PIPE - ) - assert sphinx_dummy_build.returncode == 0 - - -@pytest.mark.parametrize("data", MODULE_FOLDERS) -def test_folders_present_for_module(data): - netutils_modules = [file[15:-3] for file in glob.glob(data["netutils_module_folder"] + "*.py")] - netutils_modules = list(set(netutils_modules).difference(set(UNDOCUMENTED_FILES))) - doc_module_folders = [folder[27:-1] for folder in glob.glob(data["doc_module_folder"] + "*/")] - - for module in netutils_modules: - assert module in doc_module_folders - - -@pytest.mark.parametrize("data", MODULE_FOLDERS) -def test_folders_contain_index(data): - doc_module_folders = glob.glob(data["doc_module_folder"]) - - for folder in doc_module_folders: - assert "index.rst" in os.listdir(folder) - - -@pytest.mark.parametrize("start_end", START_END_LINES, ids=[section["name"] for section in START_END_LINES]) -def test_docs_start_end_lines(start_end): - start_line_value = _get_readme_line(start_end["name"], "start") - end_line_value = _get_readme_line(start_end["name"], "end") - assert README_LIST[start_line_value] == start_end["start_value"] - assert README_LIST[end_line_value - 1] == start_end["end_value"] - - -def test_docs_start_end_lines_fail(): - end_line_value = _get_readme_line("overview", "end") - overview = { - "name": "overview", - "start_value": "# netutils\n", - "end_value": "This is what I think the last line of the overview section will be.\n", - } - assert README_LIST[end_line_value - 1] != overview["end_value"] +def test_docs_generated(): + """Assert each generated file has been auto generated, run `python development_scripts.py` if failed.""" + assert main(test=True) is True