The Zurich release has arrived! Interested in new features and functionalities? Click here for more

Download file using REST API

Rj27
Mega Guru

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!

1 ACCEPTED SOLUTION

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')

View solution in original post

26 REPLIES 26

Hi @hozawa ,

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?

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.

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.

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?

 

 

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')