python upload file with curl - python

i'm trying to upload an apk to server
the code i used to upload using curl is written like this:
curl -u "musername:mypass" -X POST "https://myurl/upload" -F "file=#D:\path\to\location.apk"
i tried to make a script using python with requests library like this:
response = requests.post(
self.urlUpload,
files={"file" : open(self.apkLocation, 'r')},
auth=(self.BSUsername, self.BSToken)
)
but it gives me errors:
{"error":"Malformed archive"}
anyone knows why this erros appeared?

Have you had a chance to try something like below?
import requests
files = {
'file': ('/path/to/app/file/Application-debug.apk', open('/path/to/app/file/Application-debug.apk', 'rb')),
}
response = requests.post('https://api-cloud.browserstack.com/app-automate/upload',
files=files,
auth=('BSUsername ', 'BSToken'))
print (response.text)#THE APP URL (bs://<hashed appid>) RETURNED IN THE RESPONSE OF THIE CALL
Check the BrowserStack REST API doc here

Related

How to upload a file to Linkedin via Python requests?

I am trying to upload a video via REST API to LinkedIn. I have completed all the steps and everything is working fine except for the video upload API.
Here is the curl command for upload videos, mentioned on the documentation of LinkedIn:
curl -v -H "Content-Type:application/octet-stream" --upload-file docs/short_video.mp4 'https://api.linkedin.com/mediaUpload/C5400AQHpR1ANqMWqNA/uploadedVideo/0?ca=vector_feedshare&cn=uploads_secure&ccn=ambry-video&m=AQLEZ2pjh43pagYYYXRaCyztOykwDzluHkkYTbsMjNUzivrEOeObw9h3&app=1234&sync=1&v=beta&ut=1KeEm4JnMnJpo1'
When I run this curl command, the video uploaded successfully and I got the status AVAILABLE, but the same thing with python post requests is not working.
Here is the python code that I converted from the curl command:
headers = {
'Content-Type': 'application/octet-stream'
}
filePath = 'docs/short_video.mp4'
files_data = {
'upload_file': (open(filePath, 'rb'))
}
post_url = 'https://api.linkedin.com/mediaUpload/C5400AQHpR1ANqMWqNA/uploadedVideo/0?ca=vector_feedshare&cn=uploads_secure&ccn=ambry-video&m=AQLEZ2pjh43pagYYYXRaCyztOykwDzluHkkYTbsMjNUzivrEOeObw9h3&app=1234&sync=1&v=beta&ut=1KeEm4JnMnJpo1'
req = requests.put(post_url, files=files_data, headers=headers)
I am not sure what I am doing wrong in my python code. Is there something that I am missing? Any kind of help would be greatly appreciated.
upload_request_data = response_data['value']['uploadMechanism'][
'com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'
]
response = requests.post(
upload_request_data['uploadUrl'],
headers=upload_request_data['headers'],
data=open(filePath, 'rb'),
)

Passing a remote file to a http post request in python

I have a rest api that offers an upload file post functionality. To test this, I simply did this on my python test code:
fo = open('file.zip', 'rb')
rb_file = {'confile': ('file.zip', fo, 'multipart/form-data')}
resp = requests.post(url,files=rb_file)
fo.close()
This request returns a uuid response {ce9f2d23-8ecd-4c60-9d31-aef0be103d44} that is needed for initiating another post run for a scan.
From Swagger, manually passing this uuid to the scan post request generates the following curl:
curl -X POST "http://....../scan" -H "Content-Type: multipart/form-data" -F "FilID=ce9f2d23-8ecd-4c60-9d31-aef0be103d44"
My question is how to convert this curl to a python request code noting that I no longer have the file on my local machine. The server seems to be expecting a -F rather than a param. How do I pass a file that doesn't exist on my local machine to http request in this case? All I have is the filID. I tried running as param but that doesn't find the resource.
try this !
import requests
headers = {
'Content-Type': 'multipart/form-data',
}
files = {
'FilID': (None, 'ce9f2d23-8ecd-4c60-9d31-aef0be103d44'),
}
response = requests.post('http://....../scan', headers=headers, files=files)

Python 2.7 requests REST API call not working same as curl

I am trying to do a curl post query using requests python 2.7, however the API response differently using curl vs. requests lib.
The post query is pretty simple a file and name-value-pair data as the API params.
Below is the curl multipart post request:
curl -uadmin:blabla123 -X POST 127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/6a0ab661-1c43-43ed-b07f-a564f6bcb5ca/children -F filedata=#file1.txt -F name=document__55;nodeType=content
The python 2.7 code is as below:
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
from config import USER, PASSWD
def createDocument( documentFilename, documentMetadata, targetFolderNodeId):
'''
Uploads a file and its meta-data to the CMIS server under the specified
target folder
'''
with open(documentFilename, 'rb') as file:
files = {'file': file}
# createURL = 'http://127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/{0}/children'.format( targetFolderNodeId )
createURL = 'http://127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/6a0ab661-1c43-43ed-b07f-a564f6bcb5ca/children'
data = {
"name":"document__55",
"nodeType":"cm:content",
}
response = requests.post( createURL, data = data, files = files, auth=HTTPBasicAuth(USER, PASSWD) )
print(response)
print(response.json)
print(response.text)
createDocument('file1.txt', '', '')
Curl returns 200 http code but the script oddly returns 400.
Any help is much appreciate it.
At a first glace the reasons for that script failing vs curl working could be more than one:
nodeType=content in the curl, while "nodeType":"cm:content" in the script
there's an additional comma in the script's payload second line
you're not setting the Content-Type header as multipart/form-data in the script, which curl's -F option actually does
Also, the endpoint should provide a verbose error along with the 400 response. If it does, that could be helpful to identify the error cause.
in fact in the curl I have -F filedata=#file1.txt but in the script I have files = {'file': file} which is not the same so I just had to use files = {'filedata': file} :)
def createDocument( documentFilename, documentMetadata, targetFolderNodeId):
'''
Uploads a file and its meta-data to the CMIS server under the specified
target folder
'''
with open(documentFilename, 'rb') as file:
files = {'filedata': file}
createURL = 'http://127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/{0}/children'.format( targetFolderNodeId )
data = {
"name":"document__77",
"nodeType":"cm:content"
}
response = requests.post( createURL, data = data, files = files, auth=HTTPBasicAuth(USER, PASSWD) )
print(response)
print(response.json)
print(response.text)
print(response.headers)
# print([i for i in dir(response) if 'header' in i])

Unable to upload file to REST API

I have this cURL request that I want to convert into a Python Request code.
The cURL content is
curl -H "X-PrettyPrint: 1"
-F 'json={"title":"PandaTest"};type=application/json'
-F "fileData=#rename.py;type=application/octet-stream"
-X POST https://cs31.salesforce.com/services/data/v39.0/connect/files/users/me
-H 'Authorization: 00Dp000000.....CqqU0.S_5r' --insecure
For more details of the request check the SalesForce docs it contains the HTTP request message - here. Search for the section Upload a file to the Files home.
The Python counter part of it what I've written is
import requests
files = {
"fileData" : open("rename.py", "rb"),
"json" : '{"title":"PandaTest"}'
}
headers = {
'Authorization': 'OAuth 00Dp00000000u....n3ZGuoZK2wYJRCqqU0.S_5r',
"Content-Disposition": "form-data 'fileData'"
}
r = requests.post('https://cs31.salesforce.com/services/data/v39.0/connect/files/users/me/',
data=files, headers=headers)
data = json.loads(r.text)
print data
My request is sent successfully but I get an error Missing expected "fileData" binary parameter.I have a feeling the request which I'm trying to send is not formed correctly. Where exactly did I go wrong?
I have a feeling I'm not handling the 2 -F in the cURL request correctly.
This line:
"fileData" : open("rename.py", "rb"),
is setting "fileName" to the object that is returned when you open a file. If you would like "fileName" to be the actual contents of the file, then change the line to this:
"fileData" : open("rename.py", "rb").read(),
That will read all the bytes in the file and set "fileName" to them.

Python Requests Put not working with build.phonegap.com

I am making a python build script for a phonegap project.
I need to open the ios key before i build
I am trying to do this with a http put request through the requests module for python.
If i do it with cURL from command line, it works fine
curl -vvv -d 'data={"password":"myPassWord"}' -X PUT https://build.phonegap.com/api/v1/keys/ios/193686?auth_token=passwordlesstokenphg
But from python like this.
password_for_key = {'password': 'myPassword'}
authentication_token = {'auth_token': 'passwordlesstokenphg'}
requests.put('https://build.phonegap.com/api/v1/keys/ios/193686', data=password_for_key, params=authentication_token)
It just returns the json you would recieve if you did a cURL without the data.
For me it seems like the data is not being sent to phonegap correctly.
API reference from build.phonegap.com
docs.build.phonegap.com/en_US/2.9.0/developer_api_write.md.html
Please help :)
So when you do
curl -d "..." -X PUT https://example.com
curl sends exactly what's in that string. requests does not translate so directly to curl. To do something similar in requests you need to do the following:
import json
password_for_key = {'password': 'myPassword'}
authentication_token = {'auth_token': 'passwordlesstokenphg'}
requests.put('https://build.phonegap.com/api/v1/keys/ios/193686',
data={'data': json.dumps(password_for_key)},
params=authentication_token)
What requests will do is build data={"password":"myPassword"} for you if you use the above. First you have to JSON encode the data in password_for_key then pass it in the dictionary to data.

Categories