Skip to content
This repository has been archived by the owner on Mar 11, 2022. It is now read-only.

encoding with 'idna' codec failed (UnicodeError: label empty or too long) #363

Closed
Rahulvks opened this issue Feb 19, 2018 · 25 comments
Closed
Assignees
Milestone

Comments

@Rahulvks
Copy link

client = Cloudant(serviceUsername, servicePassword, url=serviceURL) client.connect()

  • Python 3
    `---------------------------------------------------------------------------
    UnicodeError Traceback (most recent call last)
    /Users/dsg281/anaconda/lib/python3.6/encodings/idna.py in encode(self, input, errors)
    164 if not (0 < len(label) < 64):
    --> 165 raise UnicodeError("label empty or too long")
    166 if len(labels[-1]) >= 64:

UnicodeError: label empty or too long

The above exception was the direct cause of the following exception:

UnicodeError Traceback (most recent call last)
in ()
1 # Use the Cloudant library to create a Cloudant client.
2 client = Cloudant(serviceUsername, servicePassword, url=serviceURL)
----> 3 client.connect()

/Users/dsg281/anaconda/lib/python3.6/site-packages/cloudant/client.py in connect(self)
140 self.r_session.headers.update(self._client_user_header)
141
--> 142 self.session_login()
143
144 # Utilize an event hook to append to the response message

/Users/dsg281/anaconda/lib/python3.6/site-packages/cloudant/client.py in session_login(self, user, passwd)
181 :param str auth_token: Authentication token used to connect to server.
182 """
--> 183 self.change_credentials(user=user, auth_token=passwd)
184
185 def change_credentials(self, user=None, auth_token=None):

/Users/dsg281/anaconda/lib/python3.6/site-packages/cloudant/client.py in change_credentials(self, user, auth_token)
191 """
192 self.r_session.set_credentials(user, auth_token)
--> 193 self.r_session.login()
194
195 def session_logout(self):

/Users/dsg281/anaconda/lib/python3.6/site-packages/cloudant/_client_session.py in login(self)
148 'POST',
149 self._session_url,
--> 150 data={'name': self._username, 'password': self._password},
151 )
152 resp.raise_for_status()

/Users/dsg281/anaconda/lib/python3.6/site-packages/cloudant/_client_session.py in request(self, method, url, **kwargs)
63 """
64 resp = super(ClientSession, self).request(
---> 65 method, url, timeout=self._timeout, **kwargs)
66
67 return resp

/Users/dsg281/anaconda/lib/python3.6/site-packages/requests/sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
497
498 settings = self.merge_environment_settings(
--> 499 prep.url, proxies, stream, verify, cert
500 )
501

/Users/dsg281/anaconda/lib/python3.6/site-packages/requests/sessions.py in merge_environment_settings(self, url, proxies, stream, verify, cert)
670 # Set environment's proxies.
671 no_proxy = proxies.get('no_proxy') if proxies is not None else None
--> 672 env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
673 for (k, v) in env_proxies.items():
674 proxies.setdefault(k, v)

/Users/dsg281/anaconda/lib/python3.6/site-packages/requests/utils.py in get_environ_proxies(url, no_proxy)
690 :rtype: dict
691 """
--> 692 if should_bypass_proxies(url, no_proxy=no_proxy):
693 return {}
694 else:

/Users/dsg281/anaconda/lib/python3.6/site-packages/requests/utils.py in should_bypass_proxies(url, no_proxy)
674 with set_environ('no_proxy', no_proxy_arg):
675 try:
--> 676 bypass = proxy_bypass(netloc)
677 except (TypeError, socket.gaierror):
678 bypass = False

/Users/dsg281/anaconda/lib/python3.6/urllib/request.py in proxy_bypass(host)
2610 return proxy_bypass_environment(host, proxies)
2611 else:
-> 2612 return proxy_bypass_macosx_sysconf(host)
2613
2614 def getproxies():

/Users/dsg281/anaconda/lib/python3.6/urllib/request.py in proxy_bypass_macosx_sysconf(host)
2587 def proxy_bypass_macosx_sysconf(host):
2588 proxy_settings = _get_proxy_settings()
-> 2589 return _proxy_bypass_macosx_sysconf(host, proxy_settings)
2590
2591 def getproxies_macosx_sysconf():

/Users/dsg281/anaconda/lib/python3.6/urllib/request.py in _proxy_bypass_macosx_sysconf(host, proxy_settings)
2560 if hostIP is None:
2561 try:
-> 2562 hostIP = socket.gethostbyname(hostonly)
2563 hostIP = ip2num(hostIP)
2564 except OSError:

UnicodeError: encoding with 'idna' codec failed (UnicodeError: label empty or too long)`

@emlaver
Copy link
Member

emlaver commented Feb 19, 2018

@Rahulvks Can you verify that your URL can be properly encoded as per the IDNA rules? (stackoverflow resource).

If the URL is properly encoded, can you share which python 3 version you are using? Our library has been tested with Python 2.7 and 3.5.

@Rahulvks
Copy link
Author

@emlaver Am using Python 3.6.3 / conda 4.3.29
this is piece of code am using to connect DB to download the logs

serviceUsername = *****-bluemix"
    servicePassword = "****"
    serviceURL = "https:*******-bluemix.cloudant.com"
client = Cloudant(serviceUsername, servicePassword, url=serviceURL)
client.connect()  

@smithsz
Copy link
Contributor

smithsz commented Feb 20, 2018

Our build passes for Python 3.6 (although not officially supported).

It seems your service URL cannot be properly encoded. Can you please contact Cloudant support via support@cloudant.com (this can also be done through your Cloudant dashboard if you prefer)? Be sure to include your full username and also reference this ticket. We'll pick it up from there and get back to you.

Thanks.

@Rahulvks
Copy link
Author

@smithsz I have raised the request through Cloudant dashboard.

Thanks

@smithsz
Copy link
Contributor

smithsz commented Feb 22, 2018

Thanks @Rahulvks. I can see your ticket 100174. I'll close this issue. We'll get back to you shortly via email.

@smithsz smithsz closed this as completed Feb 22, 2018
@Rahulvks
Copy link
Author

Rahulvks commented Mar 4, 2018

Hi @smithsz

It's working fine on Python 3.4.

I get error in Python 3.6.3

@markstur
Copy link

markstur commented Apr 5, 2018

Get this error when the URL also contains the user/pass in py3 (works in py2). Would be nice if the client could strip the redundant stuff and just work.

@smithsz
Copy link
Contributor

smithsz commented Apr 10, 2018

@markstur Can you share the client constructor please? I'm unable to reproduce this in Python 3.6.1. Does the password have any special characters etc? Thanks.

@markstur
Copy link

I had to mask user/pass and pull some code out to make a test.py, but I think this covers it. Notice that IBM Cloud generates long user/password. Also the provided URL contains user:pass@ which is very handy when it works, but w/ py3 needs to be stripped in favor of passing user/pass separately.

This output w/ py2 and py3 demonstrates that py2 correctly fails (it is not my real user/pass) but py3 hits the "...too long..." exception:

$ python test.py
401 Client Error: Unauthorized for url: https://a9a9a9a9-a9a9-a9a9-a9a9-a9a9a9a9a9a9-bluemix:a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9@d8a01891-e4d2-4102-b5f8-751fb735ce31-bluemix.cloudant.com/_session
$ python3 test.py
encoding with 'idna' codec failed (UnicodeError: label empty or too long)

Test code is here:

from cloudant.client import Cloudant

CLOUDANT_USERNAME = "a9a9a9a9-a9a9-a9a9-a9a9-a9a9a9a9a9a9-bluemix"
CLOUDANT_PASSWORD="a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9"
CLOUDANT_URL="https://a9a9a9a9-a9a9-a9a9-a9a9-a9a9a9a9a9a9-bluemix:a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9@d8a01891-e4d2-4102-b5f8-751fb735ce31-bluemix.cloudant.com"

try:
Cloudant(CLOUDANT_USERNAME,
CLOUDANT_PASSWORD,
url=CLOUDANT_URL,
connect=True)
except Exception as e:
print(e)

@ricellis
Copy link
Member

ricellis commented Apr 12, 2018

@tomblench
Copy link
Contributor

@markstur as you state, the workaround (in your case) for now is to remove the username and password from the URL.

As @ricellis pointed out, there is an underlying Python issue which is outside of our control, where long/IDNA domain names cause an error.

@DhanashreeChavan
Copy link

I see this issue in python2.7. Was this fixed ?

@ricellis
Copy link
Member

@DhanashreeChavan as far as we know the underlying Python issue only applies to 3.6+. Are you able to provide the exact python 2.7 version, build and platform that is exhibiting the UnicodeError: label empty or too long error?

In any case the workaround until Python is fixed is to strip the user:pass@ user information from the URL e.g.

# URL with user information as provided in IBM Cloud credentials
# serviceURL = "https://example-abc123-bluemix:examplepassword@example-abc123-bluemix.cloudant.com"
# URL with user information removed to workaround Python bug
serviceURL = "https://example-abc123-bluemix.cloudant.com"
# Username and password from URL
serviceUsername = "example-abc123-bluemix"
servicePassword = "examplepassword"
client = Cloudant(serviceUsername, servicePassword, url=serviceURL)
client.connect()  

@DhanashreeChavan
Copy link

DhanashreeChavan commented May 11, 2018 via email

@ricellis
Copy link
Member

I'm failing to see the connection between AWS/MQTT and this python-cloudant library, which is a library for connecting to IBM Cloudant or Apache CouchDB from Python. If that's not what you're doing we can't really help.

@DhanashreeChavan
Copy link

DhanashreeChavan commented May 11, 2018 via email

@valdirsalustino
Copy link

Dear all,
Have you guys get any update on this issue? I am having the same issue with both python3 versions:
3.4.5, 3.5.1 and 3.6.4.

I am desperate to solve this :(

Regards,

@emlaver
Copy link
Member

emlaver commented May 29, 2018

@valdirsalustino Have you tried the workaround above that strips the user/pass from the URL? #363 (comment)

We have merged a PR that removes the user/pass from the URL (#383). We'll update this issue when there's a new release.

@ricellis ricellis moved this from New to In Progress in python-cloudant Triage Jun 11, 2018
@ricellis ricellis added this to the 2.next milestone Jun 13, 2018
@ricellis
Copy link
Member

The 2.9.0 release has the code to remove user/pass from URL which will hopefully keep them short enough to workaround the bug in python.

python-cloudant Triage automation moved this from In Progress to Done Jun 13, 2018
@BeOleg
Copy link

BeOleg commented Sep 4, 2019

python 3.7 with the same issue here

@ricellis
Copy link
Member

ricellis commented Sep 5, 2019

@BeOleg there's nothing else we can do in python-cloudant to help with really long URLs, the underlying Python issue is still unresolved https://bugs.python.org/issue32958

@cjauvin
Copy link

cjauvin commented Nov 1, 2020

I stumbled on this problem with an Heroku app, with which I have a very long Redis URL with auth (using Python 3.9). I solved it using urllib.parse.urlparse to decompose the elements into the redis.Redis constructor.

@mojito317
Copy link
Contributor

@cjauvin thank you for sharing the workaround you have figured out!

@normenczepa0815
Copy link

normenczepa0815 commented Jan 27, 2021

yes i also can confirm, that urllib.parse is helpful, this is how it worked out for me

messageData = {'text': 'lambda with python webhook test'}
parseResult = urlparse(protocol+hook_url)
headers = {'Content-type': 'application/json'}
conn = http.client.HTTPSConnection(parseResult.netloc)
conn.request("POST", parseResult.path, json.dumps(messageData), headers)
response = conn.getresponse()
status = response.status
conn.close()
print("status:", status)

👍

@ErikBoesen
Copy link

ErikBoesen commented Oct 12, 2021

When using Redis, I also found success by replacing my Redis(host) instantiation with Redis.from_url(host).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
No open projects
Development

No branches or pull requests