REST API Client for Open edX |CI|_ |Codecov|_
=============================================
.. |CI| image:: https://github.com/aulasneo/openedx-api-client/workflows/Python%20CI/badge.svg?branch=master
.. _CI: https://github.com/aulasneo/openedx-rest-api-client/actions?query=workflow%3A%22Python+CI%22
.. |Codecov| image:: https://codecov.io/github/aulasneo/openedx-api-client/coverage.svg?branch=master
.. _Codecov: https://codecov.io/github/aulasneo/openedx-rest-api-client?branch=master
The REST API client for Open edX REST API allows users to communicate with various edX REST APIs.
It is based on https://github.com/edx/edx-rest-api-client, whith a few differences:
- It does not depend on Django
- What is called 'the client' in edX's version is now called 'session'.
- As the edX's version relies on Django's cache, now the token is stored in memory under the scope of the session object
- The client here encompasses the session, and one function per REST API entry point
Part of the code is also taken from Opencraft's `implementation of the openedx client`_.
.. _implementation of the openedx client: https://gist.github.com/bradenmacdonald/930c7655dca32dc648af9cb0aed4a7c5
Testing
-------
$ make validate
Usage
~~~~~
The ``OpenedxRESTAPIClient`` object starts a session with the LMS and provides methods to access the Open edX endpoints.
.. code-block:: python
from openedx_rest_api_client.client import OpenedxRESTAPIClient
client_id = 'my_client_id'
client_secret = 'my_client_secret'
lms_url = 'https://lms.example.com'
# create client
client = OpenedxRESTAPIClient(lms_url, client_id, client_secret)
# get a list of all courses
courses = client.list_all_courses()
Function Reference
------------------
list_all_courses
~~~~~~~~~~~~~~~~
Get the full list of courses visible to the requesting user.
Calls the /api/courses/v1/courses LMS endpoint
Args:
- org: filter by organization
Returns:
- List of dict in the form:
.. code-block::
[
{
"blocks_url": "https://lms.example.com/api/courses/v1/blocks/?course_id=course-v1%3A<org>%2B<code>%2B<edition>",
"effort":"01:00",
"end":"None",
"enrollment_start":"None",
"enrollment_end":"None",
"id":"course-v1:<org>+<code>+<run>",
"media":{
"course_image":{
"uri":"<img path>"
},
"course_video":{
"uri":"None"
},
"image":{
"raw":"<img url>",
"small":"<img url>",
"large":"<img url>"
}
},
"name":"Course name",
"number":"<edition>",
"org":"<org>",
"short_description":"",
"start":"2018-01-11T00:00:00Z",
"start_display":"11 de Enero de 2018",
"start_type":"timestamp",
"pacing":"instructor",
"mobile_available":true,
"hidden":false,
"invitation_only":false,
"course_id":"course-v1:<org>+<code>+<edition>"
},
...
]
change_enrollment
~~~~~~~~~~~~~~~~~
Enroll or unenroll (depending on the value of action) the list of emails in the list of courses.
Calls the /api/bulk_enroll/v1/bulk_enroll/ LMS endpoint
Args:
- emails: list of emails to enroll
- courses: list of course ids to enroll
- action: can be 'enroll' or 'unenroll'
- url: url of the LMS (base or site). If not specified, uses the base url of the session. Defaults to the LMS base.
- auto_enroll: if true, the users will be automatically enrolled as soon as they register. Defaults to true.
- email_students: if true, an email will be sent with the update. Defaults to true.
- cohorts: List of cohort names to add the students to.
Returns:
dict in the form:
.. code-block::
{
"action":"enroll",
"courses":{
"course-v1:ORG+CODE+EDITION":{
"action":"enroll",
"results":[
{
"identifier":"mail@example.com",
"after":{
"enrollment":true,
"allowed":false,
"user":true,
"auto_enroll":false
},
"before":{
"enrollment":false,
"allowed":false,
"user":true,
"auto_enroll":false
}
},
...
],
"auto_enroll":true
},
...
},
"email_students":true,
"auto_enroll":true
}
Account validation
~~~~~~~~~~~~~~~~~~
Validates the account registration form. Calls the `/api/user/v1/validation/registration` API endpoint.
Args:
* url: url of the LMS (base or site). If not specified, uses the base url of the session. Defaults to the LMS base.
* \*\*kwargs: dict with form parameters to validate. E.g.:
.. code-block::
{
email=<email>,
username=<username>,
name=<name>,
password=<password>,
honor_code=<honor_code>,
terms_of_service=<terms_of_service>,
}
Returns:
dict in the form:
.. code-block::
{
'validation_decisions': {
<field name>: <validation result, or empty if success>,
...
},
'username_suggestions': [<username suggestions * 3>]
}
Account registration
~~~~~~~~~~~~~~~~~~~~
Registers a new user account. Calls the `/api/user/v1/account/registration/` API endpoint.
Args:
* email: email to register
* username: username to register
* name: full name of the user
* password: password
* url: url of the LMS (base or site). If not specified, uses the base url of the session.
Defaults to the LMS base.
Additional default fields accepted:
* name: full name of the user
* level_of_education \*: one of:
* 'p': 'Doctorate'
* 'm': "Master's or professional degree"
* 'b': "Bachelor's degree"
* 'a': "Associate degree"
* 'hs': "Secondary/high school"
* 'jhs': "Junior secondary/junior high/middle school"
* 'el': "Elementary/primary school"
* 'none': "No formal education"
* 'other': "Other education"
* gender \*: can be 'm', 'f', or 'o'
* mailing_address *
* city *
* country: ISO3166-1 two letters country codes as used in django_countries.countries *
* goals *
* year_of_birth \*: numeric 4-digit year of birth
* honor_code \*: Bool. If mandatory and not set will not create the account.
* terms_of_service \*: Bool. If unset, will be set equally to honor_code
* marketing_emails_opt_in \*: Bool. If set, will add a is_marketable user attribute (see Student > User Attributes in Django admin)
* provider: Oauth2 provider information
* social_auth_provider: Oauth2 provider information
\* Can be set as hidden, optional or mandatory in REGISTRATION_EXTRA_FIELDS setting.
Returns:
Dict with the form:
- If successful:
.. code-block::
{
'success': True,
'redirect_url': <redirection url to finish the authorization and go to the dashboard>
}
- If error:
.. code-block::
{
<field name>: [
{'user_message': <error message>}
]
'error_code': <error code>,
'username_suggestions': [<username suggestions> * 3]
}
How to Contribute
-----------------
To contribute, please send a message to `andres@aulasneo.com`_
.. _andres@aulasneo.com: mailto:andres@aulasneo.com
Raw data
{
"_id": null,
"home_page": "https://github.com/aulasneo/openedx-rest-api-client",
"name": "openedx-rest-api-client",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "openedx rest api client",
"author": "Aulasneo",
"author_email": "andres@aulasneo.com",
"download_url": "https://files.pythonhosted.org/packages/1c/40/f8cdf8bb630742d9c6d495232f42db166482cc8b958ede0e1a7a336b60d5/openedx_rest_api_client-1.0.0.tar.gz",
"platform": null,
"description": "REST API Client for Open edX |CI|_ |Codecov|_\n=============================================\n.. |CI| image:: https://github.com/aulasneo/openedx-api-client/workflows/Python%20CI/badge.svg?branch=master\n.. _CI: https://github.com/aulasneo/openedx-rest-api-client/actions?query=workflow%3A%22Python+CI%22\n\n.. |Codecov| image:: https://codecov.io/github/aulasneo/openedx-api-client/coverage.svg?branch=master\n.. _Codecov: https://codecov.io/github/aulasneo/openedx-rest-api-client?branch=master\n\nThe REST API client for Open edX REST API allows users to communicate with various edX REST APIs.\nIt is based on https://github.com/edx/edx-rest-api-client, whith a few differences:\n\n- It does not depend on Django\n- What is called 'the client' in edX's version is now called 'session'.\n- As the edX's version relies on Django's cache, now the token is stored in memory under the scope of the session object\n- The client here encompasses the session, and one function per REST API entry point\n\nPart of the code is also taken from Opencraft's `implementation of the openedx client`_.\n\n.. _implementation of the openedx client: https://gist.github.com/bradenmacdonald/930c7655dca32dc648af9cb0aed4a7c5\n\n\nTesting\n-------\n $ make validate\n\n\nUsage\n~~~~~\n\nThe ``OpenedxRESTAPIClient`` object starts a session with the LMS and provides methods to access the Open edX endpoints.\n\n.. code-block:: python\n\n from openedx_rest_api_client.client import OpenedxRESTAPIClient\n \n client_id = 'my_client_id'\n client_secret = 'my_client_secret'\n lms_url = 'https://lms.example.com'\n\n # create client\n client = OpenedxRESTAPIClient(lms_url, client_id, client_secret)\n\n # get a list of all courses\n courses = client.list_all_courses()\n\nFunction Reference\n------------------\n\nlist_all_courses\n~~~~~~~~~~~~~~~~\nGet the full list of courses visible to the requesting user.\nCalls the /api/courses/v1/courses LMS endpoint\n\nArgs:\n\n- org: filter by organization\n\nReturns:\n\n- List of dict in the form:\n\n.. code-block::\n\n [\n {\n \"blocks_url\": \"https://lms.example.com/api/courses/v1/blocks/?course_id=course-v1%3A<org>%2B<code>%2B<edition>\",\n \"effort\":\"01:00\",\n \"end\":\"None\",\n \"enrollment_start\":\"None\",\n \"enrollment_end\":\"None\",\n \"id\":\"course-v1:<org>+<code>+<run>\",\n \"media\":{\n \"course_image\":{\n \"uri\":\"<img path>\"\n },\n \"course_video\":{\n \"uri\":\"None\"\n },\n \"image\":{\n \"raw\":\"<img url>\",\n \"small\":\"<img url>\",\n \"large\":\"<img url>\"\n }\n },\n \"name\":\"Course name\",\n \"number\":\"<edition>\",\n \"org\":\"<org>\",\n \"short_description\":\"\",\n \"start\":\"2018-01-11T00:00:00Z\",\n \"start_display\":\"11 de Enero de 2018\",\n \"start_type\":\"timestamp\",\n \"pacing\":\"instructor\",\n \"mobile_available\":true,\n \"hidden\":false,\n \"invitation_only\":false,\n \"course_id\":\"course-v1:<org>+<code>+<edition>\"\n },\n ...\n ]\n\nchange_enrollment\n~~~~~~~~~~~~~~~~~\n\nEnroll or unenroll (depending on the value of action) the list of emails in the list of courses.\nCalls the /api/bulk_enroll/v1/bulk_enroll/ LMS endpoint\n\nArgs:\n\n- emails: list of emails to enroll\n- courses: list of course ids to enroll\n- action: can be 'enroll' or 'unenroll'\n- url: url of the LMS (base or site). If not specified, uses the base url of the session. Defaults to the LMS base.\n- auto_enroll: if true, the users will be automatically enrolled as soon as they register. Defaults to true.\n- email_students: if true, an email will be sent with the update. Defaults to true.\n- cohorts: List of cohort names to add the students to.\n\nReturns:\n\ndict in the form:\n\n.. code-block::\n\n {\n \"action\":\"enroll\",\n \"courses\":{\n \"course-v1:ORG+CODE+EDITION\":{\n \"action\":\"enroll\",\n \"results\":[\n {\n \"identifier\":\"mail@example.com\",\n \"after\":{\n \"enrollment\":true,\n \"allowed\":false,\n \"user\":true,\n \"auto_enroll\":false\n },\n \"before\":{\n \"enrollment\":false,\n \"allowed\":false,\n \"user\":true,\n \"auto_enroll\":false\n }\n },\n ...\n ],\n \"auto_enroll\":true\n },\n ...\n },\n \"email_students\":true,\n \"auto_enroll\":true\n }\n\nAccount validation\n~~~~~~~~~~~~~~~~~~\n\nValidates the account registration form. Calls the `/api/user/v1/validation/registration` API endpoint.\n\nArgs:\n\n* url: url of the LMS (base or site). If not specified, uses the base url of the session. Defaults to the LMS base.\n* \\*\\*kwargs: dict with form parameters to validate. E.g.:\n\n.. code-block::\n\n {\n email=<email>,\n username=<username>,\n name=<name>,\n password=<password>,\n honor_code=<honor_code>,\n terms_of_service=<terms_of_service>,\n }\n\nReturns:\ndict in the form:\n\n.. code-block::\n\n {\n 'validation_decisions': {\n <field name>: <validation result, or empty if success>,\n ...\n },\n 'username_suggestions': [<username suggestions * 3>]\n }\n\n\nAccount registration\n~~~~~~~~~~~~~~~~~~~~\n\nRegisters a new user account. Calls the `/api/user/v1/account/registration/` API endpoint.\n\nArgs:\n\n* email: email to register\n* username: username to register\n* name: full name of the user\n* password: password\n* url: url of the LMS (base or site). If not specified, uses the base url of the session.\n Defaults to the LMS base.\n\nAdditional default fields accepted:\n\n* name: full name of the user\n* level_of_education \\*: one of:\n * 'p': 'Doctorate'\n * 'm': \"Master's or professional degree\"\n * 'b': \"Bachelor's degree\"\n * 'a': \"Associate degree\"\n * 'hs': \"Secondary/high school\"\n * 'jhs': \"Junior secondary/junior high/middle school\"\n * 'el': \"Elementary/primary school\"\n * 'none': \"No formal education\"\n * 'other': \"Other education\"\n* gender \\*: can be 'm', 'f', or 'o'\n* mailing_address *\n* city *\n* country: ISO3166-1 two letters country codes as used in django_countries.countries *\n* goals *\n* year_of_birth \\*: numeric 4-digit year of birth\n* honor_code \\*: Bool. If mandatory and not set will not create the account.\n* terms_of_service \\*: Bool. If unset, will be set equally to honor_code\n* marketing_emails_opt_in \\*: Bool. If set, will add a is_marketable user attribute (see Student > User Attributes in Django admin)\n* provider: Oauth2 provider information\n* social_auth_provider: Oauth2 provider information\n\n\\* Can be set as hidden, optional or mandatory in REGISTRATION_EXTRA_FIELDS setting.\n\n\nReturns:\nDict with the form:\n\n- If successful:\n\n.. code-block::\n\n {\n 'success': True,\n 'redirect_url': <redirection url to finish the authorization and go to the dashboard>\n }\n\n- If error:\n\n.. code-block::\n\n {\n <field name>: [\n {'user_message': <error message>}\n ]\n 'error_code': <error code>,\n 'username_suggestions': [<username suggestions> * 3]\n }\n\nHow to Contribute\n-----------------\n\nTo contribute, please send a message to `andres@aulasneo.com`_\n\n.. _andres@aulasneo.com: mailto:andres@aulasneo.com\n",
"bugtrack_url": null,
"license": "Apache",
"summary": "Standalone client used to access Open edX REST APIs.",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/aulasneo/openedx-rest-api-client"
},
"split_keywords": [
"openedx",
"rest",
"api",
"client"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "27a43c549b42d75585d72430407762ddfb8e8d53f009f00a75b10ba221b8f99a",
"md5": "26c371fa4f2a2a3cf92044ca9a400ec6",
"sha256": "770c6e0281213bcd04da45aa48972022ff098cc904f10af6ed3f6d830f16d76c"
},
"downloads": -1,
"filename": "openedx_rest_api_client-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "26c371fa4f2a2a3cf92044ca9a400ec6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 19091,
"upload_time": "2025-01-03T11:07:28",
"upload_time_iso_8601": "2025-01-03T11:07:28.194148Z",
"url": "https://files.pythonhosted.org/packages/27/a4/3c549b42d75585d72430407762ddfb8e8d53f009f00a75b10ba221b8f99a/openedx_rest_api_client-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1c40f8cdf8bb630742d9c6d495232f42db166482cc8b958ede0e1a7a336b60d5",
"md5": "d33994568802a195a324fb4ed9cfda60",
"sha256": "3960313047fe17e857e7f295c8b322b5c01be1b00bc0a30daf243d74aa274cd9"
},
"downloads": -1,
"filename": "openedx_rest_api_client-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "d33994568802a195a324fb4ed9cfda60",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 17871,
"upload_time": "2025-01-03T11:07:33",
"upload_time_iso_8601": "2025-01-03T11:07:33.855492Z",
"url": "https://files.pythonhosted.org/packages/1c/40/f8cdf8bb630742d9c6d495232f42db166482cc8b958ede0e1a7a336b60d5/openedx_rest_api_client-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-03 11:07:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "aulasneo",
"github_project": "openedx-rest-api-client",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "certifi",
"specs": [
[
"==",
"2024.12.14"
]
]
},
{
"name": "charset-normalizer",
"specs": [
[
"==",
"3.4.1"
]
]
},
{
"name": "idna",
"specs": [
[
"==",
"3.10"
]
]
},
{
"name": "requests",
"specs": [
[
"==",
"2.32.3"
]
]
},
{
"name": "requests-toolbelt",
"specs": [
[
"==",
"1.0.0"
]
]
},
{
"name": "urllib3",
"specs": [
[
"==",
"2.3.0"
]
]
}
],
"lcname": "openedx-rest-api-client"
}