Search code examples
pythonpython-requestshttp-post

Cannot upload images using Python requests


I am having problem uploading some images using python requests. The website I am trying to upload a photo is myauto.enter image description here

When I click on it and select image, I can see in the browser network tab that on this endpoint is the request sent:

https://static.my.ge/

This is form data that is sent from browser.
enter image description here

And to see the full source: enter image description here

First I tried to post the data using this script:

image_data = (
    # 'Files[]: (binary)
    ('do', 'Files'),
    ('Func', 'UploadPhotos'),
    ('SiteID', 1),
    ('UserID', 4134977),
    ('IP', 'XX.XX.XX.XX'),
    ('UploadedFiles', 0)
)
# NOTE - we can have multiple `Files[]`
image_urls = tuple()
image_urls += (('Files[]', 'some_image.jpg'),)
response = requests.request(
    method='POST',
    url='https://static.my.ge/',
    data=self.image_data + image_urls,
    headers=headers
)

Headers I am using:

headers = {
    'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
    'Accept-Encoding': "gzip, deflate, br",
    'Accept': "*/*",
    'Connection': "keep-alive",
    'Host': "static.my.ge",
    'Origin': "https://www.myauto.ge",
    'Referer': "https://www.myauto.ge/ka/add",
    'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90", "GoogleChrome";v="90"',
    'sec-ch-ua-mobile': "?0",
    'Sec-Fetch-Dest': "empty",
    'Sec-Fetch-Mode': "cors",
    'Sec-Fetch-Site': "cross-site",
    'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
    'cache-control': "no-cache"
}

But I get the following response all the time:

{'StatusID': 0, 'StatusCode': 0, 'Message': 'Incorrect Func'}

And this is the desired output:

"StatusID": 0,
"StatusCode": 1,
"Message": "Error occurred during the operation",
"Data": {
    "FilesList": [
        "https://static.my.ge/tmp/6db262b3d7a2f9bfd56618640b6deed8_thumbs.jpg"
    ],
    "imgKey": [
        "6db262b3d7a2f9bfd56618640b6deed8"
    ]
}

Then I tried to generate same Webkit Form Boundry and pass that raw string to data, but get the same result all the time. I also tried to send image blob or base64 format, but still got same error.

Then I tried to send request on this endpoint using postman, and It successfully returned the data I was expecting. I chose form-data format in body section and uploaded file through postman. Then I tried to see the logs of the requests and tried to copy it from postman and run using python script, but no success, still got same error. Finally, I tried to copy code snippet from postman code generator, but still no luck. I don't understand what is happening and ran out of ideas.

Edit:

Here is the postman script:

url = "https://static.my.ge"

payload = (
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"Files[]\"; filename=\"some_image.jpg\"\r\n"
    "Content-Type: image/jpeg\r\n\r\n\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"do\"\r\n\r\nFiles\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"SiteID\"\r\n\r\n1\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"UserID\"\r\n\r\n1902119\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"IP\"\r\n\r\nXX.XX.XX.XX\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"UploadedFiles\"\r\n\r\n0\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
    "form-data; name=\"Func\"\r\n\r\nUploadPhotos\r\n"
    "------WebKitFormBoundary7MA4YWxkTrZu0gW--"
)
response = requests.request("POST", url, data=payload, headers=headers)

Also, found out that this is how image is represented in the request. Not sure how to do same in python code: enter image description here

Update: Tried to modify postman generated script:

   payload = (
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"Files[]\"; filename=\"blob\"\r\n"
        "Content-Type: image/jpg\r\n\r\n"
        f"{image}\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"do\"\r\n\r\nFiles\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"SiteID\"\r\n\r\n1\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"UserID\"\r\n\r\n1902119\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"IP\"\r\n\r\nXX.XX.XX.XX\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"UploadedFiles\"\r\n\r\n0\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: "
        "form-data; name=\"Func\"\r\n\r\nUploadPhotos\r\n"
        "------WebKitFormBoundary7MA4YWxkTrZu0gW--"
    )

Tried to put base64 and binary images in place of f{"image"}. But got new error message from server, not sure if it's helpful.

object(Exception)#4 (7) {
  ["message":protected]=>
  string(34) "Invalid image file: /tmp/phpFMI89k"
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(7)
  ["file":protected]=>
  string(58) "/datastore/web/static.my.ge/htdocs/libs/SimpleImageNew.php"
  ["line":protected]=>
  int(130)
  ["trace":"Exception":private]=>
  array(3) {
    [0]=>
    array(6) {
      ["file"]=>
      string(44) "/datastore/web/static.my.ge/htdocs/index.php"
      ["line"]=>
      int(1300)
      ["function"]=>
      string(8) "fromFile"
      ["class"]=>
      string(14) "SimpleImageNew"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(1) {
        [0]=>
        string(14) "/tmp/phpFMI89k"
      }
    }
    [1]=>
    array(6) {
      ["file"]=>
      string(44) "/datastore/web/static.my.ge/htdocs/index.php"
      ["line"]=>
      int(494)
      ["function"]=>
      string(12) "UploadPhotos"
      ["class"]=>
      string(7) "_Static"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(0) {
      }
    }
    [2]=>
    array(6) {
      ["file"]=>
      string(44) "/datastore/web/static.my.ge/htdocs/index.php"
      ["line"]=>
      int(3066)
      ["function"]=>
      string(7) "SetFunc"
      ["class"]=>
      string(7) "_Static"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(0) {
      }
    }
  }
  ["previous":"Exception":private]=>
  NULL
}

Solution

  • import requests
    
    files = {'Files[]': ("1.png", open(r"your/image/path", 'rb'), "image/png", {})}
    
    data = {
        'Func': "UploadPhotos",
        "SiteID": "1",
        "UserID": "xx",  # your user ID here
        "IP": "xx",  # your IP here
        "UploadedFiles": 0
    }
    
    response = requests.post('https://static.my.ge/', files=files, data=data)
    
    print(response.json())
    

    And the result:

    {'StatusID': 0, 'StatusCode': 1, 'Message': 'Error occurred during the operation', 'Data': {'FilesList': ['xxxx.jpg'], 'imgKey': ['xxxx']}}