# based on: # https://gist.github.com/samuraisam/2714195 # ##### # The author disclaims copyright to this source code. In place of a legal # notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # # It is based on a snipped found in this project: # https://github.com/martinblech/mimerender import functools def parse_accept_header(accept): """ Parse the Accept header *accept*, returning a list with 3-tuples of [(str(media_type), dict(params), float(q_value)),] ordered by q values. If the accept header includes vendor-specific types like:: application/vnd.yourcompany.yourproduct-v1.1+json It will actually convert the vendor and version into parameters and convert the content type into `application/json` so appropriate content negotiation decisions can be made. Default `q` for values that are not specified is 1.0 """ result = [] for media_range in accept.split(","): parts = media_range.split(";") media_type = parts.pop(0).strip() media_params = [] # convert vendor-specific content types into something useful (see # docstring) try: typ, subtyp = media_type.split('/') except ValueError: typ = '' subtyp = '' # check for a + in the sub-type if '+' in subtyp: # if it exists, determine if the subtype is a vendor-specific type vnd, sep, extra = subtyp.partition('+') if vnd.startswith('vnd'): # and then... if it ends in something like "-v1.1" parse the # version out if '-v' in vnd: vnd, sep, rest = vnd.rpartition('-v') if len(rest): # add the version as a media param try: version = media_params.append(('version', float(rest))) except ValueError: version = 1.0 # could not be parsed # add the vendor code as a media param media_params.append(('vendor', vnd)) # and re-write media_type to something like application/json so # it can be used usefully when looking up emitters subtyp = extra q = 1.0 for part in parts: (key, value) = part.lstrip().split("=", 1) key = key.strip() value = value.strip() if key == "q": q = float(value) else: media_params.append((key, value)) result.append((typ, subtyp, dict(media_params), q)) result.sort(key=lambda n: -n[3]) return result