0

I'm looking for a way to programatically change the contents of a jupyterlab cell after it has been run as a way to "lock" it.

For my specific use-case, my cell essentially looks like

curr_id = get_curr_id()
data = load_data(curr_id)

When I run this, get_curr_id() accesses a database and finds the most recent added dataset. After the cell is run once I want to "lock" this id to the cell, so that even if new data is added to the database, this cell will still reference the original dataset it first saw. I thought the easiest way to do this would be to programatically replace "curr_id = get_curr_id()" with the returned curr_id, but am not sure how to proceed.

As more context, the database I am pulling from has new entries added every ~30 min. My typical workflow is to run a cell like above and analyze it. Then ~30 min later copy that same cell and run it again to analyze the new data that came in. However, if I now go back to the first cell, re-running it will now load the newest data, instead of the original data it found.

Solution: In any case, I found a solution using ipython, linked below

4
  • (most likely) You don't want to programatically change code. What I would do is that your get_id gets the value from the dB and stores it into a file. So when it is run for the first time, the file does not exist and the value it taken from the DB. The next time is called the file will exist and will take the value from there. Instead of a file you can use a table in a dB or any other persistent method Commented Feb 26 at 13:34
  • But if I then have two cells which are executing the same basic two line code (and are meant to refer to two separate entries in the DB, is there a way to do it with a static reference like you say? Because the actual code running in the cells is the same Commented Feb 26 at 13:46
  • 1
    If they execute the same code, how are they meant to refer to separate entries in the DB? You need to implement the logic inside get_curr_id(). For what I understand you want that the first time it's called it gets the data from the DB and freezes it, so the next time it will get the same value as before. So save the frozen value into a file, or create a new table in your DB where you store this value. Commented Feb 26 at 14:08
  • I’ve updated the original post with better explanation, and was able to find a solution that worked. Commented Feb 26 at 14:35

1 Answer 1

0

I came up with an answer that works for my use case using ipython and the "In" variable provided by Jupyter.

def lock_current_id(In,curr_id):
    curr_str = In[-1] 
    orig_str = 'curr_id = get_curr_id()'
    hold_str = '\ncurr_id = '
    new_str = orig_str + hold_str + f'"{curr_id}"'
    if (orig_str+hold_str) not in curr_str:
        curr_str = curr_str.replace(orig_str,new_str)

    
    from IPython.core.getipython import get_ipython
    shell = get_ipython()
    payload = dict(
        source='set_next_input',
        text=curr_str,
        replace=True,
    )
    shell.payload_manager.write_payload(payload, single = False)

Basically, when running as

curr_id = get_curr_id()
lock_current_id(In,curr_id)

[other code in same cell]

the lock_current_id code will edit the original cell to add a new line under the "curr_id = get_curr_id()" with the explicit ID found in the first execution. If such a line already exists, it will do nothing.

Sign up to request clarification or add additional context in comments.

2 Comments

Minor suggestion: Can you make this more pertinent to more users by stating what versions of Jupyter this has been verified to work for? For others finding this for related questions, I wonder if a custom magic and/or input transformation could do the same? See here and links therein.
<continued> A good resource for custom magics is here. Here is another example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.