key-value-store.py (2017B)
1 """Key-Value store server. 2 3 The request takes "key=" and "value=" URL parameters. The key must be UUID 4 generated by token(). 5 6 - When only the "key=" is specified, serves a 200 response whose body contains 7 the stored value specified by the key. If the stored value doesn't exist, 8 serves a 200 response with an empty body. 9 - When both the "key=" and "value=" are specified, stores the pair and serves 10 a 200 response without body. 11 """ 12 13 14 def main(request, response): 15 key = request.GET.get(b"key") 16 value = request.GET.get(b"value") 17 18 # Store the value. 19 # We have two ways to check the truthiness of `value`: 20 # 1. `if value` 21 # 2. `if value != None` 22 # While (1) is the most intuitive, we actually need (2), which is a looser 23 # check. We need the looser check so that if the URL contains `&value=` to 24 # set the value equal to the empty string (a case we need to support), this 25 # condition still evaluates to true and we enter this branch. 26 if value != None: 27 # We opted for (2) above which is the looser of the truthiness tests 28 # that lets empty strings into this branch. So you might think that when 29 # the URL contains `&value=`, then the `value` variable here would be 30 # equal `""`, but instead it equals the empty byte string. If you just 31 # store that empty byte string into the stash and retrieve it later, you 32 # actually get <Not set> because it doesn't recognize the empty byte 33 # string as a real value, so we instead have to override it to the empty 34 # normal string, and then we can store it for later use. This is 35 # because we have to support storage and retrieval of empty strings. 36 if type(value) is bytes and value == b'': 37 value = "" 38 39 request.server.stash.put(key, value) 40 return (200, [], b"") 41 42 # Get the value. 43 data = request.server.stash.take(key) 44 if not data and data != "": 45 return (200, [], b"<Not set>") 46 return (200, [], data)