Netskope Python SDK
The official Netskope Python SDK — a modern, typed, and intuitive interface to the Netskope REST API v2.
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.27pydantic>= 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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| netskope_py_sdk-1.0.3.tar.gz | 58.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.