Skip to content

Commit

Permalink
Merge fb11600 into 971ce43
Browse files Browse the repository at this point in the history
  • Loading branch information
theunkn0wn1 committed Mar 24, 2021
2 parents 971ce43 + fb11600 commit 4a028de
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 17 deletions.
6 changes: 3 additions & 3 deletions canvasapi/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from canvasapi.peer_review import PeerReview
from canvasapi.progress import Progress
from canvasapi.submission import Submission
from canvasapi.upload import Uploader
from canvasapi.upload import FileOrPathLike, Uploader
from canvasapi.user import User, UserDisplay
from canvasapi.util import combine_kwargs, obj_or_id

Expand Down Expand Up @@ -318,7 +318,7 @@ def submit(self, submission, file=None, **kwargs):

return Submission(self._requester, response_json)

def upload_to_submission(self, file, user="self", **kwargs):
def upload_to_submission(self, file: FileOrPathLike, user="self", **kwargs):
"""
Upload a file to a submission.
Expand All @@ -327,7 +327,7 @@ def upload_to_submission(self, file, user="self", **kwargs):
<https://canvas.instructure.com/doc/api/submissions.html#method.submissions_api.create_file>`_
:param file: The file or path of the file to upload.
:type file: file or str
:type file: FileLike
:param user: The object or ID of the related user, or 'self' for the
current user. Defaults to 'self'.
:type user: :class:`canvasapi.user.User`, int, or str
Expand Down
4 changes: 2 additions & 2 deletions canvasapi/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from canvasapi.submission import GroupedSubmission, Submission
from canvasapi.tab import Tab
from canvasapi.todo import Todo
from canvasapi.upload import Uploader
from canvasapi.upload import FileOrPathLike, Uploader
from canvasapi.usage_rights import UsageRights
from canvasapi.util import (
combine_kwargs,
Expand Down Expand Up @@ -2621,7 +2621,7 @@ def update_settings(self, **kwargs):
)
return response.json()

def upload(self, file, **kwargs):
def upload(self, file: FileOrPathLike, **kwargs):
"""
Upload a file to this course.
Expand Down
4 changes: 2 additions & 2 deletions canvasapi/folder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from canvasapi.canvas_object import CanvasObject
from canvasapi.paginated_list import PaginatedList
from canvasapi.upload import Uploader
from canvasapi.upload import FileOrPathLike, Uploader
from canvasapi.util import combine_kwargs, obj_or_id


Expand Down Expand Up @@ -119,7 +119,7 @@ def update(self, **kwargs):

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

def upload(self, file, **kwargs):
def upload(self, file: FileOrPathLike, **kwargs):
"""
Upload a file to this folder.
Expand Down
4 changes: 2 additions & 2 deletions canvasapi/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from canvasapi.license import License
from canvasapi.paginated_list import PaginatedList
from canvasapi.tab import Tab
from canvasapi.upload import FileOrPathLike, Uploader
from canvasapi.usage_rights import UsageRights
from canvasapi.util import combine_kwargs, is_multivalued, obj_or_id

Expand Down Expand Up @@ -966,7 +967,7 @@ def update_membership(self, user, **kwargs):
)
return GroupMembership(self._requester, response.json())

def upload(self, file, **kwargs):
def upload(self, file: FileOrPathLike, **kwargs):
"""
Upload a file to the group.
Only those with the 'Manage Files' permission on a group can upload files to the group.
Expand All @@ -983,7 +984,6 @@ def upload(self, file, **kwargs):
and the JSON response from the API.
:rtype: tuple
"""
from canvasapi.upload import Uploader

return Uploader(
self._requester, "groups/{}/files".format(self.id), file, **kwargs
Expand Down
4 changes: 2 additions & 2 deletions canvasapi/submission.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from canvasapi.canvas_object import CanvasObject
from canvasapi.paginated_list import PaginatedList
from canvasapi.peer_review import PeerReview
from canvasapi.upload import Uploader
from canvasapi.upload import FileOrPathLike, Uploader
from canvasapi.util import combine_kwargs, obj_or_id


Expand Down Expand Up @@ -143,7 +143,7 @@ def mark_unread(self, **kwargs):
)
return response.status_code == 204

def upload_comment(self, file, **kwargs):
def upload_comment(self, file: FileOrPathLike, **kwargs):
"""
Upload a file to attach to this submission as a comment.
Expand Down
15 changes: 11 additions & 4 deletions canvasapi/upload.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
import io
import json
import os
from typing import Union

from canvasapi.util import combine_kwargs

FileOrPathLike = Union[os.PathLike, str, io.IOBase, io.FileIO]
"""
A path or file-like object. May be either a :class:`os.PathLike`, a `str`, or a file-like object
"""


class Uploader(object):
"""
Upload a file to Canvas.
"""

def __init__(self, requester, url, file, **kwargs):
def __init__(self, requester, url, file: FileOrPathLike, **kwargs):
"""
:param requester: The :class:`canvasapi.requester.Requester` to pass requests through.
:type requester: :class:`canvasapi.requester.Requester`
:param url: The URL to upload the file to.
:type url: str
:param file: A file handler or path of the file to upload.
:type file: file or str
:type file: :class:`os.PathLike` or str
"""
if isinstance(file, str):
if isinstance(file, (os.PathLike, str)):
if not os.path.exists(file):
raise IOError("File " + file + " does not exist.")
raise IOError("File {} does not exist.".format(os.fspath(file)))
self._using_filename = True
else:
self._using_filename = False
Expand Down
4 changes: 2 additions & 2 deletions canvasapi/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from canvasapi.license import License
from canvasapi.paginated_list import PaginatedList
from canvasapi.pairing_code import PairingCode
from canvasapi.upload import Uploader
from canvasapi.upload import FileOrPathLike, Uploader
from canvasapi.usage_rights import UsageRights
from canvasapi.util import combine_kwargs, obj_or_id, obj_or_str

Expand Down Expand Up @@ -954,7 +954,7 @@ def update_settings(self, **kwargs):
)
return response.json()

def upload(self, file, **kwargs):
def upload(self, file: FileOrPathLike, **kwargs):
"""
Upload a file for a user.
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
from os import path

from setuptools import setup

# get version number
Expand Down
19 changes: 19 additions & 0 deletions tests/test_assignment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
import uuid
from pathlib import Path

import requests_mock

Expand Down Expand Up @@ -215,6 +216,24 @@ def test_submit_file(self, m):
finally:
cleanup_file(filename)

def test_submit_file_pathlib(self, m):
register_uris({"assignment": ["submit", "upload", "upload_final"]}, m)

filename = Path("testfile_assignment_{}".format(uuid.uuid4().hex))
filename.write_bytes(b"test data")

try:
sub_type = "online_upload"
sub_dict = {"submission_type": sub_type}
submission = self.assignment.submit(sub_dict, filename)

self.assertIsInstance(submission, Submission)
self.assertTrue(hasattr(submission, "submission_type"))
self.assertEqual(submission.submission_type, sub_type)

finally:
cleanup_file(filename)

def test_submit_file_wrong_type(self, m):
filename = "testfile_assignment_{}".format(uuid.uuid4().hex)
sub_type = "online_text_entry"
Expand Down
12 changes: 12 additions & 0 deletions tests/test_uploader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
import uuid
from pathlib import Path

import requests_mock

Expand Down Expand Up @@ -34,6 +35,17 @@ def test_start(self, m):
self.assertIsInstance(result[1], dict)
self.assertIn("url", result[1])

def test_start_pathlib(self, m):
requires = {"uploader": ["upload_response", "upload_response_upload_url"]}
register_uris(requires, m)

uploader = Uploader(self.requester, "upload_response", Path(self.filename))
result = uploader.start()

self.assertTrue(result[0])
self.assertIsInstance(result[1], dict)
self.assertIn("url", result[1])

def test_start_path(self, m):
requires = {"uploader": ["upload_response", "upload_response_upload_url"]}
register_uris(requires, m)
Expand Down

0 comments on commit 4a028de

Please sign in to comment.