gns3fy is a Python wrapper library around the GNS3 Server REST API (v2). It provides programmatic interaction with GNS3 servers for network automation, CI/CD pipelines, and Ansible integration.
- Language: Python 3.9+
- GNS3 Compatibility: v2.2+
- Package Manager: uv
- Current Version: 0.7.2
gns3fy/ # Main source package
├── __init__.py # Exports: Gns3Connector, Project, Node, Link
├── gns3fy.py # Core implementation (~2200 lines)
└── drawing_utils.py # SVG drawing helper functions
tests/
├── test_gns3fy.py # Main tests (~1600 lines)
├── test_drawing_utils.py # Drawing utility tests
└── data/ # JSON fixtures and mock data modules
docs/content/ # MkDocs documentation source
.github/workflows/tests.yml # CI pipeline
# Install dependencies
uv sync --group dev
# Run full test suite (lint + format check + tests)
task test
# Individual commands
task lint # Lint + format check
task test-only # Tests without linting
task test-ci # Tests with XML coverage output
# Documentation
task docs-generate # Generate API reference from docstrings
task docs-show # Serve docs locallyAll core classes live in gns3fy/gns3fy.py:
Gns3Connector— REST API client with HTTP session management, auth, and methods for all GNS3 resourcesProject— Pydantic dataclass for GNS3 projects; supports CRUD, nodes/links/drawings managementNode— Pydantic dataclass for network nodes; supports start/stop/suspend/reloadLink— Pydantic dataclass for network links between nodesConfig— Internal Pydantic config:validate_assignment=True,extra="ignore"
Helper decorator verify_connector_and_id() validates that a connector and required IDs are set before API operations.
Constants: NODE_TYPES (14 types), CONSOLE_TYPES (8 types), LINK_TYPES (2 types).
- Formatter/Linter: Ruff (enforced in CI) — line length 120, selects E/F/W rules
- Type Hints: Use
typingmodule (Optional,Any,Dict,List) - Data Models: Pydantic dataclasses with
@dataclass(config=Config) - Docstrings: Markdown-formatted with embedded usage examples
- Naming: PascalCase for classes, UPPER_SNAKE_CASE for constants, snake_case for functions/methods
- Private methods: Single underscore prefix (
_create_session)
- Framework: pytest with class-based test structure
- Mocking:
requests-mockadapter with custom mock classes:Gns3ConnectorMock— base mockGns3ConnectorMockStopped— stopped node variantGns3ConnectorMockSuspended— suspended node variant
- Fixtures: JSON files in
tests/data/(nodes.json, links.json, projects.json, templates.json, etc.) - Custom matcher:
post_put_matcher()for dynamic POST/PUT response handling - Coverage: pytest-cov with Codecov integration
Test classes follow the pattern TestGns3Connector, TestLink, TestNode, TestProject.
GitHub Actions (.github/workflows/tests.yml):
- Triggers on push and pull_request
- Matrix: Python 3.9, 3.10, 3.11, 3.12
- Steps: setup uv → install Task → install deps →
task lint→task test-only→task test-ci→ Codecov upload
Runtime: requests >=2.22, pydantic >=1.0,<2
Dev: pytest >=7.0, requests-mock >=1.6, pytest-cov >=4.0, coverage >=7.0, ruff >=0.9
Docs: mkdocs >=1.0, mkdocs-material >=6.1.0, pydoc-markdown
- Always run
task test(or the individual lint/format/test commands) before committing - The library uses Pydantic v1 (
pydantic >=1.0,<2) — do not use Pydantic v2 APIs - HTTP mocking in tests registers endpoints for GET/POST/PUT/DELETE across projects, nodes, links, templates, computes, snapshots, and drawings
- Documentation is auto-generated from docstrings via
pydoc-markdown— keep docstrings up to date when modifying public APIs