top of page
5.15 Technologies

How to build a Data Collector in Python for ServiceNow Incidents and Changes

ServiceNow offers a robust platform for managing incidents and changes. Accessing this data programmatically can be immensely valuable. By extracting 'Change' data, you can analyze the frequency and types of requested changes. This insight aids in impact assessment, resource allocation, and strategic planning for infrastructure upgrades.


By pulling Incident data, one can determine patterns and recurring issues. Programmatic analysis of this data helps identify recurring issues, providing insights for potential Knowledge Base articles or areas to target for automation. This blog will explore how to use Python to create a simple data collector for extracting information from ServiceNow's Incident and Change tables.


Prerequisites

For this project, the following is required: 

  • A ServiceNow Developer instance

    • Refer here for more information about obtaining a ServiceNow Developer instance.

  • Python (version 3.7+) installed on your machine.

    • Recommended IDEs: PyCharm and/or VSCode

  • Requests library installed (pip install requests)



ServiceNow API Access & Configuration

First, let’s get the ServiceNow Developer ready to accept API requests. To accomplish this, a user account will need to be created with the appropriate read permissions to the Incidents and Changes tables. The steps below outline this process:


  • Upon opening the developer instance, navigate to All -> Organization -> Users.

  • Search “system admin”

  • Click the user id “admin.”

  • Click set password.

  • Generate a password and copy this down.

  • Log out of the instance.

  • Log in with the username “admin” and password that you just copied down.

  • You will be prompted to create a new password.

    • This will be the username and password that authorizes an API call to the Developer instance.


Now that the user account has been provisioned with the necessary permissions, a few items are needed to start sending API requests. Mainly, the Developer Instance URL, our new user credentials, and API endpoint URLs for the Incidents and Changes tables. The Developer Instance URL can be found after clicking the "Start Building" button when logging into the ServiceNow Developer account, as shown below.



Next, you'll need to discover the API endpoints. ServiceNow offers comprehensive documentation for its numerous APIs, which can be found here. For the purposes of this blog, the Table API will be used. The following GET endpoints will allow for retrieval of incidents and changes:


  • /api/now/table/incident

  • /api/now/table/change_request



From the documentation, ServiceNow also allows us to include several parameters alongside the API call which allows for finer control over the data that is returned. In the following example, one such parameter being used is the “sysparm_query”, which can place filters on the records being returned by the API.


Python Script

Now that the ServiceNow Developer instance is configured, let’s get to coding! The code snippet below outlines setting up required variables and sending the request to the API:


import requests

# ServiceNow credentials and URLs
instance_url = "YOUR_INSTANCE"
username = "YOUR_USERNAME"
password = "YOUR_PASSWORD"
incident_endpoint = "/api/now/table/incident"
change_endpoint = "/api/now/table/change_request"

# Set up the request headers
headers = {"Content-Type": "application/json", "Accept": "application/json"}

# Set your date range for filtering
start_date = "2018-01-01 00:00:00"
end_date = "2023-01-31 23:59:59"

# Construct the query to filter by date range
date_query = f'sys_created_on>=javascript:gs.dateGenerate("{start_date}")^sys_created_on<=javascript:gs.dateGenerate("{end_date}")'

params = {"sysparm_query": date_query}

# Function to fetch data from ServiceNow
def fetch_data(endpoint):
    response = requests.get(
        endpoint, auth=(username, password), headers=headers, params=params
    )
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Failed to fetch data. Status code: {response.status_code}")
        return None

The code is relatively straight forward, but just to review, we utilize the Python "requests" library to send 'GET' requests to the API. As mentioned earlier, a filter by date range is included to show how to retrieve the Incidents and Change requests from the API based on user preferences. To accomplish this, the “GlideSystem” API from ServiceNow provides convenient methods for server-side JavaScript. In this instance, the gs.dateGenerate function is utilized to pass date ranges in the API request.


NOTE: It is best practice to store any credentials in a key vault or .env file when writing scripts for Production. However, since this is a lab, they are included in the script for convenience’s sake!

Usage

To use this script in your own environment, replace the ‘YOUR_INSTANCE’ with the URL to your Developer instance, ‘YOUR_USERNAME’ with the read permissions to the tables, and ‘YOUR_PASSWORD’ with the account’s password. The Start and End dates can be modified to fit the timeframe required.

 

Next, the endpoints required to collect incidents and changes will need to be provided to the “fetch_data” function. The code snippet below will create the requests for gathering incidents and change requests and provide an example of processing the resulting response data.


import csv
# Function to write data to CSV
def write_to_csv(data, filename):
    with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
        csv_writer = csv.DictWriter(csvfile, fieldnames=data[0].keys())
        csv_writer.writeheader()
        csv_writer.writerows(data)

# Fetch Incidents data
incidents_data = fetch_data(instance_url + incident_endpoint)
if incidents_data:
    # Process or store incidents_data as needed
    write_to_csv(incidents_data["result"], 'incidents_data.csv')

# Fetch Changes data
changes_data = fetch_data(instance_url + change_endpoint)
if changes_data:
    # Process or store changes_data as needed
    write_to_csv(changes_data["result"], 'changes_data.csv')

Customization and Further Development

In future blogs, expanded capabilities of the script could include the date/time range as an input to the “fetch_data” function and extending the script to perform more specific data manipulations and filtering. Additional features could include error handling, data encryption, access controls, or additional authentication methods for security.


Conclusion

Creating a data collector in Python to fetch data from ServiceNow's Incidents and Changes tables is a foundational step towards leveraging ServiceNow's capabilities programmatically. With this script as a starting point, you can further build upon it to suit your specific data retrieval and processing needs.


This simple collector script serves as a gateway to extracting valuable insights from ServiceNow's incident and change data, empowering your workflows and analytics.


If you would like assistance transforming your ServiceNow experience, reach out to 5.15 today!



Comments


bottom of page