def update_qsd(url, qsd=None, remove=None):
qsd = qsd or {}<EOL>remove = remove or []<EOL>parsed = urlparse(url)<EOL>current_qsd = OrderedDict(parse_qsl(parsed.query))<EOL>if remove == "<STR_LIT:*>":<EOL><INDENT>remove = list(current_qsd.keys())<EOL><DEDENT>for key in remove:<EOL><INDENT>if key not in qsd:<EOL><INDENT>del current_qsd[key]<EOL><DEDENT><DEDENT>for key, value in qsd.items():<EOL><INDENT>if value:<EOL><INDENT>current_qsd[key] = value<EOL><DEDENT><DEDENT>return parsed._replace(query=urlencode(current_qsd)).geturl()<EOL>
Update or remove keys from a query string in a URL

:param url: URL to update
:param qsd: dict of keys to update, a None value leaves it unchanged
:param remove: list of keys to remove, or "*" to remove all
               note: updated keys are never removed, even if unchanged
:return: updated URL