pysnow: ServiceNow HTTP Client Library
pysnow is a Python library for interacting with the ServiceNow REST API, emphasizing ease of use, simple code, and elegant syntax. It supports both Python 2 and 3. As of version 0.7.17, the library is in a stable maintenance mode, meaning essential fixes are applied, but new feature development has shifted to `aiosnow`, an asynchronous counterpart.
Common errors
-
pysnow.exceptions.InvalidUsage: You must supply either username and password or a session object
cause The `pysnow.Client` constructor was called without both `user` and `password` or a valid `session` object.fixEnsure `Client(user='...', password='...')` or `Client(session=requests.Session())` is used. Do not provide both username/password and a session object. -
pysnow.exceptions.InvalidUsage: Arguments 'instance' and 'host' are mutually exclusive, you cannot use both.
cause Both the `instance` and `host` parameters were provided to the `pysnow.Client` constructor.fixSpecify either the ServiceNow `instance` name (e.g., 'dev12345') or the full `host` URL (e.g., 'https://dev12345.service-now.com'), but not both. -
pysnow.exceptions.ResponseError: {'message': 'Unauthorized', 'detail': 'Required to authenticate with login information'}cause Authentication credentials (username/password or OAuth token) are incorrect, missing, or the ServiceNow instance's IP whitelist is blocking the connection.fixDouble-check your `user` and `password`. If using SSO, consider `pysnow.OAuthClient` or generate an OAuth token. Verify if your server's IP needs to be whitelisted in ServiceNow. -
pysnow.exceptions.QueryTypeError: 'SomeField' is of an unexpected type
cause An incorrect data type was passed to a `QueryBuilder` method (e.g., passing a string where an integer or datetime is expected for `between`, `less_than`, `greater_than`).fixReview the `QueryBuilder` method documentation and ensure the correct Python data types (e.g., `int`, `datetime`) are used for query criteria. -
Parameters on Resource.get() persist across requests leading to unexpected filtering.
cause Prior to 0.7.6, parameters set on `Resource.get()` could persist for subsequent requests on the same `Resource` object, causing unintended filtering or behavior.fixThis was largely addressed in `pysnow` versions post-0.7.6. For older versions or persistent issues, create a new `Resource` object for each distinct query or explicitly clear parameters if your version allows it. Always re-evaluate query parameters per request.
Warnings
- deprecated The `raise_on_empty` argument in `pysnow.Client` is deprecated and will be removed in future releases. By default, `pysnow` raises `NoResults` on 404 (no matching records).
- deprecated The `request_params` argument in `pysnow.Client` is deprecated. Global request parameters should be handled by configuring the underlying `requests.Session` object directly and passing it to the client.
- gotcha When initializing `pysnow.Client`, the `instance` and `host` arguments are mutually exclusive. Providing both will raise an `InvalidUsage` exception. Similarly, providing both `user`/`password` and a `session` object is not allowed.
- breaking The `UnexpectedResponseFormat` exception was re-added in version 0.7.13 for backward compatibility after being removed. Code that relied on its absence might need adjustments if upgrading from versions between its removal and re-addition.
- gotcha For fetching large amounts of data, using `incident.get(stream=True)` returns a memory-friendly generator instead of buffering the entire result, which can prevent memory exhaustion. Iterating directly over `response.all()` is generally efficient.
Install
-
pip install pysnow
Imports
- Client
import pysnow.Client
from pysnow import Client
- OAuthClient
from pysnow import OAuthClient
- QueryBuilder
from pysnow import QueryBuilder
Quickstart
import os
import pysnow
# Configure ServiceNow instance details from environment variables or provide directly
instance = os.environ.get('SNOW_INSTANCE', 'your_instance_name') # e.g., 'dev12345'
user = os.environ.get('SNOW_USER', 'your_username')
password = os.environ.get('SNOW_PASSWORD', 'your_password')
if not all([instance, user, password]):
print("Please set SNOW_INSTANCE, SNOW_USER, and SNOW_PASSWORD environment variables or provide them directly.")
else:
try:
# Create a client object
client = pysnow.Client(instance=instance, user=user, password=password)
# Define a resource, e.g., the incident table API
incident = client.resource(api_path='/table/incident')
# Query for incidents with state 1 (e.g., New) and print the first one
response = incident.get(query={'state': 1})
first_incident = response.first_or_none()
if first_incident:
print(f"Found incident: {first_incident['number']} - {first_incident['short_description']}")
else:
print("No incidents found with state 1.")
except pysnow.exceptions.InvalidUsage as e:
print(f"Client initialization error: {e}")
except pysnow.exceptions.NoResults:
print("No results returned for the query (this is expected if raise_on_empty is True and no results).")
except pysnow.exceptions.ResponseError as e:
print(f"ServiceNow API error: {e.error['message']} - {e.error['detail']}")
except Exception as e:
print(f"An unexpected error occurred: {e}")