Skip to content

Instantly share code, notes, and snippets.

@kjaquier
Created December 9, 2015 17:46
Show Gist options
  • Save kjaquier/f48f30d038934cb58e76 to your computer and use it in GitHub Desktop.
Save kjaquier/f48f30d038934cb58e76 to your computer and use it in GitHub Desktop.
Parses the Accept-Language HTTP header and returns the list of locales by order of preference.
def parse_http_accept_language_header(langs_str):
"""Returns the list of languages from a string formatted
according to the Accept-Language HTTP header, by order of
preference.
"""
def get_locale_q_pairs(lang_list):
for language in lang_list:
locale_q_pair = language.split(";")
if len(locale_q_pair) == 1:
# no q => q = 1
yield language.strip(), 1.0
else:
locale, q = locale_q_pair
yield locale.strip(), float(q.split("=")[1])
try:
locale_q_pairs = get_locale_q_pairs(langs_str.split(","))
locale_q_pairs = sorted(locale_q_pairs, key=lambda kv: kv[1])
return [locale for locale, _q in locale_q_pairs]
except (ValueError, IndexError): # format error or empty list
return None
# Example of use with Bottle :
from bottle import route, run
@route('/')
def hello():
lang_header_str = request.headers.get('Accept-Language', '')
langs = parse_http_accept_language_header(lang_header_str)
favorite_locale = langs[0] if langs else None
return "User locale: {}".format(favorite_locale)
run(host='localhost', port=8080, debug=True)
@frozax
Copy link

frozax commented Aug 30, 2024

I think the returned order is reversed. Higher 'q' should be higher priority. Therefore, you should add reverse=True to the sorted, ligne 19.
(or use favorite_locale = langs[-1] if langs else None)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment