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.2.tar.gz (155.8 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.2-py3-none-any.whl (42.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: netdoc_sdk-0.6.2.tar.gz
  • Upload date:
  • Size: 155.8 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.2.tar.gz
Algorithm Hash digest
SHA256 d615db39f5da552b24441ad1e5fe012971e9d03694ddf4e4850fab6b124f3b3a
MD5 068f76e36c099e743e2a9beb9d6dce93
BLAKE2b-256 ef0dcb9eac88b34eb56e94c3e631e363f43406079c2b365f94562129ca993e9c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: netdoc_sdk-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 42.4 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f636bd795f2ea826f55fe70715a00fc171dbb3854ff56de44a8c9f5b38e00742
MD5 257114510edda2d5dc8f66d8cab6ecb4
BLAKE2b-256 af0561109072285874353858aa4ec0f21d3cf82b72955388092804c433ca670b

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