Gcode upload with python and OpenAPI
-
RepRapFirmware: 3.5.4
OpenAPI yaml: 3.6 and also tested with 3.4 -
@cnc65 I am not a python expert but I used swagger to generate a python api using 3.6.0.
Looking at that code for your error message i found it in "rest.py":
def request(self, method, url, query_params=None, headers=None, body=None, post_params=None, _preload_content=True, _request_timeout=None): """Perform requests. :param method: http request method :param url: http request url :param query_params: query parameters in the url :param headers: http request headers :param body: request json body, for `application/json` :param post_params: request post parameters, `application/x-www-form-urlencoded` and `multipart/form-data` :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of (connection, read) timeouts. """ method = method.upper() assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS'] if post_params and body: raise ValueError( "body parameter cannot be used with post_params parameter." ) post_params = post_params or {} headers = headers or {} timeout = None if _request_timeout: if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821 timeout = urllib3.Timeout(total=_request_timeout) elif (isinstance(_request_timeout, tuple) and len(_request_timeout) == 2): timeout = urllib3.Timeout( connect=_request_timeout[0], read=_request_timeout[1]) if 'Content-Type' not in headers: headers['Content-Type'] = 'application/json' try: # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: if query_params: url += '?' + urlencode(query_params) if re.search('json', headers['Content-Type'], re.IGNORECASE): request_body = '{}' if body is not None: request_body = json.dumps(body) r = self.pool_manager.request( method, url, body=request_body, preload_content=_preload_content, timeout=timeout, headers=headers) elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501 r = self.pool_manager.request( method, url, fields=post_params, encode_multipart=False, preload_content=_preload_content, timeout=timeout, headers=headers) elif headers['Content-Type'] == 'multipart/form-data': # must del headers['Content-Type'], or the correct # Content-Type which generated by urllib3 will be # overwritten. del headers['Content-Type'] r = self.pool_manager.request( method, url, fields=post_params, encode_multipart=True, preload_content=_preload_content, timeout=timeout, headers=headers) # Pass a `string` parameter directly in the body to support # other content types than Json when `body` argument is # provided in serialized form elif isinstance(body, str): request_body = body r = self.pool_manager.request( method, url, body=request_body, preload_content=_preload_content, timeout=timeout, headers=headers) else: # Cannot generate the request from given parameters msg = """Cannot prepare a request message for provided arguments. Please check that your arguments match declared content type.""" raise ApiException(status=0, reason=msg) # For `GET`, `HEAD` .....
Does that shed any light on why its failing?
Things to try:
Use the CURL commands as a test in the documentation here;
https://github.com/Duet3D/RepRapFirmware/wiki/HTTP-requests#post-rr_upload
That proves the duet side of thingsHave thieving on the same version (preferably 3.6, so for RRF use 3.6beta4)
-
@T3P3Tony Thank you for your help.
What I have tried so far:- Update RRF to 3.6beta4
- Test CURL commands:
F:\temp>curl http://192.168.2.1/rr_connect?password= {"err":0,"sessionTimeout":8000,"boardType":"duet3mb6hc102","apiLevel":2,"sessionKey":0} F:\temp>curl --data-binary @"test.g" "http://192.168.2.1/rr_upload?name=/gcodes/test.g" {"err":0} F:\temp>
No success with Python so far.
What I dont understand is that the Python function generated from OpenAPI has only one parameter "name". The parameters "time" and "crc32" are optional. But at least two variables are required: source(path_and_filename.gcode) and destination(name) like in CURL.
rr_upload_post
Example
from __future__ import print_function import time import swagger_client from swagger_client.rest import ApiException from pprint import pprint # create an instance of the API class api_instance = swagger_client.DefaultApi() name = 'name_example' # str | Path to the file to upload time = '2013-10-20T19:20:30+01:00' # datetime | ISO8601-like represenation of the time the file was last modified (optional) crc32 = 'crc32_example' # str | CRC32 checksum of the file content as hex string *without* leading `0x`. Usage of this parameter is encouraged (optional) try: # Upload a file api_response = api_instance.rr_upload_post(name, time=time, crc32=crc32) pprint(api_response) except ApiException as e: print("Exception when calling DefaultApi->rr_upload_post: %s\n" % e)
Parameters
Name Type Description Notes name str Path to the file to upload time datetime ISO8601-like represenation of the time the file was last modified [optional] crc32 str CRC32 checksum of the file content as hex string without leading `0x`. Usage of this parameter is encouraged [optional] -
@cnc65 said in Gcode upload with python and OpenAPI:
so curl is working, there is an issue with the python implementation or the API description in YAML file
What I don't understand is that the Python function generated from OpenAPI has only one parameter "name". The parameters "time" and "crc32" are optional. But at least two variables are required: source(path_and_filename.gcode) and destination(name) like in CURL.
I think the "name" parameter is the destination path & filename. however the comments in the YAML file imply its the source:
parameters: - name: 'name' in: query description: 'Path to the file to upload' required: true schema: type: string - name: 'time' in: query description: 'ISO8601-like represenation of the time the file was last modified' required: false schema: type: string format: 'date-time' - name: 'crc32' in: query description: 'CRC32 checksum of the file content as hex string *without* leading `0x`. Usage of this parameter is encouraged' required: false schema: type: string
@chrishamm can you help?
-
Is a solution to this problem in progress?
-
undefined cnc65 marked this topic as a question
-
-
@chrishamm can you point to where it is in the API definition? I.e. where is "body" is specified in the definition?
-
-
@chrishamm thanks so this is some issue with swagger?
-
@T3P3Tony Perhaps it was the GET request, not the POST request? I'm not sure.
-
@chrishamm I looked at the swagger post code.