0

I'm using python to upload some .jpg images to my created photoscene but I'm constantly getting this error.

{'Usage': '0.48637413978577', 'Resource': '/file', 'Error': {'code': '19', 'msg': "Specified Photoscene ID doesn't exist in the database"}}

This is my code, photoscene creation works great, I get the photoscene id and copy that as a string to store it as "sceneId"


formData = {'Content-Type': 'multipart/form-data', 'Authorization': 'Bearer eyXXXX'}

sceneId = "l5w----etc-etc------qQ"

# This bit is so I can use tkinter to choose my images
application_window = tk.Tk()
application_window.withdraw()
answer = filedialog.askopenfilenames(parent=application_window,
                                    initialdir=os.getcwd(),
                                    title="Please select one or more files:",
                                    filetypes=[("Image files", ".jpg .jpeg")])
if answer != "":
    files = {
        "photosceneid":(None, sceneId),
        "type":(None, "image")
    }
    n=-1
    for a in answer:
        n = n+1
        a = a.replace("/", "//")
        files["file[{x}]".format(x=n)] = (a, open(a,"rb"))
    # This bit adds keys and values to the dictionary as "file[0]": ("path//to//image//", open("path//to//image//","rb"))

    r = requests.post("https://developer.api.autodesk.com/photo-to-3d/v1/file",headers=formData,files=files).json()
    print(r)

I'm following the snips from the official api reference

curl -v 'https://developer.api.autodesk.com/photo-to-3d/v1/file' \
  -X 'POST' \
  -H 'Authorization: Bearer eyjhbGCIOIjIuzI1NiISimtpZCI6...' \
  -F "photosceneid=hcYJcrnHUsNSPII9glhVe8lRF6lFXs4NHzGqJ3zdWMU" \
  -F "type=image" \
  -F "file[0]=@c:/sample_data/_MG_9026.jpg" \
  -F "file[1]=@c:/sample_data/_MG_9027.jpg"

Thanks for reading and for the help!

G-BC
  • 101
  • 1
  • 10
  • what was the output in the response when you created the scene? was there any error message? – Bryan Huang Apr 28 '20 at 10:07
  • Just a 200 response: `{'Usage': '0.63232898712158', 'Resource': '/photoscene', 'Photoscene': {'photosceneid': 'XX'}}` I tried deleting the photoscene today and I had no problem, even tried to delete it twice just in case but the photoscene didn't exist (because I had just deleted it), so it is working, maybe it takes some time to process the photoscene? – G-BC Apr 28 '20 at 13:27
  • Also GET progress returns a sucessful response {'Usage': '0.57368898391724', 'Resource': '/photoscene/XX/progress', 'Photoscene': {'photosceneid': 'XX', 'progressmsg': 'Created', 'progress': '0'}} Maybe it's problem of the upload endpoint I'm most doubtful of my files dict, I think the format is causing the problem. Changing the parameters for invalid ones gives the same error response (No PS with that ID) – G-BC Apr 28 '20 at 14:21
  • If serves a purpose, this is the data I'm sending when creating the scene `data = {'scenename': 'FirstTest', 'callback': 'email://my@email.com', 'format': 'rcm', 'scenetype': 'object', 'version': '2.0'}` – G-BC Apr 28 '20 at 20:09

2 Answers2

2

The problem is that you are sending the photosceneid data as a file. In the cURL snip from official api

curl -v 'https://developer.api.autodesk.com/photo-to-3d/v1/file' \
-X 'POST' \
-H 'Authorization: Bearer eyjhbGCIOIjIuzI1NiISimtpZCI6...' \
-F "photosceneid=hcYJcrnHUsNSPII9glhVe8lRF6lFXs4NHzGqJ3zdWMU" \
...

-F flag means form (in in case of cURL) and that's not necessary a file.

Thus, you'll have to send the photosceneid and the type as data, instead of file:

from requests_toolbelt import MultipartEncoder
import requests

url = "https://developer.api.autodesk.com/photo-to-3d/v1/file"

payload = MultipartEncoder(
   fields={'photosceneid': MY_PHOTOSCENE,
           'type': 'image',
           'file[0]': ("DSC_5428.JPG", open('./DSC_5428.JPG', 'rb'), 'image/jpg')
        }
  )


headers = {
 'Content-Type': payload.content_type,
 'Authorization': TOKEN
}


req = requests.request("POST",
                      url,
                      headers=headers,
                      data=payload
                     )
denis-grigor
  • 505
  • 5
  • 9
  • Your code makes more sense but still doesn't work. Same error. I tried changing the content type and making files both a list and a dict – G-BC Apr 28 '20 at 16:44
  • 1
    @G-BC I fixed the code. It turns out that the content type, instead of 'x-www-form-urlencoded', it has to be 'multipart/form-data'. For these kind of requests (posting large files), the "requests" docs recommend using "requests-toolbelt". I've fixed and tested the code, this should work now. – denis-grigor May 01 '20 at 18:57
  • That actually did it! I was using multipart/form-data but didn't know about the requests-toolbelt, just a side note for anyone reading, to append files to the fields dict you have to define it before using MultipartEncoder. – G-BC May 02 '20 at 14:59
1

For the record there's an issue with our backend that would lead to duplicate scene IDs ...

Our Engineering is actively working on this issue - for the time being as a workaround please create another scene if you ever run into similar issues again ...

And the scene id you were using in your request to upload files was incorrect ... in fact that was from our example here

If you followed the doc here to create a scene you should be able to get a scene ID in the response, such as below:

{
  "Photoscene": {
    "photosceneid": "hcYJcrnHUsNSPII9glhVe8lRF6lFXs4NHzGqJ3zdWMU"
  }
}

And be sure to reference this in your future requests ....

Bryan Huang
  • 5,247
  • 2
  • 15
  • 20
  • I was afraid the snip would cause confusion, I just added it as a reference. I am getting a new PS Id successfully every time, and I'm able to GET progress and DELETE but can't upload files. I can make the rest of the endpoints work but that one – G-BC Apr 29 '20 at 12:15