2
$\begingroup$

I'm trying to upload a file using Octoprint REST API - it seems to be possible as per the document described here, Upload file or create folder, but I can't figure it out how to do it with the Python request lib.

Currently what I'm doing is

 import requests

 def def Upload_File():
       fle={'location':"j:/max.gcode"}
       url='http://localhost:5000/api/files/{}'.format('local')
       payload={'select': 'true','print': 'false' }
       header={'content-type': 'multipart/form-data','X-Api-Key': 'FD550BD4DA2442BA906AD1850539D6DB' }
       response = requests.post(url, files=fle,data=payload,headers=header)
       print(response)

if __name__=='__main__':
    Upload_File()

The response returns status is 400

My working env is:

  • Windows 10 and Octoprint running on virtual environment.
$\endgroup$
1
  • 2
    $\begingroup$ FWIW the user posted this identical question on Octoprint's community. $\endgroup$ Commented Jun 1, 2019 at 16:23

1 Answer 1

4
$\begingroup$

I installed octoprint locally to help debug this problem.

  1. Your code snippet says "def def Upload_File" which is a syntax error.
  2. If you go into Octoprint, under Settings -> Logging, and download octoprint.log, you'll notice it says "WARNING - 400 POST /api/files/local (::1): No multipart boundary supplied". A quick google search led me to this StackOverflow question, which states to remove the custom content-type header to fix this problem.
  3. You actually need to open() the file, and assign that value to the 'file' field in the fle object definition, not just tell it where it's currently at on your machine. Additionally, you need to provide a filename field in the fle object.

I got your code snippet working as below, went ahead and swapped your API key back into it. You'll need to point the open() call to the actual location of your file on your hard drive, which I assume is j:/max.gcode, rather than mine which is just opening max.gcode from the running directory of the script.

import requests 

def Upload_File():
   fle={'file': open('max.gcode', 'rb'), 'filename': 'max.gcode'}
   url='http://localhost:5000/api/files/{}'.format('local')
   payload={'select': 'true','print': 'false' }
   header={'X-Api-Key': 'FD550BD4DA2442BA906AD1850539D6DB' }
   response = requests.post(url, files=fle,data=payload,headers=header)
   print(response)

if __name__=='__main__':
   Upload_File()

Finally, if you're going to be doing a whole lot of REST API shenanigans with your Octoprint server, may I offer a prebuilt library?

$\endgroup$
3
  • $\begingroup$ Not sure how much the REST API has changed in the last several updates, but I'd assume it has and that library hasn't been updated in a year. $\endgroup$ Commented Jun 2, 2019 at 22:17
  • $\begingroup$ I actually used that library to fix the code snippet above lol. There may be issues with it, but generally speaking REST APIs tend to be largely the same - from a development standpoint it's almost always better to simply add new functionality rather than changing old functionality, because it breaks less downstream code. The only time I'd go against that is if there's a fundamental problem with the old stuff and it needs to be totally overhauled. $\endgroup$
    – Nach0z
    Commented Jun 3, 2019 at 0:38
  • $\begingroup$ Removing the custom Content-Type header seems to working .now everything works smoothly Thank you ..! $\endgroup$ Commented Jun 3, 2019 at 8:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .