├── nornir_netmiko
├── connections
│ ├── __init__.py
│ └── netmiko.py
├── tasks
│ ├── __init__.py
│ ├── netmiko_commit.py
│ ├── netmiko_save_config.py
│ ├── netmiko_send_command.py
│ ├── netmiko_multiline.py
│ ├── netmiko_file_transfer.py
│ └── netmiko_send_config.py
└── __init__.py
├── release_process.txt
├── .nornir.meta
├── setup.cfg
├── pyproject.toml
├── .github
└── workflows
│ └── commit.yaml
├── README.md
├── .gitignore
├── LICENSE
└── poetry.lock
/nornir_netmiko/connections/__init__.py:
--------------------------------------------------------------------------------
1 | from nornir_netmiko.connections.netmiko import Netmiko
2 | from nornir_netmiko.connections.netmiko import CONNECTION_NAME
3 |
4 |
5 | __all__ = ("Netmiko", "CONNECTION_NAME")
6 |
--------------------------------------------------------------------------------
/release_process.txt:
--------------------------------------------------------------------------------
1 | # rough process
2 | source ~/VENV/nornir_test/bin/activate
3 | git tag --list
4 | git tag -a 1.0.0 -m "Version 1.0.0 Release"
5 | git tag --list
6 | git push origin_ssh 1.0.0
7 |
8 | rm dist/nornir_netmiko-1.0.0*
9 | export PATH="$HOME/.poetry/bin:$PATH"
10 | poetry build
11 | ls dist/
12 |
13 | twine upload -r pypitest dist/nornir_netmiko-1.0.0.tar.gz dist/nornir_netmiko-1.0.0-py3-none-any.whl
14 | twine upload dist/nornir_netmiko-1.0.0.tar.gz dist/nornir_netmiko-1.0.0-py3-none-any.whl
15 |
16 |
--------------------------------------------------------------------------------
/.nornir.meta:
--------------------------------------------------------------------------------
1 | ---
2 | name: nornir_netmiko
3 | summary: |
4 | Connection plugin and various tasks to interact with network equipment via `netmiko `_.
5 | nornir_version: ~3
6 | categories:
7 | - netmiko
8 | - networking
9 | intro_file: README.md
10 | connection_plugins:
11 | - nornir_netmiko.connections.Netmiko
12 | task_plugins:
13 | - nornir_netmiko.tasks.netmiko_commit
14 | - nornir_netmiko.tasks.netmiko_file_transfer
15 | - nornir_netmiko.tasks.netmiko_save_config
16 | - nornir_netmiko.tasks.netmiko_send_command
17 | - nornir_netmiko.tasks.netmiko_send_config
18 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/__init__.py:
--------------------------------------------------------------------------------
1 | from nornir_netmiko.tasks.netmiko_commit import netmiko_commit
2 | from nornir_netmiko.tasks.netmiko_file_transfer import netmiko_file_transfer
3 | from nornir_netmiko.tasks.netmiko_save_config import netmiko_save_config
4 | from nornir_netmiko.tasks.netmiko_send_command import netmiko_send_command
5 | from nornir_netmiko.tasks.netmiko_send_config import netmiko_send_config
6 | from nornir_netmiko.tasks.netmiko_multiline import netmiko_multiline
7 |
8 |
9 | __all__ = (
10 | "netmiko_commit",
11 | "netmiko_file_transfer",
12 | "netmiko_save_config",
13 | "netmiko_send_command",
14 | "netmiko_send_config",
15 | "netmiko_multiline",
16 | )
17 |
--------------------------------------------------------------------------------
/nornir_netmiko/__init__.py:
--------------------------------------------------------------------------------
1 | from nornir_netmiko.connections import Netmiko
2 | from nornir_netmiko.connections import CONNECTION_NAME
3 | from nornir_netmiko.tasks import netmiko_commit
4 | from nornir_netmiko.tasks import netmiko_file_transfer
5 | from nornir_netmiko.tasks import netmiko_save_config
6 | from nornir_netmiko.tasks import netmiko_send_command
7 | from nornir_netmiko.tasks import netmiko_send_config
8 | from nornir_netmiko.tasks import netmiko_multiline
9 |
10 |
11 | __all__ = (
12 | "Netmiko",
13 | "CONNECTION_NAME",
14 | "netmiko_commit",
15 | "netmiko_file_transfer",
16 | "netmiko_save_config",
17 | "netmiko_send_command",
18 | "netmiko_multiline",
19 | "netmiko_send_config",
20 | )
21 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/netmiko_commit.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 | from nornir.core.task import Result, Task
3 | from nornir_netmiko.connections import CONNECTION_NAME
4 |
5 |
6 | def netmiko_commit(task: Task, **kwargs: Any) -> Result:
7 | """
8 | Execute Netmiko commit method
9 |
10 | Arguments:
11 | kwargs: Additional arguments to pass to method.
12 |
13 | Returns:
14 | :obj: `nornir.core.task.Result`:
15 | * result (``str``): String showing the CLI output from the commit operation
16 | """
17 | conn = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
18 | result = conn.commit(**kwargs)
19 |
20 | if conn.check_config_mode():
21 | conn.exit_config_mode()
22 | return Result(host=task.host, result=result, changed=True)
23 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [pylama]
2 | linters = mccabe,pycodestyle,pyflakes
3 | ignore = D203,C901
4 | skip = .tox/*,.venv/*
5 |
6 | [pylama:pycodestyle]
7 | max_line_length = 100
8 |
9 | [pycodestyle]
10 | ignore = D203,C901
11 | exclude = .git,__pycache__,build,dist
12 | max-complexity = 10
13 | max-line-length = 100
14 |
15 | [tool:pytest]
16 | python_paths = ./
17 | filterwarnings =
18 | ignore::nornir.core.exceptions.ConflictingConfigurationWarning
19 |
20 | [mypy]
21 | # The mypy configurations: http://bit.ly/2zEl9WI
22 | python_version = 3.8
23 | check_untyped_defs = True
24 | disallow_any_generics = True
25 | disallow_untyped_calls = True
26 | disallow_untyped_defs = True
27 | disallow_incomplete_defs = True
28 | disallow_untyped_decorators = True
29 | ignore_errors = False
30 | ignore_missing_imports = True
31 | strict_optional = True
32 | warn_unused_configs = True
33 | warn_unused_ignores = True
34 | warn_return_any = True
35 | warn_redundant_casts = True
36 |
37 | [mypy-tests.*]
38 | ignore_errors = True
39 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "nornir_netmiko"
3 | version = "1.0.1"
4 | description = "Netmiko's plugins for Nornir"
5 | authors = ["Kirk Byers "]
6 | license = "Apache-2.0"
7 | readme = "README.md"
8 | repository = "https://github.com/ktbyers/nornir_netmiko"
9 | classifiers = [
10 | "License :: OSI Approved :: Apache Software License",
11 | "Programming Language :: Python :: 3.8",
12 | "Programming Language :: Python :: 3.9",
13 | "Programming Language :: Python :: 3.10",
14 | "Programming Language :: Python :: 3.11",
15 | "Programming Language :: Python :: 3.12",
16 | ]
17 |
18 | [tool.poetry.plugins."nornir.plugins.connections"]
19 | "netmiko" = "nornir_netmiko.connections:Netmiko"
20 |
21 | [tool.poetry.dependencies]
22 | python = "^3.8"
23 | netmiko = "^4.0.0"
24 |
25 | [tool.poetry.dev-dependencies]
26 | black = "23.11.0"
27 | mypy = "1.7.1"
28 | pylama = "8.4.1"
29 | pytest = "7.4.3"
30 |
31 | [build-system]
32 | requires = ["poetry>=1.1.8"]
33 | build-backend = "poetry.masonry.api"
34 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/netmiko_save_config.py:
--------------------------------------------------------------------------------
1 | from nornir.core.task import Result, Task
2 | from nornir_netmiko.connections import CONNECTION_NAME
3 |
4 |
5 | def netmiko_save_config(
6 | task: Task, cmd: str = "", confirm: bool = False, confirm_response: str = ""
7 | ) -> Result:
8 | """
9 | Execute Netmiko save_config method
10 |
11 | Arguments:
12 | cmd(str, optional): Command used to save the configuration.
13 | confirm(bool, optional): Does device prompt for confirmation before executing save operation
14 | confirm_response(str, optional): Response send to device when it prompts for confirmation
15 |
16 | Returns:
17 | :obj: `nornir.core.task.Result`:
18 | * result (``str``): String showing the CLI output from the save operation
19 | """
20 | conn = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
21 | if cmd:
22 | result = conn.save_config(
23 | cmd=cmd, confirm=confirm, confirm_response=confirm_response
24 | )
25 | else:
26 | result = conn.save_config(confirm=confirm, confirm_response=confirm_response)
27 | return Result(host=task.host, result=result, changed=True)
28 |
--------------------------------------------------------------------------------
/.github/workflows/commit.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Test nornir_netmiko
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | linters:
7 | name: linters
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - name: checkout repository
12 | uses: actions/checkout@v2
13 |
14 | - name: Setup python
15 | uses: actions/setup-python@v2
16 | with:
17 | python-version: 3.10.4
18 |
19 | - name: Install Poetry
20 | uses: snok/install-poetry@v1.2.0
21 | with:
22 | version: 1.3.2
23 | virtualenvs-create: true
24 | virtualenvs-in-project: true
25 |
26 | - name: Install the library itself
27 | run: poetry install --no-interaction
28 |
29 | - name: Inspecting things
30 | run: |
31 | source .venv/bin/activate
32 | echo $PATH
33 | pwd
34 | which python
35 | pip list
36 |
37 | - name: Run black
38 | run: |
39 | source .venv/bin/activate
40 | black --check .
41 |
42 | - name: Run linter
43 | run: |
44 | source .venv/bin/activate
45 | pylama .
46 |
47 | - name: Run mypy
48 | run: |
49 | source .venv/bin/activate
50 | mypy ./nornir_netmiko/
51 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/netmiko_send_command.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 | from nornir.core.task import Result, Task
3 | from nornir_netmiko.connections import CONNECTION_NAME
4 |
5 |
6 | def netmiko_send_command(
7 | task: Task,
8 | command_string: str,
9 | use_timing: bool = False,
10 | enable: bool = False,
11 | **kwargs: Any
12 | ) -> Result:
13 | """
14 | Execute Netmiko send_command method (or send_command_timing)
15 |
16 | Arguments:
17 | command_string: Command to execute on the remote network device.
18 | use_timing: Set to True to switch to send_command_timing method.
19 | enable: Set to True to force Netmiko .enable() call.
20 | kwargs: Additional arguments to pass to send_command method.
21 |
22 | Returns:
23 | Result object with the following attributes set:
24 | * result: Result of the show command (generally a string, but depends on use of TextFSM).
25 | """
26 | net_connect = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
27 | if enable:
28 | net_connect.enable()
29 | if use_timing:
30 | result = net_connect.send_command_timing(command_string, **kwargs)
31 | else:
32 | result = net_connect.send_command(command_string, **kwargs)
33 | return Result(host=task.host, result=result)
34 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/netmiko_multiline.py:
--------------------------------------------------------------------------------
1 | from typing import Sequence, Union, List, Any
2 | from nornir.core.task import Result, Task
3 | from nornir_netmiko.connections import CONNECTION_NAME
4 |
5 |
6 | def netmiko_multiline(
7 | task: Task,
8 | commands: Sequence[Union[str, List[str]]],
9 | use_timing: bool = False,
10 | enable: bool = False,
11 | **kwargs: Any
12 | ) -> Result:
13 | """
14 | Execute Netmiko send_multiline method (or send_multiline_timing)
15 |
16 | Arguments:
17 | commands: List or list of lists (see Netmiko send_multiline)
18 | use_timing: Set to True to switch to send_multiline_timing method.
19 | enable: Set to True to force Netmiko .enable() call.
20 | kwargs: Additional arguments to pass to send_multiline method.
21 |
22 | Returns:
23 | Result object with the following attributes set:
24 | * result: String result showing you the output from commands
25 | """
26 | net_connect = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
27 | if enable:
28 | net_connect.enable()
29 | if use_timing:
30 | result = net_connect.send_multiline_timing(commands, **kwargs)
31 | else:
32 | result = net_connect.send_multiline(commands, **kwargs)
33 | return Result(host=task.host, result=result)
34 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/netmiko_file_transfer.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 | from netmiko import file_transfer
3 | from nornir.core.task import Result, Task
4 | from nornir_netmiko.connections import CONNECTION_NAME
5 |
6 |
7 | def netmiko_file_transfer(
8 | task: Task, source_file: str, dest_file: str, **kwargs: Any
9 | ) -> Result:
10 | """
11 | Execute Netmiko file_transfer method
12 |
13 | Arguments:
14 | source_file: Source file.
15 | dest_file: Destination file.
16 | kwargs: Additional arguments to pass to file_transfer
17 |
18 | Returns:
19 | Result object with the following attributes set:
20 | * result (``bool``): file exists and MD5 is valid
21 | * changed (``bool``): the destination file was changed
22 |
23 | """
24 | net_connect = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
25 | kwargs.setdefault("direction", "put")
26 | scp_result = file_transfer(
27 | net_connect, source_file=source_file, dest_file=dest_file, **kwargs
28 | )
29 | if kwargs.get("disable_md5") is True:
30 | file_valid = scp_result["file_exists"]
31 | else:
32 | file_valid = scp_result["file_exists"] and scp_result["file_verified"]
33 | return Result(
34 | host=task.host, result=file_valid, changed=scp_result["file_transferred"]
35 | )
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nornir_netmiko
2 | Netmiko Plugins for [Nornir](https://github.com/nornir-automation/nornir)
3 |
4 |
5 | ## Installation
6 |
7 | ```bash
8 | pip install nornir_netmiko
9 | ```
10 |
11 | ## Plugins
12 |
13 | ### Connections
14 |
15 | - netmiko - Connect to network devices using netmiko
16 |
17 | ### Tasks
18 |
19 | - netmiko_commit - Execute Netmiko commit method
20 | - netmiko_file_transfer - Execute Netmiko file_transfer method
21 | - netmiko_multiline - Execute Netmiko send_multiline method (or send_multiline_timing)
22 | - netmiko_save_config - Execute Netmiko save_config method
23 | - netmiko_send_command - Execute Netmiko send_command method (or send_command_timing)
24 | - netmiko_send_config - Execute Netmiko send_config_set method (or send_config_from_file)
25 |
26 |
27 | ## Connection Options
28 |
29 | ### Platform
30 |
31 | For better usability for napalm and netmiko users, the connection plugin maps the NAPALM base device types into netmiko device types:
32 |
33 | ```python
34 | napalm_to_netmiko_map = {
35 | "ios": "cisco_ios",
36 | "nxos": "cisco_nxos",
37 | "nxos_ssh": "cisco_nxos",
38 | "eos": "arista_eos",
39 | "junos": "juniper_junos",
40 | "iosxr": "cisco_xr",
41 | }
42 | ```
43 |
44 | ### Extras
45 |
46 | The Connection Option `extras` are combined with the `host`, `username`, `password`, and `port` from the Host or Connection Object, and then passed to the ConnectHandler.
47 |
48 | ```yaml
49 | router1:
50 | username: cisco
51 | platform: ios
52 | connection_options:
53 | netmiko:
54 | extras:
55 | secret: secret
56 | session_log: router1.txt
57 | ```
58 |
--------------------------------------------------------------------------------
/nornir_netmiko/tasks/netmiko_send_config.py:
--------------------------------------------------------------------------------
1 | from typing import Any, List, Optional
2 | from nornir.core.task import Result, Task
3 | from nornir_netmiko.connections import CONNECTION_NAME
4 |
5 |
6 | def netmiko_send_config(
7 | task: Task,
8 | config_commands: Optional[List[str]] = None,
9 | config_file: Optional[str] = None,
10 | enable: bool = True,
11 | dry_run: Optional[bool] = None,
12 | **kwargs: Any
13 | ) -> Result:
14 | """
15 | Execute Netmiko send_config_set method (or send_config_from_file)
16 |
17 | Arguments:
18 | config_commands: Commands to configure on the remote network device.
19 | config_file: File to read configuration commands from.
20 | enable: Attempt to enter enable-mode.
21 | dry_run: Whether to apply changes or not (will raise exception)
22 | kwargs: Additional arguments to pass to method.
23 |
24 | Returns:
25 | Result object with the following attributes set:
26 | * result (``str``): string showing the CLI from the configuration changes.
27 | """
28 | net_connect = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
29 |
30 | # netmiko_send_config does not support dry_run
31 | dry_run = task.is_dry_run(dry_run)
32 | if dry_run is True:
33 | raise ValueError("netmiko_send_config does not support dry_run")
34 |
35 | if enable:
36 | net_connect.enable()
37 | if config_commands:
38 | result = net_connect.send_config_set(config_commands=config_commands, **kwargs)
39 | elif config_file:
40 | result = net_connect.send_config_from_file(config_file=config_file, **kwargs)
41 | else:
42 | raise ValueError("Must specify either config_commands or config_file")
43 |
44 | return Result(host=task.host, result=result, changed=True)
45 |
--------------------------------------------------------------------------------
/nornir_netmiko/connections/netmiko.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Dict, Optional
2 |
3 | from netmiko import ConnectHandler
4 |
5 | from nornir.core.configuration import Config
6 |
7 |
8 | CONNECTION_NAME = "netmiko"
9 |
10 | napalm_to_netmiko_map = {
11 | "ios": "cisco_ios",
12 | "nxos": "cisco_nxos",
13 | "nxos_ssh": "cisco_nxos",
14 | "eos": "arista_eos",
15 | "junos": "juniper_junos",
16 | "iosxr": "cisco_xr",
17 | }
18 |
19 |
20 | class Netmiko:
21 | """
22 | This plugin connects to the device using the Netmiko driver and sets the
23 | relevant connection.
24 | Inventory:
25 | extras: maps to argument passed to ``ConnectHandler``.
26 | """
27 |
28 | def open(
29 | self,
30 | hostname: Optional[str],
31 | username: Optional[str],
32 | password: Optional[str],
33 | port: Optional[int],
34 | platform: Optional[str],
35 | extras: Optional[Dict[str, Any]] = None,
36 | configuration: Optional[Config] = None,
37 | ) -> None:
38 | parameters = {
39 | "host": hostname,
40 | "username": username,
41 | "password": password,
42 | "port": port,
43 | }
44 |
45 | try:
46 | parameters[
47 | "ssh_config_file"
48 | ] = configuration.ssh.config_file # type: ignore
49 | except AttributeError:
50 | pass
51 |
52 | if platform is not None:
53 | # Look platform up in corresponding map, if no entry return the host.nos unmodified
54 | platform = napalm_to_netmiko_map.get(platform, platform)
55 | parameters["device_type"] = platform
56 |
57 | extras = extras or {}
58 | parameters.update(extras)
59 | connection = ConnectHandler(**parameters)
60 | self.connection = connection
61 |
62 | def close(self) -> None:
63 | self.connection.disconnect()
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2020 Kirk Byers
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/poetry.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Poetry and should not be changed by hand.
2 |
3 | [[package]]
4 | name = "bcrypt"
5 | version = "4.1.1"
6 | description = "Modern password hashing for your software and your servers"
7 | category = "main"
8 | optional = false
9 | python-versions = ">=3.7"
10 | files = [
11 | {file = "bcrypt-4.1.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:196008d91201bbb1aa4e666fee5e610face25d532e433a560cabb33bfdff958b"},
12 | {file = "bcrypt-4.1.1-cp37-abi3-macosx_13_0_universal2.whl", hash = "sha256:2e197534c884336f9020c1f3a8efbaab0aa96fc798068cb2da9c671818b7fbb0"},
13 | {file = "bcrypt-4.1.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d573885b637815a7f3a3cd5f87724d7d0822da64b0ab0aa7f7c78bae534e86dc"},
14 | {file = "bcrypt-4.1.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab33473f973e8058d1b2df8d6e095d237c49fbf7a02b527541a86a5d1dc4444"},
15 | {file = "bcrypt-4.1.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fb931cd004a7ad36a89789caf18a54c20287ec1cd62161265344b9c4554fdb2e"},
16 | {file = "bcrypt-4.1.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:12f40f78dcba4aa7d1354d35acf45fae9488862a4fb695c7eeda5ace6aae273f"},
17 | {file = "bcrypt-4.1.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2ade10e8613a3b8446214846d3ddbd56cfe9205a7d64742f0b75458c868f7492"},
18 | {file = "bcrypt-4.1.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f33b385c3e80b5a26b3a5e148e6165f873c1c202423570fdf45fe34e00e5f3e5"},
19 | {file = "bcrypt-4.1.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:755b9d27abcab678e0b8fb4d0abdebeea1f68dd1183b3f518bad8d31fa77d8be"},
20 | {file = "bcrypt-4.1.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a7a7b8a87e51e5e8ca85b9fdaf3a5dc7aaf123365a09be7a27883d54b9a0c403"},
21 | {file = "bcrypt-4.1.1-cp37-abi3-win32.whl", hash = "sha256:3d6c4e0d6963c52f8142cdea428e875042e7ce8c84812d8e5507bd1e42534e07"},
22 | {file = "bcrypt-4.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:14d41933510717f98aac63378b7956bbe548986e435df173c841d7f2bd0b2de7"},
23 | {file = "bcrypt-4.1.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:24c2ebd287b5b11016f31d506ca1052d068c3f9dc817160628504690376ff050"},
24 | {file = "bcrypt-4.1.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:476aa8e8aca554260159d4c7a97d6be529c8e177dbc1d443cb6b471e24e82c74"},
25 | {file = "bcrypt-4.1.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:12611c4b0a8b1c461646228344784a1089bc0c49975680a2f54f516e71e9b79e"},
26 | {file = "bcrypt-4.1.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c6450538a0fc32fb7ce4c6d511448c54c4ff7640b2ed81badf9898dcb9e5b737"},
27 | {file = "bcrypt-4.1.1.tar.gz", hash = "sha256:df37f5418d4f1cdcff845f60e747a015389fa4e63703c918330865e06ad80007"},
28 | ]
29 |
30 | [package.extras]
31 | tests = ["pytest (>=3.2.1,!=3.3.0)"]
32 | typecheck = ["mypy"]
33 |
34 | [[package]]
35 | name = "black"
36 | version = "23.11.0"
37 | description = "The uncompromising code formatter."
38 | category = "dev"
39 | optional = false
40 | python-versions = ">=3.8"
41 | files = [
42 | {file = "black-23.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911"},
43 | {file = "black-23.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f"},
44 | {file = "black-23.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394"},
45 | {file = "black-23.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f"},
46 | {file = "black-23.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479"},
47 | {file = "black-23.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244"},
48 | {file = "black-23.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221"},
49 | {file = "black-23.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5"},
50 | {file = "black-23.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187"},
51 | {file = "black-23.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6"},
52 | {file = "black-23.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b"},
53 | {file = "black-23.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142"},
54 | {file = "black-23.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055"},
55 | {file = "black-23.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4"},
56 | {file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"},
57 | {file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"},
58 | {file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"},
59 | {file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"},
60 | ]
61 |
62 | [package.dependencies]
63 | click = ">=8.0.0"
64 | mypy-extensions = ">=0.4.3"
65 | packaging = ">=22.0"
66 | pathspec = ">=0.9.0"
67 | platformdirs = ">=2"
68 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
69 | typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
70 |
71 | [package.extras]
72 | colorama = ["colorama (>=0.4.3)"]
73 | d = ["aiohttp (>=3.7.4)"]
74 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
75 | uvloop = ["uvloop (>=0.15.2)"]
76 |
77 | [[package]]
78 | name = "cffi"
79 | version = "1.16.0"
80 | description = "Foreign Function Interface for Python calling C code."
81 | category = "main"
82 | optional = false
83 | python-versions = ">=3.8"
84 | files = [
85 | {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
86 | {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
87 | {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
88 | {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
89 | {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
90 | {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
91 | {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
92 | {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
93 | {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
94 | {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
95 | {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
96 | {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
97 | {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
98 | {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
99 | {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
100 | {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
101 | {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
102 | {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
103 | {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
104 | {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
105 | {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
106 | {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
107 | {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
108 | {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
109 | {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
110 | {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
111 | {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
112 | {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
113 | {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
114 | {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
115 | {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
116 | {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
117 | {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"},
118 | {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"},
119 | {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"},
120 | {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"},
121 | {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"},
122 | {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"},
123 | {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"},
124 | {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"},
125 | {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
126 | {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
127 | {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
128 | {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
129 | {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
130 | {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
131 | {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
132 | {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
133 | {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
134 | {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
135 | {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
136 | {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
137 | ]
138 |
139 | [package.dependencies]
140 | pycparser = "*"
141 |
142 | [[package]]
143 | name = "click"
144 | version = "8.1.7"
145 | description = "Composable command line interface toolkit"
146 | category = "dev"
147 | optional = false
148 | python-versions = ">=3.7"
149 | files = [
150 | {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
151 | {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
152 | ]
153 |
154 | [package.dependencies]
155 | colorama = {version = "*", markers = "platform_system == \"Windows\""}
156 |
157 | [[package]]
158 | name = "colorama"
159 | version = "0.4.6"
160 | description = "Cross-platform colored terminal text."
161 | category = "dev"
162 | optional = false
163 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
164 | files = [
165 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
166 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
167 | ]
168 |
169 | [[package]]
170 | name = "cryptography"
171 | version = "41.0.7"
172 | description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
173 | category = "main"
174 | optional = false
175 | python-versions = ">=3.7"
176 | files = [
177 | {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"},
178 | {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"},
179 | {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"},
180 | {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"},
181 | {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"},
182 | {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"},
183 | {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"},
184 | {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"},
185 | {file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"},
186 | {file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"},
187 | {file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"},
188 | {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"},
189 | {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"},
190 | {file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"},
191 | {file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"},
192 | {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"},
193 | {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"},
194 | {file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"},
195 | {file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"},
196 | {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"},
197 | {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"},
198 | {file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"},
199 | {file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"},
200 | ]
201 |
202 | [package.dependencies]
203 | cffi = ">=1.12"
204 |
205 | [package.extras]
206 | docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
207 | docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
208 | nox = ["nox"]
209 | pep8test = ["black", "check-sdist", "mypy", "ruff"]
210 | sdist = ["build"]
211 | ssh = ["bcrypt (>=3.1.5)"]
212 | test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
213 | test-randomorder = ["pytest-randomly"]
214 |
215 | [[package]]
216 | name = "exceptiongroup"
217 | version = "1.2.0"
218 | description = "Backport of PEP 654 (exception groups)"
219 | category = "dev"
220 | optional = false
221 | python-versions = ">=3.7"
222 | files = [
223 | {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
224 | {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
225 | ]
226 |
227 | [package.extras]
228 | test = ["pytest (>=6)"]
229 |
230 | [[package]]
231 | name = "future"
232 | version = "0.18.3"
233 | description = "Clean single-source support for Python 3 and 2"
234 | category = "main"
235 | optional = false
236 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
237 | files = [
238 | {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"},
239 | ]
240 |
241 | [[package]]
242 | name = "iniconfig"
243 | version = "2.0.0"
244 | description = "brain-dead simple config-ini parsing"
245 | category = "dev"
246 | optional = false
247 | python-versions = ">=3.7"
248 | files = [
249 | {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
250 | {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
251 | ]
252 |
253 | [[package]]
254 | name = "mccabe"
255 | version = "0.7.0"
256 | description = "McCabe checker, plugin for flake8"
257 | category = "dev"
258 | optional = false
259 | python-versions = ">=3.6"
260 | files = [
261 | {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
262 | {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
263 | ]
264 |
265 | [[package]]
266 | name = "mypy"
267 | version = "1.7.1"
268 | description = "Optional static typing for Python"
269 | category = "dev"
270 | optional = false
271 | python-versions = ">=3.8"
272 | files = [
273 | {file = "mypy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12cce78e329838d70a204293e7b29af9faa3ab14899aec397798a4b41be7f340"},
274 | {file = "mypy-1.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1484b8fa2c10adf4474f016e09d7a159602f3239075c7bf9f1627f5acf40ad49"},
275 | {file = "mypy-1.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31902408f4bf54108bbfb2e35369877c01c95adc6192958684473658c322c8a5"},
276 | {file = "mypy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f2c2521a8e4d6d769e3234350ba7b65ff5d527137cdcde13ff4d99114b0c8e7d"},
277 | {file = "mypy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:fcd2572dd4519e8a6642b733cd3a8cfc1ef94bafd0c1ceed9c94fe736cb65b6a"},
278 | {file = "mypy-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b901927f16224d0d143b925ce9a4e6b3a758010673eeded9b748f250cf4e8f7"},
279 | {file = "mypy-1.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2f7f6985d05a4e3ce8255396df363046c28bea790e40617654e91ed580ca7c51"},
280 | {file = "mypy-1.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:944bdc21ebd620eafefc090cdf83158393ec2b1391578359776c00de00e8907a"},
281 | {file = "mypy-1.7.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9c7ac372232c928fff0645d85f273a726970c014749b924ce5710d7d89763a28"},
282 | {file = "mypy-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:f6efc9bd72258f89a3816e3a98c09d36f079c223aa345c659622f056b760ab42"},
283 | {file = "mypy-1.7.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6dbdec441c60699288adf051f51a5d512b0d818526d1dcfff5a41f8cd8b4aaf1"},
284 | {file = "mypy-1.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4fc3d14ee80cd22367caaaf6e014494415bf440980a3045bf5045b525680ac33"},
285 | {file = "mypy-1.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c6e4464ed5f01dc44dc9821caf67b60a4e5c3b04278286a85c067010653a0eb"},
286 | {file = "mypy-1.7.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:d9b338c19fa2412f76e17525c1b4f2c687a55b156320acb588df79f2e6fa9fea"},
287 | {file = "mypy-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:204e0d6de5fd2317394a4eff62065614c4892d5a4d1a7ee55b765d7a3d9e3f82"},
288 | {file = "mypy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:84860e06ba363d9c0eeabd45ac0fde4b903ad7aa4f93cd8b648385a888e23200"},
289 | {file = "mypy-1.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8c5091ebd294f7628eb25ea554852a52058ac81472c921150e3a61cdd68f75a7"},
290 | {file = "mypy-1.7.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40716d1f821b89838589e5b3106ebbc23636ffdef5abc31f7cd0266db936067e"},
291 | {file = "mypy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cf3f0c5ac72139797953bd50bc6c95ac13075e62dbfcc923571180bebb662e9"},
292 | {file = "mypy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:78e25b2fd6cbb55ddfb8058417df193f0129cad5f4ee75d1502248e588d9e0d7"},
293 | {file = "mypy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75c4d2a6effd015786c87774e04331b6da863fc3fc4e8adfc3b40aa55ab516fe"},
294 | {file = "mypy-1.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2643d145af5292ee956aa0a83c2ce1038a3bdb26e033dadeb2f7066fb0c9abce"},
295 | {file = "mypy-1.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75aa828610b67462ffe3057d4d8a4112105ed211596b750b53cbfe182f44777a"},
296 | {file = "mypy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ee5d62d28b854eb61889cde4e1dbc10fbaa5560cb39780c3995f6737f7e82120"},
297 | {file = "mypy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:72cf32ce7dd3562373f78bd751f73c96cfb441de147cc2448a92c1a308bd0ca6"},
298 | {file = "mypy-1.7.1-py3-none-any.whl", hash = "sha256:f7c5d642db47376a0cc130f0de6d055056e010debdaf0707cd2b0fc7e7ef30ea"},
299 | {file = "mypy-1.7.1.tar.gz", hash = "sha256:fcb6d9afb1b6208b4c712af0dafdc650f518836065df0d4fb1d800f5d6773db2"},
300 | ]
301 |
302 | [package.dependencies]
303 | mypy-extensions = ">=1.0.0"
304 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
305 | typing-extensions = ">=4.1.0"
306 |
307 | [package.extras]
308 | dmypy = ["psutil (>=4.0)"]
309 | install-types = ["pip"]
310 | mypyc = ["setuptools (>=50)"]
311 | reports = ["lxml"]
312 |
313 | [[package]]
314 | name = "mypy-extensions"
315 | version = "1.0.0"
316 | description = "Type system extensions for programs checked with the mypy type checker."
317 | category = "dev"
318 | optional = false
319 | python-versions = ">=3.5"
320 | files = [
321 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
322 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
323 | ]
324 |
325 | [[package]]
326 | name = "netmiko"
327 | version = "4.3.0"
328 | description = "Multi-vendor library to simplify legacy CLI connections to network devices"
329 | category = "main"
330 | optional = false
331 | python-versions = ">=3.8,<4.0"
332 | files = [
333 | {file = "netmiko-4.3.0-py3-none-any.whl", hash = "sha256:a873b186e0b61be4a2100eda51e996d917ceddce195b734346b686757e61d324"},
334 | {file = "netmiko-4.3.0.tar.gz", hash = "sha256:da90f6efdf33b4140eb6cd7f2272773c2ce144fa74ac34d5ecac1b4d4607f1fb"},
335 | ]
336 |
337 | [package.dependencies]
338 | ntc-templates = ">=2.0.0"
339 | paramiko = ">=2.9.5"
340 | pyserial = ">=3.3"
341 | pyyaml = ">=5.3"
342 | scp = ">=0.13.6"
343 | textfsm = ">=1.1.3"
344 |
345 | [[package]]
346 | name = "ntc-templates"
347 | version = "4.0.1"
348 | description = "TextFSM Templates for Network Devices, and Python wrapper for TextFSM's CliTable."
349 | category = "main"
350 | optional = false
351 | python-versions = ">=3.7,<4.0"
352 | files = [
353 | {file = "ntc_templates-4.0.1-py3-none-any.whl", hash = "sha256:4d20943fdffc70595fb2b983c6fcab926635c3e4621aaec13a9063a9a61241dd"},
354 | {file = "ntc_templates-4.0.1.tar.gz", hash = "sha256:5bd158592ac99e769a0b7e82e53fd714a410f912fc9e438e95cc0130cf7290a8"},
355 | ]
356 |
357 | [package.dependencies]
358 | textfsm = ">=1.1.0,<2.0.0"
359 |
360 | [[package]]
361 | name = "packaging"
362 | version = "23.2"
363 | description = "Core utilities for Python packages"
364 | category = "dev"
365 | optional = false
366 | python-versions = ">=3.7"
367 | files = [
368 | {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
369 | {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
370 | ]
371 |
372 | [[package]]
373 | name = "paramiko"
374 | version = "3.3.1"
375 | description = "SSH2 protocol library"
376 | category = "main"
377 | optional = false
378 | python-versions = ">=3.6"
379 | files = [
380 | {file = "paramiko-3.3.1-py3-none-any.whl", hash = "sha256:b7bc5340a43de4287bbe22fe6de728aa2c22468b2a849615498dd944c2f275eb"},
381 | {file = "paramiko-3.3.1.tar.gz", hash = "sha256:6a3777a961ac86dbef375c5f5b8d50014a1a96d0fd7f054a43bc880134b0ff77"},
382 | ]
383 |
384 | [package.dependencies]
385 | bcrypt = ">=3.2"
386 | cryptography = ">=3.3"
387 | pynacl = ">=1.5"
388 |
389 | [package.extras]
390 | all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"]
391 | gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"]
392 | invoke = ["invoke (>=2.0)"]
393 |
394 | [[package]]
395 | name = "pathspec"
396 | version = "0.11.2"
397 | description = "Utility library for gitignore style pattern matching of file paths."
398 | category = "dev"
399 | optional = false
400 | python-versions = ">=3.7"
401 | files = [
402 | {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"},
403 | {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"},
404 | ]
405 |
406 | [[package]]
407 | name = "platformdirs"
408 | version = "4.1.0"
409 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
410 | category = "dev"
411 | optional = false
412 | python-versions = ">=3.8"
413 | files = [
414 | {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"},
415 | {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"},
416 | ]
417 |
418 | [package.extras]
419 | docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
420 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
421 |
422 | [[package]]
423 | name = "pluggy"
424 | version = "1.3.0"
425 | description = "plugin and hook calling mechanisms for python"
426 | category = "dev"
427 | optional = false
428 | python-versions = ">=3.8"
429 | files = [
430 | {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
431 | {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
432 | ]
433 |
434 | [package.extras]
435 | dev = ["pre-commit", "tox"]
436 | testing = ["pytest", "pytest-benchmark"]
437 |
438 | [[package]]
439 | name = "pycodestyle"
440 | version = "2.11.1"
441 | description = "Python style guide checker"
442 | category = "dev"
443 | optional = false
444 | python-versions = ">=3.8"
445 | files = [
446 | {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
447 | {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
448 | ]
449 |
450 | [[package]]
451 | name = "pycparser"
452 | version = "2.21"
453 | description = "C parser in Python"
454 | category = "main"
455 | optional = false
456 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
457 | files = [
458 | {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
459 | {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
460 | ]
461 |
462 | [[package]]
463 | name = "pydocstyle"
464 | version = "6.3.0"
465 | description = "Python docstring style checker"
466 | category = "dev"
467 | optional = false
468 | python-versions = ">=3.6"
469 | files = [
470 | {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
471 | {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
472 | ]
473 |
474 | [package.dependencies]
475 | snowballstemmer = ">=2.2.0"
476 |
477 | [package.extras]
478 | toml = ["tomli (>=1.2.3)"]
479 |
480 | [[package]]
481 | name = "pyflakes"
482 | version = "3.1.0"
483 | description = "passive checker of Python programs"
484 | category = "dev"
485 | optional = false
486 | python-versions = ">=3.8"
487 | files = [
488 | {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"},
489 | {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
490 | ]
491 |
492 | [[package]]
493 | name = "pylama"
494 | version = "8.4.1"
495 | description = "Code audit tool for python"
496 | category = "dev"
497 | optional = false
498 | python-versions = ">=3.7"
499 | files = [
500 | {file = "pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60"},
501 | {file = "pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6"},
502 | ]
503 |
504 | [package.dependencies]
505 | mccabe = ">=0.7.0"
506 | pycodestyle = ">=2.9.1"
507 | pydocstyle = ">=6.1.1"
508 | pyflakes = ">=2.5.0"
509 |
510 | [package.extras]
511 | all = ["eradicate", "mypy", "pylint", "radon", "vulture"]
512 | eradicate = ["eradicate"]
513 | mypy = ["mypy"]
514 | pylint = ["pylint"]
515 | radon = ["radon"]
516 | tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "pytest (>=7.1.2)", "pytest-mypy", "radon (>=5.1.0)", "toml", "types-setuptools", "types-toml", "vulture"]
517 | toml = ["toml (>=0.10.2)"]
518 | vulture = ["vulture"]
519 |
520 | [[package]]
521 | name = "pynacl"
522 | version = "1.5.0"
523 | description = "Python binding to the Networking and Cryptography (NaCl) library"
524 | category = "main"
525 | optional = false
526 | python-versions = ">=3.6"
527 | files = [
528 | {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"},
529 | {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"},
530 | {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"},
531 | {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"},
532 | {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"},
533 | {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"},
534 | {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"},
535 | {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"},
536 | {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"},
537 | {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"},
538 | ]
539 |
540 | [package.dependencies]
541 | cffi = ">=1.4.1"
542 |
543 | [package.extras]
544 | docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"]
545 | tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"]
546 |
547 | [[package]]
548 | name = "pyserial"
549 | version = "3.5"
550 | description = "Python Serial Port Extension"
551 | category = "main"
552 | optional = false
553 | python-versions = "*"
554 | files = [
555 | {file = "pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0"},
556 | {file = "pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb"},
557 | ]
558 |
559 | [package.extras]
560 | cp2110 = ["hidapi"]
561 |
562 | [[package]]
563 | name = "pytest"
564 | version = "7.4.3"
565 | description = "pytest: simple powerful testing with Python"
566 | category = "dev"
567 | optional = false
568 | python-versions = ">=3.7"
569 | files = [
570 | {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"},
571 | {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"},
572 | ]
573 |
574 | [package.dependencies]
575 | colorama = {version = "*", markers = "sys_platform == \"win32\""}
576 | exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
577 | iniconfig = "*"
578 | packaging = "*"
579 | pluggy = ">=0.12,<2.0"
580 | tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
581 |
582 | [package.extras]
583 | testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
584 |
585 | [[package]]
586 | name = "pyyaml"
587 | version = "6.0.1"
588 | description = "YAML parser and emitter for Python"
589 | category = "main"
590 | optional = false
591 | python-versions = ">=3.6"
592 | files = [
593 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
594 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
595 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
596 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
597 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
598 | {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
599 | {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
600 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
601 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
602 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
603 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
604 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
605 | {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
606 | {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
607 | {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
608 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
609 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
610 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
611 | {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
612 | {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
613 | {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
614 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
615 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
616 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
617 | {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
618 | {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
619 | {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
620 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
621 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
622 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
623 | {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
624 | {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
625 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
626 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
627 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
628 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
629 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
630 | {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
631 | {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
632 | {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
633 | ]
634 |
635 | [[package]]
636 | name = "scp"
637 | version = "0.14.5"
638 | description = "scp module for paramiko"
639 | category = "main"
640 | optional = false
641 | python-versions = "*"
642 | files = [
643 | {file = "scp-0.14.5-py2.py3-none-any.whl", hash = "sha256:d224535dd8ed00294f52b0e0e18fde7a6fb7a3d06b97ede9e3f750fa7bf75c09"},
644 | {file = "scp-0.14.5.tar.gz", hash = "sha256:64f0015899b3d212cb8088e7d40ebaf0686889ff0e243d5c1242efe8b50f053e"},
645 | ]
646 |
647 | [package.dependencies]
648 | paramiko = "*"
649 |
650 | [[package]]
651 | name = "six"
652 | version = "1.16.0"
653 | description = "Python 2 and 3 compatibility utilities"
654 | category = "main"
655 | optional = false
656 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
657 | files = [
658 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
659 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
660 | ]
661 |
662 | [[package]]
663 | name = "snowballstemmer"
664 | version = "2.2.0"
665 | description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
666 | category = "dev"
667 | optional = false
668 | python-versions = "*"
669 | files = [
670 | {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
671 | {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
672 | ]
673 |
674 | [[package]]
675 | name = "textfsm"
676 | version = "1.1.3"
677 | description = "Python module for parsing semi-structured text into python tables."
678 | category = "main"
679 | optional = false
680 | python-versions = "*"
681 | files = [
682 | {file = "textfsm-1.1.3-py2.py3-none-any.whl", hash = "sha256:dcbeebc6a6137bed561c71a56344d752e6dbc04ae5ea309252cb70fb97ccc9cd"},
683 | {file = "textfsm-1.1.3.tar.gz", hash = "sha256:577ef278a9237f5341ae9b682947cefa4a2c1b24dbe486f94f2c95addc6504b5"},
684 | ]
685 |
686 | [package.dependencies]
687 | future = "*"
688 | six = "*"
689 |
690 | [[package]]
691 | name = "tomli"
692 | version = "2.0.1"
693 | description = "A lil' TOML parser"
694 | category = "dev"
695 | optional = false
696 | python-versions = ">=3.7"
697 | files = [
698 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
699 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
700 | ]
701 |
702 | [[package]]
703 | name = "typing-extensions"
704 | version = "4.8.0"
705 | description = "Backported and Experimental Type Hints for Python 3.8+"
706 | category = "dev"
707 | optional = false
708 | python-versions = ">=3.8"
709 | files = [
710 | {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
711 | {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
712 | ]
713 |
714 | [metadata]
715 | lock-version = "2.0"
716 | python-versions = "^3.8"
717 | content-hash = "01bb7499ad2a26dafea4a3c3edacf74cb5fbfb307fde81531d4e39456b305933"
718 |
--------------------------------------------------------------------------------