Multipart form post, csv and param python - python-3.x

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)

Related

Upload attachments using clickup api

I'm trying to upload the attachments to a task on clickup.
Clickup API
Click up does provide example code the below is clickup example code
from urllib2 import Request, urlopen
values = """
attachment: raw_image_file (file)
filename: example.png (string)"""
headers = {
'Authorization': '\'access_token\'',
'Content-Type': 'multipart/form-data'
}
request = Request('https://private-anon-f799579c66-clickup20.apiary-mock.com/api/v2/task/{task_id}/attachment?custom_task_ids=&team_id=
', data=values, headers=headers)
response_body = urlopen(request).read()
print response_body
I used it as reference and used requests lib for the project
Here's the code using request lib
import requests
attachment_headers = {'Authorization': self.access_token, 'Content-Type': 'multipart/form-data'}
r = requests.post(f"https://private-anon-df9b125a00-clickup20.apiary-mock.com/api/v2/task/{task_id}/attachment",
files={"attachment": ("attachment", open("attachment.png", "rb")), "filename": "example.png"},
headers=attachment_headers)
print(r)
print(r.json())
I do get the status code as 200 and no error message but when I check on clickup task it doesn't show any attachments
Thanks for the help in advance!
You must remove the 'filename' part of your files param.
file = {"attachment": ('choose_your_name.png', open('file.png', 'rb'))}
headers = {'Authorization': config.clickup_access_token}
request = requests.post(f'https://api.clickup.com/api/v2/task/{task_id}/attachment', files=file, headers=headers)
print(request.json())

Cloud Functions with Requests return 'Could not parse JSON' error

I'm running a cloud function in python to return some data from an api. The function is not executed and I have the error {'code': 400, 'message': 'Could not parse JSON'}.
Here is my code:
import requests
import json
def my_function(request):
url = 'https://blablabla/detailed'
headers = {'X-Api-Key': 'XXXXXXXX',
'content-type': 'application/json'}
data = '{"dateRangeStart":"2020-05-10T00:00:00.000","dateRangeEnd":"2020-05-16T23:59:59.000","amountShown": "HIDE_AMOUNT","detailedFilter":{ "page":"1","pageSize":"50"}}'
#req = requests.post(url, headers=headers, json=data)
req = requests.post(url, headers=headers, data=json.dumps(data))
print(req.json())
how should I format my data variable?
Just give your dict as your json argument, you don't need to specify the content-type headers requests will do it for you.
import requests
def my_function(request):
url = 'https://blablabla/detailed'
headers = {'X-Api-Key': 'XXXXXXXX', }
data = {"dateRangeStart": "2020-05-10T00:00:00.000", "dateRangeEnd": "2020-05-16T23:59:59.000", "amountShown": "HIDE_AMOUNT", "detailedFilter": { "page": "1", "pageSize": "50", }, }
req = requests.post(url, headers=headers, json=data)
print(req.json())
If you do not set a content-type header will try to set it for you:
When using the keyword argument json: it will set it to application/json
When using the keyword argument data (and the value passed respects some criteria, most of the time you don't have to worry about it): it will set it to application/x-www-form-urlencoded
If both kwargs are present data takes priority for the header so it will be set to application/x-www-form-urlencoded
I have not detailed the behaviour when the kwarg files is used as it would be really lengthy and is out of scope here.
Here's the source code.

POST Request to add a AttachmentWrapper in Archer

I am trying to call a post request to upload a file to Archer. Please find my code below :
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
data = open('testdoc.txt','rb').read()
url = "http://rsaarcher/platformapi/core/content/attachment" #my archer url
token = "<my session id token>"
headers = {
'Accept':'application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Authorization': 'Archer session-id="'+token+'"',
'content-type': "application/json;",
'cache-control': "no-cache",
}
response = requests.request("POST", url, data=data, headers=headers, verify = False)
print(response.content)
print(response.status_code)
I am getting the following error :
b'{"Message":"The request contains an entity body but no Content-Type header. The inferred media type \'application/octet-stream\' is not supported for this resource.","ExceptionMessage":"No MediaTypeFormatter is available to read an object of type \'AttachmentWrapper\' from content with media type \'application/octet-stream\'.","ExceptionType":"System.Net.Http.UnsupportedMediaTypeException","StackTrace":" at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\\r\\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"}'
Status code : 415
Nakshatra, did you convert the file you're uploading to base64 beforehand?
Ahh, I realized the data you're sending is the incorrect formatted. It should be as follows:
{
"AttachmentName" : "myFile.docx",
"AttachmentBytes" : "[base64 here]"
}

KeyError when trying to send body to API via function parameter

Attempting to send a POST request to an API via a python function, and I'm unable to iterate through a list of strings and pass strings into the function.
Successfully tested this out in Postman (the request sends a string to the API in the form of "raw Body" as shown in Postman). Copied the code over from Postman to Python, and verified that also works. The problem is that if I change the static string to the function's parameter, I get a KeyError, however if I simply replace the parameter (which is a value, not a key), to a string, then the keyerror goes away.
This works...
payload = "{\"ids\":[\"cb5f9a97c0e749ab67409e78b4fcb11d\"]}" works
But none of these work (note the error code to the right); especially the first two that are exactly the same as above...
payload = "{\"ids\":[\"{0}\"]}".format(id) #gives KeyError: '"ids"'
payload = "{\"ids\":[{0}]}".format(id) #gives KeyError: '"ids"'
payload = "{'ids':'[{0}]'}".format(id) #gives KeyError: "'ids'"
payload = "{ids:[\"{0}\"]}".format(id) #gives KeyError: 'ids'
I also tried to modify the key ('ids') within the key/value pair, which resulted in NameErrors. Since this deviates from the known working example above, I don't think the below attempts are worth continuing to try...
payload = {ids:"[{0}]".format(id)} #gives NameError: name 'ids' is not defined
payload = {ids:"{0}".format(id)} #gives NameError: name 'ids' is not defined
payload = {ids:id} #gives NameError: name 'ids' is not defined
I even verified that the string produced from the list is in fact a string.
Full (relevant) code below:
def cs_delete(id):
print(id)
url = "https://api.crowdstrike.com/devices/entities/devices-actions/v2"
querystring = {"action_name":"hide_host"}
payload = "{'ids':['{0}']}".format(id)
headers = {
'Content-Type': "application/json",
'Authorization': "Bearer " + cs_auth,
'Accept': "*/*",
'Cache-Control': "no-cache",
'Host': "api.crowdstrike.com",
'Accept-Encoding': "gzip, deflate",
'Content-Length': "83",
'Connection': "keep-alive",
'cache-control': "no-cache"
}
response = requests.request("POST", url, data=payload, headers=headers, params=querystring)
print(response.text)
for host in dfList:
print(host)
cs_delete(host)
And for completeness, dfList shows as:
['2a9cf64988e6464f7d2ba7f305a612f3', '5ba4654e1dbe418f7b6361582e3d8f47', '7c6fc20572c241f664813f48bb36c340', 'ccbaf1ebe52042fc6b8269bf86732676']
double the outer curly bracket to escape it or format() will expect the input value should be applied for outer curly bracket rather than {0}
>>> id = 'cb5f9a97c0e749ab67409e78b4fcb11d'
>>> "{{'ids':[{0}]}}".format(id)
"{'ids':[cb5f9a97c0e749ab67409e78b4fcb11d]}"

Post request error: Missing or Invalid Post Body

I'm getting the following error and I'm not sure why:
{"success":false,"errors":["Missing or invalid POST body."],"results":[]}
I'm not sure if there is a problem with how I have my code structured, sending bad json, or what. If you could give me an idea of where to troubleshoot this, that would be great. Thanks. Here is how I have my settings:
headers = {
"Accept": "application/json",
"Authorization": "bearer " + bearer_token,
"Content-Type": "application/json",
}
data = {
'limit':10,
'sort':"MinPrice DESC",
'filters':[
{
'name':'SetName',
'values':'All'
}
]
}
url = 'http://api.tcgplayer.com/V1.9.0/catalog/categories/3/search'
def catalog_data():
r = requests.post(url, headers=headers, data=data)
print(r.text)
catalog_data()
Making the change from data=data to json=data allowed my Post data to be read properly.

Resources