I’ve used requests before with Python 2.7 and I never had this issue. Now I’m coding in Python 3 and it won’t even get connect to the server.
I keep getting the error: UnicodeError: label empty or too long
Simplified code for illustration purpose:
shop_url = "https://APIKEY:[email protected]/admin/"
def get_products():
url = shop_url + "products.json"
r = requests.get(url=url, params={"limit": "250"})
response = r.json()
print(response)
I’ve read it has to do with the IDNA coding of the url before it connects to the server.
Is there anyone who knows how to solve this problem?
EDIT:
I’ve found the solution, instead of passing the APIKEY & CODE in the URL. I can pass it in the header as HTTPBasicAuth. Than the url changes to "http://SHOP.ECOMMERCE.com/admin/"
and IDNA no longer gives any issues.
2
Answers
I've found the solution, instead of passing the APIKEY & CODE in the URL. I can pass it in the header as HTTPBasicAuth. Than the url changes to "http://SHOP.ECOMMERCE.com/admin/" and IDNA no longer gives any issues.
According to the report (still open!) at Python tracker issue 32958, the issue here is that
requests
in Python 3 now passes URLs toidna.py
(a change from Python 2).idna.py
attempts to sanity-check hostnames before passing them tosocket.gethostbyname()
. It does this by first checking whether the first component (or possibly each component) of the name is less than 64 characters in length.(Each of a hostname’s dot-separated components — referred to as "labels" in RFC 1035 — has a length restriction. So, the idea behind the check is a sound one, as hostname components longer than 64 characters are invalid according to standards.):
Unfortunately, when
idna.py
checks the hostname length, it includes everything from the protocol separators up to the first.
character — including any basic-auth parameters specified in the URL.The workaround is, as you already found, to supply the auth parameters in the request headers.