How to upload a file to Linkedin via Python requests? - python

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'),
)

Related

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 upload file with curl

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

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])

how to call the API from SkyBiometry in a python script

I am new at stackoverflow and to programming with python and I am trying to get an emotion analyses for images from my hard disk by using the service of skybiometry.com. The example link of them is like: "http://api.skybiometry.com/fc/faces/detect.json?api_key=aa754b54b37&api_secret=4b3a4c6d4c&urls=http://theweeklyworld.com/wp-content/uploads/2014/08/child-happy-face1.jpg&attributes=all" and I want to do this in my python-script with my image. On their website https://skybiometry.com/documentation/ on point 4.13 they said that the request has to be formed as a MIME if I want to analyze images from my hard disk. I do not know how to handle this. In an other project of mine I have done the request like this
import requests
auth_headers = {
'api_key': api_key,
'api_secret': api_secret,
}
url = 'http://api.skybiometry.com/fc/faces/detect'
files = { 'source': open(path + ".jpg", 'rb')
}
data = { 'timeout': 60
}
response = requests.post(url, files=files, data=data, headers=auth_headers)
print (response.json())
Can anyone help me to adjust this request to make it work?
Thanks a lot!
You need to change api_key and api_secret for your own skybiometry credentials to use that python script.
Anyway, I prefer installing the api client skybiometry first for python and then use your python scripts. To install it you need to follow these steps:
git clone git#github.com:SkyBiometry/python-face-client.git
cd python-face-client
python setup.py build
python setup.py install
Then you can use the api-client using import with your skybiometry credentials, for example:
from face_client import FaceClient
client = FaceClient('API_KEY', 'API_SECRET')
Changing the API_KEY and API_SECRET for your own skybiometry credentials.
For more examples and how to use the api-client, you can watch this: https://github.com/SkyBiometry/python-face-client
Greetings.

unable to post file+data using python-requests

I'm able to post file using curl
curl -X POST -i -F name='barca' -F country='spain' -F
file=#/home/messi/Desktop/barca.png 'http://localhost:8080/new_org/hel/concerts'
Which I can get (file) as
curl -X GET -H 'Accept: image/png' 'http://localhost:8080/new_org/hel/concerts/<id or name of entity>'
But when I tried same thing using requests.post, I got error. Does anybody know why this happen. (Post Error encounter when file pointer is not at last, but when file pointer is at last, I got response 200 but file is not posted)
import requests
url = 'http://localhost:8080/new_org/hel/concerts'
file = dict(file=open('/home/messi/Desktop/barca.png', 'rb'))
data = dict(name='barca', country='spain')
response = requests.post(url, files=file, data=data)
Error: (from usergrid) with response code: 400
{u'duration': 0,
u'error': u'illegal_argument',
u'error_description': u'value is null',
u'exception': u'java.lang.IllegalArgumentException',
u'timestamp': 1448330119021}
https://github.com/apache/usergrid
I believe the problem is that Python is not sending a content-type field for the image that you are sending. I traced through the Usergrid code using a debugger and saw that curl is sending the the content-type for the image and Python is not.
I was able to get this exact code to work on my local Usergrid:
import requests
url = 'http://10.1.1.161:8080/test-organization/test-app/photos/'
files = { 'file': ('13.jpg', open('/Users/dave/Downloads/13.jpg', 'rb'), 'image/jpeg')}
data = dict(name='barca', country='spain')
response = requests.post(url, files=files, data=data)
It is possible that Waken Meng's answer did not work because of the syntax of the files variable, but I'm no Python expert.
I met a problem before when i try to upload image files. Then I read the doc and do this part:
You can set the filename, content_type and headers explicitly:
Here is how I define the file_data:
file_data = [('pic', ('test.png', open('test.png'), 'image/png'))]
r = requests.post(url, files=file_data)
file_data should be a a list: [(param_name, (file_name, file, content_type))]
This works for me, hope can help you.

Categories