- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-23-2020 07:13 AM
Hi All,
I need to download files attached to any incident using REST API.
I will be sending incident detail from my postman.
Already Referred to attachment api reference docs but could'nt find a solution.
NOTE: I don't have the option to use ui action
Is this doable?
Thanks in Advance!
Solved! Go to Solution.
- Labels:
-
Scripting and Coding

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2020 02:32 AM
I'm executing python script from the command line.
I may be missing some steps below but the general way to install python is as follows.
1. Install python
https://phoenixnap.com/kb/how-to-install-python-3-windows
2. Create subdirectory
mkdir servicenowapis
3. Move to the subdirectory
cd servicenowapis
4. Create a virtualenv
python-m venv venv
5. Activate venv
venv\Scripts\activate.bat
6. Install request module
pip install requests
7. Copy the script I've provided to the directory
8. Copy and paste content of Constants.py over import statements
9. Edit username, password
9. Edit table_api.py to use Incident number
e.g.
get_file_attachment('INC0000002')
10. Execute command
python test_api.py
import requests
SERVICENOW_URL = 'https://<instance>.service-now.com'
SERVICENOW_USER = '<username>'
SERVICENOW_PWD = '<password>'
DOWNLOAD_DIR = './downloads/'
REQUEST_HEADER = {"json": {"Content-Type": "application/xml", "Accept": "application/json"},
"png": {"Content-Type": "application/xml", "Accept": "application/png"},
"xml": {"Content-Type": "application/xml", "Accept": "application/xml"},
}
ATTACHMENT_API = '/api/now/attachment'
TABLE_API = '/api/now/table'
# TABLE_NAME = 'kb_knowledge'
TABLE_NAME = 'incident'
def get_table_data(table_name, param):
url = SERVICENOW_URL + TABLE_API + '/' + table_name + '?' + param
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
return response.json()
def get_attachment_info(sys_id):
url = SERVICENOW_URL + ATTACHMENT_API + '/' + sys_id
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print(f'Status: {response.status_code}, Headers:{response.headers}')
exit()
return response.json()
def get_attachment(att_sys_id, file_type, download_dir):
url = SERVICENOW_URL + '/' + ATTACHMENT_API + '/' + att_sys_id + '/file'
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get(file_type))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
with open(download_dir, 'wb') as f:
for chunk in response:
f.write(chunk)
def get_file_attachment(record_number):
param = 'sysparm_query=number=' + record_number + '&sysparam_limit=1'
file_info = get_table_data(TABLE_NAME, param).get('result')
if len(file_info) < 1:
print(f'There is no attachment to sys_id:{record_number}')
return
attachment_sys_id = file_info[0].get('sys_id')
param = 'sysparm_query=table_sys_id=' + attachment_sys_id + '&sysparam_limit=1'
kb_attachments = get_table_data('sys_attachment', param)
result = kb_attachments.get('result')
for attach_file in result:
attach_sys_id = attach_file.get('sys_id')
content_type = attach_file.get('content_type').split('/')
file_ext = content_type[1]
file_name = attach_file.get('file_name')
get_attachment(attach_sys_id, file_ext, DOWNLOAD_DIR + file_name)
if __name__ == '__main__':
# get_file_attachment('KB0010062') # knowledge base number
get_file_attachment('INC0000002')
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-28-2020 12:17 AM
Hi
Thanks for the effort!
Can you please help me understand if i need to try this in scripted rest api? Or fromw here is this script called?
Also, constant.py where do i need to define this?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-28-2020 06:41 AM
Just specify the kb article number as a parameter to get_kb_attachment('<kb article number>') to download all attachments on the article.
The script uses the table api so no other script is necessary.
This is a python3 script. It needs to be setup on a server that is able to execute python3.7 and has access to the MID Server. It can be installed in MID Server too.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-28-2020 07:01 AM
Re-read the question. I've written a python script to download all attachments to a kb article but the question was about downloading attachments to an incident.
I need to test this but all that's required is to change the "kb_knowledge" to "incident" in the following line.
kb_info = get_table_data('kb_knowledge', param)
The script first get the sys_id of the knowledge article (this can be an incident). It the queries the sys_attachment table with matching sys_id to get a list of sys_id of attachments. Finally, it loops and download the attachments.
BTW, my bad on saying the script need to be on a server. It can be executed from a pc. I was testing it out from my pc and it was able to download the attachment files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-28-2020 11:45 PM
Hi Hozawa,
I have few very basic questions here...
1. from where are you calling this script?
2. Do i need to install any python package for this to run?
3. Where have you defined the values under constant.py?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2020 02:32 AM
I'm executing python script from the command line.
I may be missing some steps below but the general way to install python is as follows.
1. Install python
https://phoenixnap.com/kb/how-to-install-python-3-windows
2. Create subdirectory
mkdir servicenowapis
3. Move to the subdirectory
cd servicenowapis
4. Create a virtualenv
python-m venv venv
5. Activate venv
venv\Scripts\activate.bat
6. Install request module
pip install requests
7. Copy the script I've provided to the directory
8. Copy and paste content of Constants.py over import statements
9. Edit username, password
9. Edit table_api.py to use Incident number
e.g.
get_file_attachment('INC0000002')
10. Execute command
python test_api.py
import requests
SERVICENOW_URL = 'https://<instance>.service-now.com'
SERVICENOW_USER = '<username>'
SERVICENOW_PWD = '<password>'
DOWNLOAD_DIR = './downloads/'
REQUEST_HEADER = {"json": {"Content-Type": "application/xml", "Accept": "application/json"},
"png": {"Content-Type": "application/xml", "Accept": "application/png"},
"xml": {"Content-Type": "application/xml", "Accept": "application/xml"},
}
ATTACHMENT_API = '/api/now/attachment'
TABLE_API = '/api/now/table'
# TABLE_NAME = 'kb_knowledge'
TABLE_NAME = 'incident'
def get_table_data(table_name, param):
url = SERVICENOW_URL + TABLE_API + '/' + table_name + '?' + param
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
return response.json()
def get_attachment_info(sys_id):
url = SERVICENOW_URL + ATTACHMENT_API + '/' + sys_id
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print(f'Status: {response.status_code}, Headers:{response.headers}')
exit()
return response.json()
def get_attachment(att_sys_id, file_type, download_dir):
url = SERVICENOW_URL + '/' + ATTACHMENT_API + '/' + att_sys_id + '/file'
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get(file_type))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
with open(download_dir, 'wb') as f:
for chunk in response:
f.write(chunk)
def get_file_attachment(record_number):
param = 'sysparm_query=number=' + record_number + '&sysparam_limit=1'
file_info = get_table_data(TABLE_NAME, param).get('result')
if len(file_info) < 1:
print(f'There is no attachment to sys_id:{record_number}')
return
attachment_sys_id = file_info[0].get('sys_id')
param = 'sysparm_query=table_sys_id=' + attachment_sys_id + '&sysparam_limit=1'
kb_attachments = get_table_data('sys_attachment', param)
result = kb_attachments.get('result')
for attach_file in result:
attach_sys_id = attach_file.get('sys_id')
content_type = attach_file.get('content_type').split('/')
file_ext = content_type[1]
file_name = attach_file.get('file_name')
get_attachment(attach_sys_id, file_ext, DOWNLOAD_DIR + file_name)
if __name__ == '__main__':
# get_file_attachment('KB0010062') # knowledge base number
get_file_attachment('INC0000002')