issubclass() arg 1 must be a class error on custom recipes

Hi,

I'm getting an error when I try to run custom recipes. Here are a few examples:

Sample Recipes Causing Error

from typing import Dict, Generator

import prodigy
from prodigy.components.loaders import JSONL

from annotator.recipes.utils import VALIDATION

UNLIMITED_ROWS = [
    {"view_id": "html", "html_template":
        "<div style=\"padding: 0 10px; border: 1px solid #ddd; border-radius: 4px; text-align: left;\">" +
        "<label style=\"font-size: 14px; opacity: 0.90; margin-bottom: 10px;\">intent</label>" +
        "<div style=\"max-height: 300px; overflow-y: scroll; margin-bottom: 10px;\">{{final_intent_v3}}" +
        "<br>" +
        "<br>" +
        "<label style=\"font-size: 14px; opacity: 0.90; margin-bottom: 10px;\">utterance</label>" +
        "<div style=\"max-height: 300px; overflow-y: scroll; margin-bottom: 10px;\">{{utterance}}" +
      "</div>"
    },
    {"view_id": "choice"},
    {"view_id": "html", "html_template": "<div style='float:left;'>" +
        "<input name='stt_error' id='stt_error' type='checkbox' value='STT Error' style='margin-right:10px;' data-id='{{utterance}}' onchange='updateSttError()'" +
        "<label onclick='update()'>STT Error</label>"
    },
    {"view_id": "text_input", "field_label": "notes"}
]


def add_options(
        stream, label_field="", choices=VALIDATION
) -> Generator[Dict, None, None]:
    """
    Convert each line in the ``stream`` to a ``task`` with a text and an
    options field

    :param stream: the input stream
    :param label_field: key; defaults to "label"
    :param choices: the different choices
    :yield: a task Dict with text and options
    """
    for line in stream:
        options = [word for word in choices]
        task = {
            "final_intent_v3": line["final_intent_v3"],
            "utterance": line["utterance"],
            "stt_error": False,
            "options": [
                {"id": o, "deployment": o, "prompt": o,
                "text": o} for o in options
            ]
        }

        yield task


@prodigy.recipe(
    "intent-validation",
    dataset=("The dataset to save to", "positional", None, str),
    file_path=("Path to texts", "positional", None, str)
)
def custom_labels(dataset, file_path):
    """
    Annotate the text with labels from the list from the ``label_field`` in
    the input file. Augmented with choices from ``choice_field``.
    """

    blocks = UNLIMITED_ROWS

    stream = JSONL(file_path)
    stream = add_options(stream)  # add options to each task

    javascript = """
      // Set stt_error to false by default
      prodigy.update({ stt_error: false });

      function updateSttError() {
        prodigy.update({ stt_error: document.getElementById('stt_error').checked });
      }

      document.addEventListener('prodigyanswer', (event) => {
        // Reset stt_error to false
        prodigy.update({ stt_error: false });

        document.getElementById('stt_error').checked = false;
      });
    """

    return {
        "dataset": dataset,
        "view_id": "blocks",
        "stream": list(stream),
        "config": {
          "blocks": blocks,
          "javascript": javascript
        }
    }

Errors

✘ Couldn't load Python code:
/Users/cheyannebaird/posh/annotation-service/src/annotator/recipes/intent_validation.py
issubclass() arg 1 must be a class
✘ Couldn't load Python code:
/Users/cheyannebaird/posh/annotation-service/src/annotator/recipes/eup_corpus_validation.py
issubclass() arg 1 must be a class

Hi @cheyanneb ,

It looks like the structure of the task produced by your stream is not as expected (I'm taking a note of this error not being helpful).
After the line stream = add_options(stream) in the intent-validation recipe, could print and share with me the first task in the stream at this point.
I suspect it's the transformation that's being done in add_options is at fault.
Could you also share the example input as well as the content of the VALIDATION variable?

Final question, why would you convert to stream to a list in the recipe's return statement?

Thanks!

Just wanted to add another instance where I am seeing this error is when I'm trying to use db-out:

Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/prodigy/__main__.py", line 50, in <module>
    main()
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/prodigy/__main__.py", line 44, in main
    controller = run_recipe(run_args)
  File "cython_src/prodigy/cli.pyx", line 111, in prodigy.cli.run_recipe
  File "cython_src/prodigy/cli.pyx", line 36, in prodigy.cli.get_cli
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/prodigy/recipes/__init__.py", line 1, in <module>
    from . import (
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/prodigy/recipes/audio.py", line 3, in <module>
    from ..components.preprocess import fetch_media as fetch_media_preprocessor
  File "cython_src/prodigy/components/preprocess.pyx", line 7, in init prodigy.components.preprocess
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/__init__.py", line 13, in <module>
    from . import pipeline  # noqa: F401
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/pipeline/__init__.py", line 1, in <module>
    from .attributeruler import AttributeRuler
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/pipeline/attributeruler.py", line 8, in <module>
    from ..language import Language
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/language.py", line 42, in <module>
    from .pipe_analysis import analyze_pipes, print_pipe_analysis, validate_attrs
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/pipe_analysis.py", line 6, in <module>
    from .tokens import Doc, Span, Token
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/tokens/__init__.py", line 1, in <module>
    from ._serialize import DocBin
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/tokens/_serialize.py", line 14, in <module>
    from ..vocab import Vocab
  File "spacy/vocab.pyx", line 1, in init spacy.vocab
  File "spacy/tokens/doc.pyx", line 49, in init spacy.tokens.doc
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/site-packages/spacy/schemas.py", line 272, in <module>
    class TokenPattern(BaseModel):
  File "pydantic/main.py", line 197, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 506, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 436, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 552, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 661, in pydantic.fields.ModelField._type_analysis
  File "pydantic/fields.py", line 668, in pydantic.fields.ModelField._type_analysis
  File "/opt/homebrew/Caskroom/miniforge/base/envs/prodigy/lib/python3.9/typing.py", line 847, in __subclasscheck__
    return issubclass(cls, self.__origin__)
TypeError: issubclass() arg 1 must be a class

I edited the recipe in my original post. This recipe works in our development environment with v1.14.11, but locally I am still getting this error when I try to run any Prodigy commands. I'm have the latest version of Prodigy (v1.14.12), so I may try previous versions to see if I still get this error.

I am no longer getting this error after reinstalling Prodigy again. I'm not sure why, but it appears to be resolved for now.

OK! Thanks for reporting back.