Python Rest client api to upload a file

25,785

Solution 1

requests library worked with below changes in my code :

import requests
from requests.auth import HTTPBasicAuth
import json
from pathlib import Path

file_ids = ''
headers={'Username': '[email protected]', 'apikey':'123-456'}
# Upload file

f = open('C:/Users/ADMIN/Downloads/abc.zip', 'rb')

files = {"file": ("C:/Users/ADMIN/Downloads/abc.zip", f)}

resp = requests.post("https:// ../analytics/upload_file", files=files, headers=headers )
print resp.text
print "status code " + str(resp.status_code)

if resp.status_code == 201:
    print ("Success")
    data = json.loads(resp.text)
    file_ids = data['file_ids']
    print file_ids
else:
    print ("Failure")

Solution 2

Use urllib3 module.

https://urllib3.readthedocs.io/en/latest/user-guide.html

Files & binary data

For uploading files using multipart/form-data encoding you can use the same approach as Form data and specify the file field as a tuple of (file_name, file_data):

with open('example.txt') as fp:
    file_data = fp.read()
r = http.request(
    'POST',
    'http://httpbin.org/post',
    fields={ 
        'filefield': ('example.txt', file_data),
    })

json.loads(r.data.decode('utf-8'))['files']
Share:
25,785

Related videos on Youtube

Malar Kandasamy
Author by

Malar Kandasamy

Updated on October 25, 2020

Comments

  • Malar Kandasamy
    Malar Kandasamy over 3 years

    I am using Python 2.7. My Rest server side API works fine and I am able to upload a zip file using Postman. I am trying to upload a zip file using Rest client api. I tried requests package, but it is unable to send the files. I am getting an error : missing file argument.

    This is my python server side code :

    @ns.route('/upload_file', strict_slashes=False)
    class Upload(Resource):
        @api.expect(upload_parser)
        def post(self):
    
            args = upload_parser.parse_args()
            file_nameup = args.file.filename 
    

    Here is the rest api client code :

    import requests
    from requests.auth import HTTPBasicAuth
    import json
    
    headers={'Username': '[email protected]', 'apikey':'123-e01b', 'Content-Type':'application/zip'}
    f = open('C:/Users/ADMIN/Downloads/abc.zip', 'rb')
    
    files = {"file": f}
    
    resp = requests.post("https://.../analytics/upload_file", files=files, headers=headers )
    
    print resp.text   
    
    print "status code " + str(resp.status_code)
    
    if resp.status_code == 200:
        print ("Success")
        print resp.json()
    else:
        print ("Failure")
    

    This is my error : {"message":"Input payload validation failed","errors":{"file":"Missing required parameter in an uploaded file"} status code 400 Failure

    In postman, I passed a zip file with in body with "file" as key and value as abc.zip file. It worked fine. I tried to use httplib library, but it fails as my post url does not contain port number. This the error with httplib :

    python HttpClientEx.py Traceback (most recent call last): File "HttpClientEx.py", line 4, in h = http.client.HTTPConnection(url) File "c:\python27\Lib\httplib.py", line 736, in init (self.host, self.port) = self._get_hostport(host, port) File "c:\python27\Lib\httplib.py", line 777, in _get_hostport raise InvalidURL("nonnumeric port: '%s'" % host[i+1:]) httplib.InvalidURL: nonnumeric port: '// ....net/analytics/upload_file'

    How to invoke rest url post and upload a file using urllib library. Please suggest any other ways to upload file in rest client. Thanks.

    I found another duplicate post :

    Python Requests - Post a zip file with multipart/form-data

    The solution mentioned there did not work. I found that you need to provide the full path of the file, otherwise it will not work.

    • stovfl
      stovfl over 5 years
    • Malar Kandasamy
      Malar Kandasamy over 5 years
      The solution mentioned there did not work. I found that you need to provide the full path of the file, otherwise it will not work. example: files = {"file": ("C:/Users/ADMIN/Downloads/abc.zip", f)} if I specify files = {"file": ("abc.zip", f)}, its not working. Even though my program and zip are in the same folder.
    • stovfl
      stovfl over 5 years
      to provide the full path: This makes no sense. The first parameter in the tuple is used from the server, how to name the uploaded file. I could not imagin how a local path are usefull for a server at all. its not working: This is not helpfull, edit your Question and show requests header and result.json() you get.
    • Malar Kandasamy
      Malar Kandasamy over 5 years
      'file' is the parameter name referred in my server rest api code. Refer python server side code above: file_nameup = args.file.filename What you said is correct. Somehow, the api requires a full path of zip file path, thats why I took long time to find the issue. This is my result : {"message": "File uploaded successfully", "file_ids": "123.zip"}
  • Malar Kandasamy
    Malar Kandasamy over 5 years
    Here, note I removed Content-Type from my header, also I am providing full file name with path in files = {"file": ("C:/Users/ADMIN/Downloads/abc.zip", f)}
  • eatmeimadanish
    eatmeimadanish over 5 years
    It's just an example pulled from the site. You would need to modify it for your purposes.