Code Listing#

Here is the full listing for a Redis connection in a Bluesky profile.

The definition of the redis interface can be found here at BMM’s GitHub site.

 1  import redis
 2
 3  if not os.environ.get('AZURE_TESTING'):
 4     redis_host = 'xf06bm-ioc2'
 5  else:
 6     redis_host = '127.0.0.1'
 7
 8  class NoRedis():
 9     def set(self, thing, otherthing):
10        return None
11     def get(self, thing):
12        return None
13
14  rkvs = redis.Redis(host=redis_host, port=6379, db=0)
15  #rkvs = NoRedis()

Explanation#

The block at lines 3-6 is a bit of care taken to make sure that automated testing does not trigger false negatives due to being unable to reach the Redis server at the beamline. The sort of automated testing in question tends to happen on servers located away from the beamline. Redirecting the Redis connection to the local host, prevents this false negative.

The class defined at lines 8-12 is a way to trick the profile into starting and running on a machine that does not have access to the Redis server. In that case, uncomment line 15. Not everything will work correctly with this trick in place, but at least the Bluesky session should start without complaint.

Setting and retrieving a scalar value#

This sets a scalar value:

rkvs.set('BMM:pds:element', 'Cu')

This retrieves a string and converts it from a byte string to an ordinary string:

el = rkvs.get('BMM:pds:element').decode('utf-8'))

Setting and retrieving a list, tuple, or dict#

Redis will flatten a python list to a string, which it then returns as a byte string.

This sets a list value:

rkvs.set('BMM:example:list', str(['a', 'b', 'c']))

This retrieves that list

mylist = rkvs.get('BMM:example:list')

but returns it as

b"['a', 'b', 'c']"

One way to convert this to a list is:

1  import ast
2  mylist = ast.literal_eval(rkvs.get('BMM:example:list').decode('utf-8'))

This converts the flattened byte string to a flattened string representing the list, then uses Python’s own evaluator to convert that string into a list. A bit cumbersome, but it works.

The same trick can be used to retrieve a tuple or dict stored in Redis.

See ast.literal_eval for more details and for a discussion of possible safety threats to evaluating unvetted strings in this manner.