secure-cartography


Namesecure-cartography JSON
Version 0.9.3 PyPI version JSON
download
home_pagehttps://github.com/scottpeterman/secure_cartography
SummaryA secure, Python-based network discovery and mapping tool using SSH-based device interrogation
upload_time2025-01-28 00:34:14
maintainerNone
docs_urlNone
authorScott Peterman
requires_python>=3.9
licenseNone
keywords
VCS
bugtrack_url
requirements backports.tarfile bcrypt blinker certifi cffi charset-normalizer click colorama contourpy cryptography cycler docutils et_xmlfile Flask fonttools func_timeout future idna igraph importlib_metadata importlib_resources itsdangerous jaraco.classes jaraco.context jaraco.functools Jinja2 junos-eznc keyring kiwisolver lxml markdown-it-py MarkupSafe matplotlib mdurl more-itertools n2g napalm napalm-procurve ncclient netaddr netmiko netutils networkx nh3 ntc_templates numpy openpyxl packaging paramiko pillow pkginfo pycparser pyeapi Pygments PyNaCl pynxos pyparsing PyQt6 PyQt6-Qt6 PyQt6-WebEngine PyQt6-WebEngine-Qt6 PyQt6_sip pyserial python-dateutil python-igraph pywin32-ctypes PyYAML readme_renderer requests requests-toolbelt rfc3986 rich ruamel.yaml ruamel.yaml.clib scp six textfsm texttable transitions ttp ttp-templates typing_extensions urllib3 Werkzeug yamlordereddictloader zipp
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Secure Cartography

Secure Cartography is a secure, Python-based network discovery and mapping tool designed for network engineers and IT professionals. It leverages SSH-based device interrogation to automate network discovery, visualize network topologies, and merge network maps across multi-vendor environments.

![Main Application](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/ng/future.gif)

## Version 0.9.2 Highlights

- **Major Performance Improvements**: 10x faster device discovery and processing
- **Enhanced Visualization**: 
  - Customizable device icons for both Draw.io and GraphML exports
  - Interactive icon mapping editor for personalizing device representations
  - Professional-grade network diagrams with vendor-specific shapes
  - Improved layout algorithms for cleaner topology visualization
- **Advanced Map Generation**:
  - Accurate CDP/LLDP neighbor detection and mapping
  - Intelligent interface mapping and labeling
  - Support for complex network hierarchies
  - Enhanced device platform detection
- **UI Improvements**: 
  - Quick-access buttons for browsing output folders and files
  - Modernized topology merge dialog with interactive preview
  - Enhanced dark/light mode support
  - Icon configuration interface for customizing device representations
- **CLI for automated mapping**:
  - CLI args, yaml conf, and env vars for secrets
  - Automated map generation with custom icon support
  - See Appendix for detailed CLI usage
  
## Quick Start Guide

1. **Network Discovery and Mapping**
   ```bash
   python -m secure_cartography.scart
   ```

2. **Topology Merge Tool**
   ```bash
   python -m secure_cartography.merge_dialog
   ```

## Key Features
- New improved native map viewer
- Find and Highlight Node on map
- ![Main Application](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/viewer_slides.gif)

### Network Discovery
- Multi-threaded SSH-based device discovery with optimized queue management
- Support for multiple vendor platforms:
  - Cisco IOS
  - Cisco NX-OS
  - Arista EOS
  - Aruba/HP ProCurve (non-CX)
- Improved device tracking and neighbor discovery
- Real-time progress monitoring with enhanced logging
- Smart platform detection and validation
- Configurable exclusion patterns (e.g., `othersite-,sep` to exclude specific sites and IP phones)

### Visualization
- Interactive topology viewer with Mermaid diagrams
- Dark/Light mode theme support
- Multiple export formats:
  - SVG for high-quality graphics
  - GraphML for yEd integration
  - Draw.io compatible format
- Multiple layout algorithms:
  - Kamada-Kawai (KK) for general topologies
  - Circular layout for ring networks
  - Multipartite for layered networks

### Security
- Master password-based encryption system
- Machine-specific keyring integration
 - PBKDF2-based key derivation
- Encrypted credential storage

### Map Merging
- Interactive topology preview
- Intelligent topology merging with connection deduplication
- Comprehensive merge logging
- Multiple file support

## Installation

### From PyPI
```bash
pip install secure-cartography
```

### From GitHub
```bash
git clone https://github.com/scottpeterman/secure_cartography.git
cd secure_cartography
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -r requirements.txt
```

### Running the Application
```bash
# Run as installed package
scart
merge-dialog

# Or run as module for additional console output
python -m secure_cartography.scart
python -m secure_cartography.merge_dialog
```

## System Requirements
- Python 3.9+
- PyQt6
- NetworkX
- N2G
- Matplotlib
- Cryptography
- PyYAML
- Paramiko

## System Compatibility

### Tested Environments
- Windows 10 & 11
- Ubuntu 24.04
- Mac OSX (latest as of 12-20-24)
- Python versions 3.9 and 3.12

### Known Issues
- Python 3.13: Compatibility issues with Napalm library

## External Tool Integration

### yEd GraphML (.graphml)
![yEd Example](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/ng/new_maps.png)
- Multiple automatic layout algorithms
- Advanced grouping capabilities
- Neighborhood analysis
- High-quality vector export

### draw.io (.drawio)
![draw.io Example](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/ng/drawio.png)
- Collaborative diagram editing
- Web-based access
- Multiple export formats
- Custom stencils and shapes

## Version History

### 0.7.0 (Current)
- 10x performance improvement in device discovery
- Added Aruba/HP ProCurve switch support
- New interactive Mermaid-based topology viewer
- Enhanced logging with configurable levels
- Improved UI with quick-access file management
- Better error handling and recovery

### 0.2.0
- Initial ProCurve support
- Improved device discovery reliability
- Enhanced neighbor discovery
- Added debug logging
- Improved topology mapping
- Better platform detection

## Technology Stack

### Core Technologies
- Python 3.9+
- PyQt6 for GUI
- NetworkX for graph processing
- Matplotlib for visualization
- Cryptography.io for security

### Security Components
- PBKDF2 key derivation
- Fernet encryption
- System keyring integration
- Platform-specific secure storage

### Network Interaction
- Paramiko/SSH2 for device communication
- TextFSM for output parsing
- Custom platform detection
- Enhanced interface normalization

### Data Storage
- JSON for topology data
- YAML for configuration
- SVG for visualizations
- Encrypted credential storage

## Security Architecture

### Credential Protection
1. **Master Password System**
   - PBKDF2-derived key generation
   - Machine-specific salt
   - Secure system keyring integration

2. **Storage Security**
   - Fernet encryption for credentials
   - No plaintext password storage
   - Platform-specific secure storage locations

3. **Runtime Security**
   - Memory-safe credential handling
   - Secure credential cleanup
   - Protected GUI input fields

## Appendix A: CLI Usage

Secure Cartography includes a CLI tool for automation and scripting. The tool can be run as either an installed package or module:

```bash
# Run as installed package
sc --help

# Run as module
python -m secure_cartography.sc --help
```

### Configuration Options

#### YAML Configuration
Create a YAML file with your settings:
```yaml
seed_ip: 172.16.101.1
max_devices: 500
output_dir: "./cli/home"
#username: admin   --- can be here, but its clear text! Please use the environment variable option
#password: pw
verbose: true
map_name: home_network
layout: "rt"  # Optional, defaults to kk
domain: ''    # Optional
exclude: ''   # Optional
timeout: 60   # Optional
```

#### Environment Variables
Set credentials using environment variables:
- `SC_USERNAME`: Primary device username
- `SC_PASSWORD`: Primary device password
- `SC_ALT_USERNAME`: Alternate device username (optional)
- `SC_ALT_PASSWORD`: Alternate device password (optional)

```bash
# Windows
set SC_USERNAME=admin
set SC_PASSWORD=mypass

# Linux/Mac
export SC_USERNAME=admin
export SC_PASSWORD=mypass
```

#### CLI Arguments
```bash
sc --yaml config.yaml --seed-ip 192.168.1.1 --verbose
```

Full argument list:
- `--yaml`: Path to YAML config file
- `--seed-ip`: Starting IP address
- `--username`: Device username
- `--password`: Device password
- `--alt-username`: Alternate username
- `--alt-password`: Alternate password
- `--domain`: Domain name
- `--exclude`: Comma-separated exclude patterns
- `--output-dir`: Output directory path
- `--timeout`: Connection timeout (seconds)
- `--max-devices`: Maximum devices to discover
- `--map-name`: Output map name
- `--layout`: Graph layout algorithm
- `--verbose`: Enable debug logging

### Example Usage

Basic discovery with YAML config:
```bash
sc --yaml network_config.yaml --verbose
```

Full CLI configuration:
```bash
sc --seed-ip 192.168.1.1 --username admin --password secret \
   --output-dir ./maps --max-devices 50 --timeout 60 \
   --map-name office_network --layout kk --verbose
```

Using environment variables:
```bash
export SC_USERNAME=admin
export SC_PASSWORD=secret
sc --yaml config.yaml
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/scottpeterman/secure_cartography",
    "name": "secure-cartography",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": "Scott Peterman",
    "author_email": "scottpeterman@gmail.com",
    "download_url": null,
    "platform": null,
    "description": "# Secure Cartography\r\n\r\nSecure Cartography is a secure, Python-based network discovery and mapping tool designed for network engineers and IT professionals. It leverages SSH-based device interrogation to automate network discovery, visualize network topologies, and merge network maps across multi-vendor environments.\r\n\r\n![Main Application](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/ng/future.gif)\r\n\r\n## Version 0.9.2 Highlights\r\n\r\n- **Major Performance Improvements**: 10x faster device discovery and processing\r\n- **Enhanced Visualization**: \r\n  - Customizable device icons for both Draw.io and GraphML exports\r\n  - Interactive icon mapping editor for personalizing device representations\r\n  - Professional-grade network diagrams with vendor-specific shapes\r\n  - Improved layout algorithms for cleaner topology visualization\r\n- **Advanced Map Generation**:\r\n  - Accurate CDP/LLDP neighbor detection and mapping\r\n  - Intelligent interface mapping and labeling\r\n  - Support for complex network hierarchies\r\n  - Enhanced device platform detection\r\n- **UI Improvements**: \r\n  - Quick-access buttons for browsing output folders and files\r\n  - Modernized topology merge dialog with interactive preview\r\n  - Enhanced dark/light mode support\r\n  - Icon configuration interface for customizing device representations\r\n- **CLI for automated mapping**:\r\n  - CLI args, yaml conf, and env vars for secrets\r\n  - Automated map generation with custom icon support\r\n  - See Appendix for detailed CLI usage\r\n  \r\n## Quick Start Guide\r\n\r\n1. **Network Discovery and Mapping**\r\n   ```bash\r\n   python -m secure_cartography.scart\r\n   ```\r\n\r\n2. **Topology Merge Tool**\r\n   ```bash\r\n   python -m secure_cartography.merge_dialog\r\n   ```\r\n\r\n## Key Features\r\n- New improved native map viewer\r\n- Find and Highlight Node on map\r\n- ![Main Application](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/viewer_slides.gif)\r\n\r\n### Network Discovery\r\n- Multi-threaded SSH-based device discovery with optimized queue management\r\n- Support for multiple vendor platforms:\r\n  - Cisco IOS\r\n  - Cisco NX-OS\r\n  - Arista EOS\r\n  - Aruba/HP ProCurve (non-CX)\r\n- Improved device tracking and neighbor discovery\r\n- Real-time progress monitoring with enhanced logging\r\n- Smart platform detection and validation\r\n- Configurable exclusion patterns (e.g., `othersite-,sep` to exclude specific sites and IP phones)\r\n\r\n### Visualization\r\n- Interactive topology viewer with Mermaid diagrams\r\n- Dark/Light mode theme support\r\n- Multiple export formats:\r\n  - SVG for high-quality graphics\r\n  - GraphML for yEd integration\r\n  - Draw.io compatible format\r\n- Multiple layout algorithms:\r\n  - Kamada-Kawai (KK) for general topologies\r\n  - Circular layout for ring networks\r\n  - Multipartite for layered networks\r\n\r\n### Security\r\n- Master password-based encryption system\r\n- Machine-specific keyring integration\r\n - PBKDF2-based key derivation\r\n- Encrypted credential storage\r\n\r\n### Map Merging\r\n- Interactive topology preview\r\n- Intelligent topology merging with connection deduplication\r\n- Comprehensive merge logging\r\n- Multiple file support\r\n\r\n## Installation\r\n\r\n### From PyPI\r\n```bash\r\npip install secure-cartography\r\n```\r\n\r\n### From GitHub\r\n```bash\r\ngit clone https://github.com/scottpeterman/secure_cartography.git\r\ncd secure_cartography\r\npython -m venv .venv\r\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\r\npip install -r requirements.txt\r\n```\r\n\r\n### Running the Application\r\n```bash\r\n# Run as installed package\r\nscart\r\nmerge-dialog\r\n\r\n# Or run as module for additional console output\r\npython -m secure_cartography.scart\r\npython -m secure_cartography.merge_dialog\r\n```\r\n\r\n## System Requirements\r\n- Python 3.9+\r\n- PyQt6\r\n- NetworkX\r\n- N2G\r\n- Matplotlib\r\n- Cryptography\r\n- PyYAML\r\n- Paramiko\r\n\r\n## System Compatibility\r\n\r\n### Tested Environments\r\n- Windows 10 & 11\r\n- Ubuntu 24.04\r\n- Mac OSX (latest as of 12-20-24)\r\n- Python versions 3.9 and 3.12\r\n\r\n### Known Issues\r\n- Python 3.13: Compatibility issues with Napalm library\r\n\r\n## External Tool Integration\r\n\r\n### yEd GraphML (.graphml)\r\n![yEd Example](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/ng/new_maps.png)\r\n- Multiple automatic layout algorithms\r\n- Advanced grouping capabilities\r\n- Neighborhood analysis\r\n- High-quality vector export\r\n\r\n### draw.io (.drawio)\r\n![draw.io Example](https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/ng/drawio.png)\r\n- Collaborative diagram editing\r\n- Web-based access\r\n- Multiple export formats\r\n- Custom stencils and shapes\r\n\r\n## Version History\r\n\r\n### 0.7.0 (Current)\r\n- 10x performance improvement in device discovery\r\n- Added Aruba/HP ProCurve switch support\r\n- New interactive Mermaid-based topology viewer\r\n- Enhanced logging with configurable levels\r\n- Improved UI with quick-access file management\r\n- Better error handling and recovery\r\n\r\n### 0.2.0\r\n- Initial ProCurve support\r\n- Improved device discovery reliability\r\n- Enhanced neighbor discovery\r\n- Added debug logging\r\n- Improved topology mapping\r\n- Better platform detection\r\n\r\n## Technology Stack\r\n\r\n### Core Technologies\r\n- Python 3.9+\r\n- PyQt6 for GUI\r\n- NetworkX for graph processing\r\n- Matplotlib for visualization\r\n- Cryptography.io for security\r\n\r\n### Security Components\r\n- PBKDF2 key derivation\r\n- Fernet encryption\r\n- System keyring integration\r\n- Platform-specific secure storage\r\n\r\n### Network Interaction\r\n- Paramiko/SSH2 for device communication\r\n- TextFSM for output parsing\r\n- Custom platform detection\r\n- Enhanced interface normalization\r\n\r\n### Data Storage\r\n- JSON for topology data\r\n- YAML for configuration\r\n- SVG for visualizations\r\n- Encrypted credential storage\r\n\r\n## Security Architecture\r\n\r\n### Credential Protection\r\n1. **Master Password System**\r\n   - PBKDF2-derived key generation\r\n   - Machine-specific salt\r\n   - Secure system keyring integration\r\n\r\n2. **Storage Security**\r\n   - Fernet encryption for credentials\r\n   - No plaintext password storage\r\n   - Platform-specific secure storage locations\r\n\r\n3. **Runtime Security**\r\n   - Memory-safe credential handling\r\n   - Secure credential cleanup\r\n   - Protected GUI input fields\r\n\r\n## Appendix A: CLI Usage\r\n\r\nSecure Cartography includes a CLI tool for automation and scripting. The tool can be run as either an installed package or module:\r\n\r\n```bash\r\n# Run as installed package\r\nsc --help\r\n\r\n# Run as module\r\npython -m secure_cartography.sc --help\r\n```\r\n\r\n### Configuration Options\r\n\r\n#### YAML Configuration\r\nCreate a YAML file with your settings:\r\n```yaml\r\nseed_ip: 172.16.101.1\r\nmax_devices: 500\r\noutput_dir: \"./cli/home\"\r\n#username: admin   --- can be here, but its clear text! Please use the environment variable option\r\n#password: pw\r\nverbose: true\r\nmap_name: home_network\r\nlayout: \"rt\"  # Optional, defaults to kk\r\ndomain: ''    # Optional\r\nexclude: ''   # Optional\r\ntimeout: 60   # Optional\r\n```\r\n\r\n#### Environment Variables\r\nSet credentials using environment variables:\r\n- `SC_USERNAME`: Primary device username\r\n- `SC_PASSWORD`: Primary device password\r\n- `SC_ALT_USERNAME`: Alternate device username (optional)\r\n- `SC_ALT_PASSWORD`: Alternate device password (optional)\r\n\r\n```bash\r\n# Windows\r\nset SC_USERNAME=admin\r\nset SC_PASSWORD=mypass\r\n\r\n# Linux/Mac\r\nexport SC_USERNAME=admin\r\nexport SC_PASSWORD=mypass\r\n```\r\n\r\n#### CLI Arguments\r\n```bash\r\nsc --yaml config.yaml --seed-ip 192.168.1.1 --verbose\r\n```\r\n\r\nFull argument list:\r\n- `--yaml`: Path to YAML config file\r\n- `--seed-ip`: Starting IP address\r\n- `--username`: Device username\r\n- `--password`: Device password\r\n- `--alt-username`: Alternate username\r\n- `--alt-password`: Alternate password\r\n- `--domain`: Domain name\r\n- `--exclude`: Comma-separated exclude patterns\r\n- `--output-dir`: Output directory path\r\n- `--timeout`: Connection timeout (seconds)\r\n- `--max-devices`: Maximum devices to discover\r\n- `--map-name`: Output map name\r\n- `--layout`: Graph layout algorithm\r\n- `--verbose`: Enable debug logging\r\n\r\n### Example Usage\r\n\r\nBasic discovery with YAML config:\r\n```bash\r\nsc --yaml network_config.yaml --verbose\r\n```\r\n\r\nFull CLI configuration:\r\n```bash\r\nsc --seed-ip 192.168.1.1 --username admin --password secret \\\r\n   --output-dir ./maps --max-devices 50 --timeout 60 \\\r\n   --map-name office_network --layout kk --verbose\r\n```\r\n\r\nUsing environment variables:\r\n```bash\r\nexport SC_USERNAME=admin\r\nexport SC_PASSWORD=secret\r\nsc --yaml config.yaml\r\n```\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A secure, Python-based network discovery and mapping tool using SSH-based device interrogation",
    "version": "0.9.3",
    "project_urls": {
        "Homepage": "https://github.com/scottpeterman/secure_cartography"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1923a6f2fe7ab6db9e39c7d2084efe358dc26442b4dfae6fa958a7c897f5ad8c",
                "md5": "6a2cd7373b67ef7585945a605cf41b67",
                "sha256": "ca8b28251db49e49209d72084859d7fa4a5c2a9937d7964506b4ec90bc734217"
            },
            "downloads": -1,
            "filename": "secure_cartography-0.9.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6a2cd7373b67ef7585945a605cf41b67",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 18800768,
            "upload_time": "2025-01-28T00:34:14",
            "upload_time_iso_8601": "2025-01-28T00:34:14.224770Z",
            "url": "https://files.pythonhosted.org/packages/19/23/a6f2fe7ab6db9e39c7d2084efe358dc26442b4dfae6fa958a7c897f5ad8c/secure_cartography-0.9.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-28 00:34:14",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "scottpeterman",
    "github_project": "secure_cartography",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "backports.tarfile",
            "specs": [
                [
                    ">=",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "bcrypt",
            "specs": [
                [
                    ">=",
                    "4.2.1"
                ]
            ]
        },
        {
            "name": "blinker",
            "specs": [
                [
                    ">=",
                    "1.9.0"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    ">=",
                    "2024.12.14"
                ]
            ]
        },
        {
            "name": "cffi",
            "specs": [
                [
                    ">=",
                    "1.17.1"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    ">=",
                    "3.4.0"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    ">=",
                    "8.1.8"
                ]
            ]
        },
        {
            "name": "colorama",
            "specs": [
                [
                    ">=",
                    "0.4.6"
                ]
            ]
        },
        {
            "name": "contourpy",
            "specs": [
                [
                    ">=",
                    "1.3.0"
                ]
            ]
        },
        {
            "name": "cryptography",
            "specs": [
                [
                    ">=",
                    "44.0.0"
                ]
            ]
        },
        {
            "name": "cycler",
            "specs": [
                [
                    ">=",
                    "0.12.1"
                ]
            ]
        },
        {
            "name": "docutils",
            "specs": [
                [
                    ">=",
                    "0.21.2"
                ]
            ]
        },
        {
            "name": "et_xmlfile",
            "specs": [
                [
                    ">=",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "Flask",
            "specs": [
                [
                    ">=",
                    "3.1.0"
                ]
            ]
        },
        {
            "name": "fonttools",
            "specs": [
                [
                    ">=",
                    "4.55.3"
                ]
            ]
        },
        {
            "name": "func_timeout",
            "specs": [
                [
                    ">=",
                    "4.3.5"
                ]
            ]
        },
        {
            "name": "future",
            "specs": [
                [
                    ">=",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    ">=",
                    "3.10"
                ]
            ]
        },
        {
            "name": "igraph",
            "specs": [
                [
                    ">=",
                    "0.11.8"
                ]
            ]
        },
        {
            "name": "importlib_metadata",
            "specs": [
                [
                    ">=",
                    "8.5.0"
                ]
            ]
        },
        {
            "name": "importlib_resources",
            "specs": [
                [
                    ">=",
                    "6.4.5"
                ]
            ]
        },
        {
            "name": "itsdangerous",
            "specs": [
                [
                    ">=",
                    "2.2.0"
                ]
            ]
        },
        {
            "name": "jaraco.classes",
            "specs": [
                [
                    ">=",
                    "3.4.0"
                ]
            ]
        },
        {
            "name": "jaraco.context",
            "specs": [
                [
                    ">=",
                    "6.0.1"
                ]
            ]
        },
        {
            "name": "jaraco.functools",
            "specs": [
                [
                    ">=",
                    "4.1.0"
                ]
            ]
        },
        {
            "name": "Jinja2",
            "specs": [
                [
                    ">=",
                    "3.1.5"
                ]
            ]
        },
        {
            "name": "junos-eznc",
            "specs": [
                [
                    ">=",
                    "2.7.2"
                ]
            ]
        },
        {
            "name": "keyring",
            "specs": [
                [
                    ">=",
                    "25.5.0"
                ]
            ]
        },
        {
            "name": "kiwisolver",
            "specs": [
                [
                    ">=",
                    "1.4.7"
                ]
            ]
        },
        {
            "name": "lxml",
            "specs": [
                [
                    ">=",
                    "5.3.0"
                ]
            ]
        },
        {
            "name": "markdown-it-py",
            "specs": [
                [
                    ">=",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "MarkupSafe",
            "specs": [
                [
                    ">=",
                    "3.0.2"
                ]
            ]
        },
        {
            "name": "matplotlib",
            "specs": [
                [
                    ">=",
                    "3.9.4"
                ]
            ]
        },
        {
            "name": "mdurl",
            "specs": [
                [
                    ">=",
                    "0.1.2"
                ]
            ]
        },
        {
            "name": "more-itertools",
            "specs": [
                [
                    ">=",
                    "10.5.0"
                ]
            ]
        },
        {
            "name": "n2g",
            "specs": [
                [
                    ">=",
                    "0.3.3"
                ]
            ]
        },
        {
            "name": "napalm",
            "specs": [
                [
                    ">=",
                    "5.0.0"
                ]
            ]
        },
        {
            "name": "napalm-procurve",
            "specs": [
                [
                    ">=",
                    "0.6.0"
                ]
            ]
        },
        {
            "name": "ncclient",
            "specs": [
                [
                    ">=",
                    "0.6.15"
                ]
            ]
        },
        {
            "name": "netaddr",
            "specs": [
                [
                    ">=",
                    "1.3.0"
                ]
            ]
        },
        {
            "name": "netmiko",
            "specs": [
                [
                    ">=",
                    "4.5.0"
                ]
            ]
        },
        {
            "name": "netutils",
            "specs": [
                [
                    ">=",
                    "1.10.0"
                ]
            ]
        },
        {
            "name": "networkx",
            "specs": [
                [
                    ">=",
                    "3.2.1"
                ]
            ]
        },
        {
            "name": "nh3",
            "specs": [
                [
                    ">=",
                    "0.2.20"
                ]
            ]
        },
        {
            "name": "ntc_templates",
            "specs": [
                [
                    ">=",
                    "7.5.0"
                ]
            ]
        },
        {
            "name": "numpy",
            "specs": [
                [
                    ">=",
                    "2.0.2"
                ]
            ]
        },
        {
            "name": "openpyxl",
            "specs": [
                [
                    ">=",
                    "3.1.5"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    ">=",
                    "24.2"
                ]
            ]
        },
        {
            "name": "paramiko",
            "specs": [
                [
                    ">=",
                    "3.5.0"
                ]
            ]
        },
        {
            "name": "pillow",
            "specs": [
                [
                    ">=",
                    "11.0.0"
                ]
            ]
        },
        {
            "name": "pkginfo",
            "specs": [
                [
                    ">=",
                    "1.12.0"
                ]
            ]
        },
        {
            "name": "pycparser",
            "specs": [
                [
                    ">=",
                    "2.22"
                ]
            ]
        },
        {
            "name": "pyeapi",
            "specs": [
                [
                    ">=",
                    "1.0.4"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    ">=",
                    "2.18.0"
                ]
            ]
        },
        {
            "name": "PyNaCl",
            "specs": [
                [
                    ">=",
                    "1.5.0"
                ]
            ]
        },
        {
            "name": "pynxos",
            "specs": [
                [
                    ">=",
                    "0.0.5"
                ]
            ]
        },
        {
            "name": "pyparsing",
            "specs": [
                [
                    ">=",
                    "3.2.0"
                ]
            ]
        },
        {
            "name": "PyQt6",
            "specs": [
                [
                    ">=",
                    "6.8.0"
                ]
            ]
        },
        {
            "name": "PyQt6-Qt6",
            "specs": [
                [
                    ">=",
                    "6.8.1"
                ]
            ]
        },
        {
            "name": "PyQt6-WebEngine",
            "specs": [
                [
                    ">=",
                    "6.8.0"
                ]
            ]
        },
        {
            "name": "PyQt6-WebEngine-Qt6",
            "specs": [
                [
                    ">=",
                    "6.8.1"
                ]
            ]
        },
        {
            "name": "PyQt6_sip",
            "specs": [
                [
                    ">=",
                    "13.9.1"
                ]
            ]
        },
        {
            "name": "pyserial",
            "specs": [
                [
                    ">=",
                    "3.5"
                ]
            ]
        },
        {
            "name": "python-dateutil",
            "specs": [
                [
                    ">=",
                    "2.9.0.post0"
                ]
            ]
        },
        {
            "name": "python-igraph",
            "specs": [
                [
                    ">=",
                    "0.11.8"
                ]
            ]
        },
        {
            "name": "pywin32-ctypes",
            "specs": [
                [
                    ">=",
                    "0.2.3"
                ]
            ]
        },
        {
            "name": "PyYAML",
            "specs": [
                [
                    ">=",
                    "6.0.2"
                ]
            ]
        },
        {
            "name": "readme_renderer",
            "specs": [
                [
                    ">=",
                    "44.0"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    ">=",
                    "2.32.3"
                ]
            ]
        },
        {
            "name": "requests-toolbelt",
            "specs": [
                [
                    ">=",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "rfc3986",
            "specs": [
                [
                    ">=",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    ">=",
                    "13.9.4"
                ]
            ]
        },
        {
            "name": "ruamel.yaml",
            "specs": [
                [
                    ">=",
                    "0.18.6"
                ]
            ]
        },
        {
            "name": "ruamel.yaml.clib",
            "specs": [
                [
                    ">=",
                    "0.2.12"
                ]
            ]
        },
        {
            "name": "scp",
            "specs": [
                [
                    ">=",
                    "0.15.0"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    ">=",
                    "1.17.0"
                ]
            ]
        },
        {
            "name": "textfsm",
            "specs": [
                [
                    ">=",
                    "1.1.3"
                ]
            ]
        },
        {
            "name": "texttable",
            "specs": [
                [
                    ">=",
                    "1.7.0"
                ]
            ]
        },
        {
            "name": "transitions",
            "specs": [
                [
                    ">=",
                    "0.9.2"
                ]
            ]
        },
        {
            "name": "ttp",
            "specs": [
                [
                    ">=",
                    "0.9.5"
                ]
            ]
        },
        {
            "name": "ttp-templates",
            "specs": [
                [
                    ">=",
                    "0.3.7"
                ]
            ]
        },
        {
            "name": "typing_extensions",
            "specs": [
                [
                    ">=",
                    "4.12.2"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    ">=",
                    "2.3.0"
                ]
            ]
        },
        {
            "name": "Werkzeug",
            "specs": [
                [
                    ">=",
                    "3.1.3"
                ]
            ]
        },
        {
            "name": "yamlordereddictloader",
            "specs": [
                [
                    ">=",
                    "0.4.2"
                ]
            ]
        },
        {
            "name": "zipp",
            "specs": [
                [
                    ">=",
                    "3.21.0"
                ]
            ]
        }
    ],
    "lcname": "secure-cartography"
}
        
Elapsed time: 0.60199s