I am programming an API in python to query a server if it has endpoint agents in it. The server and the endpoint belong to Apex central SaaS trend micro.
The error I get is that I'm putting the wrong parameters but I don't think the problem is there.
The code I have for the query is as follows:
import base64
import jwt
import hashlib
import requests
import time
import json
import urllib.parse
def create_checksum(http_method, raw_url, headers, request_body):
string_to_hash = http_method.upper() + '|' + raw_url.lower() + '|' + headers + '|' + request_body
base64_string = base64.b64encode(hashlib.sha256(str.encode(string_to_hash)).digest()).decode('utf-8')
return base64_string
def create_jwt_token(appication_id, api_key, http_method, raw_url, headers, request_body,
iat=time.time(), algorithm='HS256', version='V1'):
payload = {'appid': appication_id,
'iat': iat,
'version': version,
'checksum': create_checksum(http_method, raw_url, headers, request_body)}
token = jwt.encode(payload, api_key, algorithm=algorithm)
return token
# Use this region to setup the call info of the Apex Central server (server url, application id, api key)
# server info
use_url_base = 'https://arct3w.manage.trendmicro.com'
use_application_id = '52EB0005-B6DA-4249-9764-62AE3BFCDBB1'
use_api_key = 'B3FE1D91-5D05-490C-B45C-26A9EFF6C363'
productAgentAPIPath = '/WebApp/API/AgentResource/ProductAgents'
canonicalRequestHeaders = ''
useQueryString=''
payload = {
'computerId':'e34a13a1-1d0f-47bc-96e0-ae4db4288940'
}
useRequestBody = json.dumps(payload)
jwt_token = create_jwt_token(use_application_id, use_api_key, 'POST',
productAgentAPIPath + useQueryString,
canonicalRequestHeaders, useRequestBody, iat=time.time())
headers = {'Authorization': 'Bearer ' + jwt_token , 'Content-Type': 'application/json;charset=utf-8'}
#Choose by call type.
r = requests.post(use_url_base + productAgentAPIPath + useQueryString, data=useRequestBody, headers=headers, verify=False)
print(r.status_code)
if 'application/json' in r.headers.get('Content-Type', '') and len(r.content):
print(json.dumps(r.json(), indent=4))
else:
print(r.text)
I tried to do something similar to an api belonging to Vision One but it didn't work:
https://automation.trendmicro.com/xdr/api-v2#tag/Search/paths/~1v2.0~1xdr~1eiqs~1query~1endpointInfo/post
the original code of the query is :
https://automation.trendmicro.com/apex-central/api#tag/Security-Agents/operation/AgentResource_GetProductAgentsV2
I have below curl command
file_location='some/path/to/test.csv'
auth_token='my_api_token'
curl --insecure --request POST 'https://<ip_address>/eds/api/table/table_name/changes/addBulk?hasHeader=false' -H 'Csrf-Token: nocheck' -H 'AuthToken:'$auth_token'' -H 'Content-Type: multipart/form-data' --form 'data=#'$file_location'
The data in csv is just multiple rows with 1 column, for example below:
row_1
row_2
row_3
The curl command works perfectly fine, I am trying to get python alternative for it, I tried below:
files = {'file': ('test.csv', open("some/path/to/test.csv", 'rb'), 'multipart/form-data')}
auth_token="<api token here>"
url="https://" + ip_address +"/eds/api/table/" + table_name + "/changes/addBulk?hasHeader=false"
headers = {
'Csrf-Token': 'nocheck',
'AuthToken': auth_token
}
response = requests.post(url, headers=headers, files=files, verify=False)
Any help is appreciated
I noticed in your curl url you have "eds" before "/api/..." but in your python version you do not.
curl_url = "https://<ip_address>/eds/api/table/table_name/changes/addBulk?hasHeader=false"
python_url = "https://" + ip_address +"/api/table/" + table_name + "/changes/addBulk?hasHeader=false"
Also, in python 3 it is cleaner to use an f-string like this:
url = f"https://{ip_address}**/eds/**api/table/{table_name}/changes/addBulk?hasHeader=false"
Everything else looks right to me. In the future it may help to set a break point on the response to see if there is any additional information with the 400 http response.
EDIT:
Okay then, can you try modifying your header to be:
headers = {
'Csrf-Token': 'nocheck',
'AuthToken': auth_token,
'Content-Type': 'multipart/form-data'
}
Also edit your files to be:
files = {
'data': ('test.csv', open("some/path/to/test.csv", 'rb'), 'multipart/form-data')
}
Final code should be:
auth_token = "<api token here>"
files = {
'data': ('test.csv', open("some/path/to/test.csv", 'rb'), 'multipart/form-data')
}
url = f"https://{ip_address}/eds/api/table/{table_name}/changes/addBulk?hasHeader=false"
headers = {
'Csrf-Token': 'nocheck',
'AuthToken': auth_token
}
response = requests.post(url, headers=headers, files=files, verify=False)
Im having difficulty with the following code:
payload = {
'file' : ('csvtest.csv', open('csvtest.csv', 'rb')),
'parser' : '{"name":"CSV","displayName":null,"description":"Supports delimited text files with a field delimiter and optional escape and quote characters.","shortDescription":null,"properties":[{"name":"Auto Detect?","displayName":"Auto Detect?","value":"true","values":null,"placeholder":"","type":"select","hint":"Auto detect will attempt to infer delimiter from the sample file.","objectProperty":"autoDetect","selectableValues":[{"label":"true","value":"true","hint":null},{"label":"false","value":"false","hint":null}],"required":false,"group":"","groupOrder":1,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_0"},{"name":"Header?","displayName":"Header?","value":"true","values":null,"placeholder":"","type":"select","hint":"Whether file has a header.","objectProperty":"headerRow","selectableValues":[{"label":"true","value":"true","hint":null},{"label":"false","value":"false","hint":null}],"required":false,"group":"","groupOrder":2,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_1"},{"name":"Delimiter Char","displayName":"Delimiter Char","value":",","values":null,"placeholder":"","type":"string","hint":"Character separating fields","objectProperty":"separatorChar","selectableValues":[],"required":false,"group":"","groupOrder":3,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_2"},{"name":"Quote Char","displayName":"Quote Char","value":"\'","values":null,"placeholder":"","type":"string","hint":"Character enclosing a quoted string","objectProperty":"quoteChar","selectableValues":[],"required":false,"group":"","groupOrder":4,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_3"},{"name":"Escape Char","displayName":"Escape Char","value":"\\\\","values":null,"placeholder":"","type":"string","hint":"Escape character","objectProperty":"escapeChar","selectableValues":[],"required":false,"group":"","groupOrder":5,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_4"}],"objectClassType":"com.thinkbiganalytics.discovery.parsers.csv.CSVFileSchemaParser","objectShortClassType":"CSVFileSchemaParser","propertyValuesDisplayString":null,"supportsBinary":false,"generatesHiveSerde":true,"tags":["CSV","TSV"],"clientHelper":null,"allowSkipHeader":true,"groups":[{"group":"","layout":"column","properties":[{"name":"Auto Detect?","displayName":"Auto Detect?","value":"true","values":null,"placeholder":"","type":"select","hint":"Auto detect will attempt to infer delimiter from the sample file.","objectProperty":"autoDetect","selectableValues":[{"label":"true","value":"true","hint":null},{"label":"false","value":"false","hint":null}],"required":false,"group":"","groupOrder":1,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_0"},{"name":"Header?","displayName":"Header?","value":"true","values":null,"placeholder":"","type":"select","hint":"Whether file has a header.","objectProperty":"headerRow","selectableValues":[{"label":"true","value":"true","hint":null},{"label":"false","value":"false","hint":null}],"required":false,"group":"","groupOrder":2,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_1"},{"name":"Delimiter Char","displayName":"Delimiter Char","value":",","values":null,"placeholder":"","type":"string","hint":"Character separating fields","objectProperty":"separatorChar","selectableValues":[],"required":false,"group":"","groupOrder":3,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_2"},{"name":"Quote Char","displayName":"Quote Char","value":"\'","values":null,"placeholder":"","type":"string","hint":"Character enclosing a quoted string","objectProperty":"quoteChar","selectableValues":[],"required":false,"group":"","groupOrder":4,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_3"},{"name":"Escape Char","displayName":"Escape Char","value":"\\\\","values":null,"placeholder":"","type":"string","hint":"Escape character","objectProperty":"escapeChar","selectableValues":[],"required":false,"group":"","groupOrder":5,"layout":"column","hidden":false,"pattern":"","patternInvalidMessage":"Invalid Input","formKey":"property_4"}]}],"editable":true}'
}
headers = {
'accept': "application/json",
'authorization': "Basic ZGxhZG1pbjp0aGlua2JpZw==",
'cache-control': "no-cache",
}
url = "http://localhost:8400/proxy/v1/schema-discovery/hive/sample-file"
req = requests.post(url, data=payload, headers=headers)
print(req.text)
For some reason im getting the error "HTTP 415 Unsupported Media Type".
I'm trying to send a csv, along with some json in a multipart form. I originally had this working with http.client but the way I was doing it it was adding extra line breaks and carriage return literals into the multipart message body.
Any help greatly appreciated!
The issue I couldnt originally see was with declaring the file type in the file tuple, shown below as 'text/csv' in the solution.
import http.client
file = { 'file' : ('csvtest.csv', open('csvtest.csv', 'rt'), 'text/csv') }
payload = { 'parser' : '{object trimmed for comment}' }
headers = { 'accept': "application/json", 'authorization': "Basic ZGxhZG1pbjp0aGlua2JpZw==", }
url = "http://localhost:8400/proxy/v1/schema-discovery/hive/sample-file"
req = requests.post(url, data=payload, files=file, headers=headers)
pprint(req.text)