Skip to content

Instantly share code, notes, and snippets.

@cftang0827
Last active July 8, 2020 14:58
Show Gist options
  • Save cftang0827/9933ea0b5d5a0ca6f7d00d13f4a1b63f to your computer and use it in GitHub Desktop.
Save cftang0827/9933ea0b5d5a0ca6f7d00d13f4a1b63f to your computer and use it in GitHub Desktop.
import functools
import re
accept_language_re = re.compile(
r"""
([A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*|\*) # "en", "en-au", "x-y-z", "es-419", "*"
(?:\s*;\s*q=(0(?:\.\d{,3})?|1(?:\.0{,3})?))? # Optional "q=1.00", "q=0.8"
(?:\s*,\s*|$) # Multiple accepts per header.
""",
re.VERBOSE,
)
@functools.lru_cache(maxsize=1000)
def parse_accept_lang_header(lang_string):
"""
Parse the lang_string, which is the body of an HTTP Accept-Language
header, and return a tuple of (lang, q-value), ordered by 'q' values.
Return an empty tuple if there are any format errors in lang_string.
"""
result = []
pieces = accept_language_re.split(lang_string.lower())
if pieces[-1]:
return ()
for i in range(0, len(pieces) - 1, 3):
first, lang, priority = pieces[i : i + 3]
if first:
return ()
if priority:
priority = float(priority)
else:
priority = 1.0
result.append((lang, priority))
result.sort(key=lambda k: k[1], reverse=True)
return tuple(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment