misc issues: hiding buttons, implementing countdown

Hi Prodigy team,

Whenever I re-load the same annotation session, it is showing No tasks available. Also, once I open the URL and then someone else is trying to open the same URL. it is again showing No tasks available.

Is it possible for multiple people to open the same link without this issue? It would be very helpful if you can explain how to configure that setting.

Also,

while I was trying to connect to the database I encountered the error shown below. Could be please suggest a way to get around this ? I checked that prodigy.json file is a valid json file.

db=connect()
Traceback (most recent call last):
File “”, line 1, in
File “/home/vandana_p/hair_diagnostics/my_hair_selfie/lib/python3.6/site-packages/prodigy/components/db.py”, line 66, in connect
config = get_config()
File “cython_src/prodigy/util.pyx”, line 80, in prodigy.util.get_config
File “/home/vandana_p/hair_diagnostics/my_hair_selfie/lib/python3.6/site-packages/srsly/_json_api.py”, line 52, in read_json
return ujson.load(f)
ValueError: Unexpected character in found when decoding object value

Apart from the above issues, there a some design changes I am trying to make in the image mash annotation example I am trying out

  • Currently we have a red Cross button which needs to be removed in our annotations, we do not want to give an option not to respond
  • The green tick button should only work if they make a choice, otherwise page should not progress (currently it progresses even if they do not make a choice)
  • There should be a 10 second count down on each image pair, if they do not make a choice by then the page auto moves forward, and the images with the missing annotations get recycled back to the mash.

Could you please suggest how to make these changes in the prodigy setup for these design changes?

Regards,
Vandana

By default, this is expected, because Prodigy will send out a single batch to one person and wait for it to come back – so if there’s only one batch of examples, those will go out and when the next user accesses the link, there’s no second batch to send out, so Prodigy will show that no tasks are available anymore.

There are several ways to change this, depending on your use case:

  1. Implement an infinite stream as described here. If examples aren’t in the database yet, they’ll get sent out again until they’re annotated. This works well if you only have one annotator and want to make sure no batch is lost when they refresh (without haviing to restart the server). With multiple annotators and little data (only a few batches), this approach works less well, because you might get overlaps: while person A is still annotating a batch, person B might be getting the same batch, because the answers aren’t in the database yet (because person A is still working on them).
  2. Use the new named multi-user sessions by appending ?session=xxx (annotator name or ID) to the URL. By default, all data will then be sent out once to each annotator (so everyone annotates the same questions and you can use something like the review interface later on to resolve conflicts and review the decisions).

Hmm, this is strange, because it really does look like there’s something with the prodigy.json that makes ujson struggle to open it. Can you double-check the file encoding? And do you have any escaped strings in there that might confuse it?

The good news is that this isn’t specific to Prodigy, so you should be able to just test it with your own script that loads the JSON and if that works, Prodigy should be able to load it as well.

Yes, you can modify the UI pretty freely via the global_css. I wrote up different approaches for this in my comment here.

Are you using the choice interface? I haven’t tried this yet, but in that case, you could probably check the window.prodigy.content in a cusomt script and see if accept is an empty list or includes a selected option. If it’s empty, you disable the accept button, if it’s not empty, you reset it.

Alternatively, if it’s a single-choice interface (e.g. radio inputs with only one possible answer), you could also hide the accept button completely and set "choice_auto_accept": True in your recipe config. This will automatically submit the answer if the user selects an option.

You can probably also do that with a custom script: add the countdown and when it’s up, call window.prodigy.answer('ignore') automatically. This will still add the answer to the dataset with "answer": "ignore", though – so in your stream generator you’d have to check what’s in the dataset and not only send answers out if they aren’t in the dataset yet, but also if they are in the dataset but ignored.

You might also want to consider adding meta information to the task indicating that it was skipped automatically. For example, something like that:

window.prodigy.update({ skipped: true, skipped_after: 10 })
window.prodigy.answer('ignore')

This will add "skipped" and "skipped_after" to the task, so you’ll always know where it came from, that it was auto-skipped and that it was skipped after 10 seconds.

Hello,

Thanks for reply earlier.

In your reply, you mentioned to use the following code snippet for hiding the red button.

[data-prodigy-view-id=“choice”] .prodigy-buttons button:nth-child(2) {
display: none;
}

I am not very much familiar with CSS coding style.

Your below comment -
" That should hopefully be very straightfgorward with a bit of CSS in the "global_css" setting in the "config" returned by your recipe (where you also put the "choice_style" setting)"

is not very clear to me. Could you please explain where you are suggesting to add this code snippet exactly? in the custom python recipe for my task? Also, Not just the red button, but I am planning to remove all the buttons and I want an image mesh with three images where the user has only option to opt for selection button to progress further. Could you please suggest me a way to remove all the below buttons all together?

Regards,
Vandana

If you want to remove all the buttons, that’s going to be more straightforward, because you can just hide the whole .prodigy-buttons container.

.prodigy-buttons {
    display: none;
}

Yes, exactly. Your recipe returns a dictionary of components and one of them can be a dict "config". For example:

# Somewhere in your recipe
global_css = ".prodigy-buttons { display: none }"

# At the end of your recipe
return {
    "dataset": dataset,
    # and so on...
    "config": {
        "global_css": global_css
    }
}

Thanks a lot for your reply. I added the cope snippet as you mentioned but I m still seeing the buttons. Just to cross check I am doing it right.

import prodigy
from prodigy.components.loaders import JSONL

@prodigy.recipe('sentiment',
    dataset=prodigy.recipe_args['dataset'],
    file_path=("Path to texts", "positional", None, str))
def sentiment(dataset, file_path):
    """Annotate the sentiment of texts using different mood options."""
    stream = JSONL(file_path)     # load in the JSONL file
    stream = add_options(stream)  # add options to each task
    
    global_css = ".prodigy-buttons { display: none }"

    return {
        'dataset': dataset,   # save annotations in this dataset
        'view_id': 'choice',  # use the choice interface
        'stream': stream,
        "config": {
        "global_css": global_css
        }
    }

Also, one of the previous queries I had regarding 10 sec count down, Do you have a custom function which does that? unfortunately, It is not clear to me how to execute your suggestion.

Thank you for your wonderful support addressing my issues.

Your code looks correct. Are you using the latest version of Prodigy? You can check by running prodigy stats on the command line. The global CSS option and classes were only added recently, so you’ll need at least Prodigy v1.7.0. Also make sure that your prodigy.json doesn’t include a "global_css" setting that overrides the recipe config.

No, this is something you’d have to write in JavaScript – we don’t have an example of this, since it’s a pretty specific implementation. But you can find examples of adding custom JavaScript to Prodigy in this thread and in the PRODIGY_README.html.

So in the JavaScript code you pass in as "javascript", you’d have to create the countdown, add it to the page and then call into Prodigy’s helper functions when the countdown is up etc. None of this is specific to Prodigy and just regular Vanilla JavaScript – so if you haven’t done this before, you can probably find someone else who can write that countdown script for you in JavaScript.