Пример #1
0
def print_canvas_courses(args):
    """Show a list of current teacher's courses from Canvas via the API.
    """

    g = Grader(args.path)
    if 'canvas-token' not in g.config:
        logger.error(
            "canvas-token configuration is missing! Please set the Canvas API access "
            "token before attempting to use Canvas API functionality")
        print("Canvas course listing failed: missing Canvas API access token.")
        return

    canvas = CanvasAPI(g.config["canvas-token"], g.config["canvas-host"])

    courses = canvas.get_instructor_courses()

    if not courses:
        print("No courses found where current user is a teacher.")
        return

    output = PrettyTable(["#", "ID", "Name"])
    output.align["Name"] = "l"

    for ix, c in enumerate(sorted(courses, key=lambda c: c['id'],
                                  reverse=True)):
        output.add_row((ix + 1, c['id'], c['name']))

    print(output)
Пример #2
0
def print_canvas_courses(conf, _):
    """Show a list of current teacher's courses from Canvas via the API.
    """
    if 'canvas-token' not in conf:
        logger.error(
            "canvas-token configuration is missing! Please set the Canvas API access "
            "token before attempting to use Canvas API functionality")
        print("Canvas course listing failed: missing Canvas API access token.")
        return

    canvas = CanvasAPI(conf["canvas-token"], conf["canvas-host"])

    try:
        courses = canvas.get_instructor_courses()
    except AuthenticationFailed as e:
        logger.debug(e)
        logger.error(
            "Canvas authentication failed. Is your token missing or expired?")
        return

    if not courses:
        print("No courses found where current user is a teacher.")
        return

    output = PrettyTable(["#", "ID", "Name"])
    output.align["Name"] = "l"

    for ix, c in enumerate(sorted(courses, key=lambda c: c['id'],
                                  reverse=True)):
        output.add_row((ix + 1, c['id'], c['name']))

    print(output)
Пример #3
0
    def test_retries_on_5xx(self):
        self.mock_get.side_effect = HTTPError(response=FakeResponse(503))

        api = CanvasAPI("test token", "mst.instructure.com")
        with self.assertRaises(HTTPError):
            api.get_instructor_courses()

        self.assertEqual(5, self.mock_get.call_count)
Пример #4
0
def import_from_canvas(conf, backend, args):
    """Imports students from a Canvas course to the roster.
    """
    if 'canvas-token' not in conf:
        logger.error(
            "canvas-token configuration is missing! Please set the Canvas API access "
            "token before attempting to import users from Canvas")
        print("Import from canvas failed: missing Canvas API access token.")
        return

    course_id = args.id
    section = args.section
    force = args.force
    username_column = args.username_column

    canvas = CanvasAPI(conf["canvas-token"], conf["canvas-host"])

    try:
        students = canvas.get_course_students(course_id)
        if "canvas-courses" not in conf:
            conf["canvas-courses"] = []
        add_to_courses(conf["canvas-courses"], int(course_id), section)

    except AuthenticationFailed as e:
        logger.debug(e)
        logger.error(
            "Canvas authentication failed. Is your token missing or expired?")
        return
    except CourseNotFound as e:
        logger.debug(e)
        logger.error(
            "Course ID %s not found. Make sure to use the ID, not the row number.",
            course_id)
        return

    for s in students:
        logger.debug(s)
        if username_column not in s or not s[username_column]:
            logger.error("Could not get username for %s", s['sortable_name'])

        try:
            add_to_roster(conf, backend, conf.roster, s['sortable_name'],
                          s[username_column], section, force, s['id'])
        except DuplicateUserError:
            logger.warning("User %s is already in the roster, skipping",
                           s[username_column])

    print("Imported {} students.".format(len(students)))
Пример #5
0
def import_from_canvas(args):
    """Imports students from a Canvas course to the roster.
    """

    g = Grader(args.path)
    if 'canvas-token' not in g.config:
        logger.error(
            "canvas-token configuration is missing! Please set the Canvas API access "
            "token before attempting to import users from Canvas")
        print("Import from canvas failed: missing Canvas API access token.")
        return

    course_id = args.id
    force = args.force

    canvas = CanvasAPI(g.config["canvas-token"], g.config["canvas-host"])

    students = canvas.get_course_students(course_id)

    for s in students:
        if 'sis_user_id' not in s:
            logger.error("Could not get username for %s", s['sortable_name'])

        if not force:
            for student in g.config.roster:
                if student['name'] == s['sortable_name']:
                    logger.warning(
                        "User %s is already in the roster, skipping",
                        s['sis_user_id'])
                    break
            else:
                g.config.roster.append({
                    'name': s['sortable_name'],
                    'id': s['sis_user_id']
                })
        else:
            g.config.roster.append({
                'name': s['sortable_name'],
                'id': s['sis_user_id']
            })

    print("Imported {} students.".format(len(students)))
    g.config.save()
Пример #6
0
    def get_api(cls, conf: Config) -> CanvasAPI:
        if not cls._api:
            if "canvas-token" not in conf:
                logger.error(
                    "canvas-token configuration is missing! Please set the Canvas API access "
                    "token before attempting to use Canvas API functionality")
                print(
                    "Canvas course listing failed: missing Canvas API access token."
                )
                raise KeyError
            cls._api = CanvasAPI(conf["canvas-token"], conf["canvas-host"])

        return cls._api
Пример #7
0
    def test_failed_dns(self):
        self.mock_get.side_effect = HTTPError("Name or service not known")

        api = CanvasAPI("test token", "mst.instructure.com")

        with self.assertRaises(NameResolutionFailed):
            api.get_instructor_courses()

        with self.assertRaises(NameResolutionFailed):
            api.get_course_students(420)
Пример #8
0
 def lookup_canvas_ids(
         conf: Config, canvas: CanvasAPI,
         hw_name: str) -> Tuple[Dict[str, int], Dict[str, int]]:
     """
     Retrieves the list of internal Canvas IDs for a given assignment
     and the relevant sections
     :param hw_name: the name of the homework assignment to search for on Canvas
     :return: "section_ids", a map of section names/identifiers onto
     Canvas internal course IDs and "assignment_ids", a map of section
     names/identifiers onto the Canvas internal assignment IDs for a given assignment
     """
     if "canvas-courses" not in conf or not conf["canvas-courses"]:
         logger.error(
             'canvas-courses configuration is missing! Please use the "assigner canvas import"'
             "command to associate course IDs with section names")
         print(
             "Canvas course listing failed: missing section Canvas course IDs."
         )
         raise CourseNotFound
     courses = conf["canvas-courses"]
     section_ids = {course["section"]: course["id"] for course in courses}
     min_name = re.search(r"[A-Za-z]+\d+", hw_name).group(0)
     assignment_ids = {}
     for section, course_id in section_ids.items():
         try:
             canvas_assignments = canvas.get_course_assignments(
                 course_id, min_name)
         except CourseNotFound:
             logger.error("Failed to pull assignment list from Canvas")
             raise
         if len(canvas_assignments) != 1:
             logger.warning(
                 "Could not uniquely identify Canvas assignment from name %s and section %s, using first assignment listed",
                 min_name,
                 section,
             )
         assignment_ids[section] = canvas_assignments[0]["id"]
     return (section_ids, assignment_ids)
Пример #9
0
    def test_course_not_found(self):
        self.mock_get.side_effect = HTTPError(response=FakeResponse(404))

        api = CanvasAPI("test token", "mst.instructure.com")
        with self.assertRaises(CourseNotFound):
            api.get_course_students(420)
Пример #10
0
    def test_students_auth_failure(self):
        self.mock_get.side_effect = HTTPError(response=FakeResponse(401))

        api = CanvasAPI("test token", "mst.instructure.com")
        with self.assertRaises(AuthenticationFailed):
            api.get_course_students(420)
Пример #11
0
 def test_http_urls_are_httpsified(self):
     api = CanvasAPI("test token", "http://mst.instructure.com")
     self.assertEqual("https://mst.instructure.com", api.website_root)