Python Requests: Post JSON and file in single request

前端 未结 6 510
天涯浪人
天涯浪人 2020-12-01 05:16

I need to do a API call to upload a file along with a JSON string with details about the file.

I am trying to use the python requests lib to do this:



        
相关标签:
6条回答
  • 2020-12-01 05:36

    What is more:

    files = {
        'document': open('file_name.pdf', 'rb')
    }
    

    That will only work if your file is at the same directory where your script is.

    If you want to append file from different directory you should do:

    files = {
        'document': open(os.path.join(dir_path, 'file_name.pdf'), 'rb')
    }
    

    Where dir_path is a directory with your 'file_name.pdf' file.

    But what if you'd like to send multiple PDFs ?

    You can simply make a custom function to return a list of files you need (in your case that can be only those with .pdf extension). That also includes files in subdirectories (search for files recursively):

    def prepare_pdfs():
        return sorted([os.path.join(root, filename) for root, dirnames, filenames in os.walk(dir_path) for filename in filenames if filename.endswith('.pdf')])
    

    Then you can call it:

    my_data = prepare_pdfs()
    

    And with simple loop:

    for file in my_data:
    
        pdf = open(file, 'rb')
    
        files = {
            'document': pdf
        }
    
        r = requests.post(url, files=files, ...)
    
    0 讨论(0)
  • 2020-12-01 05:37

    I'm don't think you can send both data and files in a multipart encoded file, so you need to make your data a "file" too:

    files = {
        'data' : data,
        'document': open('file_name.pdf', 'rb')
    }
    
    r = requests.post(url, files=files, headers=headers)
    
    0 讨论(0)
  • 2020-12-01 05:39

    Don't encode using json.

    import requests
    
    info = {
        'var1' : 'this',
        'var2'  : 'that',
    }
    
    data = {
        'token' : auth_token,
        'info'  : info,
    }
    
    headers = {'Content-type': 'multipart/form-data'}
    
    files = {'document': open('file_name.pdf', 'rb')}
    
    r = requests.post(url, files=files, data=data, headers=headers)
    

    Note that this may not necessarily be what you want, as it will become another form-data section.

    0 讨论(0)
  • 2020-12-01 05:40

    See this thread How to send JSON as part of multipart POST-request

    Do not set the Content-type header yourself, leave that to pyrequests to generate

    def send_request():
        payload = {"param_1": "value_1", "param_2": "value_2"}
        files = {
            'json': (None, json.dumps(payload), 'application/json'),
            'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
        }
    
        r = requests.post(url, files=files)
        print(r.content)
    
    0 讨论(0)
  • 2020-12-01 05:49

    For sending Facebook Messenger API, I changed all the payload dictionary values to be strings. Then, I can pass the payload as data parameter.

    import requests
    
    ACCESS_TOKEN = ''
    
    url = 'https://graph.facebook.com/v2.6/me/messages'
    payload = {
            'access_token' : ACCESS_TOKEN,
            'messaging_type' : "UPDATE",
            'recipient' : '{"id":"1111111111111"}',
            'message' : '{"attachment":{"type":"image", "payload":{"is_reusable":true}}}',
    }
    files = {'filedata': (file, open(file, 'rb'), 'image/png')}
    r = requests.post(url, files=files, data=payload)
    
    0 讨论(0)
  • 2020-12-01 05:52

    I have been using requests==2.22.0

    For me , the below code worked.

    import requests
    
    
    data = {
        'var1': 'this',
        'var2': 'that'
    }
    
    r = requests.post("http://api.example.com/v1/api/some/",
        files={'document': open('doocument.pdf', 'rb')},
        data=data,
        headers={"Authorization": "Token jfhgfgsdadhfghfgvgjhN"}. #since I had to authenticate for the same
    )
    
    print (r.json())
    
    0 讨论(0)
提交回复
热议问题