Grading with a custom XBlock

Hi, I’m having trouble determining whether or not the custom
xblock
I’m working on is publishing grades within devstack. Other
than in the logs below, I have seen no indication that the grading
machinery is active.


image

In the above screen shot of the progress page, I expected to see some
indication that a grade had been submitted. For what it’s worth I have
set the grading type of the section, as shown below.


More documentation would help a great deal, ideally, an example that
demonstrates the simplest possible xblock that submits a
grade. However, if anyone knows of a suitable xblock to learn from
then please post a link to it!

As it is, I have found two helpful sources for xblock grading
information:

https://openedx.atlassian.net/wiki/spaces/AC/pages/161400730/Open+edX+Runtime+XBlock+API
https://edx.readthedocs.io/projects/xblock-tutorial/en/latest/concepts/events.html

Unfortunately, none of the XBlock examples interact with the grading mechanism.

If it exists, could someone please point to some documentation about
what is required of an xblock for it to be included as a graded
element of the course? I don’t know if I’m missing a method, or I’m
failing to register it with the framework?

Some questions I have:

Does anyone know about where the progress.Progress class is defined as
mention in this post


Finally, I don’t know if it will help, but I’ve included the 6
log entries which are emitted after running my handler method
resposible for grading.

edx.devstack.lms | 2022-01-12 20:25:28,486 INFO 855 [tracking]
[user 3] [ip 172.24.0.1] logger.py:41 - {
  "name": "/courses/course-v1:Bar+Bar+BAR2/xblock/block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e/handler/load_hub_data",
  "context": {
    "course_id": "course-v1:Bar+Bar+BAR2",
    "course_user_tags": {},
    "user_id": 3,
    "path": "/courses/course-v1:Bar+Bar+BAR2/xblock/block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e/handler/load_hub_data",
    "org_id": "Bar",
    "enterprise_uuid": ""
  },
  "username": "edx",
  "session": "a11803c65463847398f69b4c953e1add",
  "ip": "172.24.0.1",
  "host": "localhost:18000",
  "referer": "http://localhost:18000/xblock/block-v1:Bar+Bar+BAR2+type@vertical+block@3131ddcc9c2343728def45a2ad7cdf9d?show_title=0&show_bookmark_button=0&recheck_access=1&view=student_view&format=Lab",
  "accept_language": "en-US,en;q=0.9",
  "event": "{\"GET\": {}, \"POST\": {\"{}\": [\"\"]}}",
  "time": "2022-01-12T20:25:28.486664+00:00",
  "event_type": "/courses/course-v1:Bar+Bar+BAR2/xblock/block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e/handler/load_hub_data",
  "event_source": "server",
  "page": null
}

edx.devstack.lms | 2022-01-12 20:25:29,175 INFO 855
[tracking] [user 3] [ip 172.24.0.1] logger.py:41 - {
  "name": "edx.grades.problem.submitted",
  "context": {
    "course_id": "course-v1:Bar+Bar+BAR2",
    "course_user_tags": {},
    "user_id": 3,
    "path": "/courses/course-v1:Bar+Bar+BAR2/xblock/block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e/handler/load_hub_data",
    "org_id": "Bar",
    "enterprise_uuid": "",
    "module": {
      "display_name": "TestLab1",
      "usage_key": "block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e"
    }
  },
  "username": "edx",
  "session": "a11803c65463847398f69b4c953e1add",
  "ip": "172.24.0.1",
  "host": "localhost:18000",
  "referer": "http://localhost:18000/xblock/block-v1:Bar+Bar+BAR2+type@vertical+block@3131ddcc9c2343728def45a2ad7cdf9d?show_title=0&show_bookmark_button=0&recheck_access=1&view=student_view&format=Lab",
  "accept_language": "en-US,en;q=0.9",
  "event": {
    "user_id": "3",
    "course_id": "course-v1:Bar+Bar+BAR2",
    "problem_id": "block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e",
    "event_transaction_id": "901e437a-2658-4f8f-8c1d-778d2f1475b1",
    "event_transaction_type": "edx.grades.problem.submitted",
    "weighted_earned": 1,
    "weighted_possible": 2
  },
  "time": "2022-01-12T20:25:29.174693+00:00",
  "event_type": "edx.grades.problem.submitted",
  "event_source": "server",
  "page": null
}
 
edx.devstack.lms | 2022-01-12 20:25:29,614 INFO 855
[tracking] [user 3] [ip 172.24.0.1] logger.py:41 - {
  "name": "edx.course.grade.now_failed",
  "context": {
    "course_id": "course-v1:Bar+Bar+BAR2",
    "course_user_tags": {},
    "user_id": 3,
    "path": "/courses/course-v1:Bar+Bar+BAR2/xblock/block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e/handler/load_hub_data",
    "org_id": "Bar",
    "enterprise_uuid": "",
    "module": {
      "display_name": "TestLab1",
      "usage_key": "block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e"
    }
  },
  "username": "edx",
  "session": "a11803c65463847398f69b4c953e1add",
  "ip": "172.24.0.1",
  "host": "localhost:18000",
  "referer": "http://localhost:18000/xblock/block-v1:Bar+Bar+BAR2+type@vertical+block@3131ddcc9c2343728def45a2ad7cdf9d?show_title=0&show_bookmark_button=0&recheck_access=1&view=student_view&format=Lab",
  "accept_language": "en-US,en;q=0.9",
  "event": {
    "user_id": "3",
    "course_id": "course-v1:Bar+Bar+BAR2",
    "event_transaction_id": "901e437a-2658-4f8f-8c1d-778d2f1475b1",
    "event_transaction_type": "edx.grades.problem.submitted"
  },
  "time": "2022-01-12T20:25:29.614415+00:00",
  "event_type": "edx.course.grade.now_failed",
  "event_source": "server",
  "page": null
}

edx.devstack.lms | 2022-01-12 20:25:29,644 INFO 855
[lms.djangoapps.grades.course_grade_factory] [user 3] [ip 172.24.0.1] 
course_grade_factory.py:218 - 
Grades: Update, 
Course: course_key: course-v1:Bar+Bar+BAR2, 
version: 61df0b1e3a45da4c833c2ec1, 
edited_on: 2022-01-12 17:08:46.236000+00:00, 
grading_policy: c34yC5vKVtq/R5aAKECJXwKs7lg=, 
User: 3, 
Course Grade: percent: 0.0, 
letter_grade: None, 
passed: False, 
persisted: False

edx.devstack.lms | 2022-01-12 20:25:29,645 INFO 855 
[celery.app.trace] [user 3] [ip 172.24.0.1] trace.py:125 - 
Task lms.djangoapps.grades.tasks.recalculate_subsection_grade_v3[9f70a4ba-2287-4934-b689-f3b66fa8144a] 
succeeded in 0.4678689439970185s: None

edx.devstack.lms | 2022-01-12 20:25:29,645 INFO 855 
[celery_utils.logged_task] [user 3] [ip 172.24.0.1] logged_task.py:25 - 
Task lms.djangoapps.grades.tasks.recalculate_subsection_grade_v3[9f70a4ba-2287-4934-b689-f3b66fa8144a] 
submitted with arguments None, {
  'user_id': 3, 
  'anonymous_user_id': None, 
  'course_id': 'course-v1:Bar+Bar+BAR2', 
  'usage_id': 'block-v1:Bar+Bar+BAR2+type@remoxblock+block@26e64ab9d92344b1993184d175648d2e', 
  'only_if_higher': False, 
  'expected_modified_time': 1642019129,
  'score_deleted': None, 'event_transaction_id':
  '901e437a-2658-4f8f-8c1d-778d2f1475b1', 'event_transaction_type':
  'edx.grades.problem.submitted',
  'score_db_table': 'csm', 
  'force_update_subsections': False
}

From those logs can anyone determine if a grade was actually
submitted?

Any hints would be greatly appreciated. Thanks.

staff graded xblock is pretty simple and might be a nice point of comparison? This document may also be a useful reference.

From looking at your code I suspect you might be missing max_score() like this. If you don’t implement it, it defaults to None which may be the issue.

Hi Braden, thanks for taking time to answer my question and for all the links you posted.

It’s working now! Besides max_score() two other changes were necessary:

adding a weight field on the model, which enabled “graded: True” to appear in the STAFF DEBUG INFO modal:

image

Secondly, implementing publish_grade, was necessary, which only entailed calling the _public_grade method found on ScorableXBlockMixin,

def publish_grade(self):
    self._publish_grade(self.calculate_score())

Thanks again Braden!

1 Like