django-lti-provider provides LTI functionality for the Django web framework. This work began as a port of MIT's LTI Flask Sample, which demonstrates a sample LTI provider for the Flask Framework based on the Python LTI library, PyLTI.
Additional work was completed to provide fuller functionality and support the idiosyncrasies of various LMS systems such as Canvas, Blackboard, Moodle and EdEx.
django-lti-provider offers:
- an authentication backend to complete an oAuth handshake (optional)
- a templated view for config.xml generation
- a templated landing page view for those LMS who do not have a 'launch in new tab' option, i.e. Canvas
- support for Canvas' embedded tool extensions
- routing for multiple external assignment end points.
The library is used at Columbia University's Center for Teaching And Learning.
See an example Django app using the library at Django LTI Provider Example.
You can install django-lti-provider
through pip
:
$ pip install django-lti-provider
Or, if you're using virtualenv, add django-lti-provider
to your requirements.txt
.
Add to INSTALLED_APPS
in your settings.py
::
'lti_provider',
- Django
- nameparser
- httplib2
- oauth2
- oauthlib
- pylti
Add the URL route::
url(r'^lti/', include('lti_provider.urls'))
Add the LTIBackend to your AUTHENTICATION_BACKENDS:
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'lti_provider.auth.LTIBackend',
]
Complete a migration
./manage.py migrate
The LTI_TOOL_CONFIGURATION
variable in your settings.py
allows you to
configure your application's config.xml and set other options for the library. (Edu Apps has good documentation
on configuring an lti provider through xml.)
LTI_TOOL_CONFIGURATION = {
'title': '<your lti provider title>',
'description': '<your description>',
'launch_url': 'lti/',
'embed_url': '<the view endpoint for an embed tool>' or '',
'embed_icon_url': '<the icon url to use for an embed tool>' or '',
'embed_tool_id': '<the embed tool id>' or '',
'landing_url': '<the view landing page>',
'course_aware': <True or False>,
'course_navigation': <True or False>,
'new_tab': <True or False>,
'frame_width': <width in pixels>,
'frame_height': <height in pixels>,
'custom_fields': <dictionary>,
'assignments': {
'<name>': '<landing_url>',
'<name>': '<landing_url>',
'<name>': '<landing_url>',
},
}
To stash custom properties in your session, populate the LTI_PROPERTY_LIST_EX
variable in your settings.py
. This is useful for LMS specific custom_x
parameters that will be needed later. The default value for LTI_PROPERTY_LIST_EX
is: ['custom_canvas_user_login_id', 'context_title', 'lis_course_offering_sourcedid', 'custom_canvas_api_domain']
.
LTI_PROPERTY_LIST_EX = ['custom_parameter1', 'custom_parameter2']
Please note that you will need to add the following settings in your applications settings.py
:
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
SESSION_COOKIE_SAMESITE = None
Because Canvas sends the information that we are storing in a POST
request on the LTI launch, we need to disable the restriction on cookies only being allowed to be set from the same site. For more information on this read here.
To specify a custom username property, add the LTI_PROPERTY_USER_USERNAME
variable to your settings.py
. By default, LTI_PROPERTY_USER_USERNAME
is custom_canvas_user_login_id
. This value can vary depending on your LMS.
To pass through extra LTI parameters to your provider, populate the LTI_EXTRA_PARAMETERS
variable in your settings.py
.
This is useful for custom parameters you may specify at installation time.
LTI_EXTRA_PARAMETERS = ['lti_version'] # example
The PYLTI_CONFIG
variable in your settings.py
configures the
application consumers and secrets.
PYLTI_CONFIG = {
'consumers': {
'<random number string>': {
'secret': '<random number string>'
}
}
}
Additionally you will need to make sure to add the following to your settings.py
file:
X_FRAME_OPTIONS = "ALLOW-FROM https://<your-org-subdomain>.instructure.com"
This ensures that the Django application will allow requests from your orgs Canvas instance. For more on X_FRAME_OPTIONS
please consult here.
To support multiple assignments:
- Create multiple endpoint views
- Add the assignment urls to the `LTI_TOOL_CONFIGURATION['assignments'] map
- Add an assignment, using the External Tool option.
- Update the URL to be
https://<your domain name>/lti/assignment/<assignment_name>
- The
assignment_name
variable should match a landing_url in the LTI_TOOL_CONFIGURATION dict. - Full example here: Django LTI Provider Example.