Skip to main content

Netskope Python SDK

Read the documentation

The official Netskope Python SDK — a modern, typed, and intuitive interface to the Netskope REST API v2.

PyPI Python License

Why This SDK?

  • Hierarchical namespaces — client.alerts.list(), client.scim.users.create() — explore the entire API through autocomplete
  • Automatic pagination — just iterate, no page loops needed
  • Full type safety — Pydantic v2 models with complete type annotations
  • Sync + Async — choose the right client for your use case
  • Automatic retries — exponential backoff with jitter for transient errors
  • Rich exceptions — specific error types with request IDs for support escalation
  • Minimal dependencies — only httpx + pydantic
  • Python 3.11+ — modern Python, no legacy baggage

Installation

pip install netskope-py-sdk

Quick Start

from netskope import NetskopeClient

# Create a client (or set NETSKOPE_TENANT and NETSKOPE_API_TOKEN env vars)
client = NetskopeClient(
    tenant="mycompany.goskope.com",
    api_token="your-v2-api-token",
)

# List high-severity alerts — pagination is automatic
for alert in client.alerts.list(query='severity eq "high"'):
    print(f"{alert.alert_name} — {alert.user} — {alert.severity}")

# Query network events
for event in client.events.list("network", query='user eq "alice@example.com"'):
    print(f"{event.src_ip} → {event.dst_ip}")

# Manage URL allow/block lists
blocklist = client.url_lists.create("threat-iocs", ["malware.example.com"])
client.url_lists.deploy()  # deploy pending changes

# List publishers
for pub in client.publishers.list():
    print(f"{pub.publisher_name} — {pub.status}")

# SCIM user provisioning
for user in client.scim.users.list():
    print(f"{user.user_name} active={user.active}")

Async Usage

from netskope import AsyncNetskopeClient

async with AsyncNetskopeClient(tenant="...", api_token="...") as client:
    async for alert in client.alerts.list():
        print(alert.alert_name)

Configuration

Environment Variables

Variable Description
NETSKOPE_TENANT Tenant hostname (e.g. mycompany.goskope.com)
NETSKOPE_API_TOKEN REST API v2 token

Client Options

client = NetskopeClient(
    tenant="mycompany.goskope.com",
    api_token="...",
    timeout=60.0,           # request timeout (seconds)
    max_retries=5,          # retry count for transient errors
    backoff_factor=1.0,     # exponential backoff base
)

Multiple Tenants

prod = NetskopeClient(tenant="prod.goskope.com", api_token=prod_token)
staging = NetskopeClient(tenant="staging.goskope.com", api_token=staging_token)

API Reference

Alerts

# List with JQL filtering
alerts = client.alerts.list(query='alert_type eq "DLP"')
for alert in alerts:
    print(alert.alert_name, alert.severity, alert.user)

# Get a single alert
alert = client.alerts.get("alert-id-123")

# Page-level access
for page in client.alerts.list().pages():
    print(f"Page: {len(page.items)} items, {page.total} total")

# Collect all at once (with safety limit)
all_alerts = client.alerts.list().to_list(max_items=5000)

Events

from datetime import datetime

# Query by event type
for event in client.events.list("application"):
    print(event.user, event.app, event.activity)

# Network events with time range
for event in client.events.list(
    "network",
    start_time=datetime(2026, 1, 1),
    end_time=datetime(2026, 3, 1),
):
    print(event.src_ip, event.dst_ip)

# Supported types: alert, application, network, page, incident,
#   audit, infrastructure, clientstatus, epdlp, transaction

URL Lists

# CRUD operations
url_list = client.url_lists.create("blocklist", ["bad.com", "evil.org"])
url_list = client.url_lists.update(url_list.id, urls=["bad.com", "evil.org", "new.bad.com"])
client.url_lists.delete(url_list.id)

# Deploy all pending changes
client.url_lists.deploy()

Publishers

# List all publishers
for pub in client.publishers.list():
    print(f"{pub.publisher_name}: {pub.status} ({pub.apps_count} apps)")

# Create a publisher
new_pub = client.publishers.create(name="aws-us-east-1")

# Get by ID
pub = client.publishers.get(publisher_id=42)

Private Apps (ZTNA)

# List private apps
for app in client.private_apps.list():
    print(f"{app.app_name} → {app.host}:{app.port}")

# Create a private app
app = client.private_apps.create(
    name="internal-dashboard",
    host="10.0.0.5",
    port="443",
    protocols=["TCP"],
    publisher_ids=[1, 2],
)

SCIM (Users & Groups)

# Users
for user in client.scim.users.list():
    print(user.user_name, user.active)

user = client.scim.users.create(
    user_name="alice@example.com",
    email="alice@example.com",
    display_name="Alice Smith",
)

# Groups
for group in client.scim.groups.list():
    print(f"{group.display_name}: {len(group.members)} members")

Incidents

# List incidents
for incident in client.incidents.list(query='severity eq "critical"'):
    print(incident.incident_id, incident.severity, incident.status)

# Get user risk score
uci = client.incidents.get_uci("user@example.com")
print(f"Risk score: {uci.score}")

# Get UBA anomalies
anomalies = client.incidents.get_anomalies(["user@example.com"])

Steering & Infrastructure

# Get steering config
config = client.steering.get_config("npa")

# List PoPs
for pop in client.steering.list_pops():
    print(f"{pop.name} — {pop.region}")

# List IPSec tunnels
for tunnel in client.steering.list_tunnels():
    print(f"{tunnel.name}: {tunnel.status}")

Error Handling

from netskope import (
    NetskopeError,
    AuthenticationError,
    NotFoundError,
    RateLimitError,
    ForbiddenError,
)

try:
    alert = client.alerts.get("nonexistent")
except NotFoundError as e:
    print(f"Not found: {e.message}")
    print(f"Request ID: {e.request_id}")  # for support escalation
except RateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}s")
except AuthenticationError:
    print("Invalid or expired API token")
except ForbiddenError:
    print("Token lacks required scope")
except NetskopeError as e:
    print(f"SDK error: {e}")

Context Managers

# Sync
with NetskopeClient(tenant="...", api_token="...") as client:
    alerts = client.alerts.list().to_list()

# Async
async with AsyncNetskopeClient(tenant="...", api_token="...") as client:
    alerts = await client.alerts.list().to_list()

Logging

import logging

# See all requests at INFO level
logging.getLogger("netskope").setLevel(logging.INFO)

# Full request/response debug (tokens redacted)
logging.getLogger("netskope").setLevel(logging.DEBUG)

Requirements

  • Python 3.11+
  • httpx >= 0.27
  • pydantic >= 2.0

License

MIT

Metadata

Release files for netskope-py-sdk 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for netskope-py-sdk 1.0.3
File Size Uploaded Provenance
netskope_py_sdk-1.0.3.tar.gz 58.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for netskope-py-sdk 1.0.3
File Interpreter ABI Platform
netskope_py_sdk-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 98.0 kB

Release files / netskope_py_sdk-1.0.3.tar.gz

Download URL netskope_py_sdk-1.0.3.tar.gz
Size 58.4 kB
Tags Source
SHA-256 checksum
How to use checksums
65aa6cbb89a48fb3b92f5430b4c5398d5dbcec76999caed4b24e3eefdfa2a575
BLAKE2b-256 checksum
How to use checksums
5a48d45cd8a3a5baa559874a5e85888a02da28c0bc430fb4b986b54ee1f4fd9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.14.0 Darwin/25.3.0

Release files / netskope_py_sdk-1.0.3-py3-none-any.whl

Download URL netskope_py_sdk-1.0.3-py3-none-any.whl
Size 39.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b4000f35b9830aadb563a58d6a6726c4df77ef1878dfd3e6bfd6e590ad5eaac7
BLAKE2b-256 checksum
How to use checksums
6562e12c49d8049ed786e8d0fca65d3beaacd668710414853ca83439379317c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.14.0 Darwin/25.3.0

Security for netskope-py-sdk 1.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page