I tried using Selenium to replicate browser functionality, which worked, but ended up being extremely fragile and not suitable for long-term use. After a renewed investigation I have finally found the solution: import json
import requests
from datetime import datetime
from dateutil import tz
tz_est = tz.gettz('US/Eastern')
tz_utc = tz.UTC
session = requests.Session()
url_initial = 'https://the.splunk.domain/en-US/account/login?session_expired=1'
resp_initial = session.get(url_initial) # Response is good (200)
str_session_id = session.cookies['session_id_8000']
str_token = session.cookies['splunkweb_csrf_token_8000']
str_splunkd = session.cookies['splunkd_8000']
str_json_cookies = json.dumps(session.cookies.get_dict())
# Create headers and params
dict_headers = {
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*',
'Accept-encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Host': 'the.splunk.domain',
'Origin': 'https://the.splunk.domain',
'Pragma': 'no-cache',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': 'Windows',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'X-Requested-With': 'XMLHttpRequest',
'X-Splunk-Form-Key': str_token
}
dict_params = {'output_mode': 'json'}
# Create a search job
url_post = 'https://the.splunk.domain/en-US/splunkd/__raw/servicesNS/myusername/search/search/jobs'
str_query = 'index="*" | head 8'
dt_start_date = datetime(2021, 12, 15).astimezone(tz_utc)
dt_start_ms = int(datetime.timestamp(dt_start_date))
dt_end_date = datetime(2021, 12, 16).astimezone(tz_utc)
dt_end_ms = int(datetime.timestamp(dt_end_date))
dict_data = {
'rf': '*',
'auto_cancel': '30',
'status_buckets': '300',
'output_mode': 'json',
'custom.display.page.search.mode': 'fast',
'custom.dispatch.sample_ration': 1,
'custom.search': str_query,
'custom.dispatch.earliest_time': dt_start_ms,
'custom.dispatch.latest_time': dt_end_ms,
'name': 'jobs',
'search': f'search {str_query}',
'earliest_time': dt_start_ms,
'latest_time': dt_end_ms,
'ui_dispatch_app': 'search',
'preview': 1,
'adhoc_search_level': 'fast',
'sample_ratio': 1,
'check_risky_command': False,
'provenance': 'UI:Search'
}
resp_post = session.post(url_post, headers=headers_post, data=dict_data)
resp_post.ok # True
resp_post.json() # {'sid': '123456789.0987654'} The most notable points are: Ensure the headers include: 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 'X-Splunk-Form-Key': str_token (the splunkweb_csrf_token_8000 cookie value) When POSTing, ensure you pass your data dictionary with the data keyword instead of json. The json keyword serializes the dictionary but the data keyword submits it string/form encoded (which is apparently necessary here). Hooray!
... View more