Skip to content

Commit

Permalink
Merge pull request #344 from ucfopen/develop
Browse files Browse the repository at this point in the history
Release v0.15.0
  • Loading branch information
Thetwam authored Nov 19, 2019
2 parents 44cf6a6 + 177c43e commit 7d3527d
Show file tree
Hide file tree
Showing 59 changed files with 2,347 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Below you'll find guidelines for contributing that will keep our codebase clean
* [Writing tests](#writing-tests)
* [API Coverage Tests](#api-coverage-tests)
* [Engine tests](#engine-tests)
* [Running tests / coverage reports](#running-tests-coverage-reports)
* [Running tests / coverage reports](#running-tests--coverage-reports)
* [Making a Pull Request](#making-a-pull-request)
* [Code style guidelines](#code-style-guidelines)
* [Foolish consistency](#foolish-consistency)
Expand Down
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ Steps to reproduce the behavior:

A clear and concise description of what you expected to happen.

# Environment information (please complete the following information)
# Environment information

<!--(please complete the following information)-->

- Python version (`python --version`)
- CanvasAPI version (`pip show canvasapi`)
Expand Down
5 changes: 5 additions & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,28 @@ Patches and Suggestions
- Bill Wrbican [@wjw27](https://github.com/wjw27)
- Bradford Lynch [@bradfordlynch](https://github.com/bradfordlynch)
- Catherine Abbruzzese [@cat0698](https://github.com/cat0698))
- Cameron Cuff [@ctcuff](https://github.com/ctcuff)
- Dalton Durst [@UniversalSuperBox](https://github.com/UniversalSuperBox)
- Daniel Brinkman [@DanBrink91](https://github.com/DanBrink91)
- Daniel Grobani [@dgrobani](https://github.com/dgrobani)
- David Warden [@dfwarden](https://github.com/dfwarden)
- Davis Goff [@Goff-Davis](https://github.com/Goff-Davis)
- Devin Singh [@devints47](https://github.com/devints47)
- Elise Heron [@thedarkestknight](https://github.com/thedarkestknight)
- Elli Howard [@qwertynerd97](https://github.com/qwertynerd97)
- Erik Tews [@eriktews](https://github.com/eriktews)
- Ethan Finlay [@atarisafari](https://github.com/atarisafari)
- Gabriela Dijkhoffz [@gdijkhoffz](https://github.com/gdijkhoffz)
- Henry Acevedo [@Colombiangmr](https://github.com/Colombiangmr)
- Ian Altgilbers [@altgilbers](https://github.com/altgilbers)
- Ian Turgeon [@iturgeon](https://github.com/iturgeon)
- [@jackrsteiner](https://github.com/jackrsteiner)
- Joon Ro [@joonro](https://github.com/joonro)
- Jonathan Guilbe [@JonGuilbe](https://github.com/JonGuilbe)
- John Raible [@rebelaide](https://github.com/rebelaide)
- Jose Silveti [@jrsilveti](https://github.com/jrsilveti)
- [@kensler](https://github.com/kensler)
- Lawrence Oks [@ljoks](https://github.com/ljoks)
- Mark Lalor [@MarkLalor](https://github.com/MarkLalor)
- Markus [@elec3647](https://github.com/elec3647)
- Matthew Fedder [@matthewf-ucsd](https://github.com/matthewf-ucsd)
Expand Down
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
# Change Log

## [0.15.0] - 2019-11-19

### New Endpoint Coverage

- Assignment Extensions (Thanks, [@ljoks](https://github.com/ljoks))
- AssignmentGroup (Thanks, [@ctcuff](https://github.com/ctcuff))
- List Assignments
- Authentications Log (Thanks, [@weining-li](https://github.com/weining-li))
- Brand Configs (Thanks, [@bennettscience](https://github.com/bennettscience))
- Comm Messages (Thanks, [@ljoks](https://github.com/ljoks))
- File Usage Rights (Thanks, [@atarisafari](https://github.com/atarisafari) and [@joonro](https://github.com/joonro))
- Gradebook History (Thanks, [@gdijkhoffz](https://github.com/gdijkhoffz))
- Quiz Reports (Thanks, [@atarisafari](https://github.com/atarisafari)
- Quiz Submission Events (Thanks, [@Goff-Davis](https://github.com/Goff-Davis))
- Quiz Submission User List (Thanks, [@gdijkhoffz](https://github.com/gdijkhoffz))
- Rubric Associations (Thanks, [@weining-li](https://github.com/weining-li))

### General

- Throw `IndexError` when using negative indexes on `PaginatedList` objects (Thanks, [@UniversalSuperBox](https://github.com/UniversalSuperBox))
- `Assignment.overrides` now returns a list of `AssignmentOverride` objects.

### Deprecation Warnings

- `CanvasObject.attributes` is now deprecated and will be removed in a future version.
- `CanvasObject.to_json()` is now deprecated and will be removed in a future version. To view the original attributes sent by Canvas, enable logs from the requests library.

### Bugfixes

- Fixed an issue where `util.clean_headers()` would throw a `ValueError` if a user accidentally included a space in their API token. (Thanks, [@keeeeeegan](https://github.com/keeeeeegan))
- Fixed an issue where `QuizSubmission` objects sometimes wouldn't have a course_id, making some methods unusable. (Thanks, [@bennettscience](https://github.com/bennettscience))
- Fixed an issue where `get_user()` did not accept arbitrary keyword arguments (Thanks, [@eriktews](https://github.com/eriktews))
- Fixed an issue where an import was triggering a `DeprecationWarning` (Thanks, [@Screeeech](https://github.com/Screeeech))
- Fixed an issue where a GroupedSubmission wasn't saving the `submissions` attribute properly

## [0.14.0] - 2019-08-20

### New Endpoint Coverage
Expand Down Expand Up @@ -368,6 +403,7 @@ Huge thanks to [@liblit](https://github.com/liblit) for lots of issues, suggesti
- Fixed some incorrectly defined parameters
- Fixed an issue where tests would fail due to an improperly configured requires block

[0.15.0]: https://github.com/ucfopen/canvasapi/compare/v0.14.0...v0.15.0
[0.14.0]: https://github.com/ucfopen/canvasapi/compare/v0.13.0...v0.14.0
[0.13.0]: https://github.com/ucfopen/canvasapi/compare/v0.12.0...v0.13.0
[0.12.0]: https://github.com/ucfopen/canvasapi/compare/v0.11.0...v0.12.0
Expand Down
2 changes: 1 addition & 1 deletion canvasapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

__all__ = ["Canvas"]

__version__ = "0.14.0"
__version__ = "0.15.0"
20 changes: 20 additions & 0 deletions canvasapi/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,26 @@ def get_all_outcome_links_in_context(self):
"accounts/{}/outcome_group_links".format(self.id),
)

def get_authentication_events(self, **kwargs):
"""
List authentication events for a given account.
:calls: `GET /api/v1/audit/authentication/accounts/:account_id \
<https://canvas.instructure.com/doc/api/authentications_log.html#method.authentication_audit_api.for_account>`_
:rtype: :class:`canvasapi.paginated_list.PaginatedList` of
:class:`canvasapi.authentication_event.AuthenticationEvent`
"""
from canvasapi.authentication_event import AuthenticationEvent

return PaginatedList(
AuthenticationEvent,
self._requester,
"GET",
"audit/authentication/accounts/{}".format(self.id),
_kwargs=combine_kwargs(**kwargs),
)

def get_authentication_provider(self, authentication_provider, **kwargs):
"""
Get the specified authentication provider
Expand Down
134 changes: 100 additions & 34 deletions canvasapi/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@

@python_2_unicode_compatible
class Assignment(CanvasObject):
def __init__(self, requester, attributes):
super(Assignment, self).__init__(requester, attributes)

if "overrides" in attributes:
self.overrides = [
AssignmentOverride(requester, override)
for override in attributes["overrides"]
]

def __str__(self):
return "{} ({})".format(self.name, self.id)

Expand Down Expand Up @@ -202,6 +211,75 @@ def get_submissions(self, **kwargs):
_kwargs=combine_kwargs(**kwargs),
)

def set_extensions(self, assignment_extensions, **kwargs):
"""
Set extensions for student assignment submissions
:calls: `POST /api/v1/courses/:course_id/assignments/:assignment_id/extensions \
<https://canvas.instructure.com/doc/api/assignment_extensions.html#method.assignment_extensions.create>`_
:param assignment_extensions: list of dictionaries representing extensions
:type assignment_extensions: list
:rtype: list of :class:`canvasapi.assignment.AssignmentExtension`
Example Usage:
>>> assignment.set_extensions([
... {
... 'user_id': 3,
... 'extra_attempts: 2
... },
... {
... 'user_id': 2,
... 'extra_attempts: 2
... }
... ])
"""
if not isinstance(assignment_extensions, list) or not assignment_extensions:
raise ValueError("Param `assignment_extensions` must be a non-empty list.")

if any(not isinstance(extension, dict) for extension in assignment_extensions):
raise ValueError(
"Param `assignment_extensions` must only contain dictionaries"
)

if any("user_id" not in extension for extension in assignment_extensions):
raise RequiredFieldMissing(
"Dictionaries in `assignment_extensions` must contain key `user_id`"
)
kwargs["assignment_extensions"] = assignment_extensions
response = self._requester.request(
"POST",
"courses/{}/assignments/{}/extensions".format(self.course_id, self.id),
_kwargs=combine_kwargs(**kwargs),
)
extension_list = response.json()["assignment_extensions"]
return [
AssignmentExtension(self._requester, extension)
for extension in extension_list
]

def submissions_bulk_update(self, **kwargs):
"""
Update the grading and comments on multiple student's assignment
submissions in an asynchronous job.
:calls: `POST /api/v1/courses/:course_id/assignments/:assignment_id/ \
submissions/update_grades \
<https://canvas.instructure.com/doc/api/submissions.html#method.submissions_api.bulk_update>`_
:rtype: :class:`canvasapi.progress.Progress`
"""
response = self._requester.request(
"POST",
"courses/{}/assignments/{}/submissions/update_grades".format(
self.course_id, self.id
),
_kwargs=combine_kwargs(**kwargs),
)
return Progress(self._requester, response.json())

def submit(self, submission, file=None, **kwargs):
"""
Makes a submission for an assignment.
Expand Down Expand Up @@ -246,26 +324,6 @@ def submit(self, submission, file=None, **kwargs):

return Submission(self._requester, response_json)

def submissions_bulk_update(self, **kwargs):
"""
Update the grading and comments on multiple student's assignment
submissions in an asynchronous job.
:calls: `POST /api/v1/courses/:course_id/assignments/:assignment_id/ \
submissions/update_grades \
<https://canvas.instructure.com/doc/api/submissions.html#method.submissions_api.bulk_update>`_
:rtype: :class:`canvasapi.progress.Progress`
"""
response = self._requester.request(
"POST",
"courses/{}/assignments/{}/submissions/update_grades".format(
self.course_id, self.id
),
_kwargs=combine_kwargs(**kwargs),
)
return Progress(self._requester, response.json())

def upload_to_submission(self, file, user="self", **kwargs):
"""
Upload a file to a submission.
Expand Down Expand Up @@ -296,45 +354,51 @@ def upload_to_submission(self, file, user="self", **kwargs):
).start()


@python_2_unicode_compatible
class AssignmentExtension(CanvasObject):
def __str__(self):
return "{} ({})".format(self.assignment_id, self.user_id)


@python_2_unicode_compatible
class AssignmentGroup(CanvasObject):
def __str__(self):
return "{} ({})".format(self.name, self.id)

def edit(self, **kwargs):
def delete(self, **kwargs):
"""
Modify this assignment group.
Delete this assignment.
:calls: `PUT /api/v1/courses/:course_id/assignment_groups/:assignment_group_id \
<https://canvas.instructure.com/doc/api/assignment_groups.html#method.assignment_groups_api.update>`_
:calls: `DELETE /api/v1/courses/:course_id/assignment_groups/:assignment_group_id \
<https://canvas.instructure.com/doc/api/assignment_groups.html#method.assignment_groups_api.destroy>`_
:rtype: :class:`canvasapi.assignment.AssignmentGroup`
"""
response = self._requester.request(
"PUT",
"DELETE",
"courses/{}/assignment_groups/{}".format(self.course_id, self.id),
_kwargs=combine_kwargs(**kwargs),
)

if "name" in response.json():
super(AssignmentGroup, self).set_attributes(response.json())

return AssignmentGroup(self._requester, response.json())

def delete(self, **kwargs):
def edit(self, **kwargs):
"""
Delete this assignment.
Modify this assignment group.
:calls: `DELETE /api/v1/courses/:course_id/assignment_groups/:assignment_group_id \
<https://canvas.instructure.com/doc/api/assignment_groups.html#method.assignment_groups_api.destroy>`_
:calls: `PUT /api/v1/courses/:course_id/assignment_groups/:assignment_group_id \
<https://canvas.instructure.com/doc/api/assignment_groups.html#method.assignment_groups_api.update>`_
:rtype: :class:`canvasapi.assignment.AssignmentGroup`
"""
response = self._requester.request(
"DELETE",
"PUT",
"courses/{}/assignment_groups/{}".format(self.course_id, self.id),
_kwargs=combine_kwargs(**kwargs),
)

if "name" in response.json():
super(AssignmentGroup, self).set_attributes(response.json())

return AssignmentGroup(self._requester, response.json())


Expand All @@ -358,6 +422,7 @@ def delete(self, **kwargs):
"courses/{}/assignments/{}/overrides/{}".format(
self.course_id, self.assignment_id, self.id
),
_kwargs=combine_kwargs(**kwargs),
)

response_json = response.json()
Expand All @@ -381,6 +446,7 @@ def edit(self, **kwargs):
"courses/{}/assignments/{}/overrides/{}".format(
self.course_id, self.assignment_id, self.id
),
_kwargs=combine_kwargs(**kwargs),
)

response_json = response.json()
Expand Down
11 changes: 11 additions & 0 deletions canvasapi/authentication_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from __future__ import absolute_import, division, print_function, unicode_literals

from six import python_2_unicode_compatible

from canvasapi.canvas_object import CanvasObject


@python_2_unicode_compatible
class AuthenticationEvent(CanvasObject):
def __str__(self):
return "{} {} ({})".format(self.created_at, self.event_type, self.pseudonym_id)
Loading

0 comments on commit 7d3527d

Please sign in to comment.