Skip to content

DataStore

The DataStore object represents a Blissdata instance you are connected to. From there you can manipulate scans, either to create or read scans in this instance (or both).

Connecting to a database#

Connecting to a Blissdata instance is done by creating a DataStore from a Redis URL:

from blissdata.redis_engine.store import DataStore

data_store = DataStore("redis://localhost:6379")

Because each DataStore is not holding one socket to Redis, but a pool of them, there is no need to create many. The number of sockets in the pool automatically scales up if there is a demand for parallel requests.

It is even recommended to reuse the same DataStore instance as most as possible, as it reuses previously open sockets. This prevents from opening new ones every time.

Open scans#

In Blissdata, each Scan is identified by a key looking like this one: esrf:scan:01HCYP7ARJ4NSG9VGPGDX6SN2X

Therefore, the first thing you need to access a scan is to obtain its key. Here are the possible options:

  • get_next_scan(since=None, block=True, timeout=0):

    The scan doesn't exist yet and you are waiting for it.

    from blissdata.redis_engine.exceptions import NoScanAvailable
    
    # Wait 10 seconds for a new scan
    try:
        timestamp, key = data_store.get_next_scan(timeout=10)
    except NoScanAvailable:
        raise Exception("No scan started within 10 seconds")
    scan_1 = data_store.load_scan(key)
    
    # -------------- PROCESS scan_1 --------------
    
    # Wait for the immediate next scan
    timestamp, key = data_store.get_next_scan(since=timestamp)
    scan_2 = data_store.load_scan(key)
    
    # -------------- PROCESS scan_2 --------------
    
    # Get the next scan immediately or raise an Exception
    try:
        timestamp, key = data_store.get_next_scan(since=timestamp, block=False)
    except NoScanAvailable:
        raise Exception("No scan started while scan_2 processing")
    scan_3 = data_store.load_scan(key)
    

    Tip

    Reusing the previous timestamp ensure you don't miss any new scan while processing a previous one.

  • get_last_scan():

    The scan just ran.

    from blissdata.redis_engine.exceptions import NoScanAvailable
    
    try:
        timestamp, key = data_store.get_last_scan()
    except NoScanAvailable:
        raise Exception("There is no scan at all !")
    scan = data_store.load_scan(key)
    

  • search_existing_scans(**kwargs):

    The scan already exists and you want to find it among existing ones.

    timestamp, keys = data_store.search_existing_scans(session="my_session", proposal=..., ...)
    # load each scan from key, or simply uses keys to count how many scans correspond to your search...
    
    **kwargs can contain any key present in scan identity model (eg. name, number, data_policy, session, proposal, collection, dataset, path)

    Tip

    timestamp is not used there, but you can provide it to get_next_scan(since=timestamp) to make it relative to a previous research.

Create scans#

Scan are created from the DataStore object with the help of .create_scan() method:

>>> scan = data_store.create_scan(*args, **kwargs)
>>> print(scan.key)
esrf:scan:01JBXVGZM0G32HDSZJXS6MSESN
However, the arguments to provide and the resulting Scan object are better described in the Scan creation section.