0

I thought I'd be able to solve this with thinking and google, but I'm not...

There's an asana API python wrapper that I forked and extended so it handles file uploads.

I use it inside my administration web app to create tasks and attach .pdf files to them.

The asana API docs specify that

Only the UTF-8 character encoding is supported for both requests and responses.

Everything works fine as long as I don't have German umlauts (ö in this case) in the name of the files I attach.

Here's what I do: I fetch a file URL from a mysql database (everything in utf-8) and take that as an argument for the attach_to_task() function.

This would be an example:

u'/Users/Foo/directory/inv\xf6ice.pdf'

The POST method of the asana API python wrapper then throws a 'Received non 2xx or 404 status code on call' and doesn't upload the file.

However, if I upload the file containing an 'ö' in the filename to asana manually, and then use the python API wrapper to fetch information about the attachments of a task, I get

{u'id': 99347997, u'name': u'inv\xf6ice.pdf'} back.

In someone else's post it says that

'ö' in UTF-8 is '\xc3\xb6'.

But I really don't see what the difference is between the \xf6 I'm trying to upload and the \xf6 they're giving back. However, the problem must reside in the filename containing an umlaut, because with umlaut-free files, it works perfectly fine.

Can someone hint at what I'm doing wrong, please? Thank you.

==========

EDIT

Here's the full error message:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/webapp2-2.5.1-py2.7.egg/webapp2.py", line 1536,     in __call__
rv = self.handle_exception(request, response, e)
  File "/Library/Python/2.7/site-packages/webapp2-2.5.1-py2.7.egg/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/Library/Python/2.7/site-packages/webapp2-2.5.1-py2.7.egg/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
   File "/Library/Python/2.7/site-packages/webapp2-2.5.1-py2.7.egg/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Library/Python/2.7/site-packages/webapp2-2.5.1-py2.7.egg/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Library/Python/2.7/site-packages/webapp2-2.5.1-py2.7.egg/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "main.py", line 877, in post
    self.asana_handler.attach_file_to_task(int(new_task_id), rechn[:-3] + 'pdf')
   File "/Users/Peter/Projekte/app/utils/asana.py", line 401, in  attach_file_to_task
     return self._asana_post('tasks/%d/attachments' % task_id, payload, files=True)
  File "/Users/Peter/Projekte/app/utils/asana.py", line 119, in _asana_post
    if (self.handle_exception(r) > 0):
  File "/Users/Peter/Projekte/app/utils/asana.py", line 60, in handle_exception
    raise AsanaException('Received non 2xx or 404 status code on call')
AsanaException: Received non 2xx or 404 status code on call

===========================

EDIT 2

This is the response header:

{'x-robots-tag': 'none', 'transfer-encoding': 'chunked', 'set-cookie': 
'TooBusyRedirectCount=0', 'x-asana-content-string-length': '54', 'server': 'nginx', 
'connection': 'keep-alive', 'pragma': 'no-cache', 'cache-control': 'no-store', 'date': 
'Fri, 31 Jan 2014 19:47:28 GMT', 'x-asana-preferred-release-revision': 
'20140131_010208_eb5bb829738a01056cb5d46b626ed2169387b5ed', 'content-type': 
'application/json; charset=UTF-8'}

In verbose (debug) mode, I also get this:

{u'errors': [{u'message': u'file: File is not an object'}]}

And curl -v does the job no problem and says the following:

* Adding handle: conn: 0x7f88da803a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f88da803a00) send_pipe: 1, recv_pipe: 0
* About to connect() to app.asana.com port 443 (#0)
*   Trying 107.20.161.243...
* Connected to app.asana.com (107.20.161.243) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
* Server certificate: *.asana.com
* Server certificate: Go Daddy Secure Certification Authority
* Server certificate: Go Daddy Class 2 Certification Authority
* Server auth using Basic with user 'f83V8fK8LZfoVRoA2CSIF'
> POST /api/1.0/tasks/986184874/attachments HTTP/1.1
> Authorization: Basic ZjgzVjhmSy42S0pXOExaZm9WUm9BMkNTSUY6
> User-Agent: curl/7.30.0
> Host: app.asana.com
> Accept: */*
> Content-Length: 28625
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=----------------------------212d9ef46409
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Fri, 31 Jan 2014 20:08:38 GMT
< Content-Type: application/json; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Asana-Content-String-Length: 66
< Pragma: no-cache
< Set-Cookie: TooBusyRedirectCount=0
< Cache-Control: no-store
< X-Server-Name: prod-ws020.ec2
< X-Asana-Preferred-Release-Revision:  20140131_010208_eb5bb829738a01056cb5d46b626ed2169387b5ed
< X-Robots-Tag: none
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Datacenter-Time-End: 1391198918.072
<
* Connection #0 to host app.asana.com left intact
{"data":{"id":995785926,"name":"invöic.pdf"}}
Community
  • 1
  • 1
creimers
  • 4,975
  • 4
  • 33
  • 55
  • Can you include the actual response you get with the error message? The error message you include is coming from the library, not Asana. It's easiest to debug with the full request *and* response - including headers and body of both, ideally. You can remove auth information and truncate the file, obviously. – agnoster Jan 30 '14 at 23:14
  • Actual error message is there now. – creimers Jan 30 '14 at 23:21
  • So, that's the stack trace from the library. Maybe I wasn't clear earlier: the library is swallowing the actual error Asana sends back and only giving you "Received non 2xx or 404 status code on call", without actually saying what the status code was, or what the server responded. And it certainly doesn't show the actual request headers & body. Can you check if there's a verbose mode, or replicate the request with `curl -v`? It's really quite difficult to know what's going on without seeing the actual HTTP request/response. – agnoster Jan 31 '14 at 16:19
  • Sorry, hadn't found the time to add the header info earlier. Additional info is there now. Thank you. – creimers Jan 31 '14 at 20:13
  • Testing in curl is often a good step. In this case, we now know that the API accepts the upload and correctly returns the name of the file (using curl), which suggests that the issue is somewhere in the Python library, possibly in how it sends its data. I guess that's not much help, but if the issue were with the Asana API I'd have been debugging it. Sorry! – agnoster Jan 31 '14 at 20:45
  • Here's what I find so strange: The file DOES exist, I open it with `open(file_url, 'rb')` inside the API wrapper and it works, I try to post it to asana, and they say `{"errors":[{"message":"file: File is not an object"}]}`. Any clue what that could be a sign of? – creimers Feb 01 '14 at 15:28
  • Right - it's not an issue of the file not existing, it's an issue of the filename being improperly encoded. Curl does it fine, but the python library you're using apparently doesn't. – agnoster Feb 03 '14 at 18:09

0 Answers0