An LTI provider must run on a server accessible by your LTI consumer. This documentation assumes your LTI consumer is edX, but the principle is the same for other LTI consumers.
Heroku is a popular hosting service that offers free deployment for low volume applications and a sliding pricing model for higher demand applications. For the purpose of documentation we will use Heroku as our deployment target though you may deploy to any host or hosting service you choose.
The following steps have these prerequisites:
Note
The following steps presume that you have a collection of command line utilities installed on your machine. These utilities are installed by default on Linux machines, and freely available for OSX. This link will guide you to resources for your operation system: Command Line Tools
The documentation that Heroku provides for preparing your machine and installing required software is excellent. Start there by getting a Heroku account and following the Python track of their tutorial.
foreman start
heroku create
Creating salty-tundra-1591... done, stack is cedar-14
https://salty-tundra-1591.herokuapp.com/ | git@heroku.com:salty-tundra-1591.git
The create command returns useful information. It indicates
You can now use the URL of your deployed app on Heroku to test the sample against your edX course.
We recommend not storing secrets inside the git repository such as the OAuth keys needed for LTI security. As a result, we have instrumented the config.py file to have an example of using environment variables to store these secrets.
For example:
# secret key for authentication
SECRET_KEY = os.environ.get("FLASK_SECRET_KEY", "you-will-never-guess")
CONSUMER_KEY_PEM_FILE = os.path.abspath('consumer_key.pem')
with open(CONSUMER_KEY_PEM_FILE, 'w') as wfile:
wfile.write(os.environ.get('CONSUMER_KEY_CERT', ''))
PYLTI_CONFIG = {
"consumers": {
"__consumer_key__": {
"secret": os.environ.get("CONSUMER_KEY_SECRET", "__lti_secret__"),
"cert": CONSUMER_KEY_PEM_FILE
}
}
}
Now it is attempting to get the FLASK_SECRET_KEY, the CONSUMER_KEY_CERT and CONSUMER_KEY_SECRET environment variable values for the actual secrets. To do this in Heroku you can set these variables with the heroku config commands. To set the flask secret to pink_unicorns and __consumer_key__ secret to horn_of_plenty you would run:
heroku config:set FLASK_SECRET_KEY=pink_unicorn CONSUMER_KEY_SECRET=horn_of_plenty
To check your configuration, you can run heroku config by itself, and it will show what environment variables are set for your application.
To replicate the secure configuration locally using foreman you can create a file in the root of the application at .env that contains K=V values for configuration. i.e.
FLASK_SECRET_KEY=pink_unicorn
CONSUMER_KEY_SECRET=horn_of_plenty
Note
Environment variables can be absolutely huge, so there is no problem storing full client SSL certificates in the CONSUMER_KEY_PEM_FILE if your application requires client certificates in addition to the OAuth scheme. config.py above, for example, reads the environment variable the SSL certificate and key and writes it out to a file for use by httplib during execution on Heroku.
Note
Developers whose LTI app will be consumed by MITx will need an application certificate issued by MIT IS&T to be able to send grades to edX. You can request an application certificate by following the instructions at this support page https://wikis.mit.edu/confluence/display/devtools/How+to+acquire+and+verify+a+x509+Application+Certificate
The items described below are in the sample solely to support Heroku deployment. If you don’t deploy to Heroku, you can ignore or remove them.
Heroku requires a text file named Procfile to reside in the application’s root directory. Heroku documents the contents of the Procfile here: https://devcenter.heroku.com/articles/procfile
Heroku uses the contents of runtime.txt to pin a specific version of the Python runtime to a specific version. The app has been tested with the Python runtime version found in the file.