@classmethod
    def from_v2(cls, case_block):
        """
        Gets a case update from a version 2 case. 
        Spec: https://github.com/dimagi/commcare/wiki/casexml20
        """
        
        def _to_attr(val):
            return "@%s" % val
    
        case_id_attr = _to_attr(const.CASE_TAG_ID) 
        if case_id_attr not in case_block:
            raise CaseGenerationException(
                "No case_id attribute found in v2 case block, "
                "this is a required property."
            )
        
        user_id = case_block.get(_to_attr(const.CASE_TAG_USER_ID), "")
        modified_on = case_block.get(_to_attr(const.CASE_TAG_MODIFIED), "")
        return cls(id=case_block[case_id_attr],
                   version=V2,
                   block=case_block,
                   user_id=user_id,
                   modified_on_str=modified_on)


# this section is what maps various things to their v1/v2 parsers
dataset/ETHPy150Open dimagi/commcare-hq/corehq/ex-submodules/casexml/apps/case/xml/parser.py/CaseUpdate.from_v2/original