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

Dockerized Faculty Tools #22

Open
wants to merge 52 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
cb65910
Dockerized Faculty Tools
ssilverm Mar 30, 2021
b0031a6
Removing settings.py.template
ssilverm Apr 6, 2021
ea97747
Fixes naming confusion
ssilverm Apr 6, 2021
c5bc16e
CI test
ssilverm Apr 6, 2021
1a1532f
CI test
ssilverm Apr 6, 2021
32300df
CI test
ssilverm Apr 6, 2021
5dd2415
CI test
ssilverm Apr 6, 2021
9c1cb3e
flake8
ssilverm Apr 6, 2021
2601e5d
black
ssilverm Apr 6, 2021
0721d34
CI/CD + black
ssilverm Apr 6, 2021
3d1cee5
README MDL
ssilverm Apr 7, 2021
98ee7b9
Trying with nginx and uwsgi files
ssilverm Apr 7, 2021
a5d3d5f
README
ssilverm Apr 7, 2021
71e6278
README
ssilverm Apr 7, 2021
2ec1f22
Load ENV?
ssilverm Apr 7, 2021
58952fd
.env
ssilverm Apr 7, 2021
8d8cf31
Fixing status test
ssilverm Apr 20, 2021
0851770
Key / Secret env template
ssilverm Apr 20, 2021
d916489
Better dockeriziation
ssilverm Mar 29, 2022
db4b2d4
Fixed linting
ssilverm Mar 30, 2022
30b4620
testing github docker image push
ssilverm Mar 31, 2022
9c523bb
req + on needs
ssilverm Mar 31, 2022
1b56e91
CICD
ssilverm Mar 31, 2022
5c8096a
cicd
ssilverm Mar 31, 2022
912864c
requirements?
ssilverm Mar 31, 2022
52da810
Env?
ssilverm Apr 1, 2022
10629f9
Env?
ssilverm Apr 1, 2022
aaef398
Env?
ssilverm Apr 1, 2022
b4902aa
build args
ssilverm Apr 5, 2022
d87cfa6
adding git hash to ci
ssilverm Apr 12, 2022
4af0af2
sha
ssilverm Apr 12, 2022
e3e1865
sha
ssilverm Apr 12, 2022
f7750fe
sha
ssilverm Apr 12, 2022
11ae104
sha
ssilverm Apr 12, 2022
b6ecd9f
sha
ssilverm Apr 12, 2022
3c3f49d
using tags based on branch
ssilverm Apr 13, 2022
e39ee49
Log handler
ssilverm Apr 13, 2022
be52aeb
flake8 linting
ssilverm Apr 13, 2022
fa30299
changed env to remove https for demo
ssilverm Apr 14, 2022
6c2fd0c
Passing tests
ssilverm Apr 18, 2022
6d80d5d
Tests passing
ssilverm Apr 18, 2022
06d3a24
Fixed formatting
ssilverm Apr 18, 2022
6dc0cd3
First fixes
ssilverm Apr 25, 2022
8fd80ee
Linted
ssilverm Apr 26, 2022
e60651b
MDL
ssilverm Apr 26, 2022
dcd0c27
config comment change
ssilverm Apr 26, 2022
af2863a
Testing ARM
ssilverm May 16, 2022
cd8784d
Testing ARM platforms
ssilverm May 16, 2022
e43eb0f
Testing ARM platforms
ssilverm May 16, 2022
6649bed
Testing ARM platforms
ssilverm May 16, 2022
ef62752
Testing ARM platforms
ssilverm May 16, 2022
b2f2f11
Testing ARM platforms
ssilverm May 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.dockerignore
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
venv*
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
*.log
.git
*.template
.env*
fake-s3
16 changes: 16 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
TOOL_TITLE=Faculty Tools
THEME_DIR=
BASE_CANVAS_SERVER_URL=https://example.com/
SECRET_KEY=CHANGEME
LTI_KEY=key
LTI_SECRET=secret
OAUTH2_URI=http://127.0.0.1:9001/oauthlogin
OAUTH2_ID=CHANGEME
OAUTH2_KEY=CHANGEME
GOOGLE_ANALYTICS=GA-000000
CONFIG=config.DevelopmentConfig
DATABASE_URI=mysql://root:secret@db/faculty_tools

REQUIREMENTS=test_requirements.txt

WHITELIST_JSON=whitelist.json
73 changes: 73 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Run Python Tests and Build Image

on:
push:
branches:
- issue/21-dockerize
- develop
- master

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
REQUIREMENTS: requirements.txt

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Python 3
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r test_requirements.txt
pip install coveralls
- name: Setup Repo
run: |
cp whitelist.json.template whitelist.json
cp .env.template .env
- name: Run flake8
run: flake8
- name: Run black
run: black --check .
- name: Lint markdown files
uses: bewuethr/mdl-action@v1
# - name: Load dotenv
# uses: falti/[email protected]
- name: Environment Variables from Dotenv
uses: c-py/action-dotenv-to-setenv@v3
- name: Print Repo
run: |
env
- name: Run unittests
run: coverage run -m unittest discover


- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: REQUIREMENTS=${{ env.REQUIREMENTS }}



2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# config/settings
logs
settings.py
whitelist.json
.env

# local theming
themes/*
Expand Down
23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.7 as base
ARG REQUIREMENTS
COPY requirements.txt /app/
COPY test_requirements.txt /app/
RUN pip install -r /app/$REQUIREMENTS
WORKDIR /app
COPY ./ /app/
EXPOSE 9001
CMD ["gunicorn", "--conf", "gunicorn_conf.py", "--bind", "0.0.0.0:9001", "lti:app"]
70 changes: 29 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@

# Documentation for Faculty Tools

## Settings
## Setting up Faculty Tools with Docker & Docker-Compose

Create a new `settings.py` file from the template
First clone and setup the repo.

```sh
cp settings.py.template settings.py
git clone [email protected]:ucfopen/faculty-tools.git
cp whitelist.json.template whitelist.json
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
cp .env.template .env
mkdir logs
touch logs/faculty-tools.log
```

Edit `settings.py` to configure the application. All fields are required,
Edit `.env` to configure the application. All fields are required,
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
unless specifically noted.

## Developer Key
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -57,67 +61,51 @@ Add the tools you want instructors and faculty to see to `whitelist.json`.
]
```

## Virtual Environment

Create a new virtual environment.

```sh
virtualenv env
```

Activate the environment.

```sh
source env/bin/activate
```

Install everything:

```sh
pip install -r requirements.txt
```

## Create DB

Change directory into the project folder. Create the database in python shell:
We need to generate the database and tables for faculty tools to run properly.
The MySQL docker image automatically creates the user, password, and database
name set in the `docker-compose.yml` file.

```sh
from lti import db
docker-compose run lti python
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
from main import db
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
db.create_all()
```

If you want to look at your users table in the future, you can do so in the
python shell:

```python
from lti import Users
docker-compose run lti python
from main import Users
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
Users.query.all()
```

## Environment Variables
## Run the App

Set the flask app to `lti.py` and debug to true.
It's time to use docker-compose to bring up the application.

```sh
export FLASK_APP=lti.py
export FLASK_DEBUG=1
docker-compose up -d
```

Alternatively, you can run the setup script to simultaneously setup environment
variables and the virtual environment.
Go to the /xml page, <http://127.0.0.1:9001/facultytools/xml> by default.

```sh
source setup.sh
```
Copy the xml, and install it into a course (Course->Settings->Apps).

## Run the App
## View the Logs

Run the lti script while your virtual environment is active.
To view the logs while the application is running use this docker command:

```sh
flask run
docker-compose logs -f
```

Go to the /xml page, [http://0.0.0.0:5000/xml](http://0.0.0.0:5000/xml) by default
## Stopping the App

To shutdown Faculty Tools

Copy the xml, install it into a course.
```sh
docker-compose down
```
75 changes: 67 additions & 8 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,105 @@
import settings
import os


class Config(object):
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
# make the warning shut up until Flask-SQLAlchemy v3 comes out
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_DATABASE_URI = settings.select_db("Config")

PYLTI_CONFIG = settings.PYLTI_CONFIG
# LTI consumer key and shared secret
CONSUMER_KEY = os.environ.get("LTI_KEY")
SHARED_SECRET = os.environ.get("LTI_SECRET")

# Configuration for pylti library. Uses the above key and secret
PYLTI_CONFIG = {
"consumers": {CONSUMER_KEY: {"secret": SHARED_SECRET}},
# Custom configurable roles
"roles": {
"staff": [
"urn:lti:instrole:ims/lis/Administrator",
"Instructor",
"ContentDeveloper",
"urn:lti:role:ims/lis/TeachingAssistant",
]
},
}

SESSION_COOKIE_NAME = "ft_session"

# Chrome 80 SameSite=None; Secure fix
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "None"

SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URI")


class BaseConfig(object):
DEBUG = False
TESTING = False

# make the warning shut up until Flask-SQLAlchemy v3 comes out
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_DATABASE_URI = settings.select_db("BaseConfig")

PYLTI_CONFIG = settings.PYLTI_CONFIG

SESSION_COOKIE_NAME = "ft_session"

# Chrome 80 SameSite=None; Secure fix
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "None"

SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URI")

# Title of the tool. Appears in the <title> element, headers, and configuration XML
TOOL_TITLE = os.environ.get("TOOL_TITLE", "Faculty Tools")

# Which theme directory to use. Leave blank for default.
THEME_DIR = os.environ.get("THEME_DIR", "")

# Canvas instance URL. ex: https://example.instructure.com/
BASE_URL = os.environ.get("BASE_CANVAS_SERVER_URL", "https://example.com")
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
API_URL = BASE_URL + "api/v1/"

# Secret key to sign Flask sessions with. KEEP THIS SECRET!
SECRET_KEY = os.environ.get("SECRET_KEY")
ssilverm marked this conversation as resolved.
Show resolved Hide resolved

# LTI consumer key and shared secret
CONSUMER_KEY = os.environ.get("LTI_KEY")
SHARED_SECRET = os.environ.get("LTI_SECRET")

# Configuration for pylti library. Uses the above key and secret
PYLTI_CONFIG = {
"consumers": {CONSUMER_KEY: {"secret": SHARED_SECRET}},
# Custom configurable roles
"roles": {
"staff": [
"urn:lti:instrole:ims/lis/Administrator",
"Instructor",
"ContentDeveloper",
"urn:lti:role:ims/lis/TeachingAssistant",
]
},
}

# The "Oauth2 Redirect URI" that you provided to Instructure.
OAUTH2_URI = os.environ.get("OAUTH2_URI") # ex. 'https://localhost:5000/oauthlogin'
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
# The Client_ID Instructure gave you
OAUTH2_ID = os.environ.get("OAUTH2_ID")
# The Secret Instructure gave you
OAUTH2_KEY = os.environ.get("OAUTH2_KEY")

WHITELIST = os.environ.get("WHITELIST_JSON")

# Google Analytics Tracking ID (optional)
GOOGLE_ANALYTICS = os.environ.get("GOOGLE_ANALYTICS", "GA-")


class DevelopmentConfig(BaseConfig):
DEBUG = True
TESTING = True

SQLALCHEMY_DATABASE_URI = settings.select_db("DevelopmentConfig")
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URI")
ssilverm marked this conversation as resolved.
Show resolved Hide resolved


class TestingConfig(BaseConfig):
DEBUG = False
TESTING = True

SQLALCHEMY_DATABASE_URI = settings.select_db("TestingConfig")
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URI")
Loading