1from fnmatch import fnmatch
2
3# special marker object to return empty content for any status code
4# e.g. in app method do "return NoContent, 201"
5NoContent = object()
6
7
8class MediaTypeDict(dict):
9 """
10 A dictionary where keys can be either media types or media type ranges. When fetching a
11 value from the dictionary, the provided key is checked against the ranges. The most specific
12 key is chosen as prescribed by the OpenAPI spec, with `type/*` being preferred above
13 `*/subtype`.
14 """
15
16 def __getitem__(self, item):
17 # Sort keys in order of specificity
18 for key in sorted(self, key=lambda k: ("*" not in k, k), reverse=True):
19 if fnmatch(item, key):
20 return super().__getitem__(key)
21 raise super().__getitem__(item)
22
23 def get(self, item, default=None):
24 try:
25 return self[item]
26 except KeyError:
27 return default
28
29 def __contains__(self, item):
30 try:
31 self[item]
32 except KeyError:
33 return False
34 else:
35 return True