Convert Word to PDF request authentication issue in Python using Aspose.Words REST API

Ref: https://forum.aspose.cloud/t/error-from-aspose-api-conversion-to-pdf/2182

Following the issue detailed in the reference ticket, we changed our code to use the latest Cloud SDK.
It was working for a few days.

But starting today, we are again seeing the same error message. Please take a look and help us resolve this issue once and for all. We are nearing a production install date.

Please find the log extract below:

DEBUG:SAM-Quote:eSignature for quote france,Product01,201809000555, converting to PDF /tmp/tmpaMWZ_d/proposal-fca716ea-c8d7-43fc-b81d-04d9c6cbe5e5/Standard_Proposal_201809000555/Standard_Bulletin_de_souscription_201809000555.docx
INFO:SAM-Quote:Aspose: Converting file '/tmp/tmpaMWZ_d/proposal-fca716ea-c8d7-43fc-b81d-04d9c6cbe5e5/Standard_Proposal_201809000555/Standard_Bulletin_de_souscription_201809000555.docx' to PDF
{"timestamp": "2018-09-20T08:45:32.617137Z", "message": "eSignature for quote france,Product01,201809000555, document generated (146460 bytes)", "level": "DEBUG"}
{"timestamp": "2018-09-20T08:45:32.617499Z", "message": "eSignature for quote france,Product01,201809000555, converting to PDF /tmp/tmpaMWZ_d/proposal-fca716ea-c8d7-43fc-b81d-04d9c6cbe5e5/Standard_Proposal_201809000555/Standard_Bulletin_de_souscription_201809000555.docx", "level": "DEBUG"}
proposal: convert_document_to_pdf
  proposal: PDF path: /tmp/tmpaMWZ_d/proposal-fca716ea-c8d7-43fc-b81d-04d9c6cbe5e5/Standard_Proposal_201809000555/Standard_Bulletin_de_souscription_201809000555.pdf
aspose: convert_docx_to_pdf
{"timestamp": "2018-09-20T08:45:32.617697Z", "message": "Aspose: Converting file '/tmp/tmpaMWZ_d/proposal-fca716ea-c8d7-43fc-b81d-04d9c6cbe5e5/Standard_Proposal_201809000555/Standard_Bulletin_de_souscription_201809000555.docx' to PDF", "level": "INFO"}
TMPDIR: /tmp/tmpznh0Rx
Ensuring reference index
[2018-09-20 08:45:34,360] ERROR in app: Exception on /sign-documents [GET]
Traceback (most recent call last):
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./ui/server.py", line 237, in wrapper
    return func(*args, **kwargs)
  File "./ui/server.py", line 6400, in get_sign_documents
    document_path = proposal.convert_document_to_pdf(document_path)
  File "./proposal/proposal.py", line 153, in convert_document_to_pdf
    aspose.convert_docx_to_pdf(docx_path, pdf_path)
  File "./ui/aspose.py", line 78, in convert_docx_to_pdf
    response_path = wordsApi.get_document_with_format(request)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/apis/words_api.py", line 6564, in get_document_with_format
    self.__refresh_token()
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/apis/words_api.py", line 16830, in __refresh_token
    files={}, _return_http_data_only=True)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py", line 331, in call_api
    _preload_content, _request_timeout)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py", line 167, in __call_api
    _request_timeout=_request_timeout)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py", line 374, in request
    body=body)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/rest.py", line 284, in POST
    body=body)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/rest.py", line 237, in request
    raise ApiException(http_resp=r)
ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Content-Length': '25', 'X-Powered-By': 'ASP.NET', 'Expires': '-1', 'Server': 'Microsoft-IIS/10.0', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'Date': 'Thu, 20 Sep 2018 08:45:34 GMT', 'Content-Type': 'application/json;charset=UTF-8'})
HTTP response body: {"error":"invalid_grant"}
ERROR:SAM-Quote:Internal error: Traceback (most recent call last):
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
{"timestamp": "2018-09-20T08:45:34.368728Z", "message": "Internal error: Traceback (most recent call last):\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py\", line 1982, in wsgi_app\n    response = self.full_dispatch_request()\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py\", line 1614, in full_dispatch_request\n    rv = self.handle_user_exception(e)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py\", line 1517, in handle_user_exception\n    reraise(exc_type, exc_value, tb)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py\", line 1612, in full_dispatch_request\n    rv = self.dispatch_request()\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py\", line 1598, in dispatch_request\n    return self.view_functions[rule.endpoint](**req.view_args)\n  File \"./ui/server.py\", line 237, in wrapper\n    return func(*args, **kwargs)\n  File \"./ui/server.py\", line 6400, in get_sign_documents\n    document_path = proposal.convert_document_to_pdf(document_path)\n  File \"./proposal/proposal.py\", line 153, in convert_document_to_pdf\n    aspose.convert_docx_to_pdf(docx_path, pdf_path)\n  File \"./ui/aspose.py\", line 78, in convert_docx_to_pdf\n    response_path = wordsApi.get_document_with_format(request)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/apis/words_api.py\", line 6564, in get_document_with_format\n    self.__refresh_token()\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/apis/words_api.py\", line 16830, in __refresh_token\n    files={}, _return_http_data_only=True)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py\", line 331, in call_api\n    _preload_content, _request_timeout)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py\", line 167, in __call_api\n    _request_timeout=_request_timeout)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py\
", line 374, in request\n    body=body)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/rest.py\", line 284, in POST\n    body=body)\n  File \"/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/rest.py\", line 237, in request\n    raise ApiException(http_resp=r)\nApiException: (400)\nReason: Bad Request\nHTTP response headers: HTTPHeaderDict({'Content-Length': '25', 'X-Powered-By': 'ASP.NET', 'Expires': '-1', 'Server': 'Microsoft-IIS/10.0', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'Date': 'Thu, 20 Sep 2018 08:45:34 GMT', 'Content-Type': 'application/json;charset=UTF-8'})\nHTTP response body: {\"error\":\"invalid_grant\"}\n\n", "level": "ERROR"}
    response = self.full_dispatch_request()
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/quofeb/venv/local/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./ui/server.py", line 237, in wrapper
    return func(*args, **kwargs)
  File "./ui/server.py", line 6400, in get_sign_documents
    document_path = proposal.convert_document_to_pdf(document_path)
  File "./proposal/proposal.py", line 153, in convert_document_to_pdf
    aspose.convert_docx_to_pdf(docx_path, pdf_path)
  File "./ui/aspose.py", line 78, in convert_docx_to_pdf
    response_path = wordsApi.get_document_with_format(request)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/apis/words_api.py", line 6564, in get_document_with_format
    self.__refresh_token()
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/apis/words_api.py", line 16830, in __refresh_token
    files={}, _return_http_data_only=True)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py", line 331, in call_api
    _preload_content, _request_timeout)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py", line 167, in __call_api
    _request_timeout=_request_timeout)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/api_client.py", line 374, in request
    body=body)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/rest.py", line 284, in POST
    body=body)
  File "/quofeb/venv/local/lib/python2.7/site-packages/asposewordscloud/rest.py", line 237, in request
    raise ApiException(http_resp=r)
ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Content-Length': '25', 'X-Powered-By': 'ASP.NET', 'Expires': '-1', 'Server': 'Microsoft-IIS/10.0', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'Date': 'Thu, 20 Sep 2018 08:45:34 GMT', 'Content-Type': 'application/json;charset=UTF-8'})
HTTP response body: {"error":"invalid_grant"}
None

@Alexandre_Leclercq

We are unable to reproduce the issue on our end, refresh_token method is working perfectly fine on our end. Nevertheless, we are still looking into this issue (WORDSCLOUD-574) and we would appreciate if you could share the sample code that may help us in diagnosing the issue.

Here’s the sample code:

def initialize():
    storageApiClient = asposestoragecloud.ApiClient(apiKey=apiKey, appSid=appSid)
    storageApi = asposestoragecloud.apis.storage_api.StorageApi(storageApiClient)

    wordsApiClient = asposewordscloud.ApiClient()
    wordsApiClient.configuration.host = '<https://api.aspose.cloud'>
    wordsApiClient.configuration.api_key['api_key'] = api_key
    wordsApiClient.configuration.api_key['app_sid'] = app_sid
    wordsApi = asposewordscloud.WordsApi(wordsApiClient)

def convert_docx_to_pdf(input_path, output_path):
    input_file_name = os.path.basename(input_path)

    with open(input_path, 'rb') as file:
        data = file.read()
    storageApi.put_create(input_file_name, data)

    request = asposewordscloud.models.requests.GetDocumentWithFormatRequest(input_file_name, "pdf")
    response_path = wordsApi.get_document_with_format(request)
    print "Response: {}".format(response_path)
    move(response_path, output_path)

Thanks for sharing the sample code.

Please let us know if any other information is required.

@Alexandre_Leclercq

You are continuously getting invalid_grant error, or are you getting the error occasionally?

We receive it continuously.

Hello Sohail,
We are waiting for this error to be fixed before going live in Production on Wednesday. We work in Paris business hours and you seem to be available during Asia hours.
I propose we set up a call today. It will help us understand and resolve the issue faster.

Could you please let us know how we can call you?

Thanks in advance.

@Alexandre_Leclercq

As per our investigations, OAuth authentication is causing issues in a multithreaded environment. If we make multiple requests in parallel (from different threads) to get Access/Refresh token, one of the API responses returns the empty body.

We are updating the SDK to fix this issue.

Could you please let us know how we can call you?

Unfortunately, we only offer support on the forum.

Hi Sohail,
I see that the status is “analysis complete” for WORDSCLOUD-574.
Could you please share the results of your investigation?

Thank you

@Alexandre_Leclercq

We have deployed the fix to the production. Please spare us some time for extensively testing the few Use Cases. Very soon we will let you know to use the updated SDK.

Do you think your fix in Production will break the applications that currently use your API? Do we need to make some code changes on our end to match your fix in Production?
Please let us know ASAP as we install a new release of our application in Prod today.

@Alexandre_Leclercq

No, all you need to do is just update the SDK, once we released it.

When is the planned release date?

@Alexandre_Leclercq

We have decided that there is no need to make any change in the SDK as changes are deployed on the backend (that let you make API calls in a multi-threaded environment).

Please test the APIs now, things should work fine on your end.

Hi Sohail,

Since the latest changes on the aspose side and our migration to using:
asposewordscloud==18.7.0
asposestoragecloud==1.0.6
we have been experiencing an issue in our Production.

We have hundreds of Users using our tool and PDF conversion is a key feature.
Current situation is pretty damaging to us. Your prompt support would be much appreciated.

The Oauth token handling of the libraries SDK seems faulty.
Once the token becomes expired, basically it is not automatically renewed by the library itself.
On our production, after one day after a deployment, we then cannot use PDF conversion feature.
Could you please investigate this as we believe it requires a change on the SDK and production release on our side?

Our developer raised the following issue directly to you on github for the technical discussion:

@Alexandre_Leclercq

This is really embarrassing. We are looking into the issue at the top priority.

Hi Sohail,

Thanks for your message and making this topic “top priority”.

To allow better communication with Users and planning our new delivery in Production, can you please share with us an estimated date for the availability of the fix. Many thanks.

@Alexandre_Leclercq

We have released an updated version of Aspose.Words Cloud SDK. Please use latest package of Aspose.Words Cloud SDK for Python in production, hopefully, you will not face this issue again.

@Alexandre_Leclercq

Please note the latest API Version V4.0 has no dependency on Aspose.Storage API for storage operations. Now, it has its own storage API methods. And newer version has better memory management and API structure than earlier API versions. Please try the latest version of Aspose.Words Cloud SDK for Python and feel free to contact us for any assistance.