on 2024 Jan 03 8:58 PM
Hello Community,
I'm reaching out for support regarding an issue I'm encountering while trying to trigger a multi-action using Python with the SAC API. Despite extensive research and testing, I've hit a roadblock that I hope someone here can help me resolve.
Background and Research:
Python Implementation Challenge: My script successfully runs multi-actions when initiated from Postman to Visual Studio. However, integrating code for obtaining the API token, CSRF token, and building headers for the multi-action endpoint is problematic.
Code Snippets and Output: I'm providing code and execution output (with sensitive data omitted). The issue seems to lie in the headers section of the run_multi_action function, where the session/Bearer/csrf token combination is not accepted. Replacing the run_multi_action header with one from Postman triggers successful script execution.
-----------------------------------------------------------------Actual Code------------------------------------------------------------------------------
import json
import requests
import base64
import os
# Constants
API_OAUTH_CLIENT_ID = '<<Client ID>>'
API_SECRET = '<<secret key>>'
API_URL_BASE = 'https://<<sac tenent URL>>/api/v1/csrf'
API_TOKEN_URL = 'https://<<sac tenent URL>>/oauth/token'
API_MULTIACTION_URL = "https://<<sac tenent URL>>/executions"
AUTH_URL = 'https://<<sac tenent URL>>/oauth/authorize'
def get_api_token():
"""Retrieve the API token."""
print("get_api_token: started")
auth = f'{API_OAUTH_CLIENT_ID}:{API_SECRET}'
token_headers = {
'Authorization': f'Basic {base64.b64encode(auth.encode()).decode()}',
'Content-Type': 'application/json'
}
params = {'grant_type': 'client_credentials'}
try:
response = requests.post(API_TOKEN_URL, headers=token_headers, params=params)
data = json.loads(response.content.decode('utf-8'))
api_token = data['access_token']
print(len(api_token))
return response.json()
except requests.RequestException as e:
print(f"Error getting API token: {e}")
return None
def get_crsf_token(api_token):
"""Get the CSRF token."""
headers = {
'Authorization': f'Bearer {api_token}',
'x-sap-sac-custom-auth': 'true',
'x-csrf-token': 'fetch'
}
try:
response = requests.get(API_URL_BASE, headers=headers)
response.raise_for_status()
return response
except requests.RequestException as e:
print(f"Error getting CSRF token: {e}")
return None
def run_multi_action(api_token, csrf_token, csrf_cookies):
"""Run a multi-action with the provided tokens and cookies."""
headers = {
'x-csrf-token': csrf_token,
'Content-Type': 'application/json',
'Authorization': f'Bearer {api_token}',
'Cookie': f'signature; JSESSIONID={csrf_cookies["JSESSIONID"]}; __VCAP_ID__={csrf_cookies["__VCAP_ID__"]}'
}
payload = json.dumps({"parameterValues": []})
print("Sending request to:", API_MULTIACTION_URL)
print("Headers:", headers)
print("Payload:", payload)
try:
response = requests.post(API_MULTIACTION_URL, headers=headers, data=payload)
response.raise_for_status()
return response.text
except requests.RequestException as e:
error_message = f"Request Exception: {e}"
if hasattr(e, 'response'):
error_message += f"\nResponse: {e.response.text}\nStatus Code: {e.response.status_code}"
print(error_message)
return None
def main():
"""Main function to execute the script logic."""
print("Script started")
api_token_info = get_api_token()
if not api_token_info:
print("Failed to get API token")
return
api_token = api_token_info['access_token']
print(f"Token Length: {len(api_token)}")
csrf_response = get_crsf_token(api_token)
if not csrf_response:
return
csrf_token = csrf_response.headers['x-csrf-token']
csrf_cookies = csrf_response.cookies
multi_action_response = run_multi_action(api_token, csrf_token, csrf_cookies)
if multi_action_response:
print(multi_action_response)
if __name__ == "__main__":
main()
-----------------------------------------------------------------Code End------------------------------------------------------------------------------
Output
Script started
get_api_token: started
2038
Token Length: 2038
Sending request to: <<sac tenent URL>>/api/v1/multiActions/t.cfgsd50/executions
Headers: {'x-csrf-token': '<<csrf_token>>', 'Content-Type': 'application/json', 'Authorization': 'Bearer <<bearer_token>>', 'Cookie': 'signature; JSESSIONID=<<session_id>>; __VCAP_ID__=<<vcap_id>>'}
Payload: {"parameterValues": []}
Request Exception: 401 Client Error: Unauthorized for url: <<sac tenent URL>>/api/v1/multiActions/<<multiaction_id>>/executions
Response: Unauthorized
Status Code: 401
New Challenge with Bearer Token:
Steps Taken to Investigate:
Specific Problem: The headers section in the run_multi_action function seems to be the issue. When using headers from Postman, the script works, but not with the generated headers in Python.
Request for Assistance: Could anyone provide insights or suggestions on how to correctly format or authenticate the headers in Python for successful multi-action execution? Any help or guidance would be greatly appreciated.
Request clarification before answering.
User | Count |
---|---|
52 | |
6 | |
6 | |
5 | |
5 | |
4 | |
3 | |
3 | |
3 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.