Skip to content
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: api migration #213

Merged
merged 15 commits into from
Jan 5, 2024
Merged

feat: api migration #213

merged 15 commits into from
Jan 5, 2024

Conversation

volodymyr-chekyrta
Copy link
Contributor

Migration API endpoints from the RG API plugin to the edx-platform upstream.

New endpoints:
Delete account
api/user/v1/accounts/deactivate_logout/
Dashboard Courses
api/mobile/v3/users/{USERNAME}/course_enrollments
Add Comment / Response
api/discussion/v1/comments/
Discovery And Search
api/courses/v1/courses/
Get Course Details
api/mobile/v3/course_info/{COURSE_ID}/info
Get Course Structure
api/mobile/v3/course_info/blocks/
@volodymyr-chekyrta volodymyr-chekyrta self-assigned this Dec 18, 2023
@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Dec 18, 2023
@openedx-webhooks
Copy link

Thanks for the pull request, @volodymyr-chekyrta! 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:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

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.

Core/Core/Data/Model/Data_Dashboard.swift Outdated Show resolved Hide resolved
Core/Core/Data/Model/Data_Dashboard.swift Outdated Show resolved Hide resolved
@volodymyr-chekyrta volodymyr-chekyrta changed the title DRAFT: feat: api migration feat: api migration Dec 19, 2023
rnr
rnr previously approved these changes Dec 27, 2023
@rnr
Copy link
Contributor

rnr commented Dec 28, 2023

@miankhalid Is @saeedbashir available from Axinite side to review PRs or maybe @shafqat-muneer could do it? Thank you

@shafqat-muneer
Copy link
Contributor

@miankhalid Is @saeedbashir available from Axinite side to review PRs or maybe @shafqat-muneer could do it? Thank you

@rnr Sure, I will review from Axinite side.

@rnr rnr requested review from shafqat-muneer and removed request for saeedbashir December 28, 2023 12:59
@shafqat-muneer
Copy link
Contributor

shafqat-muneer commented Dec 29, 2023

This endpoint is giving 404 error and not able to load course details:

https://raccoonapis.sandbox.edx.org/api/mobile/v3/course_info/course-v1:edx+1+2023/info

@volodymyr-chekyrta
Copy link
Contributor Author

This endpoint is giving 404 error and not able to load course details:

https://raccoonapis.sandbox.edx.org/api/mobile/v3/course_info/course-v1:edx+1+2023/info

Got the same feedback on the Android PR.

Can you make sure you've got the latest changes from upstream?
openedx/edx-platform#33646

Works fine on my env.
image

@shafqat-muneer
Copy link
Contributor

Got the same feedback on the Android PR.

Can you make sure you've got the latest changes from upstream? openedx/edx-platform#33646

Works fine on my env. image

@volodymyr-chekyrta Our build pipeline is currently under code freeze, so, new changes might not have been deployed to our stage and prod environments
as for the https://raccoonapis.sandbox.edx.org/ sandbox that we use, our backend team will need to push the latest changes once they are back on Monday

@shafqat-muneer
Copy link
Contributor

Upon tapping the logout button, the application crashes and displays an error:

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Screenshot 2024-01-01 at 1 37 58 PM

@volodymyr-chekyrta
Copy link
Contributor Author

Upon tapping the logout button, the application crashes and displays an error:

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Screenshot 2024-01-01 at 1 37 58 PM

Thank you! I've merged the develop branch into this one and resolved the issue.

@volodymyr-chekyrta
Copy link
Contributor Author

Got the same feedback on the Android PR.
Can you make sure you've got the latest changes from upstream? openedx/edx-platform#33646
Works fine on my env. image

@volodymyr-chekyrta Our build pipeline is currently under code freeze, so, new changes might not have been deployed to our stage and prod environments as for the https://raccoonapis.sandbox.edx.org/ sandbox that we use, our backend team will need to push the latest changes once they are back on Monday

@shafqat-muneer hi!
Do you have any updates regarding the latest changes? Has your backend team pushed them?

@miankhalid
Copy link

Got the same feedback on the Android PR.
Can you make sure you've got the latest changes from upstream? openedx/edx-platform#33646
Works fine on my env. image

@volodymyr-chekyrta Our build pipeline is currently under code freeze, so, new changes might not have been deployed to our stage and prod environments as for the https://raccoonapis.sandbox.edx.org/ sandbox that we use, our backend team will need to push the latest changes once they are back on Monday

@shafqat-muneer hi! Do you have any updates regarding the latest changes? Has your backend team pushed them?

Something weird is going on as only this API isn’t working on our end while the Enrollments v3 API (/api/mobile/v3/users/{username}/course_enrollments/) is working just fine, even though both have been deployed on our sandboxes.

our backend team is looking into this issue. in the meanwhile, @volodymyr-chekyrta do you know of any waffle flags or configurations that need to be done on the discovery service’s side for this API to work?

@volodymyr-chekyrta
Copy link
Contributor Author

Got the same feedback on the Android PR.
Can you make sure you've got the latest changes from upstream? openedx/edx-platform#33646
Works fine on my env. image

@volodymyr-chekyrta Our build pipeline is currently under code freeze, so, new changes might not have been deployed to our stage and prod environments as for the https://raccoonapis.sandbox.edx.org/ sandbox that we use, our backend team will need to push the latest changes once they are back on Monday

@shafqat-muneer hi! Do you have any updates regarding the latest changes? Has your backend team pushed them?

Something weird is going on as only this API isn’t working on our end while the Enrollments v3 API (/api/mobile/v3/users/{username}/course_enrollments/) is working just fine, even though both have been deployed on our sandboxes.

our backend team is looking into this issue. in the meanwhile, @volodymyr-chekyrta do you know of any waffle flags or configurations that need to be done on the discovery service’s side for this API to work?

Got it, thank you!
I think there are no additional waffle flags or configurations for this endpoint if /api/mobile/v3/users/{username}/course_enrollments/ is already working fine.

@volodymyr-chekyrta
Copy link
Contributor Author

@saeedbashir I've fixed the issue. Can you please retest it?

@saeedbashir
Copy link
Contributor

@saeedbashir I've fixed the issue. Can you please retest it?

@volodymyr-chekyrta I'm still getting the following error

dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "enrollments", intValue: nil), 
CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 2", intValue: 2), CodingKeys(stringValue: 
"course_modes", intValue: nil), _JSONKey(stringValue: "Index 1", intValue: 1), CodingKeys(stringValue: "slug", intValue: nil)], 
debugDescription: "Cannot initialize Mode from invalid String value verified", underlyingError: nil))

@saeedbashir
Copy link
Contributor

saeedbashir commented Jan 3, 2024

mode

@volodymyr-chekyrta I've figured out the issue. You need to add verified in the Mode enum.

enum Mode: String, Codable {
        case audit
        case honor
        case verified
    }

@volodymyr-chekyrta
Copy link
Contributor Author

@saeedbashir I've fixed the issue. Can you please retest it?

@volodymyr-chekyrta I'm still getting the following error

dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "enrollments", intValue: nil), 
CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 2", intValue: 2), CodingKeys(stringValue: 
"course_modes", intValue: nil), _JSONKey(stringValue: "Index 1", intValue: 1), CodingKeys(stringValue: "slug", intValue: nil)], 
debugDescription: "Cannot initialize Mode from invalid String value verified", underlyingError: nil))

Fixed. Please try now

@saeedbashir
Copy link
Contributor

@volodymyr-chekyrta It's working now. Is it possible to make the parsing a bit lenient so that if an unknown value comes up, it will get ignored?

Now I'm getting 404 for the API Response: GET https://courses.edx.org/api/mobile/v1/users/rtester2/course_status_info/course-v1:EC-Council+DFE-112-53+3T2022 (404)

Response:

{"has_access":false,"error_code":"audit_expired","developer_message":"User rtester2 had access to 
<CourseBlockWithMixins @4BC5 license=None, parent=None, name=None, tags=[], display_name='Digital Forensics 
Essentials (DFE)', course_edit_method='Studio', days_early_for_beta=None, due=None, edxnotes=False, 
edxnotes_visibility=True, giturl=None, graceperiod=datetime.timedelta(0), graded=False, group_access={}, 
in_entrance_exam=False, matlab_api_key=None, max_attempts=None, relative_weeks_due=None, rerandomize='never', 
self_paced=True, show_correctness='always', show_reset_button=False, showanswer='finished', 
start=datetime.datetime(2023, 1, 19, 6, 30, tzinfo=<bson.tz_util.FixedOffset object at 0x7f517c9768e0>), 
static_asset_path='', use_latex_compiler=False, user_partitions=[], video_auto_advance=False, video_bumper={},
video_speed_optimizations=True, visible_to_staff_only=False, xqa_key=None, chrome=None, default_tab=None, 
format=None, hide_from_toc=False, source_file=None, children=[BlockUsageLocator(CourseLocator('EC-Council', 'DFE-
112-53', '3T2022', None, None), 'chapter', 'dd520dc51f1f455daabff367407ce06f'), BlockUsageLocator(CourseLocator('EC-
Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 'f67c4fdff6d946a7ab3931339dee60ff'), 
BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 
'8db154fc3a0741c7aa956d265522a4c4'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, 
None), 'chapter', 'd54cb1e875074f5f8e2381333972b412'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', 
'3T2022', None, None), 'chapter', '24c138a330c64ad596064db4f5321235'), BlockUsageLocator(CourseLocator('EC-
Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '8ada2783a1564fdd9b7cc34545d160ee'), 
BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 
'989c98dba47949cb9536e6a82980532f'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, 
None), 'chapter', '8f4c812c1b164418b37ba5933ddf7a44'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', 
'3T2022', None, None), 'chapter', '620abe5a14bc4463bc1f348b4f47b42f'), BlockUsageLocator(CourseLocator('EC-
Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '5b8bc39124b24aca9f709847e949203b'), 
BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 'a11df613290145319e870559804545df'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '8b9c9f69ca83418bb7863a53b0add79b'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '8488d0834de5431b8ce4776f64474d76'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 'e376d6d8e98e4f07bb8e9b493f3ff40f')], default_time_limit_minutes=None, exam_review_rules='', hide_after_due=False, is_entrance_exam=False, is_onboarding_exam=False, is_practice_exam=False, is_proctored_enabled=False, is_time_limited=False, position=None, xml_attributes={}, advanced_modules=['lti_consumer'], advertised_start=None, allow_anonymous=True, allow_anonymous_to_peers=False, allow_proctoring_opt_out=False, allow_public_wiki_access=False, allow_unsupported_xblocks=False, announcement=None, banner_image='images_course_image.jpg', catalog_visibility='both', ccx_connector='', cert_html_view_enabled=True, cert_html_view_overrides={}, cert_name_long='', cert_name_short='', certificate_available_date=None, certificates={'certificates': [{'course_title': '', 'name': 'Name of the certificate', 'description': 'Description of the certificate', 'version': 1, 'is_active': True, 'editing': False, 'signatories': [{'name': 'Jay Bavisi', 'title': 'President and Chief Executive Officer', 'organization': 'EC-Council', 'signature_image_path': '/asset-v1:EC-Council+DFE-112-53+3T2022+type@asset+block@EC-Council_Certifcation_Signature_Image.png', 'certificate': None, 'id': 256576954}], 'id': 68069528}]}, certificates_display_behavior='end', certificates_show_before_end=False, cohort_config={}, cosmetic_display_price=0, course_image='course_image.jpg', course_survey_name=None, course_survey_required=False, course_visibility='private', course_wide_css=[], course_wide_js=[], create_zendesk_tickets=True, css_class='', disable_progress_graph=False, discussion_blackouts=[], discussion_link=None, discussion_topics={'General': {'id': 'course'}}, discussions_settings={'enable_in_context': True, 'enable_graded_units': False, 'unit_level_visibility': True}, display_coursenumber='', display_organization=None, due_date_display_format=None, enable_ccx=False, enable_proctored_exams=False, enable_subsection_gating=False, enable_timed_exams=True, end=datetime.datetime(2025, 11, 25, 6, 30, tzinfo=<bson.tz_util.FixedOffset object at 0x7f517c9768e0>), end_of_course_survey_url=None, enrollment_domain=None, enrollment_end=None, enrollment_start=None, entrance_exam_enabled=False, entrance_exam_id=None, entrance_exam_minimum_score_pct=65, force_on_flexible_peer_openassessments=False, grading_policy={'GRADER': [{'type': 'Quiz', 'min_count': 59, 'drop_count': 0, 'short_label': 'Quiz', 'weight': 0.44}, {'type': 'Lab', 'min_count': 11, 'drop_count': 0, 'short_label': 'Lab', 'weight': 0.56}], 'GRADE_CUTOFFS': {'Pass': 0.6}}, hide_progress_tab=None, highlights_enabled_for_messaging=False, html_textbooks=[], instructor_info={'instructors': []}, invitation_only=False, is_new=None, language='en', learning_info=[], lti_passports=['EC Council - Edx - LTI 1.1:cb6a0576-c3cc-43b5-9666-c30650a3632c:dffae861-0772-400a-b2bf-85e63ffd1f9b'], max_student_enrollments_allowed=None, minimum_grade_credit=0.8, mobile_available=False, no_grade=False, other_course_settings={}, pdf_textbooks=[], pre_requisite_courses=[], proctoring_escalation_email=None, proctoring_provider='software_secure', remote_gradebook={}, show_calculator=False, show_timezone=True, social_sharing_url=None, tabs=[<lms.djangoapps.courseware.tabs.CoursewareTab object at 0x7f5177112730>, <lms.djangoapps.courseware.tabs.ProgressTab object at 0x7f5186e5e820>, <lms.djangoapps.courseware.tabs.DatesTab object at 0x7f517de8fac0>, <lms.djangoapps.discussion.plugins.DiscussionTab object at 0x7f517de8fd30>, <lms.djangoapps.course_wiki.tab.WikiTab object at 0x7f5195820d30>, <lms.djangoapps.courseware.tabs.TextbookTabs object at 0x7f517c976460>], teams_configuration=<TeamsConfig default_max_team_size=50 teamsets=[] enabled=False>, textbooks=[], video_sharing_options='per-video', video_thumbnail_image='images_course_image.jpg', 
video_upload_pipeline={}, wiki_slug='DFE-112-53'> until 2023-11-06 06:47:34+00:00","user_message":"Access expired on 
Nov 06, 2023","additional_context_user_message":"Access to Digital Forensics Essentials (DFE) expired on Nov 06, 
2023","user_fragment":null}

@volodymyr-chekyrta
Copy link
Contributor Author

@volodymyr-chekyrta It's working now. Is it possible to make the parsing a bit lenient so that if an unknown value comes up, it will get ignored?

Now I'm getting 404 for the API Response: GET https://courses.edx.org/api/mobile/v1/users/rtester2/course_status_info/course-v1:EC-Council+DFE-112-53+3T2022 (404)

Response:

{"has_access":false,"error_code":"audit_expired","developer_message":"User rtester2 had access to 
<CourseBlockWithMixins @4BC5 license=None, parent=None, name=None, tags=[], display_name='Digital Forensics 
Essentials (DFE)', course_edit_method='Studio', days_early_for_beta=None, due=None, edxnotes=False, 
edxnotes_visibility=True, giturl=None, graceperiod=datetime.timedelta(0), graded=False, group_access={}, 
in_entrance_exam=False, matlab_api_key=None, max_attempts=None, relative_weeks_due=None, rerandomize='never', 
self_paced=True, show_correctness='always', show_reset_button=False, showanswer='finished', 
start=datetime.datetime(2023, 1, 19, 6, 30, tzinfo=<bson.tz_util.FixedOffset object at 0x7f517c9768e0>), 
static_asset_path='', use_latex_compiler=False, user_partitions=[], video_auto_advance=False, video_bumper={},
video_speed_optimizations=True, visible_to_staff_only=False, xqa_key=None, chrome=None, default_tab=None, 
format=None, hide_from_toc=False, source_file=None, children=[BlockUsageLocator(CourseLocator('EC-Council', 'DFE-
112-53', '3T2022', None, None), 'chapter', 'dd520dc51f1f455daabff367407ce06f'), BlockUsageLocator(CourseLocator('EC-
Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 'f67c4fdff6d946a7ab3931339dee60ff'), 
BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 
'8db154fc3a0741c7aa956d265522a4c4'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, 
None), 'chapter', 'd54cb1e875074f5f8e2381333972b412'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', 
'3T2022', None, None), 'chapter', '24c138a330c64ad596064db4f5321235'), BlockUsageLocator(CourseLocator('EC-
Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '8ada2783a1564fdd9b7cc34545d160ee'), 
BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 
'989c98dba47949cb9536e6a82980532f'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, 
None), 'chapter', '8f4c812c1b164418b37ba5933ddf7a44'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', 
'3T2022', None, None), 'chapter', '620abe5a14bc4463bc1f348b4f47b42f'), BlockUsageLocator(CourseLocator('EC-
Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '5b8bc39124b24aca9f709847e949203b'), 
BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 'a11df613290145319e870559804545df'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '8b9c9f69ca83418bb7863a53b0add79b'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', '8488d0834de5431b8ce4776f64474d76'), BlockUsageLocator(CourseLocator('EC-Council', 'DFE-112-53', '3T2022', None, None), 'chapter', 'e376d6d8e98e4f07bb8e9b493f3ff40f')], default_time_limit_minutes=None, exam_review_rules='', hide_after_due=False, is_entrance_exam=False, is_onboarding_exam=False, is_practice_exam=False, is_proctored_enabled=False, is_time_limited=False, position=None, xml_attributes={}, advanced_modules=['lti_consumer'], advertised_start=None, allow_anonymous=True, allow_anonymous_to_peers=False, allow_proctoring_opt_out=False, allow_public_wiki_access=False, allow_unsupported_xblocks=False, announcement=None, banner_image='images_course_image.jpg', catalog_visibility='both', ccx_connector='', cert_html_view_enabled=True, cert_html_view_overrides={}, cert_name_long='', cert_name_short='', certificate_available_date=None, certificates={'certificates': [{'course_title': '', 'name': 'Name of the certificate', 'description': 'Description of the certificate', 'version': 1, 'is_active': True, 'editing': False, 'signatories': [{'name': 'Jay Bavisi', 'title': 'President and Chief Executive Officer', 'organization': 'EC-Council', 'signature_image_path': '/asset-v1:EC-Council+DFE-112-53+3T2022+type@asset+block@EC-Council_Certifcation_Signature_Image.png', 'certificate': None, 'id': 256576954}], 'id': 68069528}]}, certificates_display_behavior='end', certificates_show_before_end=False, cohort_config={}, cosmetic_display_price=0, course_image='course_image.jpg', course_survey_name=None, course_survey_required=False, course_visibility='private', course_wide_css=[], course_wide_js=[], create_zendesk_tickets=True, css_class='', disable_progress_graph=False, discussion_blackouts=[], discussion_link=None, discussion_topics={'General': {'id': 'course'}}, discussions_settings={'enable_in_context': True, 'enable_graded_units': False, 'unit_level_visibility': True}, display_coursenumber='', display_organization=None, due_date_display_format=None, enable_ccx=False, enable_proctored_exams=False, enable_subsection_gating=False, enable_timed_exams=True, end=datetime.datetime(2025, 11, 25, 6, 30, tzinfo=<bson.tz_util.FixedOffset object at 0x7f517c9768e0>), end_of_course_survey_url=None, enrollment_domain=None, enrollment_end=None, enrollment_start=None, entrance_exam_enabled=False, entrance_exam_id=None, entrance_exam_minimum_score_pct=65, force_on_flexible_peer_openassessments=False, grading_policy={'GRADER': [{'type': 'Quiz', 'min_count': 59, 'drop_count': 0, 'short_label': 'Quiz', 'weight': 0.44}, {'type': 'Lab', 'min_count': 11, 'drop_count': 0, 'short_label': 'Lab', 'weight': 0.56}], 'GRADE_CUTOFFS': {'Pass': 0.6}}, hide_progress_tab=None, highlights_enabled_for_messaging=False, html_textbooks=[], instructor_info={'instructors': []}, invitation_only=False, is_new=None, language='en', learning_info=[], lti_passports=['EC Council - Edx - LTI 1.1:cb6a0576-c3cc-43b5-9666-c30650a3632c:dffae861-0772-400a-b2bf-85e63ffd1f9b'], max_student_enrollments_allowed=None, minimum_grade_credit=0.8, mobile_available=False, no_grade=False, other_course_settings={}, pdf_textbooks=[], pre_requisite_courses=[], proctoring_escalation_email=None, proctoring_provider='software_secure', remote_gradebook={}, show_calculator=False, show_timezone=True, social_sharing_url=None, tabs=[<lms.djangoapps.courseware.tabs.CoursewareTab object at 0x7f5177112730>, <lms.djangoapps.courseware.tabs.ProgressTab object at 0x7f5186e5e820>, <lms.djangoapps.courseware.tabs.DatesTab object at 0x7f517de8fac0>, <lms.djangoapps.discussion.plugins.DiscussionTab object at 0x7f517de8fd30>, <lms.djangoapps.course_wiki.tab.WikiTab object at 0x7f5195820d30>, <lms.djangoapps.courseware.tabs.TextbookTabs object at 0x7f517c976460>], teams_configuration=<TeamsConfig default_max_team_size=50 teamsets=[] enabled=False>, textbooks=[], video_sharing_options='per-video', video_thumbnail_image='images_course_image.jpg', 
video_upload_pipeline={}, wiki_slug='DFE-112-53'> until 2023-11-06 06:47:34+00:00","user_message":"Access expired on 
Nov 06, 2023","additional_context_user_message":"Access to Digital Forensics Essentials (DFE) expired on Nov 06, 
2023","user_fragment":null}

I'm a bit confused. A 404 response with a body.
Can you please attach the log from XCode to help me identify the exact error?

@volodymyr-chekyrta
Copy link
Contributor Author

@saeedbashir, this endpoint is not related to this PR. Can we address this issue in a separate PR?

@saeedbashir
Copy link
Contributor

It seems the issue is with the courseware_access. When the user doesn't have access to the courseware, then the course content API's behavior is broken.

Examples:

Response: GET https://courses.edx.org/api/course_home/v1/dates/course-v1:HarvardX+PH125.8x+1T2023 (403)

https://courses.edx.org/api/discussion/v1/course_topics/course-v1:HarvardX+PH125.8x+1T2023 (404)
{"developer_message":"Course not found."}

Can you please handle the case and add a full-screen error on the course dashboard screen? and don't hit any API like blocks, etc if the user doesn't have access.

Here is the sample response for courseware_access where the user does not have access.

"courseware_access": {
"has_access": false,
"error_code": "audit_expired",
"developer_message": "User rtester2 had access to course-v1:EC-Council+DFE-112-53+3T2022 until 2023-11-06 06:47:34+00:00",
"user_message": "Access expired on Nov 06, 2023",
"additional_context_user_message": "Access to Digital Forensics Essentials (DFE) expired on Nov 06, 2023",
"user_fragment": null
},

@volodymyr-chekyrta
Copy link
Contributor Author

volodymyr-chekyrta commented Jan 3, 2024

Could you please confirm which endpoint you are referring to?
Also, is this issue related to any of the new endpoints?

@saeedbashir
Copy link
Contributor

Could you please confirm which endpoint you are referring to?

The enrollments API/api/mobile/v3/users/\(username)/course_enrollments is returning the courseware_access. We are parsing it but not using it further.

The parsing of the enrollment API is also not working for a course ccx-v1:HarvardX+MCB64.1x+2T2016+ccx@28 because the server is returning string for start_type and known values to the codebase are empty and timestamp.

It's very hard to put all the data values in the parsing list until we get all possible values for each key from the server, which seems impossible for now, and even a new value can be added in the future. We need to come up with a way to ignore the unknown values.

@volodymyr-chekyrta
Copy link
Contributor Author

I got it, thank you.
It seems like a new behavior for an application that hasn't been implemented before and is unrelated to changing URLs.

I agree that this is very important behavior to handle access to courses; what if we create a ticket and handle this case in a separate PR, since this PR focuses on API switching but not on adding new functionality?

@saeedbashir
Copy link
Contributor

I agree that this is very important behavior to handle access to courses; what if we create a ticket and handle this case in a separate PR, since this PR focuses on API switching but not on adding new functionality?

Yes, we can handle this under a separate ticket.

But I guess we need to handle the parsing for unknown values because the app behavior breaks on receiving an unknown value.

@volodymyr-chekyrta
Copy link
Contributor Author

I agree that this is very important behavior to handle access to courses; what if we create a ticket and handle this case in a separate PR, since this PR focuses on API switching but not on adding new functionality?

Yes, we can handle this under a separate ticket.

But I guess we need to handle the parsing for unknown values because the app behavior breaks on receiving an unknown value.

Yes, I completely agree with that.
Can you help me understand specifically where the parsing issue lies? Function name or endpoint?

@saeedbashir
Copy link
Contributor

It's failing for /api/mobile/v3/users/\(username)/course_enrollments. For fixing it what you can do is you can remove a know value from enum for example you can remove timestamp from the StartType enum and make it working by ignoring the value.

enum StartType: String, Codable {
        case empty
        case timestamp
    }```

@volodymyr-chekyrta
Copy link
Contributor Author

It's failing for /api/mobile/v3/users/\(username)/course_enrollments. For fixing it what you can do is you can remove a know value from enum for example you can remove timestamp from the StartType enum and make it working by ignoring the value.

enum StartType: String, Codable {
        case empty
        case timestamp
    }```

Got it, thank you!
I have an idea, give me a few minutes to try 😄

@volodymyr-chekyrta
Copy link
Contributor Author

@saeedbashir I've added a fallback to the enum; please try now, it should works

saeedbashir
saeedbashir previously approved these changes Jan 4, 2024
Copy link
Contributor

@saeedbashir saeedbashir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested the highlighted APIs on the edX prod environment https://courses.edx.org and they are working fine 👍


enum Org: String, Codable {
case organization = "Organization"
case univerity = "Univerity"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[curious] is this a typo that got missed? or is this a known edge case being handled this way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, need to check 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fun fact, this enum is not used.
I don't know how it ended up there, but I've removed it from the code.

@saeedbashir
Copy link
Contributor

@volodymyr-chekyrta if all is well, then can you please merge this PR?

@volodymyr-chekyrta volodymyr-chekyrta merged commit 3bca8bf into develop Jan 5, 2024
2 of 3 checks passed
@openedx-webhooks
Copy link

@volodymyr-chekyrta 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future.

@volodymyr-chekyrta volodymyr-chekyrta deleted the feat/api_migration branch January 5, 2024 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-source-contribution PR author is not from Axim or 2U
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants