Skip to main content

Network Documentation Platform - SDK

Project description

NetDoc SDK

Python Version PyPI version License

Async Python SDK for the NetDoc /api/v1 API. Provides a modern, type-safe interface for building network discoveries, managing inventory, and querying topology data.

Table of Contents

Installation

Via pip (PyPI)

pip install netdoc-sdk

Development version

git clone https://github.com/netdoclab/netdoc-sdk.git
cd netdoc-sdk
pip install -e .

Quick Start

Basic usage with async context manager:

import asyncio
from netdoc_sdk import NetDocClient

async def main():
    # Create client and connect
    async with NetDocClient("https://netdoc.example.com", token="your-api-token") as client:
        # List snapshots
        snapshots = await client.snapshots_list()
        print(f"Found {len(snapshots)} snapshots")

        # Get a specific snapshot
        snapshot = await client.snapshots_retrieve(id="snapshot-1")
        print(f"Snapshot: {snapshot.label}")

asyncio.run(main())

Creating Network Topology

Build and submit network snapshots using the fluent builder API:

import asyncio
from netdoc_sdk import NetDocClient, DeviceBuilder, SnapshotBuilder

async def main():
    async with NetDocClient("https://netdoc.example.com", token="your-api-token") as client:
        # Build topology
        snapshot = (
            SnapshotBuilder(label="nightly", description="Nightly collection")
            .add_device(
                DeviceBuilder("switch-01", snapshot="snapshot-id")
                .vendor("cisco")
                .platform("ios-xe")
                .software_version("17.9")
                .add_vlan(10, "Users")
                .add_interface("GigabitEthernet1/0/1", switchport_mode="trunk")
                .add_ip_address("Vlan10", "10.0.10.1/24", is_primary=True)
                .add_route("0.0.0.0/0", next_hop="10.0.10.254", protocol="static")
                .build()
            )
            .add_link("switch-01", "GigabitEthernet1/0/1", "switch-02", "GigabitEthernet1/0/1")
            .build()
        )

        # Submit to server
        result = await client.snapshots_create(snapshot)
        print(f"Created snapshot: {result.id}")

asyncio.run(main())

Querying Network Data

async with NetDocClient(base_url, token=token) as client:
    # List all devices in a snapshot
    devices = await client.devices_list(snapshot="snapshot-id", page_size=50)

    # Get topology graph
    topology = await client.get_topology_graph(
        snapshot="snapshot-id",
        include_endpoints=True
    )

    # Query specific device
    device = await client.devices_retrieve(id="device-1")
    interfaces = await client.devices_interfaces_list(device=device.id)

    # Fetch L2 topology
    vlans = await client.vlan_list(snapshot="snapshot-id")
    mac_table = await client.mac_entry_list(snapshot="snapshot-id")

Features

Full API Coverage - Every OpenAPI operation exposed as a method ✅ Async/Await - Modern async/await syntax for non-blocking I/O ✅ Type Safe - Full type hints and IDE autocomplete support ✅ Builder Pattern - Fluent API for constructing complex objects ✅ Error Handling - Structured exceptions with status codes and details ✅ Pagination - Automatic page size handling for list operations ✅ Flexible Auth - Token-based or username/password authentication ✅ Multi-tenant - Support for tenant scoping with tenant_idConnection Pooling - Efficient HTTP connection reuse ✅ Comprehensive Docs - Inline docstrings and examples

API Reference

Discovery & Snapshots

# Snapshot management
await client.snapshots_list()
await client.snapshots_create(snapshot)
await client.snapshots_retrieve(id="...")
await client.snapshots_latest_retrieve()
await client.snapshots_pin_create(id="...")
await client.snapshots_unpin_create(id="...")

# Device management
await client.devices_list(snapshot="...", page_size=50)
await client.devices_create(snapshot, device)
await client.devices_retrieve(id="...")
await client.devices_create_many_create(snapshot, devices)

# Device details
await client.devices_interfaces_list(device="...")
await client.devices_routes_list(device="...")

Network Inventory

Query and explore network elements:

# VLANs, IP addresses, routes
await client.vlan_list(snapshot="...")
await client.ip_address_list(snapshot="...")
await client.route_list(snapshot="...")

# MAC and ARP
await client.mac_entry_list(snapshot="...")
await client.arp_entry_list(snapshot="...")

# Endpoints
await client.endpoint_list(snapshot="...")
await client.canonical_endpoint_list()

# VRF routing
await client.vrf_list(snapshot="...")

Topology

Analyze network topology and connections:

# Topology graph
await client.get_topology_graph(snapshot="...", include_endpoints=True)

# Device connections
await client.device_connection_list(snapshot="...")

# Tunnel connections
await client.tunnel_connection_list(snapshot="...")

# Endpoint connections
await client.endpoint_connection_list(snapshot="...")

# L2 domain lookup
await client.l2_domain_lookup(snapshot="...", vlan=10)

Core / Tenants

Manage credentials, users, and access:

# Credentials
await client.credential_list()
await client.credential_create(credential)

# Tenants
await client.tenant_list()
await client.tenant_create(tenant)

# Users
await client.user_list()
await client.user_create(user)

# Tokens
await client.token_list()
await client.token_create(token)

# Profile
await client.profile_read()

Base URL handling:

  • base_url accepts server root: https://netdoc.example.com
  • Or API endpoint: https://netdoc.example.com/api/v1
  • Client automatically normalizes both forms

Friendly Aliases

Common operations have shorter aliases:

# Long form
await client.snapshots_list()
await client.snapshots_create(snapshot)
await client.snapshots_retrieve(id="...")

# Short aliases (equivalent)
await client.list_snapshots()
await client.create_snapshot(snapshot)
await client.get_snapshot("...")

# More aliases
await client.list_devices()
await client.create_device(...)
await client.get_topology_graph(...)

Authentication

Token Authentication

Recommended for production use:

client = NetDocClient(
    base_url="https://netdoc.example.com",
    token="your-api-token"
)

Tokens are sent as Authorization: Token <token> header.

Username/Password Authentication

Authenticate with credentials:

client = await NetDocClient.from_credentials(
    base_url="https://netdoc.example.com",
    username="collector",
    password="secret",
)

Tenant Scoping

For superuser access across tenants:

client = NetDocClient(
    base_url="https://netdoc.example.com",
    token="admin-token",
    tenant_id="tenant-uuid",  # Sent as X-Tenant-ID header
)

Custom Headers

Add custom headers to all requests:

client = NetDocClient(
    base_url="...",
    token="...",
    headers={
        "X-Custom-Header": "value",
        "X-Request-ID": "12345",
    }
)

Error Handling

Exception Types

from netdoc_sdk.exceptions import (
    NetDocError,              # Base exception
    AuthenticationError,      # 401 Unauthorized
    PermissionDeniedError,    # 403 Forbidden
    NotFoundError,            # 404 Not Found
    ValidationError,          # 400 Bad Request
    ConflictError,            # 409 Conflict
    RateLimitError,           # 429 Too Many Requests
    ServerError,              # 500+ Server Error
    ConnectionError,          # Network/connection error
)

Handling Errors

from netdoc_sdk import NotFoundError, ValidationError

try:
    snapshot = await client.snapshots_retrieve("missing-id")
except NotFoundError as exc:
    print(f"Not found: {exc.detail}")
    print(f"Status: {exc.status_code}")
except ValidationError as exc:
    print(f"Validation errors: {exc.errors}")
except Exception as exc:
    print(f"Unexpected error: {exc}")

Error Details

All SDK exceptions include:

try:
    await client.device_create(snapshot, device)
except ValidationError as exc:
    exc.status_code  # HTTP status (400)
    exc.detail       # Human-readable error message
    exc.errors       # Structured validation errors dict
    str(exc)         # Full error representation

Advanced Usage

Pagination

Automatic pagination for list operations:

# Get all devices with automatic pagination
all_devices = []
async for device in await client.devices_list(snapshot="...", page_size=100):
    all_devices.append(device)

# Or fetch specific page
response = await client.devices_list(snapshot="...", page=2, page_size=50)

Filtering

Many list operations support filtering:

# Filter devices by vendor
devices = await client.devices_list(
    snapshot="snapshot-1",
    vendor="cisco",
    page_size=100,
)

# Filter snapshots by status
snapshots = await client.snapshots_list(status="completed")

Response Objects

All responses are Pydantic models with type safety:

snapshot = await client.snapshots_retrieve("...")
print(snapshot.id)           # IDE autocomplete
print(snapshot.label)        # Type checking
print(snapshot.created_at)   # datetime object

Connection Management

Explicit connection lifecycle:

# Via context manager (recommended)
async with NetDocClient(base_url, token=token) as client:
    result = await client.snapshots_list()

# Manual lifecycle
client = NetDocClient(base_url, token=token)
result = await client.snapshots_list()
await client.close()

Troubleshooting

Connection Issues

Problem: ConnectionError: Failed to connect to netdoc.example.com

Solutions:

  • Verify server is running and accessible
  • Check firewall rules and network connectivity
  • Ensure HTTPS/HTTP protocol is correct
  • Try with curl: curl -H "Authorization: Token $TOKEN" https://netdoc.example.com/api/v1/snapshots/

Authentication Errors

Problem: AuthenticationError: 401 Unauthorized

Solutions:

  • Verify API token is correct
  • Check token hasn't expired
  • Ensure token is passed correctly (not URL encoded)
  • Try creating a new token in the web UI

Validation Errors

Problem: ValidationError: 400 Bad Request

Solutions:

  • Check error message for specific field issues
  • Verify request data matches API schema
  • Inspect exc.errors dict for per-field details
  • Review example in quick start above

Type Issues

Problem: mypy or IDE errors about type mismatcements

Solutions:

  • Ensure SDK is installed: pip install netdoc-sdk
  • Update IDE/mypy cache: Restart IDE or mypy --no-incremental
  • Check Python version is 3.12+: python --version

Source Code

The SDK source code is well-documented and organized:

  • Comprehensive docstrings - All classes, functions, and modules have detailed docstrings
  • Type hints - Full typing throughout for IDE support and mypy checking
  • Clean architecture - Layered design with clear separation of concerns

For detailed information about the source code structure, internal implementation, and development guidelines, see Source Code Reference.

Key Modules

Module Purpose Lines
client.py Main async HTTP client 773
exceptions.py Exception hierarchy 270+
models/ Pydantic request/response models 612

For Developers

  • Contributing Code: See CONTRIBUTING.md for development workflow, code standards, and PR process
  • Running Tests: See tests/README.md for comprehensive test documentation
  • Source Architecture: See docs/source-code.md for internal implementation details

Requirements

  • Python: 3.12 or higher
  • Dependencies: httpx, pydantic, python-dateutil

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines on:

  • Development setup
  • Running tests
  • Code quality standards
  • Commit conventions
  • Pull request process

Support

License

MIT License - see LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

netdoc_sdk-0.6.5.tar.gz (156.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

netdoc_sdk-0.6.5-py3-none-any.whl (42.9 kB view details)

Uploaded Python 3

File details

Details for the file netdoc_sdk-0.6.5.tar.gz.

File metadata

  • Download URL: netdoc_sdk-0.6.5.tar.gz
  • Upload date:
  • Size: 156.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for netdoc_sdk-0.6.5.tar.gz
Algorithm Hash digest
SHA256 f20a0c7a41af66d9a371e479914a0fc352c0e3b0b2fcb1a7529f3162d61d9b7f
MD5 70df5ffbeac70282e075c346dec03314
BLAKE2b-256 244ad3cea01b31a5c06804a5f71b7a5f8a5e4e4c3dcbb24077039565e35b6337

See more details on using hashes here.

File details

Details for the file netdoc_sdk-0.6.5-py3-none-any.whl.

File metadata

  • Download URL: netdoc_sdk-0.6.5-py3-none-any.whl
  • Upload date:
  • Size: 42.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for netdoc_sdk-0.6.5-py3-none-any.whl
Algorithm Hash digest
SHA256 11abddbf584675fd7b7be49d584ff23f9e749f2f06cad11993a2dfe9edd99f16
MD5 8f58493635a3d754d8da51fec86faa99
BLAKE2b-256 3c4ab05ff32b14665eff370a4bdac0b52a67bf27c27f1f69b607026dd5f39539

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page