Ejemplo n.º 1
0
Archivo: xapi.py Proyecto: ubc/compair
    def _emit_to_lrs(cls, statement_json):
        if not cls.enabled:
            return

        # should only be called by delayed task send_lrs_statement
        lrs_settings = {
            'version': cls._version,
            'endpoint': current_app.config.get('LRS_XAPI_STATEMENT_ENDPOINT')
        }

        if current_app.config.get('LRS_XAPI_AUTH'):
            lrs_settings['auth'] = current_app.config.get('LRS_XAPI_AUTH')
        else:
            lrs_settings['username'] = current_app.config.get(
                'LRS_XAPI_USERNAME')
            lrs_settings['password'] = current_app.config.get(
                'LRS_XAPI_PASSWORD')

        statement = Statement(statement_json)
        lrs = RemoteLRS(**lrs_settings)
        lrs_response = lrs.save_statement(statement)

        if not lrs_response.success:
            current_app.logger.error("xAPI Failed with: " +
                                     str(lrs_response.data))
            current_app.logger.error("xAPI Request Body: " +
                                     lrs_response.request.content)
Ejemplo n.º 2
0
def send_statement_without_timeout(statement, success, result):
    # construct an LRS
    lrs = RemoteLRS(
        version=settings.LRS_VERSION,
        endpoint=settings.LRS_ENDPOINT,
        auth=settings.LRS_AUTH,
    )
    try:
        # save our statement to the remote_lrs and store the response in 'response'
        lrs_response = lrs.save_statement(statement)
        if lrs_response:
            if lrs_response.success:
                try:
                    # retrieve our statement from the remote_lrs using the id returned in the response
                    lrs_response = lrs.retrieve_statement(
                        lrs_response.content.id)
                    if lrs_response.success:
                        result = lrs_response.content
                        success = True
                    else:
                        result = lrs_response.data
                except Exception as e:
                    result = e
            else:
                result = lrs_response.data
    except Exception as e:
        result = e
Ejemplo n.º 3
0
def xApi(verb_id,verb_disp,extension_dict):
    
    #orismos LRS 
    lrs = RemoteLRS(
        version=lrs_actor.version,
        endpoint=lrs_actor.endpoint,
        username=lrs_actor.username,
        password=lrs_actor.password,
    )

    #orismos actor 
    actor=Agent(name=lrs_actor.actorName, mbox='mailto:'+lrs_actor.actorMail,) 
    #orimos verb
    verb = Verb(
                id=verb_id,
                display=LanguageMap({'en-US': verb_disp}),
                )
    #ορισμός object
    object = Activity(
                      id='https://pithos.okeanos.grnet.gr/public/8jiz0aVKZxjVI2CvNl7XV3',
                      definition=ActivityDefinition(
                    name=LanguageMap({'en-US': 'Python file'}),
                    description=LanguageMap({'en-US': 'A python source code file'}),
                    ),
                      )
    #ορισμος extension 
    extension=Extensions(extension_dict)
    #ορισμός context
    context = Context(extensions=extension)
    #Κατασκευή statement
    statement = Statement(
                          actor=actor,
                          verb=verb,
                          object=object,
                          context=context
                          )

    # save our statement to the remote_lrs and store the response in 'response'
    print "saving the Statement..."
    response = lrs.save_statement(statement)

    if not response:
        raise ValueError("statement failed to save")
        error_icon="images/error_icon.png"
#        msgbox("Can't save statement!\n Check the file: lrs_actor.py",title="Error!!!",image=error_icon)
        print "Can't save statement!!\n Check the file: lrs_actor.py"

    print "...done     verb: " ,verb_disp 
Ejemplo n.º 4
0
    def _send_lrs_statement(cls, statement_json):
        if not cls.enabled:
            return

        # should only be called by delayed task send_lrs_statement
        lrs_settings = {
            'version': cls._version,
            'endpoint': current_app.config.get('LRS_STATEMENT_ENDPOINT')
        }

        if current_app.config.get('LRS_AUTH'):
            lrs_settings['auth'] = current_app.config.get('LRS_AUTH')
        else:
            lrs_settings['username'] = current_app.config.get('LRS_USERNAME')
            lrs_settings['password'] = current_app.config.get('LRS_PASSWORD')

        statement = Statement(statement_json)
        # check statement.result.response, object.definition.name, object.definition.description
        if statement.result and statement.result.response:
            statement.result.response = cls._trim_text_to_size(
                statement.result.response)
        if statement.object and statement.object.definition and statement.object.definition.name:
            statement.object.definition.name['en-US'] = cls._trim_text_to_size(
                statement.object.definition.name['en-US'])
        if statement.object and statement.object.definition and statement.object.definition.description:
            statement.object.definition.description[
                'en-US'] = cls._trim_text_to_size(
                    statement.object.definition.description['en-US'])

        lrs = RemoteLRS(**lrs_settings)
        lrs_response = lrs.save_statement(statement)

        if not lrs_response.success:
            current_app.logger.error("xAPI Failed with: " +
                                     str(lrs_response.data))
            current_app.logger.error("xAPI Request Body: " +
                                     lrs_response.request.content)
Ejemplo n.º 5
0
class RemoteLRSTest(unittest.TestCase):
    def setUp(self):
        self.endpoint = lrs_properties.endpoint
        self.version = lrs_properties.version
        self.username = lrs_properties.username
        self.password = lrs_properties.password
        self.lrs = RemoteLRS(
            version=self.version,
            endpoint=self.endpoint,
            username=self.username,
            password=self.password,
        )

        self.agent = Agent(mbox="mailto:[email protected]")
        self.agent2 = Agent(mbox="Agent2.mailto:[email protected]")
        self.verb = Verb(
            id="http://adlnet.gov/expapi/verbs/experienced",
            display=LanguageMap({"en-US": "experienced"})
        )

        self.group = Group(member=[self.agent, self.agent2])

        self.activity = Activity(
            id="http://tincanapi.com/TinCanPython/Test/Unit/0",
            definition=ActivityDefinition()
        )
        self.activity.definition.type = "http://id.tincanapi.com/activitytype/unit-test"
        self.activity.definition.name = LanguageMap({"en-US": "Python Tests"})
        self.activity.definition.description = LanguageMap(
            {"en-US": "Unit test in the test suite for the Python library"}
        )
        self.activity.object_type = 'Activity'

        self.parent = Activity(
            id="http://tincanapi.com/TinCanPython/Test",
            definition=ActivityDefinition())
        self.parent.definition.type = "http://id.tincanapi.com/activitytype/unit-test-suite"
        self.parent.definition.name = LanguageMap({"en-US": "Python Tests"})
        self.parent.definition.description = LanguageMap(
            {"en-US": "Unit test in the test suite for the Python library"}
        )
        self.parent.object_type = 'Activity'

        self.statement_ref = StatementRef(id=uuid.uuid4())

        self.context = Context(registration=uuid.uuid4(), statement=self.statement_ref)
        # self.context.context_activities = ContextActivities(parent=[self.parent])

        self.score = Score(
            raw=97,
            scaled=0.97,
            max=100,
            min=0
        )

        self.result = Result(
            score=self.score,
            success=True,
            completion=True,
            duration="PT120S"
        )

        self.substatement = SubStatement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity,
        )

    def tearDown(self):
        pass

    def test_instantiation(self):
        lrs = RemoteLRS()
        self.assertIsInstance(lrs, RemoteLRS)
        self.assertIsNone(lrs.endpoint)
        self.assertIsNone(lrs.auth)
        self.assertEqual(Version.latest, lrs.version)

    def test_about(self):
        response = self.lrs.about()

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsInstance(response.content, About)

    def test_about_failure(self):
        lrs = RemoteLRS(endpoint="http://cloud.scorm.com/tc/3TQLAI9/sandbox/")
        response = lrs.about()

        self.assertFalse(response.success)

    def test_save_statement(self):
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity
        )
        response = self.lrs.save_statement(statement)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.content.id)
        self._vars_verifier(statement, response.content, ['_authority', '_stored'])

    def test_save_statement_with_id(self):
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity,
            id=str(uuid.uuid4())
        )
        response = self.lrs.save_statement(statement)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(statement, response.content)

    def test_save_statement_conflict(self):
        test_id = unicode(uuid.uuid4())

        statement1 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.substatement,
            id=test_id
        )
        statement2 = Statement(
            actor=self.agent2,
            verb=self.verb,
            object=self.substatement,
            id=test_id
        )
        response = self.lrs.save_statement(statement1)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

        response = self.lrs.save_statement(statement2)

        self.assertIsInstance(response, LRSResponse)
        self.assertFalse(response.success)
        self.assertEquals(response.response.status, 409)

    def test_save_statement_ref(self):
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.statement_ref,
            id=str(uuid.uuid4())
        )
        response = self.lrs.save_statement(statement)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(statement, response.content, ['_authority', '_stored'])

    def test_save_statement_group(self):
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.group,
            id=str(uuid.uuid4())
        )
        response = self.lrs.save_statement(statement)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(statement, response.content)

    def test_save_statement_substatement(self):
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.substatement,
            id=str(uuid.uuid4())
        )
        response = self.lrs.save_statement(statement)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(statement, response.content, ['_authority', '_stored'])

    def test_save_statements(self):
        statement1 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity
        )
        statement2 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity,
            context=self.context
        )
        response = self.lrs.save_statements([statement1, statement2])

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.content[0].id)
        self.assertIsNotNone(response.content[1].id)
        self._vars_verifier(statement1, response.content[0], ['_authority', '_stored'])
        self._vars_verifier(statement2, response.content[1], ['_authority', '_stored'])

    @unittest.skip("LRS truncates timestamps which makes returned statements evaluate not equal")
    def test_retrieve_statement(self):
        id_str = str(uuid.uuid4())
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity,
            context=self.context,
            result=self.result,
            id=id_str,
            version=Version.latest,
            timestamp=utc.localize(datetime.utcnow())
        )
        save_resp = self.lrs.save_statement(statement)

        self.assertTrue(save_resp.success)
        response = self.lrs.retrieve_statement(save_resp.content.id)
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(response.content, statement, ['_authority', '_stored'])

    def test_retrieve_statement_no_microsecond(self):
        id_str = str(uuid.uuid4())
        dt = utc.localize(datetime.utcnow())
        statement = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.activity,
            context=self.context,
            result=self.result,
            id=id_str,
            version=Version.latest,
            timestamp=dt
        )
        save_resp = self.lrs.save_statement(statement)

        self.assertTrue(save_resp.success)
        response = self.lrs.retrieve_statement(save_resp.content.id)
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(response.content, statement, ['_authority', '_stored'])

    @unittest.skip("LRS truncates timestamps which makes returned statements evaluate not equal")
    def test_query_statements(self):
        tstamp = utc.localize(datetime.utcnow())
        s1 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4()),
            timestamp=tstamp
        )
        self.lrs.save_statement(s1)

        s2 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4()),
            timestamp=tstamp
        )
        self.lrs.save_statement(s2)

        s3 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4()),
            timestamp=tstamp
        )
        self.lrs.save_statement(s3)

        query = {
            "agent": self.agent,
            "verb": self.verb,
            "activity": self.parent,
            "related_activities": True,
            "related_agents": True,
            "limit": 2
        }
        response = self.lrs.query_statements(query)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsInstance(response.content, StatementsResult)
        self.assertTrue(hasattr(response.content, 'more'))
        self.assertIsNotNone(response.content.more)
        self._vars_verifier(s1, response.content.statements[0])
        self._vars_verifier(s2, response.content.statements[1])

    def test_query_statements_no_microsecond(self):
        tstamp = utc.localize(datetime.utcnow())
        s1 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4()),
            timestamp=tstamp
        )
        self.lrs.save_statement(s1)

        s2 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4()),
            timestamp=tstamp
        )
        self.lrs.save_statement(s2)

        s3 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4()),
            timestamp=tstamp
        )
        self.lrs.save_statement(s3)

        query = {
            "agent": self.agent,
            "verb": self.verb,
            "activity": self.parent,
            "related_activities": True,
            "related_agents": True,
            "limit": 2
        }
        response = self.lrs.query_statements(query)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsInstance(response.content, StatementsResult)
        self.assertTrue(hasattr(response.content, 'more'))
        self.assertIsNotNone(response.content.more)
        self._vars_verifier(s1, response.content.statements[0])
        self._vars_verifier(s2, response.content.statements[1])

    def test_query_none(self):
        query = {
            "agent": self.agent,
            "verb": self.verb,
            "activity": self.parent,
            "related_activities": True,
            "related_agents": True,
            "format": "ids",
            "limit": 2,
            "registration": unicode(uuid.uuid4()),
        }
        response = self.lrs.query_statements(query)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsInstance(response.content, StatementsResult)
        self.assertTrue(hasattr(response.content, 'more'))
        self.assertTrue(hasattr(response.content, 'statements'))
        self.assertEquals(response.content.statements, [])

    def test_more_statements(self):
        s1 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4())
        )
        self.lrs.save_statement(s1)

        s2 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4())
        )
        self.lrs.save_statement(s2)

        s3 = Statement(
            actor=self.agent,
            verb=self.verb,
            object=self.parent,
            result=self.result,
            id=str(uuid.uuid4())
        )
        self.lrs.save_statement(s3)

        query = {
            "agent": self.agent,
            "verb": self.verb,
            "activity": self.parent,
            "related_activities": True,
            "related_agents": True,
            "format": "ids",
            "limit": 2
        }
        query_resp = self.lrs.query_statements(query)

        self.assertIsInstance(query_resp, LRSResponse)
        self.assertTrue(query_resp.success)
        self.assertIsNotNone(query_resp.content.more)

        response = self.lrs.more_statements(query_resp.content)
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self.assertIsInstance(response.content, StatementsResult)

    def test_retrieve_state_ids(self):
        response = self.lrs.retrieve_state_ids(activity=self.activity, agent=self.agent)
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_retrieve_state(self):
        response = self.lrs.retrieve_state(
            activity=self.activity,
            agent=self.agent,
            state_id="test"
        )
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_save_state(self):
        doc = StateDocument(
            activity=self.activity,
            agent=self.agent,
            id="test",
            content=bytearray("Test value", encoding="utf-8")
        )
        saveResp = self.lrs.save_state(doc)

        self.assertIsInstance(saveResp, LRSResponse)
        self.assertTrue(saveResp.success)

        response = self.lrs.retrieve_state(
            activity=self.activity,
            agent=self.agent,
            state_id="test"
        )
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(response.content, doc)

    def test_delete_state(self):
        doc = StateDocument(
            activity=self.activity,
            agent=self.agent,
            id="test"
        )
        response = self.lrs.delete_state(doc)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_clear_state(self):
        response = self.lrs.clear_state(activity=self.activity, agent=self.agent)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_retrieve_activity_profile_ids(self):
        response = self.lrs.retrieve_activity_profile_ids(activity=self.activity)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_retrieve_activity_profile(self):
        response = self.lrs.retrieve_activity_profile(activity=self.activity, profile_id="test")

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_save_activity_profile(self):
        doc = ActivityProfileDocument(
            activity=self.activity,
            id="test",
            content=bytearray("Test value", encoding="utf-8")
        )
        saveResp = self.lrs.save_activity_profile(doc)

        self.assertIsInstance(saveResp, LRSResponse)
        self.assertTrue(saveResp.success)

        response = self.lrs.retrieve_activity_profile(
            activity=self.activity,
            profile_id="test"
        )
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(response.content, doc)

    def test_delete_activity_profile(self):
        doc = ActivityProfileDocument(activity=self.activity, id="test")
        response = self.lrs.delete_activity_profile(doc)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_retrieve_agent_profile_ids(self):
        response = self.lrs.retrieve_agent_profile_ids(self.agent)
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_retrieve_agent_profile(self):
        response = self.lrs.retrieve_agent_profile(agent=self.agent, profile_id="test")
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def test_save_agent_profile(self):
        doc = AgentProfileDocument(
            agent=self.agent,
            id="test",
            content=bytearray("Test value", encoding="utf-8")
        )
        saveResp = self.lrs.save_agent_profile(doc)
        self.assertIsInstance(saveResp, LRSResponse)
        self.assertTrue(saveResp.success)

        response = self.lrs.retrieve_agent_profile(
            agent=self.agent,
            profile_id="test"
        )
        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)
        self._vars_verifier(response.content, doc)

    def test_delete_agent_profile(self):
        doc = AgentProfileDocument(agent=self.agent, id="test")
        response = self.lrs.delete_agent_profile(doc)

        self.assertIsInstance(response, LRSResponse)
        self.assertTrue(response.success)

    def _vars_verifier(self, obj1, obj2, _ignored_attrs=None):
        if _ignored_attrs is None:
            _ignored_attrs = ['_authority', '_stored', '_id']
        for k, v in vars(obj1).iteritems():
            if k in _ignored_attrs:
                continue
            elif isinstance(v, datetime):
                dt1 = getattr(obj1, k)
                dt2 = getattr(obj2, k)
                ts1 = timegm(dt1.timetuple())
                ts2 = timegm(dt2.timetuple())
                self.assertEqual(ts1, ts2)

                #
                # dealing in math operations on the microsecond was too much of a pain,
                # and the value should be truncated as opposed to rounded so it is just
                # as easy to deal with it in string form, so convert to string, zero pad
                # to 6 characters, then truncate to only the first 3 of those characters
                # and then string compare
                #
                self.assertEqual(str(dt1.microsecond).zfill(6)[:3], str(dt2.microsecond).zfill(6)[:3])
            elif isinstance(v, Base):
                self._vars_verifier(getattr(obj1, k), getattr(obj2, k))
            else:
                self.assertEqual(getattr(obj1, k), getattr(obj2, k))
Ejemplo n.º 6
0
)
print "...done"

# construct the actual statement
print "constructing the Statement..."
statement = Statement(
    actor=actor,
    verb=verb,
    object=object,
    context=context,
)
print "...done"

# save our statement to the remote_lrs and store the response in 'response'
print "saving the Statement..."
response = lrs.save_statement(statement)

if not response:
    raise ValueError("statement failed to save")
print "...done"

# retrieve our statement from the remote_lrs using the id returned in the response
print "Now, retrieving statement..."
response = lrs.retrieve_statement(response.content.id)

if not response.success:
    raise ValueError("statement could not be retrieved")
print "...done"

print "constructing new Statement from retrieved statement data..."
ret_statement = response.content
Ejemplo n.º 7
0
if __name__ == '__main__':
    import fileinput
    import sys

    csv_entries = (l.strip() for l in fileinput.input())

    remote_lrs = RemoteLRS(
        endpoint=lrs['endpoint'],
        # RemoteLRS uses HTTP Basic Auth
        # so username, password will be sent out
        # with the authorization header.
        username=lrs['username'],
        password=lrs['password'],
    )

    for csv_entry in csv_entries:
        try:
            statement = create_statement(csv_entry)
        except ValueError, e:
            # ignore invalid entries
            print("Failed to create statement for %s with the error: %s" %
                  (csv_entry, e),
                  file=sys.stderr)
            continue
        # XXX: Look out for response == None
        # and possibly add the statement to a retry queue
        response = remote_lrs.save_statement(statement)
        if not response.success:
            print("Failed to save statement for %s" % (csv_entry, ))
Ejemplo n.º 8
0
)
print "...done"

# construct the actual statement
print "constructing the Statement..."
statement = Statement(
    actor=actor,
    verb=verb,
    object=object,
    context=context,
)
print "...done"

# save our statement to the remote_lrs and store the response in 'response'
print "saving the Statement..."
response = lrs.save_statement(statement)

if not response:
    raise ValueError("statement failed to save")
print "...done"

# retrieve our statement from the remote_lrs using the id returned in the response
print "Now, retrieving statement..."
response = lrs.retrieve_statement(response.content.id)

if not response.success:
    raise ValueError("statement could not be retrieved")
print "...done"

print "constructing new Statement from retrieved statement data..."
ret_statement = response.content
Ejemplo n.º 9
0

    csv_entries = (l.strip() for l in fileinput.input())
    
    remote_lrs = RemoteLRS(
        endpoint=lrs['endpoint'],
        # RemoteLRS uses HTTP Basic Auth
        # so username, password will be sent out
        # with the authorization header.
        username=lrs['username'],
        password=lrs['password'],
    )
    
    for csv_entry in csv_entries:
        try:
            statement = create_statement(csv_entry)
        except ValueError, e:
            # ignore invalid entries
            print("Failed to create statement for %s with the error: %s"
                  % (csv_entry, e), file=sys.stderr)
            continue
        # XXX: Look out for response == None
        # and possibly add the statement to a retry queue
        response = remote_lrs.save_statement(statement)
        if not response.success:
            print("Failed to save statement for %s" % (csv_entry,))