-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add new learning events for course grades and badges #303
Conversation
Thanks for the pull request, @kyrylo-kh! Please note that it may take us up to several weeks or months to complete a review and merge your PR. Feel free to add as much of the following information to the ticket as you can:
All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here. Please let us know once your PR is ready for our review and all tests are green. |
Hi @kyrylo-kh! Thanks for this contribution. It looks like you're contributing on behalf of Raccoon Gang. In order to get you added to Raccoon Gang's entity CLA agreement, please have your manager reach out to [email protected]. Thank you! |
Context: Credentials Badges (+Credly integration). This is a WIP PR to make possible early feedback. We have started from the bare minimum, but the details are still a matter of shaping. |
openedx_events/learning/data.py
Outdated
@attr.s(frozen=True) | ||
class UserCourseData: | ||
""" | ||
Attributes defined for Open edX user course data object. | ||
|
||
Arguments: | ||
user (UserData): user associated with the Course Enrollment. | ||
course (CourseData): course where the user is enrolled in. | ||
""" | ||
|
||
user = attr.ib(type=UserData) | ||
course = attr.ib(type=CourseData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this just being a combination of UserData
and CourseData
, should we instead possibly make this a GradeData
data class?
Since this is being used in the new COURSE_GRADE_NOW_PASSED
and COURSE_GRADE_NOW_FAILED
events, it could be useful to the folks who may be consuming this event in the future to have the actual grade data available as part of the event.
Hopefully we could include some items like percent_grade
, letter_grade
and other model fields from the PersistentCourseGrade
model of the LMS?
Seems like we're missing an opportunity here to include that data for future event bus consumers.
4b67a57
to
19e9217
Compare
* feat: [ACI-75] new public events * feat: [ACI-139, ACI-145] new events for badge
…urse (#5) * feat: [ACI-512] describe ccx course payload dataclass * feat: [ACI-510] define ccx-course-grade-passed signal * feat: [ACI-511] define ccx-course-grade-failed signal * feat: [ACI-510, ACI-511, ACI-512] new events and dataclass for ccx course * style: [ACI-512] fix line-too-long and trailing-whitespace --------- Co-authored-by: Andrii <[email protected]>
* feat: [ACI-512] update CCX events payload * chore(deps): upgrade dependencies * feat(deps): add edx-ccx-keys library
Co-authored-by: Andrii <[email protected]>
* refactor: [ACI-502, ACI-503] redesign course grading events payload * refactor: include passing status to data class * refactor: merge passing/failing signals to a single status signal * refactor: update avro schemas
@kyrylo-kh pls update the description as well. |
* fix: [ACI-152] fix django tests failure * style: [ACI-152] adjust code style to pylint requirements --------- Co-authored-by: Andrii <[email protected]>
6a918eb
to
9d2a80d
Compare
* fix: [ACI-152] fix django tests failure * style: [ACI-152] adjust code style to pylint requirements --------- Co-authored-by: Andrii <[email protected]>
* test: [ACI-949] increase coverage & fix status field problem * refactor: [ACI-949] remove redundant comments --------- Co-authored-by: Andrii <[email protected]>
Do you folks have a draft PR in the service from where these events will be sent? |
@mariajgrimaldi here related Platform draft PR. |
I like the suggestion of refactoring the |
class TestCCXLocatorSerailizer(TestCase): | ||
def test_serialize(self): | ||
obj1 = CCXLocator(org="edx", course="DemoX", run="Demo_course", ccx="1") | ||
expected1 = "ccx-v1:edx+DemoX+Demo_course+ccx@1" | ||
result1 = CcxCourseLocatorAvroSerializer.serialize(obj1) | ||
self.assertEqual(result1, expected1) | ||
|
||
def test_deseialize(self): | ||
data1 = "ccx-v1:edx+DemoX+Demo_course+ccx@1" | ||
expected1 = CCXLocator(org="edx", course="DemoX", run="Demo_course", ccx="1") | ||
result1 = CcxCourseLocatorAvroSerializer.deserialize(data1) | ||
self.assertEqual(result1, expected1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add docstrings here? Thanks!
openedx_events/learning/data.py
Outdated
in which the grade was updated. | ||
""" | ||
|
||
status = attr.ib(type=str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Picking up the conversation about whether using status='passing' | 'failing'
or `is_passing=True':
Option 1 status='passing' | 'failing'
:
Pros
- Explicit status attribute for
CoursePassingStatus...
Cons
- Hard-coded constant
- No validation support yet. Status could be anything.
- The integration PR would need to know the status format:
CCX_COURSE_PASSING_STATUS_UPDATED.send_event(
course_passing_status=CcxCoursePassingStatusData(
status='passing',
user=UserData(
pii=UserPersonalData(
username=user.username,
email=user.email,
name=user.get_full_name(),
),
id=user.id,
is_active=user.is_active,
),
course=CcxCourseData(
ccx_course_key=course_id,
master_course_key=course_id.to_course_locator(),
),
)
)
status='passing'
was previously CcxCoursePassingStatusData.PASSING
, which was standardized but then dropped altogether with the validator, but for maintainability reasons, we shouldn't use status='passing'
.
Option 2 is_passing=True
:
Pros
- It's similar to what's currently used by the PersistentCourseGrade model to send the events: https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/grades/course_grade_factory.py#L180
passed=grade.passed
- Doesn't need validation, it could be either True or False
Cons
- Is it explicit enough?
Which of the options should we choose? I'm leaning towards option 2, but you folks have more context on the problem you're solving. Please, let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mariajgrimaldi.
We discussed it internally and decided to go with the second option: we'll update status
in favor of the is_passing=True|False
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mariajgrimaldi we've refactored as discussed. Please, review.
@GlugovGrGlib fyi.
* chore: Updating Python Requirements (openedx#343) * chore: Updating Python Requirements (openedx#344) * refactor: [ACI-972] change course status to is_passing & add docs * chore: [ACI-972] requirements update * fix: remove local development index from requirements --------- Co-authored-by: edX requirements bot <[email protected]> Co-authored-by: Andrii <[email protected]> Co-authored-by: wowkalucky <[email protected]>
@mariajgrimaldi This is ready for the final review, it'll be good if we could bump version and merge related edx-platform PR after requirements update before Redwood cut |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few minor comments left to address. Thank you!
@mariajgrimaldi fixed. |
@wowkalucky: could you please address this last comment? Thank you. I'll merge @ 11am est or once that's done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll merge this now as is. Thank you again!
@kyrylo-kh 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future. |
v9.10.0 released! Thank you all. |
Description:
This is a prerequisite work for the new Badges with Credly integration feature.
Changes
Adds a new dependency:
edx-ccx-keys
Implements new custom serializer:
CcxCourseLocatorAvroSerializer
Implements new data classes:
CcxCourseData
(CCX specific course data)CoursePassingStatusData
(current course grade passing status for user)CcxCoursePassingStatusData
(current CCX course grade passing status for user)BadgeTemplateData
(badge template credential type)BadgeData
(badge user credential)Adds new public signals:
COURSE_PASSING_STATUS_UPDATED
(course grade update with passing status)CCX_COURSE_PASSING_STATUS_UPDATED
(CCX course grade update with passing status)BADGE_AWARDED
(new badge awarding for user)BADGE_REVOKED
(existing badge revocation for user)ISSUE: openedx/platform-roadmap#280
Dependencies: this PR itself is a blocker for 2 PRs (LMS, Credentials) which are work in progress.
Merge deadline: ASAP when possible.
Installation instructions: nothing special.
Testing instructions: noting special.
Reviewers:
Merge checklist:
Post merge:
finished.
Author concerns:
This PR is a blocker for further LMS/Credentials contribution, since both services depend on the future
openedx-events
version that includes these signals/data.